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 "crypto"
26 "crypto/dsa"
27 "io"
28 "math/big"
29
30 "github.com/pkg/errors"
31
32 pkcs11 "github.com/miekg/pkcs11"
33 )
34
35
36 type pkcs11PrivateKeyDSA struct {
37 pkcs11PrivateKey
38 }
39
40
41 func exportDSAPublicKey(session *pkcs11Session, pubHandle pkcs11.ObjectHandle) (crypto.PublicKey, error) {
42 template := []*pkcs11.Attribute{
43 pkcs11.NewAttribute(pkcs11.CKA_PRIME, nil),
44 pkcs11.NewAttribute(pkcs11.CKA_SUBPRIME, nil),
45 pkcs11.NewAttribute(pkcs11.CKA_BASE, nil),
46 pkcs11.NewAttribute(pkcs11.CKA_VALUE, nil),
47 }
48 exported, err := session.ctx.GetAttributeValue(session.handle, pubHandle, template)
49 if err != nil {
50 return nil, err
51 }
52 var p, q, g, y big.Int
53 p.SetBytes(exported[0].Value)
54 q.SetBytes(exported[1].Value)
55 g.SetBytes(exported[2].Value)
56 y.SetBytes(exported[3].Value)
57 result := dsa.PublicKey{
58 Parameters: dsa.Parameters{
59 P: &p,
60 Q: &q,
61 G: &g,
62 },
63 Y: &y,
64 }
65 return &result, nil
66 }
67
68 func notNilBytes(obj []byte, name string) error {
69 if obj == nil {
70 return errors.Errorf("%s cannot be nil", name)
71 }
72 return nil
73 }
74
75
76
77 func (c *Context) GenerateDSAKeyPair(id []byte, params *dsa.Parameters) (Signer, error) {
78 if c.closed.Get() {
79 return nil, errClosed
80 }
81
82 public, err := NewAttributeSetWithID(id)
83 if err != nil {
84 return nil, err
85 }
86
87 private := public.Copy()
88
89 return c.GenerateDSAKeyPairWithAttributes(public, private, params)
90 }
91
92
93
94 func (c *Context) GenerateDSAKeyPairWithLabel(id, label []byte, params *dsa.Parameters) (Signer, error) {
95 if c.closed.Get() {
96 return nil, errClosed
97 }
98
99 public, err := NewAttributeSetWithIDAndLabel(id, label)
100 if err != nil {
101 return nil, err
102 }
103
104 private := public.Copy()
105
106 return c.GenerateDSAKeyPairWithAttributes(public, private, params)
107 }
108
109
110
111
112 func (c *Context) GenerateDSAKeyPairWithAttributes(public, private AttributeSet, params *dsa.Parameters) (Signer, error) {
113 if c.closed.Get() {
114 return nil, errClosed
115 }
116
117 var k Signer
118 err := c.withSession(func(session *pkcs11Session) error {
119 p := params.P.Bytes()
120 q := params.Q.Bytes()
121 g := params.G.Bytes()
122
123 public.AddIfNotPresent([]*pkcs11.Attribute{
124 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
125 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_DSA),
126 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
127 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
128 pkcs11.NewAttribute(pkcs11.CKA_PRIME, p),
129 pkcs11.NewAttribute(pkcs11.CKA_SUBPRIME, q),
130 pkcs11.NewAttribute(pkcs11.CKA_BASE, g),
131 })
132 private.AddIfNotPresent([]*pkcs11.Attribute{
133 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
134 pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
135 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),
136 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),
137 })
138
139 mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_DSA_KEY_PAIR_GEN, nil)}
140 pubHandle, privHandle, err := session.ctx.GenerateKeyPair(session.handle,
141 mech,
142 public.ToSlice(),
143 private.ToSlice())
144 if err != nil {
145 return err
146 }
147 pub, err := exportDSAPublicKey(session, pubHandle)
148 if err != nil {
149 return err
150 }
151 k = &pkcs11PrivateKeyDSA{
152 pkcs11PrivateKey: pkcs11PrivateKey{
153 pkcs11Object: pkcs11Object{
154 handle: privHandle,
155 context: c,
156 },
157 pubKeyHandle: pubHandle,
158 pubKey: pub,
159 }}
160 return nil
161
162 })
163 return k, err
164 }
165
166
167
168
169
170
171
172
173 func (signer *pkcs11PrivateKeyDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
174 return signer.context.dsaGeneric(signer.handle, pkcs11.CKM_DSA, digest)
175 }
176
View as plain text