1
2
3
4
5 package x509
6
7 import (
8 "crypto/ecdh"
9 "crypto/ecdsa"
10 "crypto/elliptic"
11 "encoding/asn1"
12 "errors"
13 "fmt"
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 privateKey, err := key.Bytes()
58 if err != nil {
59 return nil, err
60 }
61 publicKey, err := key.PublicKey.Bytes()
62 if err != nil {
63 return nil, err
64 }
65 return asn1.Marshal(ecPrivateKey{
66 Version: 1,
67 PrivateKey: privateKey,
68 NamedCurveOID: oid,
69 PublicKey: asn1.BitString{Bytes: publicKey},
70 })
71 }
72
73
74
75 func marshalECDHPrivateKey(key *ecdh.PrivateKey) ([]byte, error) {
76 return asn1.Marshal(ecPrivateKey{
77 Version: 1,
78 PrivateKey: key.Bytes(),
79 PublicKey: asn1.BitString{Bytes: key.PublicKey().Bytes()},
80 })
81 }
82
83
84
85
86
87 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
88 var privKey ecPrivateKey
89 if _, err := asn1.Unmarshal(der, &privKey); err != nil {
90 if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
91 return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
92 }
93 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
94 return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
95 }
96 return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
97 }
98 if privKey.Version != ecPrivKeyVersion {
99 return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
100 }
101
102 var curve elliptic.Curve
103 if namedCurveOID != nil {
104 curve = namedCurveFromOID(*namedCurveOID)
105 } else {
106 curve = namedCurveFromOID(privKey.NamedCurveOID)
107 }
108 if curve == nil {
109 return nil, errors.New("x509: unknown elliptic curve")
110 }
111
112 size := (curve.Params().N.BitLen() + 7) / 8
113 privateKey := make([]byte, size)
114
115
116
117 for len(privKey.PrivateKey) > len(privateKey) {
118 if privKey.PrivateKey[0] != 0 {
119 return nil, errors.New("x509: invalid private key length")
120 }
121 privKey.PrivateKey = privKey.PrivateKey[1:]
122 }
123
124
125
126
127 copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
128
129 return ecdsa.ParseRawPrivateKey(curve, privateKey)
130 }
131
View as plain text