diff --git a/internal/cert_manager/manager.go b/internal/cert_manager/manager.go index 2a7d4017..d876def7 100644 --- a/internal/cert_manager/manager.go +++ b/internal/cert_manager/manager.go @@ -49,6 +49,8 @@ type GetContext interface { type keyType string const keyRSA keyType = "rsa" +const keyECDSA keyType = "ecdsa" +const keyUnknown keyType = "unknown" // Interface inspired to https://godoc.org/golang.org/x/crypto/acme/autocert#Manager but not compatible guarantee type Manager struct { @@ -609,7 +611,7 @@ func storeCertificate(ctx context.Context, cache cache.Cache, certName certNameT logger.Panic("Logical error - try to save to locked certificate") } - var keyType keyType + var keyType = getKeyType(cert) var certBuf bytes.Buffer for _, block := range cert.Certificate { @@ -623,9 +625,9 @@ func storeCertificate(ctx context.Context, cache cache.Cache, certName certNameT var privateKeyBuf bytes.Buffer - switch privateKey := cert.PrivateKey.(type) { - case *rsa.PrivateKey: - keyType = keyRSA + switch keyType { + case keyRSA: + privateKey := cert.PrivateKey.(*rsa.PrivateKey) keyBytes := x509.MarshalPKCS1PrivateKey(privateKey) pemBlock := pem.Block{Type: "RSA PRIVATE KEY", Bytes: keyBytes} err := pem.Encode(&privateKeyBuf, &pemBlock) @@ -669,11 +671,28 @@ func storeCertificateMeta(ctx context.Context, storage cache.Cache, key certName ExpireDate: certificate.Leaf.NotAfter, } infoBytes, _ := json.MarshalIndent(info, "", " ") - err := storage.Put(ctx, key.String()+".json", infoBytes) + keyTypeName := string(getKeyType(certificate)) + keyName := fmt.Sprintf("%v.%v.json", key.String(), keyTypeName) + err := storage.Put(ctx, keyName, infoBytes) log.DebugDPanicCtx(ctx, err, "Save cert metadata") return err } +func getKeyType(cert *tls.Certificate) keyType { + if cert == nil || cert.PrivateKey == nil { + return keyUnknown + } + + switch cert.PrivateKey.(type) { + case *rsa.PrivateKey: + return keyRSA + case *ecdsa.PrivateKey: + return keyECDSA + default: + return keyUnknown + } +} + func getCertificate(ctx context.Context, cache cache.Cache, certName certNameType, keyType keyType) (cert *tls.Certificate, err error) { logger := zc.L(ctx) logger.Debug("Check certificate in cache") diff --git a/internal/cert_manager/manager_test.go b/internal/cert_manager/manager_test.go index e398e9e2..43eb1cbf 100644 --- a/internal/cert_manager/manager_test.go +++ b/internal/cert_manager/manager_test.go @@ -3,6 +3,7 @@ package cert_manager import ( "context" + "crypto/ecdsa" "crypto/rand" "crypto/rsa" "crypto/tls" @@ -72,6 +73,30 @@ func createTestClient(t *testing.T) *acme.Client { return &client } +func TestGetKeyType(t *testing.T) { + td := testdeep.NewT(t) + cert := &tls.Certificate{ + PrivateKey: &rsa.PrivateKey{}, + } + td.CmpDeeply(getKeyType(cert), keyRSA) + + cert = &tls.Certificate{ + PrivateKey: &ecdsa.PrivateKey{}, + } + td.CmpDeeply(getKeyType(cert), keyECDSA) + + cert = &tls.Certificate{ + PrivateKey: "string - no key", + } + td.CmpDeeply(getKeyType(cert), keyUnknown) + + cert = &tls.Certificate{} + td.CmpDeeply(getKeyType(cert), keyUnknown) + + cert = nil + td.CmpDeeply(getKeyType(cert), keyUnknown) +} + func TestStoreCertificate(t *testing.T) { ctx, flush := th.TestContext() defer flush()