]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: allow certificates and key to be in either order.
authorAdam Langley <agl@golang.org>
Thu, 13 Sep 2012 15:00:16 +0000 (11:00 -0400)
committerAdam Langley <agl@golang.org>
Thu, 13 Sep 2012 15:00:16 +0000 (11:00 -0400)
X509KeyPair wasn't really supposed to allow the certificate and
key to be in the same file, but it did work if you put the key
first. Since some HTTPS servers support loading keys and certs
like this, this change makes it work in either order.

Fixes #3986.

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/6499103

src/pkg/crypto/tls/tls.go
src/pkg/crypto/tls/tls_test.go [new file with mode: 0644]

index 09df5ad445ca86b8a1ba6c27ee85a4c2a7574d57..80f852edf7ba9d80cf1ca00518b0681588da9a36 100644 (file)
@@ -146,10 +146,16 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error)
                return
        }
 
-       keyDERBlock, _ := pem.Decode(keyPEMBlock)
-       if keyDERBlock == nil {
-               err = errors.New("crypto/tls: failed to parse key PEM data")
-               return
+       var keyDERBlock *pem.Block
+       for {
+               keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
+               if keyDERBlock == nil {
+                       err = errors.New("crypto/tls: failed to parse key PEM data")
+                       return
+               }
+               if keyDERBlock.Type != "CERTIFICATE" {
+                       break
+               }
        }
 
        // OpenSSL 0.9.8 generates PKCS#1 private keys by default, while
diff --git a/src/pkg/crypto/tls/tls_test.go b/src/pkg/crypto/tls/tls_test.go
new file mode 100644 (file)
index 0000000..5df43c3
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+       "testing"
+)
+
+var certPEM = `-----BEGIN CERTIFICATE-----
+MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
+hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
+rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
+zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
+r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
+-----END CERTIFICATE-----
+`
+
+var keyPEM = `-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
+k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
+6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
+MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
+SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
+xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
+D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
+-----END RSA PRIVATE KEY-----
+`
+
+func TestX509KeyPair(t *testing.T) {
+       _, err := X509KeyPair([]byte(keyPEM+certPEM), []byte(keyPEM+certPEM))
+       if err != nil {
+               t.Errorf("Failed to load key followed by cert: %s", err)
+       }
+
+       _, err = X509KeyPair([]byte(certPEM+keyPEM), []byte(certPEM+keyPEM))
+       if err != nil {
+               t.Errorf("Failed to load cert followed by key: %s", err)
+               println(err.Error())
+       }
+}