2018-01-21 13:18:26 +00:00
|
|
|
package pki
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/elliptic"
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/base64"
|
|
|
|
"encoding/pem"
|
|
|
|
"os"
|
2018-01-21 14:26:45 +00:00
|
|
|
"strings"
|
2018-01-21 13:18:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
2018-01-21 14:26:45 +00:00
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
2018-01-21 13:18:26 +00:00
|
|
|
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
|
|
|
|
}
|