1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package crypto11
23
24 import (
25 "bytes"
26 "crypto"
27 "crypto/ecdsa"
28 "crypto/elliptic"
29 "encoding/asn1"
30 "io"
31 "math/big"
32
33 "github.com/miekg/pkcs11"
34 "github.com/pkg/errors"
35 )
36
37
38
39
40
41 var errUnsupportedEllipticCurve = errors.New("unsupported elliptic curve")
42
43
44 type pkcs11PrivateKeyECDSA struct {
45 pkcs11PrivateKey
46 }
47
48
49 type curveInfo struct {
50
51 oid []byte
52
53
54 curve elliptic.Curve
55 }
56
57
58 func mustMarshal(val interface{}) []byte {
59 if b, err := asn1.Marshal(val); err != nil {
60 panic(err)
61 } else {
62 return b
63 }
64 }
65
66
67
68
69
70
71
72
73
74 var wellKnownCurves = map[string]curveInfo{
75 "P-192": {
76 mustMarshal(asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 1}),
77 nil,
78 },
79 "P-224": {
80 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 33}),
81 elliptic.P224(),
82 },
83 "P-256": {
84 mustMarshal(asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}),
85 elliptic.P256(),
86 },
87 "P-384": {
88 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 34}),
89 elliptic.P384(),
90 },
91 "P-521": {
92 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 35}),
93 elliptic.P521(),
94 },
95
96 "K-163": {
97 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 1}),
98 nil,
99 },
100 "K-233": {
101 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 26}),
102 nil,
103 },
104 "K-283": {
105 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 16}),
106 nil,
107 },
108 "K-409": {
109 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 36}),
110 nil,
111 },
112 "K-571": {
113 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 38}),
114 nil,
115 },
116
117 "B-163": {
118 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 15}),
119 nil,
120 },
121 "B-233": {
122 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 27}),
123 nil,
124 },
125 "B-283": {
126 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 17}),
127 nil,
128 },
129 "B-409": {
130 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 37}),
131 nil,
132 },
133 "B-571": {
134 mustMarshal(asn1.ObjectIdentifier{1, 3, 132, 0, 39}),
135 nil,
136 },
137 }
138
139 func marshalEcParams(c elliptic.Curve) ([]byte, error) {
140 if ci, ok := wellKnownCurves[c.Params().Name]; ok {
141 return ci.oid, nil
142 }
143
144 return nil, errUnsupportedEllipticCurve
145 }
146
147 func unmarshalEcParams(b []byte) (elliptic.Curve, error) {
148
149 for _, ci := range wellKnownCurves {
150 if bytes.Equal(b, ci.oid) {
151 if ci.curve != nil {
152 return ci.curve, nil
153 }
154 return nil, errUnsupportedEllipticCurve
155 }
156 }
157
158 return nil, errUnsupportedEllipticCurve
159 }
160
161 func unmarshalEcPoint(b []byte, c elliptic.Curve) (*big.Int, *big.Int, error) {
162 var pointBytes []byte
163 extra, err := asn1.Unmarshal(b, &pointBytes)
164 if err != nil {
165 return nil, nil, errors.WithMessage(err, "elliptic curve point is invalid ASN.1")
166 }
167
168 if len(extra) > 0 {
169
170 return nil, nil, errors.New("unexpected data found when parsing elliptic curve point")
171 }
172
173 x, y := elliptic.Unmarshal(c, pointBytes)
174 if x == nil || y == nil {
175 return nil, nil, errors.New("failed to parse elliptic curve point")
176 }
177 return x, y, nil
178 }
179
180
181 func exportECDSAPublicKey(session *pkcs11Session, pubHandle pkcs11.ObjectHandle) (crypto.PublicKey, error) {
182 var err error
183 var attributes []*pkcs11.Attribute
184 var pub ecdsa.PublicKey
185 template := []*pkcs11.Attribute{
186 pkcs11.NewAttribute(pkcs11.CKA_ECDSA_PARAMS, nil),
187 pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil),
188 }
189 if attributes, err = session.ctx.GetAttributeValue(session.handle, pubHandle, template); err != nil {
190 return nil, err
191 }
192 if pub.Curve, err = unmarshalEcParams(attributes[0].Value); err != nil {
193 return nil, err
194 }
195 if pub.X, pub.Y, err = unmarshalEcPoint(attributes[1].Value, pub.Curve); err != nil {
196 return nil, err
197 }
198 return &pub, nil
199 }
200
201
202
203
204 func (c *Context) GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (Signer, error) {
205 if c.closed.Get() {
206 return nil, errClosed
207 }
208
209 public, err := NewAttributeSetWithID(id)
210 if err != nil {
211 return nil, err
212 }
213
214 private := public.Copy()
215
216 return c.GenerateECDSAKeyPairWithAttributes(public, private, curve)
217 }
218
219
220
221
222 func (c *Context) GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (Signer, error) {
223 if c.closed.Get() {
224 return nil, errClosed
225 }
226
227 public, err := NewAttributeSetWithIDAndLabel(id, label)
228 if err != nil {
229 return nil, err
230 }
231
232 private := public.Copy()
233
234 return c.GenerateECDSAKeyPairWithAttributes(public, private, curve)
235 }
236
237
238
239
240 func (c *Context) GenerateECDSAKeyPairWithAttributes(public, private AttributeSet, curve elliptic.Curve) (Signer, error) {
241 if c.closed.Get() {
242 return nil, errClosed
243 }
244
245 var k Signer
246 err := c.withSession(func(session *pkcs11Session) error {
247
248 parameters, err := marshalEcParams(curve)
249 if err != nil {
250 return err
251 }
252 public.AddIfNotPresent([]*pkcs11.Attribute{
253 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
254 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA),
255 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
256 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
257 pkcs11.NewAttribute(pkcs11.CKA_ECDSA_PARAMS, parameters),
258 })
259 private.AddIfNotPresent([]*pkcs11.Attribute{
260 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
261 pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
262 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),
263 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),
264 })
265
266 mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_KEY_PAIR_GEN, nil)}
267 pubHandle, privHandle, err := session.ctx.GenerateKeyPair(session.handle,
268 mech,
269 public.ToSlice(),
270 private.ToSlice())
271 if err != nil {
272 return err
273 }
274
275 pub, err := exportECDSAPublicKey(session, pubHandle)
276 if err != nil {
277 return err
278 }
279 k = &pkcs11PrivateKeyECDSA{
280 pkcs11PrivateKey: pkcs11PrivateKey{
281 pkcs11Object: pkcs11Object{
282 handle: privHandle,
283 context: c,
284 },
285 pubKeyHandle: pubHandle,
286 pubKey: pub,
287 }}
288 return nil
289 })
290 return k, err
291 }
292
293
294
295
296
297
298
299
300 func (signer *pkcs11PrivateKeyECDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
301 return signer.context.dsaGeneric(signer.handle, pkcs11.CKM_ECDSA, digest)
302 }
303
View as plain text