gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/x509/sec1.go (about) 1 // Copyright 2012 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 /* 8 x509/sec1.go 椭圆曲线公私钥与其SEC 1, ASN.1 DER字节数组之间的相互转换 9 目前支持sm2, ecdsa 10 11 ParseECPrivateKey : 将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 12 MarshalECPrivateKey : 将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 13 */ 14 15 import ( 16 "crypto/ecdsa" 17 "crypto/elliptic" 18 "encoding/asn1" 19 "errors" 20 "fmt" 21 "gitee.com/ks-custle/core-gm/ecdsa_ext" 22 "math/big" 23 24 "gitee.com/ks-custle/core-gm/sm2" 25 ) 26 27 const ecPrivKeyVersion = 1 28 29 // ecPrivateKey 椭圆曲线私钥结构体, 添加用于识别私钥类型的字段(目前支持sm2/ecdsa/ecdsa_ext) 30 // 31 // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. 32 // 33 // References: 34 // 35 // RFC 5915 36 // SEC1 - http://www.secg.org/sec1-v2.pdf 37 // 38 // Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in 39 // most cases it is not. 40 type ecPrivateKey struct { 41 Version int 42 PrivateKey []byte 43 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 44 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 45 46 // 用于识别私钥类型的字段 47 PrivType string `asn1:"optional,explicit,tag:2"` 48 } 49 50 // ParseECPrivateKey 将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 51 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 52 // 53 // ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form. 54 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 55 func ParseECPrivateKey(der []byte) (interface{}, error) { 56 return parseECPrivateKey(nil, der) 57 } 58 59 // MarshalECPrivateKey 将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 60 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 61 // 62 // MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form. 63 // 64 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 65 // For a more flexible key format which is not EC specific, use 66 // MarshalPKCS8PrivateKey. 67 func MarshalECPrivateKey(key interface{}) ([]byte, error) { 68 switch priv := key.(type) { 69 case *ecdsa.PrivateKey: 70 oid, ok := oidFromNamedCurve(priv.Curve) 71 if !ok { 72 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 73 } 74 if oid.Equal(oidNamedCurveP256SM2) { 75 return nil, errors.New("gmx509.MarshalECPrivateKey: not ecdsa curves") 76 } 77 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 78 return asn1.Marshal(ecPrivateKey{ 79 Version: ecPrivKeyVersion, 80 PrivateKey: priv.D.FillBytes(privateKey), 81 NamedCurveOID: oid, 82 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 83 PrivType: "ecdsa", 84 }) 85 case *ecdsa_ext.PrivateKey: 86 oid, ok := oidFromNamedCurve(priv.Curve) 87 if !ok { 88 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 89 } 90 if oid.Equal(oidNamedCurveP256SM2) { 91 return nil, errors.New("gmx509.MarshalECPrivateKey: not ecdsa curves") 92 } 93 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 94 return asn1.Marshal(ecPrivateKey{ 95 Version: ecPrivKeyVersion, 96 PrivateKey: priv.D.FillBytes(privateKey), 97 NamedCurveOID: oid, 98 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 99 PrivType: "ecdsa_ext", 100 }) 101 case *sm2.PrivateKey: 102 oid, ok := oidFromNamedCurve(priv.Curve) 103 if !ok { 104 return nil, errors.New("gmx509.MarshalECPrivateKey: unknown elliptic curve") 105 } 106 if !oid.Equal(oidNamedCurveP256SM2) { 107 return nil, errors.New("gmx509.MarshalECPrivateKey: not sm2 curve") 108 } 109 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 110 return asn1.Marshal(ecPrivateKey{ 111 Version: ecPrivKeyVersion, 112 PrivateKey: priv.D.FillBytes(privateKey), 113 NamedCurveOID: oid, 114 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 115 PrivType: "sm2", 116 }) 117 // var ecPriv ecPrivateKey 118 // ecPriv.Version = ecPrivKeyVersion 119 // ecPriv.NamedCurveOID = oidNamedCurveP256SM2 120 // ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)} 121 // ecPriv.PrivateKey = priv.D.Bytes() 122 // return asn1.Marshal(ecPriv) 123 } 124 return nil, errors.New("x509: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey") 125 } 126 127 // parseECPrivateKey根据namedCurveOID获取对应的椭圆曲线,并将SEC 1, ASN.1 DER格式字节数组转为EC(椭圆曲线)私钥 128 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 129 // 130 // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 131 // The OID for the named curve may be provided from another source (such as 132 // the PKCS8 container) - if it is provided then use this instead of the OID 133 // that may exist in the EC private key structure. 134 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key interface{}, err error) { 135 var privKey ecPrivateKey 136 // 尝试将 der 反序列化到 privKey 137 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 138 if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil { 139 return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)") 140 } 141 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil { 142 return nil, errors.New("gmx509.parseECPrivateKey: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)") 143 } 144 return nil, fmt.Errorf("gmx509.parseECPrivateKey: failed to parse EC private key: %s", err.Error()) 145 } 146 // 检查版本 147 if privKey.Version != ecPrivKeyVersion { 148 return nil, fmt.Errorf("gmx509.parseECPrivateKey: unknown EC private key version %d", privKey.Version) 149 } 150 var curve elliptic.Curve 151 // namedCurveOID有可能为nil,因为ecdsa在其序列化(pkcs8.go的MarshalPKCS8PrivateKey)分支里并没有传入oid到序列化结构中去。 152 if namedCurveOID != nil { 153 // 根据namedCurveOID获取曲线 154 curve = namedCurveFromOID(*namedCurveOID) 155 } else { 156 // namedCurveOID为空则使用私钥的NamedCurveOID 157 curve = namedCurveFromOID(privKey.NamedCurveOID) 158 } 159 if curve == nil { 160 return nil, errors.New("gmx509.parseECPrivateKey: unknown elliptic curve") 161 } 162 // 检查私钥数值是否小于曲线参数N 163 k := new(big.Int).SetBytes(privKey.PrivateKey) 164 curveOrder := curve.Params().N 165 if k.Cmp(curveOrder) >= 0 { 166 return nil, errors.New("gmx509.parseECPrivateKey: invalid elliptic curve private key value") 167 } 168 // 根据曲线选择生成对应完整私钥 169 switch curve { 170 case sm2.P256Sm2(): 171 priv := new(sm2.PrivateKey) 172 priv.Curve = curve 173 priv.D = k 174 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 175 // Some private keys have leading zero padding. This is invalid 176 // according to [SEC1], but this code will ignore it. 177 for len(privKey.PrivateKey) > len(privateKey) { 178 if privKey.PrivateKey[0] != 0 { 179 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 180 } 181 privKey.PrivateKey = privKey.PrivateKey[1:] 182 } 183 // Some private keys remove all leading zeros, this is also invalid 184 // according to [SEC1] but since OpenSSL used to do this, we ignore 185 // this too. 186 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 187 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 188 return priv, nil 189 case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521(): 190 switch privKey.PrivType { 191 case "ecdsa", "": 192 priv := new(ecdsa.PrivateKey) 193 priv.Curve = curve 194 priv.D = k 195 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 196 // Some private keys have leading zero padding. This is invalid 197 // according to [SEC1], but this code will ignore it. 198 for len(privKey.PrivateKey) > len(privateKey) { 199 if privKey.PrivateKey[0] != 0 { 200 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 201 } 202 privKey.PrivateKey = privKey.PrivateKey[1:] 203 } 204 // Some private keys remove all leading zeros, this is also invalid 205 // according to [SEC1] but since OpenSSL used to do this, we ignore 206 // this too. 207 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 208 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 209 return priv, nil 210 case "ecdsa_ext": 211 priv := new(ecdsa_ext.PrivateKey) 212 priv.Curve = curve 213 priv.D = k 214 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 215 // Some private keys have leading zero padding. This is invalid 216 // according to [SEC1], but this code will ignore it. 217 for len(privKey.PrivateKey) > len(privateKey) { 218 if privKey.PrivateKey[0] != 0 { 219 return nil, errors.New("gmx509.parseECPrivateKey: invalid private key length") 220 } 221 privKey.PrivateKey = privKey.PrivateKey[1:] 222 } 223 // Some private keys remove all leading zeros, this is also invalid 224 // according to [SEC1] but since OpenSSL used to do this, we ignore 225 // this too. 226 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 227 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 228 return priv, nil 229 } 230 } 231 return nil, errors.New("gmx509.parseECPrivateKey: failed to parseECPrivateKey: Unknown curve") 232 } 233 234 // marshalECPrivateKeyWithOID根据oid将EC(椭圆曲线)私钥转为SEC 1, ASN.1 DER格式字节数组 235 // 私钥目前支持: *sm2.PrivateKey, *ecdsa.PrivateKey, *ecdsa_ext.PrivateKey 236 // 237 // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and 238 // sets the curve ID to the given OID, or omits it if OID is nil. 239 func marshalECPrivateKeyWithOID(key interface{}, oid asn1.ObjectIdentifier) ([]byte, error) { 240 switch priv := key.(type) { 241 case *ecdsa.PrivateKey: 242 if oid.Equal(oidNamedCurveP256SM2) { 243 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not ecdsa curves") 244 } 245 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 246 return asn1.Marshal(ecPrivateKey{ 247 Version: ecPrivKeyVersion, 248 PrivateKey: priv.D.FillBytes(privateKey), 249 NamedCurveOID: oid, 250 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 251 PrivType: "ecdsa", 252 }) 253 case *ecdsa_ext.PrivateKey: 254 if oid.Equal(oidNamedCurveP256SM2) { 255 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not ecdsa curves") 256 } 257 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 258 return asn1.Marshal(ecPrivateKey{ 259 Version: ecPrivKeyVersion, 260 PrivateKey: priv.D.FillBytes(privateKey), 261 NamedCurveOID: oid, 262 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 263 PrivType: "ecdsa_ext", 264 }) 265 case *sm2.PrivateKey: 266 if !oid.Equal(oidNamedCurveP256SM2) { 267 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: not sm2 curve") 268 } 269 privateKey := make([]byte, (priv.Curve.Params().N.BitLen()+7)/8) 270 return asn1.Marshal(ecPrivateKey{ 271 Version: ecPrivKeyVersion, 272 PrivateKey: priv.D.FillBytes(privateKey), 273 NamedCurveOID: oid, 274 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)}, 275 PrivType: "sm2", 276 }) 277 // var ecPriv ecPrivateKey 278 // ecPriv.Version = ecPrivKeyVersion 279 // ecPriv.NamedCurveOID = oidNamedCurveP256SM2 280 // ecPriv.PublicKey = asn1.BitString{Bytes: elliptic.Marshal(priv.Curve, priv.X, priv.Y)} 281 // ecPriv.PrivateKey = priv.D.Bytes() 282 // return asn1.Marshal(ecPriv) 283 } 284 return nil, errors.New("gmx509.marshalECPrivateKeyWithOID: failed to marshalECPrivateKeyWithOID: Unknown PrivateKey") 285 }