소스 검색

Add -ecdsa for generating certificates with ECDSA keys

Fixes #118
Filippo Valsorda 6 년 전
부모
커밋
5bb0c47df7
3개의 변경된 파일30개의 추가작업 그리고 9개의 파일을 삭제
  1. 3 0
      README.md
  2. 20 7
      cert.go
  3. 7 2
      main.go

+ 3 - 0
README.md

@@ -125,6 +125,9 @@ mkcert supports the following root stores:
 	-cert-file FILE, -key-file FILE, -p12-file FILE
 	    Customize the output paths.
 
+	-ecdsa
+	    Generate a certificate with an ECDSA key.
+
 	-pkcs12
 	    Generate a ".p12" PKCS #12 file, also know as a ".pfx" file,
 	    containing certificate and key for legacy applications.

+ 20 - 7
cert.go

@@ -5,6 +5,9 @@
 package main
 
 import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
 	"crypto/rand"
 	"crypto/rsa"
 	"crypto/sha1"
@@ -44,8 +47,9 @@ func (m *mkcert) makeCert(hosts []string) {
 		log.Fatalln("ERROR: can't create new certificates because the CA key (rootCA-key.pem) is missing")
 	}
 
-	priv, err := rsa.GenerateKey(rand.Reader, 2048)
+	priv, err := m.generateKey(false)
 	fatalIfErr(err, "failed to generate certificate key")
+	pub := priv.(crypto.Signer).Public()
 
 	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
 	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
@@ -79,8 +83,7 @@ func (m *mkcert) makeCert(hosts []string) {
 		tpl.Subject.CommonName = hosts[0]
 	}
 
-	pub := priv.PublicKey
-	cert, err := x509.CreateCertificate(rand.Reader, tpl, m.caCert, &pub, m.caKey)
+	cert, err := x509.CreateCertificate(rand.Reader, tpl, m.caCert, pub, m.caKey)
 	fatalIfErr(err, "failed to generate certificate")
 
 	certFile, keyFile, p12File := m.fileNames(hosts)
@@ -127,6 +130,16 @@ func (m *mkcert) makeCert(hosts []string) {
 	}
 }
 
+func (m *mkcert) generateKey(rootCA bool) (crypto.PrivateKey, error) {
+	if m.ecdsa {
+		return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	}
+	if rootCA {
+		return rsa.GenerateKey(rand.Reader, 3072)
+	}
+	return rsa.GenerateKey(rand.Reader, 2048)
+}
+
 func (m *mkcert) fileNames(hosts []string) (certFile, keyFile, p12File string) {
 	defaultName := strings.Replace(hosts[0], ":", "_", -1)
 	defaultName = strings.Replace(defaultName, "*", "_wildcard", -1)
@@ -182,15 +195,15 @@ func (m *mkcert) loadCA() {
 }
 
 func (m *mkcert) newCA() {
-	priv, err := rsa.GenerateKey(rand.Reader, 3072)
+	priv, err := m.generateKey(true)
 	fatalIfErr(err, "failed to generate the CA key")
-	pub := priv.PublicKey
+	pub := priv.(crypto.Signer).Public()
 
 	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
 	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
 	fatalIfErr(err, "failed to generate serial number")
 
-	spkiASN1, err := x509.MarshalPKIXPublicKey(&pub)
+	spkiASN1, err := x509.MarshalPKIXPublicKey(pub)
 	fatalIfErr(err, "failed to encode public key")
 
 	var spki struct {
@@ -225,7 +238,7 @@ func (m *mkcert) newCA() {
 		MaxPathLenZero:        true,
 	}
 
-	cert, err := x509.CreateCertificate(rand.Reader, tpl, tpl, &pub, priv)
+	cert, err := x509.CreateCertificate(rand.Reader, tpl, tpl, pub, priv)
 	fatalIfErr(err, "failed to generate CA certificate")
 
 	privDER, err := x509.MarshalPKCS8PrivateKey(priv)

+ 7 - 2
main.go

@@ -44,6 +44,9 @@ const advancedUsage = `Advanced options:
 	-cert-file FILE, -key-file FILE, -p12-file FILE
 	    Customize the output paths.
 
+	-ecdsa
+	    Generate a certificate with an ECDSA key.
+
 	-pkcs12
 	    Generate a ".p12" PKCS #12 file, also know as a ".pfx" file,
 	    containing certificate and key for legacy applications.
@@ -63,6 +66,7 @@ func main() {
 		installFlag   = flag.Bool("install", false, "")
 		uninstallFlag = flag.Bool("uninstall", false, "")
 		pkcs12Flag    = flag.Bool("pkcs12", false, "")
+		ecdsaFlag     = flag.Bool("ecdsa", false, "")
 		helpFlag      = flag.Bool("help", false, "")
 		carootFlag    = flag.Bool("CAROOT", false, "")
 		certFileFlag  = flag.String("cert-file", "", "")
@@ -90,7 +94,8 @@ func main() {
 		log.Fatalln("ERROR: you can't set -install and -uninstall at the same time")
 	}
 	(&mkcert{
-		installMode: *installFlag, uninstallMode: *uninstallFlag, pkcs12: *pkcs12Flag,
+		installMode: *installFlag, uninstallMode: *uninstallFlag,
+		pkcs12: *pkcs12Flag, ecdsa: *ecdsaFlag,
 		certFile: *certFileFlag, keyFile: *keyFileFlag, p12File: *p12FileFlag,
 	}).Run(flag.Args())
 }
@@ -100,7 +105,7 @@ const rootKeyName = "rootCA-key.pem"
 
 type mkcert struct {
 	installMode, uninstallMode bool
-	pkcs12                     bool
+	pkcs12, ecdsa              bool
 	keyFile, certFile, p12File string
 
 	CAROOT string