github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/crypto/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 import ( 8 "crypto/ecdh" 9 "crypto/ecdsa" 10 "crypto/elliptic" 11 "encoding/asn1" 12 "errors" 13 "fmt" 14 "math/big" 15 ) 16 17 const ecPrivKeyVersion = 1 18 19 // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. 20 // References: 21 // 22 // RFC 5915 23 // SEC1 - http://www.secg.org/sec1-v2.pdf 24 // 25 // Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in 26 // most cases it is not. 27 type ecPrivateKey struct { 28 Version int 29 PrivateKey []byte 30 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 31 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 32 } 33 34 // ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form. 35 // 36 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 37 func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) { 38 return parseECPrivateKey(nil, der) 39 } 40 41 // MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form. 42 // 43 // This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". 44 // For a more flexible key format which is not EC specific, use 45 // [MarshalPKCS8PrivateKey]. 46 func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { 47 oid, ok := oidFromNamedCurve(key.Curve) 48 if !ok { 49 return nil, errors.New("x509: unknown elliptic curve") 50 } 51 52 return marshalECPrivateKeyWithOID(key, oid) 53 } 54 55 // marshalECPrivateKeyWithOID marshals an EC private key into ASN.1, DER format and 56 // sets the curve ID to the given OID, or omits it if OID is nil. 57 func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) { 58 if !key.Curve.IsOnCurve(key.X, key.Y) { 59 return nil, errors.New("invalid elliptic key public key") 60 } 61 privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) 62 return asn1.Marshal(ecPrivateKey{ 63 Version: 1, 64 PrivateKey: key.D.FillBytes(privateKey), 65 NamedCurveOID: oid, 66 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, 67 }) 68 } 69 70 // marshalECDHPrivateKey marshals an EC private key into ASN.1, DER format 71 // suitable for NIST curves. 72 func marshalECDHPrivateKey(key *ecdh.PrivateKey) ([]byte, error) { 73 return asn1.Marshal(ecPrivateKey{ 74 Version: 1, 75 PrivateKey: key.Bytes(), 76 PublicKey: asn1.BitString{Bytes: key.PublicKey().Bytes()}, 77 }) 78 } 79 80 // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 81 // The OID for the named curve may be provided from another source (such as 82 // the PKCS8 container) - if it is provided then use this instead of the OID 83 // that may exist in the EC private key structure. 84 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) { 85 var privKey ecPrivateKey 86 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 87 if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil { 88 return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)") 89 } 90 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil { 91 return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)") 92 } 93 return nil, errors.New("x509: failed to parse EC private key: " + err.Error()) 94 } 95 if privKey.Version != ecPrivKeyVersion { 96 return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) 97 } 98 99 var curve elliptic.Curve 100 if namedCurveOID != nil { 101 curve = namedCurveFromOID(*namedCurveOID) 102 } else { 103 curve = namedCurveFromOID(privKey.NamedCurveOID) 104 } 105 if curve == nil { 106 return nil, errors.New("x509: unknown elliptic curve") 107 } 108 109 k := new(big.Int).SetBytes(privKey.PrivateKey) 110 curveOrder := curve.Params().N 111 if k.Cmp(curveOrder) >= 0 { 112 return nil, errors.New("x509: invalid elliptic curve private key value") 113 } 114 priv := new(ecdsa.PrivateKey) 115 priv.Curve = curve 116 priv.D = k 117 118 privateKey := make([]byte, (curveOrder.BitLen()+7)/8) 119 120 // Some private keys have leading zero padding. This is invalid 121 // according to [SEC1], but this code will ignore it. 122 for len(privKey.PrivateKey) > len(privateKey) { 123 if privKey.PrivateKey[0] != 0 { 124 return nil, errors.New("x509: invalid private key length") 125 } 126 privKey.PrivateKey = privKey.PrivateKey[1:] 127 } 128 129 // Some private keys remove all leading zeros, this is also invalid 130 // according to [SEC1] but since OpenSSL used to do this, we ignore 131 // this too. 132 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) 133 priv.X, priv.Y = curve.ScalarBaseMult(privateKey) 134 135 return priv, nil 136 }