crypto/tls: allow certificates and key to be in either order.

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
This commit is contained in:
Adam Langley 2012-09-13 11:00:16 -04:00
parent a0608ba23c
commit d263b7d38c
2 changed files with 57 additions and 4 deletions

8
tls.go
View File

@ -146,11 +146,17 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error)
return return
} }
keyDERBlock, _ := pem.Decode(keyPEMBlock) var keyDERBlock *pem.Block
for {
keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
if keyDERBlock == nil { if keyDERBlock == nil {
err = errors.New("crypto/tls: failed to parse key PEM data") err = errors.New("crypto/tls: failed to parse key PEM data")
return return
} }
if keyDERBlock.Type != "CERTIFICATE" {
break
}
}
// OpenSSL 0.9.8 generates PKCS#1 private keys by default, while // OpenSSL 0.9.8 generates PKCS#1 private keys by default, while
// OpenSSL 1.0.0 generates PKCS#8 keys. We try both. // OpenSSL 1.0.0 generates PKCS#8 keys. We try both.

47
tls_test.go Normal file
View File

@ -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())
}
}