diff --git a/certcrypto/crypto.go b/certcrypto/crypto.go index bb99d7d2..c9d0c109 100644 --- a/certcrypto/crypto.go +++ b/certcrypto/crypto.go @@ -124,6 +124,10 @@ func GenerateCSR(privateKey crypto.PrivateKey, domain string, san []string, must } func PEMEncode(data interface{}) []byte { + return pem.EncodeToMemory(PEMBlock(data)) +} + +func PEMBlock(data interface{}) *pem.Block { var pemBlock *pem.Block switch key := data.(type) { case *ecdsa.PrivateKey: @@ -137,7 +141,7 @@ func PEMEncode(data interface{}) []byte { pemBlock = &pem.Block{Type: "CERTIFICATE", Bytes: []byte(data.(DERCertificateBytes))} } - return pem.EncodeToMemory(pemBlock) + return pemBlock } func pemDecode(data []byte) (*pem.Block, error) { diff --git a/cmd/accounts_storage.go b/cmd/accounts_storage.go index 4c1f18ec..1469cad1 100644 --- a/cmd/accounts_storage.go +++ b/cmd/accounts_storage.go @@ -2,9 +2,6 @@ package cmd import ( "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" "crypto/x509" "encoding/json" "encoding/pem" @@ -17,6 +14,7 @@ import ( "strings" "github.com/urfave/cli" + "github.com/xenolf/lego/certcrypto" "github.com/xenolf/lego/lego" "github.com/xenolf/lego/log" "github.com/xenolf/lego/registration" @@ -157,14 +155,14 @@ func (s *AccountsStorage) LoadAccount(privateKey crypto.PrivateKey) *Account { return &account } -func (s *AccountsStorage) GetPrivateKey() crypto.PrivateKey { +func (s *AccountsStorage) GetPrivateKey(keyType certcrypto.KeyType) crypto.PrivateKey { accKeyPath := filepath.Join(s.keysPath, s.userID+".key") if _, err := os.Stat(accKeyPath); os.IsNotExist(err) { - log.Printf("No key found for account %s. Generating a curve P384 EC key.", s.userID) + log.Printf("No key found for account %s. Generating a %s key.", s.userID, keyType) s.createKeysFolder() - privateKey, err := generatePrivateKey(accKeyPath) + privateKey, err := generatePrivateKey(accKeyPath, keyType) if err != nil { log.Fatalf("Could not generate RSA private account key for account %s: %v", s.userID, err) } @@ -187,26 +185,20 @@ func (s *AccountsStorage) createKeysFolder() { } } -func generatePrivateKey(file string) (crypto.PrivateKey, error) { - privateKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) +func generatePrivateKey(file string, keyType certcrypto.KeyType) (crypto.PrivateKey, error) { + privateKey, err := certcrypto.GeneratePrivateKey(keyType) if err != nil { return nil, err } - keyBytes, err := x509.MarshalECPrivateKey(privateKey) - if err != nil { - return nil, err - } - - pemKey := pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes} - certOut, err := os.Create(file) if err != nil { return nil, err } defer certOut.Close() - err = pem.Encode(certOut, &pemKey) + pemKey := certcrypto.PEMBlock(privateKey) + err = pem.Encode(certOut, pemKey) if err != nil { return nil, err } diff --git a/cmd/flags.go b/cmd/flags.go index 432e8c76..84d3d5b1 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -42,7 +42,7 @@ func CreateFlags(defaultPath string) []cli.Flag { }, cli.StringFlag{ Name: "key-type, k", - Value: "rsa2048", + Value: "ec384", Usage: "Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384.", }, cli.StringFlag{ diff --git a/cmd/setup.go b/cmd/setup.go index efcc28b3..976b3cbb 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -19,7 +19,8 @@ import ( const filePerm os.FileMode = 0600 func setup(ctx *cli.Context, accountsStorage *AccountsStorage) (*Account, *lego.Client) { - privateKey := accountsStorage.GetPrivateKey() + keyType := getKeyType(ctx) + privateKey := accountsStorage.GetPrivateKey(keyType) var account *Account if accountsStorage.ExistsAccountFilePath() { @@ -28,17 +29,17 @@ func setup(ctx *cli.Context, accountsStorage *AccountsStorage) (*Account, *lego. account = &Account{Email: accountsStorage.GetUserID(), key: privateKey} } - client := newClient(ctx, account) + client := newClient(ctx, account, keyType) return account, client } -func newClient(ctx *cli.Context, acc registration.User) *lego.Client { +func newClient(ctx *cli.Context, acc registration.User, keyType certcrypto.KeyType) *lego.Client { config := lego.NewConfig(acc) config.CADirURL = ctx.GlobalString("server") config.Certificate = lego.CertificateConfig{ - KeyType: getKeyType(ctx), + KeyType: keyType, Timeout: time.Duration(ctx.GlobalInt("cert.timeout")) * time.Second, } config.UserAgent = fmt.Sprintf("lego-cli/%s", ctx.App.Version)