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