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