Skip to content

Commit 0bdf260

Browse files
authored
Rotate tls CA with missing subject key id, re-use private key (#1012)
* Rotate tls CA with missing subject key id, re-use private key * Check for authority key id changes
1 parent 29a4292 commit 0bdf260

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

pkg/util/certificates.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package util
22

33
import (
4+
"bytes"
45
cryptorand "crypto/rand"
56
"crypto/rsa"
67
"crypto/x509"
@@ -375,10 +376,38 @@ func (cf *CertificateFactory) UserCert(principal *models.Principal, apiURL strin
375376
}
376377

377378
func loadOrCreateCA(kluster *v1.Kluster, name string, cert, key *string, certUpdates *[]CertUpdates) (*Bundle, error) {
378-
if *cert != "" && *key != "" {
379+
var existingKey *rsa.PrivateKey
380+
regenerate := false
381+
382+
if name == "TLS" && *cert != "" {
383+
block, _ := pem.Decode([]byte(*cert))
384+
if block == nil {
385+
return nil, fmt.Errorf("Failed to decode TLS CA certificate")
386+
}
387+
caCert, err := x509.ParseCertificate(block.Bytes)
388+
if err != nil {
389+
return nil, fmt.Errorf("Failed to parse TLS CA certificate: %s", err)
390+
}
391+
if caCert.SubjectKeyId == nil {
392+
regenerate = true
393+
394+
var isRSAKey bool
395+
k, err := keyutil.ParsePrivateKeyPEM([]byte(*key))
396+
if err != nil {
397+
return nil, err
398+
}
399+
existingKey, isRSAKey = k.(*rsa.PrivateKey)
400+
if !isRSAKey {
401+
return nil, errors.New("Key does not seem to be of type RSA")
402+
}
403+
}
404+
}
405+
406+
if *cert != "" && *key != "" && !regenerate {
379407
return NewBundle([]byte(*key), []byte(*cert))
380408
}
381-
caBundle, err := createCA(kluster.Name, name)
409+
410+
caBundle, err := createCA(kluster.Name, name, existingKey)
382411
if err != nil {
383412
return nil, err
384413
}
@@ -483,10 +512,17 @@ func ensureServerCertificate(ca *Bundle, cn string, dnsNames []string, ips []net
483512
return nil
484513
}
485514

486-
func createCA(klusterName, name string) (*Bundle, error) {
487-
privateKey, err := NewPrivateKey()
488-
if err != nil {
489-
return nil, fmt.Errorf("Failed to generate private key for %s ca: %s", name, err)
515+
func createCA(klusterName, name string, existingKey *rsa.PrivateKey) (*Bundle, error) {
516+
var privateKey *rsa.PrivateKey
517+
var err error
518+
519+
if existingKey != nil {
520+
privateKey = existingKey
521+
} else {
522+
privateKey, err = NewPrivateKey()
523+
if err != nil {
524+
return nil, fmt.Errorf("Failed to generate private key for %s ca: %s", name, err)
525+
}
490526
}
491527

492528
now := time.Now()
@@ -523,6 +559,10 @@ func isCertChangedOrExpires(origCert, newCert, caCert *x509.Certificate, duratio
523559
return "SAN IP changes: " + strings.Join(IPSliceDiff(origCert.IPAddresses, newCert.IPAddresses), " "), true
524560
}
525561

562+
if !bytes.Equal(origCert.AuthorityKeyId, newCert.AuthorityKeyId) {
563+
return fmt.Sprintf("Authority key identifier changes: %v != %v", origCert.AuthorityKeyId, newCert.AuthorityKeyId), true
564+
}
565+
526566
expire := time.Now().Add(duration)
527567
if expire.After(origCert.NotAfter) {
528568
return fmt.Sprintf("Certificate expires at %s", origCert.NotAfter), true

0 commit comments

Comments
 (0)