github.com/fisco-bcos/crypto@v0.0.0-20200202032121-bd8ab0b5d4f1/x509/pkcs8.go (about) 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. 4 5 package x509 6 7 import ( 8 "github.com/FISCO-BCOS/crypto/ecdsa" 9 "crypto/ed25519" 10 "crypto/rsa" 11 "crypto/x509/pkix" 12 "encoding/asn1" 13 "errors" 14 "fmt" 15 ) 16 17 // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See 18 // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn 19 // and RFC 5208. 20 type pkcs8 struct { 21 Version int 22 Algo pkix.AlgorithmIdentifier 23 PrivateKey []byte 24 // optional attributes omitted. 25 } 26 27 // ParsePKCS8PrivateKey parses an unencrypted private key in PKCS#8, ASN.1 DER form. 28 // 29 // It returns a *rsa.PrivateKey, a *ecdsa.PrivateKey, or a ed25519.PrivateKey. 30 // More types might be supported in the future. 31 // 32 // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY". 33 func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { 34 var privKey pkcs8 35 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 36 if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil { 37 return nil, errors.New("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)") 38 } 39 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil { 40 return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)") 41 } 42 return nil, err 43 } 44 switch { 45 case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA): 46 key, err = ParsePKCS1PrivateKey(privKey.PrivateKey) 47 if err != nil { 48 return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error()) 49 } 50 return key, nil 51 52 case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA): 53 bytes := privKey.Algo.Parameters.FullBytes 54 namedCurveOID := new(asn1.ObjectIdentifier) 55 if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { 56 namedCurveOID = nil 57 } 58 key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) 59 if err != nil { 60 return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error()) 61 } 62 return key, nil 63 64 case privKey.Algo.Algorithm.Equal(oidPublicKeyEd25519): 65 if l := len(privKey.Algo.Parameters.FullBytes); l != 0 { 66 return nil, errors.New("x509: invalid Ed25519 private key parameters") 67 } 68 var curvePrivateKey []byte 69 if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil { 70 return nil, fmt.Errorf("x509: invalid Ed25519 private key: %v", err) 71 } 72 if l := len(curvePrivateKey); l != ed25519.SeedSize { 73 return nil, fmt.Errorf("x509: invalid Ed25519 private key length: %d", l) 74 } 75 return ed25519.NewKeyFromSeed(curvePrivateKey), nil 76 77 default: 78 return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) 79 } 80 } 81 82 // MarshalPKCS8PrivateKey converts an RSA private key to PKCS#8, ASN.1 DER form. 83 // 84 // The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey 85 // and ed25519.PrivateKey. Unsupported key types result in an error. 86 // 87 // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY". 88 func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) { 89 var privKey pkcs8 90 91 switch k := key.(type) { 92 case *rsa.PrivateKey: 93 privKey.Algo = pkix.AlgorithmIdentifier{ 94 Algorithm: oidPublicKeyRSA, 95 Parameters: asn1.NullRawValue, 96 } 97 privKey.PrivateKey = MarshalPKCS1PrivateKey(k) 98 99 case *ecdsa.PrivateKey: 100 oid, ok := oidFromNamedCurve(k.Curve) 101 if !ok { 102 return nil, errors.New("x509: unknown curve while marshaling to PKCS#8") 103 } 104 105 oidBytes, err := asn1.Marshal(oid) 106 if err != nil { 107 return nil, errors.New("x509: failed to marshal curve OID: " + err.Error()) 108 } 109 110 privKey.Algo = pkix.AlgorithmIdentifier{ 111 Algorithm: oidPublicKeyECDSA, 112 Parameters: asn1.RawValue{ 113 FullBytes: oidBytes, 114 }, 115 } 116 117 if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil { 118 return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error()) 119 } 120 121 case ed25519.PrivateKey: 122 privKey.Algo = pkix.AlgorithmIdentifier{ 123 Algorithm: oidPublicKeyEd25519, 124 } 125 curvePrivateKey, err := asn1.Marshal(k.Seed()) 126 if err != nil { 127 return nil, fmt.Errorf("x509: failed to marshal private key: %v", err) 128 } 129 privKey.PrivateKey = curvePrivateKey 130 131 default: 132 return nil, fmt.Errorf("x509: unknown key type while marshaling PKCS#8: %T", key) 133 } 134 135 return asn1.Marshal(privKey) 136 }