1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See
17 // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
21 Algo pkix
.AlgorithmIdentifier
23 // optional attributes omitted.
26 // ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key.
28 func ParsePKCS8PrivateKey(der
[]byte) (key
interface{}, err error
) {
30 if _
, err
:= asn1
.Unmarshal(der
, &privKey
); err
!= nil {
34 case privKey
.Algo
.Algorithm
.Equal(oidPublicKeyRSA
):
35 key
, err
= ParsePKCS1PrivateKey(privKey
.PrivateKey
)
37 return nil, errors
.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err
.Error())
41 case privKey
.Algo
.Algorithm
.Equal(oidPublicKeyECDSA
):
42 bytes
:= privKey
.Algo
.Parameters
.FullBytes
43 namedCurveOID
:= new(asn1
.ObjectIdentifier
)
44 if _
, err
:= asn1
.Unmarshal(bytes
, namedCurveOID
); err
!= nil {
47 key
, err
= parseECPrivateKey(namedCurveOID
, privKey
.PrivateKey
)
49 return nil, errors
.New("x509: failed to parse EC private key embedded in PKCS#8: " + err
.Error())
54 return nil, fmt
.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey
.Algo
.Algorithm
)
58 // MarshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form.
59 // The following key types are supported: *rsa.PrivateKey, *ecdsa.PublicKey.
60 // Unsupported key types result in an error.
63 func MarshalPKCS8PrivateKey(key
interface{}) ([]byte, error
) {
66 switch k
:= key
.(type) {
68 privKey
.Algo
= pkix
.AlgorithmIdentifier
{
69 Algorithm
: oidPublicKeyRSA
,
70 Parameters
: asn1
.NullRawValue
,
72 privKey
.PrivateKey
= MarshalPKCS1PrivateKey(k
)
74 case *ecdsa
.PrivateKey
:
75 oid
, ok
:= oidFromNamedCurve(k
.Curve
)
77 return nil, errors
.New("x509: unknown curve while marshalling to PKCS#8")
80 oidBytes
, err
:= asn1
.Marshal(oid
)
82 return nil, errors
.New("x509: failed to marshal curve OID: " + err
.Error())
85 privKey
.Algo
= pkix
.AlgorithmIdentifier
{
86 Algorithm
: oidPublicKeyECDSA
,
87 Parameters
: asn1
.RawValue
{
92 if privKey
.PrivateKey
, err
= marshalECPrivateKeyWithOID(k
, nil); err
!= nil {
93 return nil, errors
.New("x509: failed to marshal EC private key while building PKCS#8: " + err
.Error())
97 return nil, fmt
.Errorf("x509: unknown key type while marshalling PKCS#8: %T", key
)
100 return asn1
.Marshal(privKey
)