github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/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 87 key, err = tjx509.ParseSm2PrivateKey(privKey.PrivateKey) 88 if err != nil { 89 return nil, errors.New("x509: failed to parse sm2 private key embedded in PKCS#8: " + err.Error()) 90 } 91 return key, nil 92 } 93 94 // MarshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form. 95 // The following key types are supported: *rsa.PrivateKey, *ecdsa.PrivateKey. 96 // Unsupported key types result in an error. 97 // 98 // See RFC 5208. 99 func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) { 100 var privKey pkcs8 101 102 switch k := key.(type) { 103 case *rsa.PrivateKey: 104 privKey.Algo = pkix.AlgorithmIdentifier{ 105 Algorithm: oidPublicKeyRSA, 106 Parameters: asn1.NullRawValue, 107 } 108 privKey.PrivateKey = MarshalPKCS1PrivateKey(k) 109 110 case *ecdsa.PrivateKey: 111 oid, ok := oidFromNamedCurve(k.Curve) 112 if !ok { 113 return nil, errors.New("x509: unknown curve while marshalling to PKCS#8") 114 } 115 116 oidBytes, err := asn1.Marshal(oid) 117 if err != nil { 118 return nil, errors.New("x509: failed to marshal curve OID: " + err.Error()) 119 } 120 121 privKey.Algo = pkix.AlgorithmIdentifier{ 122 Algorithm: oidPublicKeyECDSA, 123 Parameters: asn1.RawValue{ 124 FullBytes: oidBytes, 125 }, 126 } 127 128 if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil { 129 return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error()) 130 } 131 132 case *sm2.PrivateKey: 133 oid, ok := oidFromNamedCurve(k.Curve) 134 if !ok { 135 return nil, errors.New("x509: unknown curve while marshalling to PKCS#8") 136 } 137 138 oidBytes, err := asn1.Marshal(oid) 139 if err != nil { 140 return nil, errors.New("x509: failed to marshal curve OID: " + err.Error()) 141 } 142 143 privKey.Algo = pkix.AlgorithmIdentifier{ 144 Algorithm: oidPublicKeyECDSA, 145 Parameters: asn1.RawValue{ 146 FullBytes: oidBytes, 147 }, 148 } 149 150 if privKey.PrivateKey, err = tjx509.MarshalSm2UnecryptedPrivateKey(k); err != nil { 151 return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error()) 152 } 153 154 default: 155 return nil, fmt.Errorf("x509: unknown key type while marshalling PKCS#8: %T", key) 156 } 157 158 return asn1.Marshal(privKey) 159 }