gitee.com/lh-her-team/common@v1.5.1/crypto/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 "crypto/ecdsa" 9 "crypto/rsa" 10 "crypto/x509/pkix" 11 "encoding/asn1" 12 "errors" 13 "fmt" 14 15 "github.com/tjfoc/gmsm/sm2" 16 tjx509 "github.com/tjfoc/gmsm/x509" 17 ) 18 19 // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See 20 // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn 21 // and RFC 5208. 22 type pkcs8 struct { 23 Version int 24 Algo pkix.AlgorithmIdentifier 25 PrivateKey []byte 26 // optional attributes omitted. 27 } 28 29 // ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key. 30 // See RFC 5208. 31 func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { 32 var privKey pkcs8 33 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 34 return nil, err 35 } 36 switch { 37 case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA): 38 return parsePKCS8PrivateKeyRSA(&privKey) 39 case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA): 40 return parsePKCS8PrivateKeyECDSA(&privKey) 41 case privKey.Algo.Algorithm.Equal(oidPublicKeySM2): 42 return parsePKCS8PrivateKeySM2(&privKey) 43 default: 44 return nil, fmt.Errorf( 45 "x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", 46 privKey.Algo.Algorithm, 47 ) 48 } 49 } 50 51 func parsePKCS8PrivateKeyRSA(privKey *pkcs8) (key interface{}, err error) { 52 key, err = ParsePKCS1PrivateKey(privKey.PrivateKey) 53 if err != nil { 54 return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error()) 55 } 56 return key, nil 57 } 58 59 func parsePKCS8PrivateKeyECDSA(privKey *pkcs8) (key interface{}, err error) { 60 bytes := privKey.Algo.Parameters.FullBytes 61 namedCurveOID := new(asn1.ObjectIdentifier) 62 if _, err = asn1.Unmarshal(bytes, namedCurveOID); err != nil { 63 namedCurveOID = nil 64 } 65 if namedCurveOID != nil && namedCurveOID.Equal(oidNamedCurveSm2) { 66 key, err = tjx509.ParseSm2PrivateKey(privKey.PrivateKey) 67 if err != nil { 68 return nil, errors.New("x509: failed to parse sm2 private key embedded in PKCS#8: " + err.Error()) 69 } 70 } else { 71 key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) 72 if err != nil { 73 return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error()) 74 } 75 } 76 return key, nil 77 } 78 79 // nolint: ineffassign 80 func parsePKCS8PrivateKeySM2(privKey *pkcs8) (key interface{}, err error) { 81 bytes := privKey.Algo.Parameters.FullBytes 82 namedCurveOID := new(asn1.ObjectIdentifier) 83 if _, err = asn1.Unmarshal(bytes, namedCurveOID); err != nil { 84 namedCurveOID = nil 85 } 86 key, err = tjx509.ParseSm2PrivateKey(privKey.PrivateKey) 87 if err != nil { 88 return nil, errors.New("x509: failed to parse sm2 private key embedded in PKCS#8: " + err.Error()) 89 } 90 return key, nil 91 } 92 93 // MarshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form. 94 // The following key types are supported: *rsa.PrivateKey, *ecdsa.PrivateKey. 95 // Unsupported key types result in an error. 96 // 97 // See RFC 5208. 98 func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) { 99 var privKey pkcs8 100 switch k := key.(type) { 101 case *rsa.PrivateKey: 102 privKey.Algo = pkix.AlgorithmIdentifier{ 103 Algorithm: oidPublicKeyRSA, 104 Parameters: asn1.NullRawValue, 105 } 106 privKey.PrivateKey = MarshalPKCS1PrivateKey(k) 107 case *ecdsa.PrivateKey: 108 oid, ok := oidFromNamedCurve(k.Curve) 109 if !ok { 110 return nil, errors.New("x509: unknown curve while marshalling to PKCS#8") 111 } 112 oidBytes, err := asn1.Marshal(oid) 113 if err != nil { 114 return nil, errors.New("x509: failed to marshal curve OID: " + err.Error()) 115 } 116 privKey.Algo = pkix.AlgorithmIdentifier{ 117 Algorithm: oidPublicKeyECDSA, 118 Parameters: asn1.RawValue{ 119 FullBytes: oidBytes, 120 }, 121 } 122 if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil { 123 return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error()) 124 } 125 case *sm2.PrivateKey: 126 oid, ok := oidFromNamedCurve(k.Curve) 127 if !ok { 128 return nil, errors.New("x509: unknown curve while marshalling to PKCS#8") 129 } 130 oidBytes, err := asn1.Marshal(oid) 131 if err != nil { 132 return nil, errors.New("x509: failed to marshal curve OID: " + err.Error()) 133 } 134 privKey.Algo = pkix.AlgorithmIdentifier{ 135 Algorithm: oidPublicKeyECDSA, 136 Parameters: asn1.RawValue{ 137 FullBytes: oidBytes, 138 }, 139 } 140 if privKey.PrivateKey, err = tjx509.MarshalSm2UnecryptedPrivateKey(k); err != nil { 141 return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error()) 142 } 143 default: 144 return nil, fmt.Errorf("x509: unknown key type while marshalling PKCS#8: %T", key) 145 } 146 return asn1.Marshal(privKey) 147 }