github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/ct/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/ecdsa" 9 "crypto/elliptic" 10 // START CT CHANGES 11 "github.com/zmap/zcrypto/ct/asn1" 12 // START CT CHANGES 13 "errors" 14 "fmt" 15 "math/big" 16 ) 17 18 const ecPrivKeyVersion = 1 19 20 // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. 21 // References: 22 // 23 // RFC5915 24 // SEC1 - http://www.secg.org/download/aid-780/sec1-v2.pdf 25 // 26 // Per RFC5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in 27 // most cases it is not. 28 type ecPrivateKey struct { 29 Version int 30 PrivateKey []byte 31 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 32 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 33 } 34 35 // ParseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 36 func ParseECPrivateKey(der []byte) (key *ecdsa.PrivateKey, err error) { 37 return parseECPrivateKey(nil, der) 38 } 39 40 // MarshalECPrivateKey marshals an EC private key into ASN.1, DER format. 41 func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { 42 oid, ok := oidFromNamedCurve(key.Curve) 43 if !ok { 44 return nil, errors.New("x509: unknown elliptic curve") 45 } 46 return asn1.Marshal(ecPrivateKey{ 47 Version: 1, 48 PrivateKey: key.D.Bytes(), 49 NamedCurveOID: oid, 50 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, 51 }) 52 } 53 54 // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 55 // The OID for the named curve may be provided from another source (such as 56 // the PKCS8 container) - if it is provided then use this instead of the OID 57 // that may exist in the EC private key structure. 58 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) { 59 var privKey ecPrivateKey 60 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 61 return nil, errors.New("x509: failed to parse EC private key: " + err.Error()) 62 } 63 if privKey.Version != ecPrivKeyVersion { 64 return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) 65 } 66 67 var curve elliptic.Curve 68 if namedCurveOID != nil { 69 curve = namedCurveFromOID(*namedCurveOID) 70 } else { 71 curve = namedCurveFromOID(privKey.NamedCurveOID) 72 } 73 if curve == nil { 74 return nil, errors.New("x509: unknown elliptic curve") 75 } 76 77 k := new(big.Int).SetBytes(privKey.PrivateKey) 78 if k.Cmp(curve.Params().N) >= 0 { 79 return nil, errors.New("x509: invalid elliptic curve private key value") 80 } 81 priv := new(ecdsa.PrivateKey) 82 priv.Curve = curve 83 priv.D = k 84 priv.X, priv.Y = curve.ScalarBaseMult(privKey.PrivateKey) 85 86 return priv, nil 87 }