diff --git a/certificate/_fixtures/certificate-valid-pkcs8.pem b/certificate/_fixtures/certificate-valid-pkcs8.pem new file mode 100644 index 00000000..0bf15798 --- /dev/null +++ b/certificate/_fixtures/certificate-valid-pkcs8.pem @@ -0,0 +1,60 @@ +Bag Attributes + localKeyID: 8C 1A 9F 00 66 BD 24 42 B9 5D 1E EB FE 5E 8B CA 04 3D 73 83 + friendlyName: APNS/2 Private Key +subject=/C=NZ/ST=Wellington/L=Wellington/O=Internet Widgits Pty Ltd/OU=9ZEH62KRVV/CN=APNS/2 Development IOS Push Services: com.sideshow.Apns2 +issuer=/C=NZ/ST=Wellington/L=Wellington/O=APNS/2 Inc./OU=APNS/2 Worldwide Developer Relations/CN=APNS/2 Worldwide Developer Relations Certification Authority +-----BEGIN CERTIFICATE----- +MIID6zCCAtMCAQIwDQYJKoZIhvcNAQELBQAwgcMxCzAJBgNVBAYTAk5aMRMwEQYD +VQQIEwpXZWxsaW5ndG9uMRMwEQYDVQQHEwpXZWxsaW5ndG9uMRQwEgYDVQQKEwtB +UE5TLzIgSW5jLjEtMCsGA1UECxMkQVBOUy8yIFdvcmxkd2lkZSBEZXZlbG9wZXIg +UmVsYXRpb25zMUUwQwYDVQQDEzxBUE5TLzIgV29ybGR3aWRlIERldmVsb3BlciBS +ZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTYwMTA4MDgzNDMw +WhcNMjYwMTA1MDgzNDMwWjCBsjELMAkGA1UEBhMCTloxEzARBgNVBAgTCldlbGxp +bmd0b24xEzARBgNVBAcTCldlbGxpbmd0b24xITAfBgNVBAoTGEludGVybmV0IFdp +ZGdpdHMgUHR5IEx0ZDETMBEGA1UECxMKOVpFSDYyS1JWVjFBMD8GA1UEAxM4QVBO +Uy8yIERldmVsb3BtZW50IElPUyBQdXNoIFNlcnZpY2VzOiBjb20uc2lkZXNob3cu +QXBuczIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDY0c1TKB5oZPwQ +7t1CwMIrvqB6GIU3tPy6RhckZXTkOB8YeBWJ7UKfCz8HGHFVomBP0T5OUbeqQzqW +YJbQzZ8a6ZMszbL0lO4X9++3Oi5/TtAwOUOK8rOFN25m2KfsayHQZ/4vWStK2Fwm +5aJbGLlpH/b/7z1D4vhmMgoBuT1IuyhGiyFxlZ9EtTloFvsqM1E5fYZOSZACyXTa +K4vdgbQMgUVsI714FAgLTlK0UeiRkmKm3pdbtfVbrthzI+IHXKItUIy+Fn20PRMh +dSnaztSz7tgBWCIx22qvcYogHWiOgUYIM772zE2y8UVOr8DsiRlsOHSA7EI4MJcQ +G2FUq2Z/AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGyfyO2HMgcdeBcz3bt5BILX +f7RA2/UmVIwcKR1qotTsF+PnBmcILeyOQgDe9tGU5cRc79kDt3JRmMYROFIMgFRf +Wf22uOKtho7GQQaKvG+bkgMVdYFRlBHnF+KeqKH81qb9p+CT4Iw0GehIL1DijFLR +VIAIBYpz4oBPCIE1ISVT+Fgaf3JAh59kbPbNw9AIDxaBtP8EuzSTNwfbxoGbCobS +Wi1U8IsCwQFt8tM1m4ZXD1CcZIrGdryeAhVkvKIJRiU5QYWI2nqZN+JqQucm9ad0 +mYO5mJkIobUa4+ZJhCPKEdmgpFbRGk0wVuaDM9Cv6P2srsYAjaO4y3VP0GvNKRI= +-----END CERTIFICATE----- +Bag Attributes + localKeyID: 8C 1A 9F 00 66 BD 24 42 B9 5D 1E EB FE 5E 8B CA 04 3D 73 83 + friendlyName: APNS/2 Private Key +Key Attributes: +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDY0c1TKB5oZPwQ +7t1CwMIrvqB6GIU3tPy6RhckZXTkOB8YeBWJ7UKfCz8HGHFVomBP0T5OUbeqQzqW +YJbQzZ8a6ZMszbL0lO4X9++3Oi5/TtAwOUOK8rOFN25m2KfsayHQZ/4vWStK2Fwm +5aJbGLlpH/b/7z1D4vhmMgoBuT1IuyhGiyFxlZ9EtTloFvsqM1E5fYZOSZACyXTa +K4vdgbQMgUVsI714FAgLTlK0UeiRkmKm3pdbtfVbrthzI+IHXKItUIy+Fn20PRMh +dSnaztSz7tgBWCIx22qvcYogHWiOgUYIM772zE2y8UVOr8DsiRlsOHSA7EI4MJcQ +G2FUq2Z/AgMBAAECggEBAJbxkIj44Bp7W0SKln0XZtY/csctdOjwVhV0ID5VZ4hO +Tc+iIhSQmZXRpYJSEOy2C2jl2gN6PmwJO6te+P/Kdp6sx6okVhaR7CPBlyAvIBm/ +C47W/t+n0TTH/1MYN+eOOc815q6d3FbRw23M5jeXQdUezL0ml7dANwAmi/LhO/n6 +EVjiQPFQEazKO+FJxWAqDm0uQlyWbew678sbIuqnA0jc4kB0wi5UPg3YFnVo4Rqn +qanbLwh7T9HhhZxpnkDg/DvFQ+XpJdz265r/vxBMRG08Lp6PIIGITTlrybdDeK53 +de2eXLCzYrCGAEB8TozjNH9/c5AHtkhcyHJmmZlnDnECgYEA9ifzgiuUhB61ZB+8 +90zsrOCHpQMcK6CeUIOCHBilEkaLyEx+5lXE0itgAnMtgNDTWUUlEmBZdNxurP00 +HPWeGD5w07PX8pj7fx65157oM1ibO0/uMM/aOdpL522MLyEBc5ucWob42KUwMsu7 +ppGasloiZuNKt/IuITqa8nu7zWcCgYEA4X2D3fBnSYvWuTazlbAcZM1T8do62ZZL +jPuQDt/hBpG5v4zCmlmaYNk8emJlfsE9xnOI49CH7GfsipEahBYEvKQFW3zNkWgt +kmgJHefreV7HkDin/Q+nWAVmtH7Ffw9hWizfJ56JbI8qxdc1zSzlDAdlxfpZvwQd +OFNcYIF61ykCgYAx5AkL0g9o89xp7bDcIsA5jcyQWmAES6qqwOzHCwux95BvSWnS +/4FD47yy4mtPl4OurUAFSHf5IpBgCXXdhL7FRSqTDflv1yfqLO0X0cJYXdYgoGOz +iv09Coyl3GM0TilAKEL5ai/XoStysC5ZZVuIWJJubhT/0VseKwWqrf9zcwKBgH6/ +NK4+AXDfv7SgQNW1BmDK4ZKink3MI299v/38bdppc0Vuc7ya/SHPOiV4xaA4Mucn +7hxQDPcfe2BwK71vOv5mG/TO9CX1rxgKjoVW5Y91bStuDU87y064yoBOeejv1kL/ +0ffNL2XsG5jVXZKU17KpPdXI4UVzpJESmmxMm6XxAoGADGdAHwwDvM9Qu7VyXJok +t20R1E+QpY3uUpim1zR79Ud9KwrGx5aR+qLOBdnnWRBOtPplvodhF/ALWYxcdZEp +HJiMCcLFWKbphB34pVPj2JEMMCIgWgwYDiK+9wiWd6o5lk8MigonrQiM78NkdaTD +mYuNoitP6pDdcAZ0kDXeFyY= +-----END PRIVATE KEY----- diff --git a/certificate/certificate.go b/certificate/certificate.go index 46d5bd09..cfd78def 100644 --- a/certificate/certificate.go +++ b/certificate/certificate.go @@ -16,11 +16,11 @@ import ( // Possible errors when parsing a certificate. var ( - ErrFailedToDecryptKey = errors.New("failed to decrypt private key") - ErrFailedToParsePKCS1PrivateKey = errors.New("failed to parse PKCS1 private key") - ErrFailedToParseCertificate = errors.New("failed to parse certificate PEM data") - ErrNoPrivateKey = errors.New("no private key") - ErrNoCertificate = errors.New("no certificate") + ErrFailedToDecryptKey = errors.New("failed to decrypt private key") + ErrFailedToParsePrivateKey = errors.New("failed to parse private key") + ErrFailedToParseCertificate = errors.New("failed to parse certificate PEM data") + ErrNoPrivateKey = errors.New("no private key") + ErrNoCertificate = errors.New("no certificate") ) // FromP12File loads a PKCS#12 certificate from a local file and returns a @@ -120,9 +120,14 @@ func unencryptPrivateKey(block *pem.Block, password string) (crypto.PrivateKey, } func parsePrivateKey(bytes []byte) (crypto.PrivateKey, error) { + var key crypto.PrivateKey key, err := x509.ParsePKCS1PrivateKey(bytes) - if err != nil { - return nil, ErrFailedToParsePKCS1PrivateKey + if err == nil { + return key, nil + } + key, err = x509.ParsePKCS8PrivateKey(bytes) + if err == nil { + return key, nil } - return key, nil + return nil, ErrFailedToParsePrivateKey } diff --git a/certificate/certificate_test.go b/certificate/certificate_test.go index 7b1bf2a5..06290d62 100644 --- a/certificate/certificate_test.go +++ b/certificate/certificate_test.go @@ -58,6 +58,19 @@ func TestValidCertificateFromPemBytes(t *testing.T) { assert.Nil(t, verifyHostname(cer)) } +func TestValidCertificateFromPemFileWithPKCS8PrivateKey(t *testing.T) { + cer, err := certificate.FromPemFile("_fixtures/certificate-valid-pkcs8.pem", "") + assert.NoError(t, err) + assert.Nil(t, verifyHostname(cer)) +} + +func TestValidCertificateFromPemBytesWithPKCS8PrivateKey(t *testing.T) { + bytes, _ := ioutil.ReadFile("_fixtures/certificate-valid-pkcs8.pem") + cer, err := certificate.FromPemBytes(bytes, "") + assert.NoError(t, err) + assert.Nil(t, verifyHostname(cer)) +} + func TestEncryptedValidCertificateFromPemFile(t *testing.T) { cer, err := certificate.FromPemFile("_fixtures/certificate-valid-encrypted.pem", "password") assert.NoError(t, err) @@ -79,7 +92,7 @@ func TestBadPasswordPemFile(t *testing.T) { func TestBadKeyPemFile(t *testing.T) { cer, err := certificate.FromPemFile("_fixtures/certificate-bad-key.pem", "") assert.Equal(t, tls.Certificate{}, cer) - assert.Equal(t, certificate.ErrFailedToParsePKCS1PrivateKey, err) + assert.Equal(t, certificate.ErrFailedToParsePrivateKey, err) } func TestNoKeyPemFile(t *testing.T) {