...
1
2
3
4
5 package x509
6
7 import (
8 "crypto/ecdsa"
9 "crypto/elliptic"
10 "errors"
11 "fmt"
12 "math/big"
13
14 "github.com/google/certificate-transparency-go/asn1"
15 )
16
17 const ecPrivKeyVersion = 1
18
19
20
21
22
23
24
25
26
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
35
36
37 func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) {
38 return parseECPrivateKey(nil, der)
39 }
40
41
42
43
44
45
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
56
57 func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) {
58 privateKeyBytes := key.D.Bytes()
59 paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
60 copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes)
61
62 return asn1.Marshal(ecPrivateKey{
63 Version: 1,
64 PrivateKey: paddedPrivateKey,
65 NamedCurveOID: oid,
66 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
67 })
68 }
69
70
71
72
73
74 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
75 var privKey ecPrivateKey
76 if _, err := asn1.Unmarshal(der, &privKey); err != nil {
77 if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
78 return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
79 }
80 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
81 return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
82 }
83 return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
84 }
85 if privKey.Version != ecPrivKeyVersion {
86 return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
87 }
88
89 var nfe NonFatalErrors
90 var curve elliptic.Curve
91 if namedCurveOID != nil {
92 curve = namedCurveFromOID(*namedCurveOID, &nfe)
93 } else {
94 curve = namedCurveFromOID(privKey.NamedCurveOID, &nfe)
95 }
96 if curve == nil {
97 return nil, errors.New("x509: unknown elliptic curve")
98 }
99
100 k := new(big.Int).SetBytes(privKey.PrivateKey)
101 curveOrder := curve.Params().N
102 if k.Cmp(curveOrder) >= 0 {
103 return nil, errors.New("x509: invalid elliptic curve private key value")
104 }
105 priv := new(ecdsa.PrivateKey)
106 priv.Curve = curve
107 priv.D = k
108
109 privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
110
111
112
113 for len(privKey.PrivateKey) > len(privateKey) {
114 if privKey.PrivateKey[0] != 0 {
115 return nil, errors.New("x509: invalid private key length")
116 }
117 privKey.PrivateKey = privKey.PrivateKey[1:]
118 }
119
120
121
122
123 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
124 priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
125
126 return priv, nil
127 }
128
View as plain text