Skip to content

Commit 5aa178a

Browse files
authored
Add option to reuse key material (#78)
It needs to be opt-in via a command-line option. The code currently does not check whether the read key has the requested algorithm / key size.
1 parent 9c2925f commit 5aa178a

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

main.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,29 @@ type issuer struct {
3838
cert *x509.Certificate
3939
}
4040

41-
func getIssuer(keyFile, certFile string, alg x509.PublicKeyAlgorithm) (*issuer, error) {
41+
func getIssuer(keyFile, certFile string, alg x509.PublicKeyAlgorithm, reuseKey bool) (*issuer, error) {
4242
keyContents, keyErr := ioutil.ReadFile(keyFile)
4343
certContents, certErr := ioutil.ReadFile(certFile)
4444
if os.IsNotExist(keyErr) && os.IsNotExist(certErr) {
4545
err := makeIssuer(keyFile, certFile, alg)
4646
if err != nil {
4747
return nil, err
4848
}
49-
return getIssuer(keyFile, certFile, alg)
49+
return getIssuer(keyFile, certFile, alg, false)
5050
} else if keyErr != nil {
5151
return nil, fmt.Errorf("%s (but %s exists)", keyErr, certFile)
5252
} else if certErr != nil {
53+
if reuseKey {
54+
key, err := readPrivateKey(keyContents)
55+
if err != nil {
56+
return nil, fmt.Errorf("reading private key from %s: %s", keyFile, err)
57+
}
58+
_, err = makeRootCert(key, certFile)
59+
if err != nil {
60+
return nil, err
61+
}
62+
return getIssuer(keyFile, certFile, alg, false)
63+
}
5364
return nil, fmt.Errorf("%s (but %s exists)", certErr, keyFile)
5465
}
5566
key, err := readPrivateKey(keyContents)
@@ -240,7 +251,7 @@ func calculateSKID(pubKey crypto.PublicKey) ([]byte, error) {
240251
return skid[:], nil
241252
}
242253

243-
func sign(iss *issuer, domains []string, ipAddresses []string, alg x509.PublicKeyAlgorithm) (*x509.Certificate, error) {
254+
func sign(iss *issuer, domains []string, ipAddresses []string, alg x509.PublicKeyAlgorithm, reuseKey bool) (*x509.Certificate, error) {
244255
var cn string
245256
if len(domains) > 0 {
246257
cn = domains[0]
@@ -254,9 +265,22 @@ func sign(iss *issuer, domains []string, ipAddresses []string, alg x509.PublicKe
254265
if err != nil && !os.IsExist(err) {
255266
return nil, err
256267
}
257-
key, err := makeKey(fmt.Sprintf("%s/key.pem", cnFolder), alg)
258-
if err != nil {
259-
return nil, err
268+
var keyFile = fmt.Sprintf("%s/key.pem", cnFolder)
269+
var key crypto.Signer
270+
if reuseKey {
271+
keyContents, keyErr := ioutil.ReadFile(keyFile)
272+
if keyErr == nil {
273+
key, err = readPrivateKey(keyContents)
274+
if err != nil {
275+
return nil, fmt.Errorf("reading private key from %s: %s", keyFile, err)
276+
}
277+
}
278+
}
279+
if key == nil {
280+
key, err = makeKey(keyFile, alg)
281+
if err != nil {
282+
return nil, err
283+
}
260284
}
261285
parsedIPs, err := parseIPs(ipAddresses)
262286
if err != nil {
@@ -315,6 +339,7 @@ func main2() error {
315339
var caKey = flag.String("ca-key", "minica-key.pem", "Root private key filename, PEM encoded.")
316340
var caCert = flag.String("ca-cert", "minica.pem", "Root certificate filename, PEM encoded.")
317341
var caAlg = flag.String("ca-alg", "ecdsa", "Algorithm for any new keypairs: RSA or ECDSA.")
342+
var reuseKeys = flag.Bool("reuse-keys", false, "If only the key file exists, reuse it to generate the certificate")
318343
var domains = flag.String("domains", "", "Comma separated domain names to include as Server Alternative Names.")
319344
var ipAddresses = flag.String("ip-addresses", "", "Comma separated IP addresses to include as Server Alternative Names.")
320345
flag.Usage = func() {
@@ -371,10 +396,10 @@ will not overwrite existing keys or certificates.
371396
os.Exit(1)
372397
}
373398
}
374-
issuer, err := getIssuer(*caKey, *caCert, alg)
399+
issuer, err := getIssuer(*caKey, *caCert, alg, *reuseKeys)
375400
if err != nil {
376401
return err
377402
}
378-
_, err = sign(issuer, domainSlice, ipSlice, alg)
403+
_, err = sign(issuer, domainSlice, ipSlice, alg, *reuseKeys)
379404
return err
380405
}

0 commit comments

Comments
 (0)