mirror of
https://github.com/golang/go
synced 2024-11-20 00:44:45 -07:00
crypto/x509, crypto/tls: support PKCS#8 private keys.
OpenSSL 1.0.0 has switched to generating PKCS#8 format private keys by default. This change allows http.ListenAndServeTLS to work with either types of keys. See http://groups.google.com/group/golang-nuts/browse_thread/thread/84715b5f0c9e3c30/63a8a27b53e102a6 R=bradfitz CC=golang-dev https://golang.org/cl/5416059
This commit is contained in:
parent
85255f9942
commit
7c161b05aa
@ -157,12 +157,23 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes)
|
// OpenSSL 0.9.8 generates PKCS#1 private keys by default, while
|
||||||
if err != nil {
|
// OpenSSL 1.0.0 generates PKCS#8 keys. We try both.
|
||||||
|
var key *rsa.PrivateKey
|
||||||
|
if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err != nil {
|
||||||
|
var privKey interface{}
|
||||||
|
if privKey, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err != nil {
|
||||||
err = errors.New("crypto/tls: failed to parse key: " + err.Error())
|
err = errors.New("crypto/tls: failed to parse key: " + err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
if key, ok = privKey.(*rsa.PrivateKey); !ok {
|
||||||
|
err = errors.New("crypto/tls: found non-RSA private key in PKCS#8 wrapping")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cert.PrivateKey = key
|
cert.PrivateKey = key
|
||||||
|
|
||||||
// We don't need to parse the public key for TLS, but we so do anyway
|
// We don't need to parse the public key for TLS, but we so do anyway
|
||||||
|
@ -8,6 +8,7 @@ TARG=crypto/x509
|
|||||||
GOFILES=\
|
GOFILES=\
|
||||||
cert_pool.go\
|
cert_pool.go\
|
||||||
pkcs1.go\
|
pkcs1.go\
|
||||||
|
pkcs8.go\
|
||||||
verify.go\
|
verify.go\
|
||||||
x509.go\
|
x509.go\
|
||||||
|
|
||||||
|
42
src/pkg/crypto/x509/pkcs8.go
Normal file
42
src/pkg/crypto/x509/pkcs8.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2011 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 x509
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/asn1"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See
|
||||||
|
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn.
|
||||||
|
type pkcs8 struct {
|
||||||
|
Version int
|
||||||
|
Algo pkix.AlgorithmIdentifier
|
||||||
|
PrivateKey []byte
|
||||||
|
// optional attributes omitted.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key. See
|
||||||
|
// http://www.rsa.com/rsalabs/node.asp?id=2130
|
||||||
|
func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
|
||||||
|
var privKey pkcs8
|
||||||
|
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case privKey.Algo.Algorithm.Equal(oidRSA):
|
||||||
|
key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("crypto/x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
|
||||||
|
}
|
||||||
|
return key, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("crypto/x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
20
src/pkg/crypto/x509/pkcs8_test.go
Normal file
20
src/pkg/crypto/x509/pkcs8_test.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2011 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 x509
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var pkcs8PrivateKeyHex = `30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031`
|
||||||
|
|
||||||
|
func TestPKCS8(t *testing.T) {
|
||||||
|
derBytes, _ := hex.DecodeString(pkcs8PrivateKeyHex)
|
||||||
|
_, err := ParsePKCS8PrivateKey(derBytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to decode PKCS8 key: %s", err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user