@@ -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