|
1 | 1 | package util |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | cryptorand "crypto/rand" |
5 | 6 | "crypto/rsa" |
6 | 7 | "crypto/x509" |
@@ -375,10 +376,38 @@ func (cf *CertificateFactory) UserCert(principal *models.Principal, apiURL strin |
375 | 376 | } |
376 | 377 |
|
377 | 378 | 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 { |
379 | 407 | return NewBundle([]byte(*key), []byte(*cert)) |
380 | 408 | } |
381 | | - caBundle, err := createCA(kluster.Name, name) |
| 409 | + |
| 410 | + caBundle, err := createCA(kluster.Name, name, existingKey) |
382 | 411 | if err != nil { |
383 | 412 | return nil, err |
384 | 413 | } |
@@ -483,10 +512,17 @@ func ensureServerCertificate(ca *Bundle, cn string, dnsNames []string, ips []net |
483 | 512 | return nil |
484 | 513 | } |
485 | 514 |
|
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 | + } |
490 | 526 | } |
491 | 527 |
|
492 | 528 | now := time.Now() |
@@ -523,6 +559,10 @@ func isCertChangedOrExpires(origCert, newCert, caCert *x509.Certificate, duratio |
523 | 559 | return "SAN IP changes: " + strings.Join(IPSliceDiff(origCert.IPAddresses, newCert.IPAddresses), " "), true |
524 | 560 | } |
525 | 561 |
|
| 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 | + |
526 | 566 | expire := time.Now().Add(duration) |
527 | 567 | if expire.After(origCert.NotAfter) { |
528 | 568 | return fmt.Sprintf("Certificate expires at %s", origCert.NotAfter), true |
|
0 commit comments