From 0248557d4a81bb03784f80b7c8f626fc976cfc80 Mon Sep 17 00:00:00 2001 From: Michael Morello Date: Fri, 21 Aug 2020 12:26:04 +0200 Subject: [PATCH 1/2] Support user provided encrypted keys --- pkg/controller/common/certificates/pem.go | 6 ++++ pkg/controller/common/certificates/secret.go | 2 +- .../common/certificates/secret_test.go | 11 +++++++ .../certificates/testdata/encrypted.key | 30 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 pkg/controller/common/certificates/testdata/encrypted.key diff --git a/pkg/controller/common/certificates/pem.go b/pkg/controller/common/certificates/pem.go index 7a65d9e1b1..496ee3e7ec 100644 --- a/pkg/controller/common/certificates/pem.go +++ b/pkg/controller/common/certificates/pem.go @@ -13,6 +13,8 @@ import ( "github.com/pkg/errors" ) +var ErrEncryptedPrivateKey = errors.New("encrypted private key") + // ParsePEMCerts returns a list of certificates from the given PEM certs data // Based on the code of x509.CertPool.AppendCertsFromPEM (https://golang.org/src/crypto/x509/cert_pool.go) // We don't rely on x509.CertPool.AppendCertsFromPEM directly here since it returns an interface from which @@ -57,6 +59,7 @@ func EncodePEMPrivateKey(privateKey rsa.PrivateKey) []byte { } // ParsePEMPrivateKey parses the given private key in the PEM format +// ErrEncryptedPrivateKey is returned as an error if the private key is encrypted. func ParsePEMPrivateKey(pemData []byte) (*rsa.PrivateKey, error) { block, _ := pem.Decode(pemData) if block == nil { @@ -64,6 +67,9 @@ func ParsePEMPrivateKey(pemData []byte) (*rsa.PrivateKey, error) { } switch { + case x509.IsEncryptedPEMBlock(block): + // Private key is encrypted, do not attempt to parse it + return nil, ErrEncryptedPrivateKey case block.Type == "PRIVATE KEY": return parsePKCS8PrivateKey(block.Bytes) case block.Type == "RSA PRIVATE KEY" && len(block.Headers) == 0: diff --git a/pkg/controller/common/certificates/secret.go b/pkg/controller/common/certificates/secret.go index d95d0ca8d5..50e47e5dd3 100644 --- a/pkg/controller/common/certificates/secret.go +++ b/pkg/controller/common/certificates/secret.go @@ -90,7 +90,7 @@ func (s CertificatesSecret) Validate() error { return pkgerrors.Errorf("can't find private key %s in %s/%s", KeyFileName, s.Namespace, s.Name) } _, err := ParsePEMPrivateKey(key) - if err != nil { + if err != nil && err != ErrEncryptedPrivateKey { return err } // Validate host certificate diff --git a/pkg/controller/common/certificates/secret_test.go b/pkg/controller/common/certificates/secret_test.go index db7c8f7d4f..614ddaee6e 100644 --- a/pkg/controller/common/certificates/secret_test.go +++ b/pkg/controller/common/certificates/secret_test.go @@ -73,6 +73,7 @@ func TestCertificatesSecret_Validate(t *testing.T) { tls := loadFileBytes("tls.crt") key := loadFileBytes("tls.key") corruptedKey := loadFileBytes("corrupted.key") + encryptedKey := loadFileBytes("encrypted.key") tests := []struct { name string @@ -128,6 +129,16 @@ func TestCertificatesSecret_Validate(t *testing.T) { }, { name: "Corrupted key", + s: CertificatesSecret{ + Data: map[string][]byte{ + CertFileName: tls, + KeyFileName: encryptedKey, + }, + }, + wantErr: false, + }, + { + name: "Encrypted private key", s: CertificatesSecret{ Data: map[string][]byte{ CertFileName: tls, diff --git a/pkg/controller/common/certificates/testdata/encrypted.key b/pkg/controller/common/certificates/testdata/encrypted.key new file mode 100644 index 0000000000..2099b1a989 --- /dev/null +++ b/pkg/controller/common/certificates/testdata/encrypted.key @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,C65BA14BBA311477F2CD6A1096EA608A + +9SHgmDq6nVicp7Q45Ufeb1CMTZn9R2DICvS3Pv1bqboGSJ6JazkG37YeF+N1T76p +5niP1sJQiKSk4CHy7IXZkPEFX5AXIJJ1wdby0ZinNsR8IyKiv0A6l8JTJKeF35ID +cAYqgCepav+qfDvfbSI4SRM6qsU55MVZwXm+/n5uBhEErq4evQNwdt2FfL15u5V3 +9IiciTJ3MB2mMjZSXfrop2W9S1zsrKo4nD/TNiP4OFnHDLwBHCxseLUxI37PIusZ +8vbpzZaZb++ehiQ08c7qBFCNpX5T9xz2MsiVI2mhnEPSwH7xxWYduRRhABbXb3Fc +Hd3mGKOE5+e9Sa1PY6c07vDEquQ6Uv4pukM5QB7e3vfZNevYl6FLApGqmQUn8Io5 +PajV9SrnTGYXF9DPq5YRQPYdAcvNRoyXbbUW82a0yCPCh1GXe7QewsI28tcxTYHg +PJp7bdPFj65slw7NjS08Ra2VGlqGlAcBLFAt/rUILzoS6QKMPRiV+tSrI3Fjc3px +Z4KJzTWmCpHUvvn65FGeElDeZpVknSZ2F35C09GuQyfibaQTZjCoc1cK+tbUDjfa +2pJW32T4+Dp6vhYv+pq+TqXMNsNDAqLG1rqOnngd0UbckZmGiAQOwUi3zB67Do+s +pPwnlkdqnRTYPHtYWJvZuhu8UW228wQRrOLdnAwkCa8wCGePVpotyBzM9t1Cm+We +iteulyIwBmr+h4kFxOkjRAzYgFBLB89IWrjVZuqSPWveG32MBkhXmwd6uo2T2f18 +A4hc/gh2lFsEnRltEltL9aBPZgs1xZg4v/8mRPvw+ZUOGySa4kT4MtCinxpLZitR +v0KeLLYUuJB8QlMBTH1JD+O1MTmxIXLG7VmJVGMMbZd+zWC1KSpEqHElWr2nMnBK +Nj2f/Rd4oEbIVapC4HTP0njwcckeODGF0sPulhDhDUWwY20ode5Ywqfw5X4OHsrj +PBPe8264CfdQk/hl9hEPidEO1ycNe5PaG4UcOC7XWZ3kRL19dQmh5dk0ri68+eXj +038cpiYul6TbTbZNxIG7JcXiBdfVVpXKQsBJGOQNunlpea+2+ym+hi6jNZgwkYj/ +9eT8HYgzXCf0gEnA9BYNEJWSteyKWKzkXHcu4JmHzQ0lzvSryvc64jpgNnpjo0qq +0jwjWRctmlbMaTo/nzEH5n3qUXaipFENPSHgeXyx83f6STs3lQEq+UnJUwxFaRvM +5NjAfMTyS+frJ8WV8gnK6Z3mBJf4tRy+ID9779PLR0Do4uP0ci0gGUG6zu4o349L +JOSXIvFL8DM2uA8EP47c7ILY0lZSrZlK6wUemeErELbf4g/qzK5G+Ky2rItiBX4a +tRZoMhDrtEa7qa/vAqhbG0X/P3Rcrm0Ceixh4iBsEV/+adyMA/WtNO5TVwmVfpQK +Zfsp5cjkR1tatSCd/+m1MsvqApShEzxOk2jojk1sFWqGJ+9ev8hkoUUZyNFq1xOy +FcborTmArlGLoTDqFhb10LaA6Yyk6Zpd6B9LEYmbslGPC2VUUvAh4TW7py99vY2u +44ZJXxti0UHuUSLpzwyQhjYWtF+4U2uoqKZ5nx0GuBG6zMeh5oNGmVoWuy5TR7/4 +-----END RSA PRIVATE KEY----- \ No newline at end of file From 890277bc23c4901e01280306990e59d365d3e49f Mon Sep 17 00:00:00 2001 From: Michael Morello Date: Wed, 26 Aug 2020 08:10:28 +0200 Subject: [PATCH 2/2] Use errors.Is to compare error --- pkg/controller/common/certificates/secret.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/controller/common/certificates/secret.go b/pkg/controller/common/certificates/secret.go index 50e47e5dd3..a08340f601 100644 --- a/pkg/controller/common/certificates/secret.go +++ b/pkg/controller/common/certificates/secret.go @@ -5,6 +5,8 @@ package certificates import ( + "errors" + pkgerrors "github.com/pkg/errors" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -90,7 +92,7 @@ func (s CertificatesSecret) Validate() error { return pkgerrors.Errorf("can't find private key %s in %s/%s", KeyFileName, s.Namespace, s.Name) } _, err := ParsePEMPrivateKey(key) - if err != nil && err != ErrEncryptedPrivateKey { + if err != nil && !errors.Is(err, ErrEncryptedPrivateKey) { return err } // Validate host certificate