package pki import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/x509" "encoding/base64" "encoding/pem" "os" "strings" ) var PKIDir string func GeneratePassword() (password string, err error) { // This will make a 12 chars long password b := make([]byte, 9) if _, err = rand.Read(b); err != nil { return } password = base64.StdEncoding.EncodeToString(b) // Avoid hard to read characters for _, i := range [][2]string{ {"v", "*"}, {"u", "("}, {"l", "%"}, {"1", "?"}, {"o", "@"}, {"O", "!"}, {"0", ">"}, // This one is to avoid problem with openssl {"/", "^"}, } { password = strings.Replace(password, i[0], i[1], -1) } return } func GeneratePrivKey() (pub *ecdsa.PublicKey, priv *ecdsa.PrivateKey, err error) { if priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader); err == nil { pub = &priv.PublicKey } return } func saveCertificate(path string, cert []byte) error { if certOut, err := os.Create(path); err != nil { return err } else { pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: cert}) certOut.Close() } return nil } func savePrivateKey(path string, private *ecdsa.PrivateKey) error { if keyOut, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600); err != nil { return err } else if key_b, err := x509.MarshalECPrivateKey(private); err != nil { return err } else { pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: key_b}) keyOut.Close() } return nil } func savePrivateKeyEncrypted(path string, private *ecdsa.PrivateKey, password string) error { if password == "" { return savePrivateKey(path, private) } if keyOut, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600); err != nil { return err } else { defer keyOut.Close() if key_b, err := x509.MarshalECPrivateKey(private); err != nil { return err } else if key_c, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", key_b, []byte(password), x509.PEMCipherAES256); err != nil { return err } else { pem.Encode(keyOut, key_c) } } return nil }