1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package pkcs11
17
18 import (
19 "crypto"
20 "crypto/ecdsa"
21 "crypto/rand"
22 "crypto/rsa"
23 "crypto/sha1"
24 "crypto/sha256"
25 "errors"
26 "fmt"
27 "hash"
28 "io"
29 "strconv"
30 "strings"
31
32 "github.com/google/go-pkcs11/pkcs11"
33 )
34
35
36 func ParseHexString(str string) (i uint32, err error) {
37 stripped := strings.Replace(str, "0x", "", -1)
38 resultUint64, err := strconv.ParseUint(stripped, 16, 32)
39 if err != nil {
40 return 0, err
41 }
42 return uint32(resultUint64), nil
43 }
44
45
46
47 func Cred(pkcs11Module string, slotUint32Str string, label string, userPin string) (*Key, error) {
48 module, err := pkcs11.Open(pkcs11Module)
49 if err != nil {
50 return nil, err
51 }
52 slotUint32, err := ParseHexString(slotUint32Str)
53 if err != nil {
54 return nil, err
55 }
56 kslot, err := module.Slot(slotUint32, pkcs11.Options{PIN: userPin})
57 if err != nil {
58 return nil, err
59 }
60
61 certs, err := kslot.Objects(pkcs11.Filter{Class: pkcs11.ClassCertificate, Label: label})
62 if err != nil {
63 return nil, err
64 }
65
66 if len(certs) < 1 {
67 return nil, fmt.Errorf("No certificate object was found with label %s.", label)
68 }
69
70 cert, err := certs[0].Certificate()
71 if err != nil {
72 return nil, err
73 }
74 x509, err := cert.X509()
75 if err != nil {
76 return nil, err
77 }
78 var kchain [][]byte
79 kchain = append(kchain, x509.Raw)
80
81 pubKeys, err := kslot.Objects(pkcs11.Filter{Class: pkcs11.ClassPublicKey, Label: label})
82 if err != nil {
83 return nil, err
84 }
85
86 if len(pubKeys) < 1 {
87 return nil, fmt.Errorf("No public key object was found with label %s.", label)
88 }
89
90 pubKey, err := pubKeys[0].PublicKey()
91 if err != nil {
92 return nil, err
93 }
94
95 privkeys, err := kslot.Objects(pkcs11.Filter{Class: pkcs11.ClassPrivateKey, Label: label})
96 if err != nil {
97 return nil, err
98 }
99
100 if len(privkeys) < 1 {
101 return nil, fmt.Errorf("No private key object was found with label %s.", label)
102 }
103
104 privKey, err := privkeys[0].PrivateKey(pubKey)
105 if err != nil {
106 return nil, err
107 }
108 ksigner, ok := privKey.(crypto.Signer)
109 if !ok {
110 return nil, errors.New("PrivateKey does not implement crypto.Signer")
111 }
112 kdecrypter, _ := privKey.(crypto.Decrypter)
113 defaultHash := crypto.SHA256
114 return &Key{
115 slot: kslot,
116 signer: ksigner,
117 chain: kchain,
118 privKey: privKey,
119 label: label,
120 module: *module,
121 hash: defaultHash,
122 decrypter: kdecrypter,
123 }, nil
124 }
125
126
127
128 type Key struct {
129 slot *pkcs11.Slot
130 signer crypto.Signer
131 chain [][]byte
132 privKey crypto.PrivateKey
133 label string
134 module pkcs11.Module
135 hash crypto.Hash
136 decrypter crypto.Decrypter
137 }
138
139
140
141 func (k *Key) CertificateChain() [][]byte {
142 return k.chain
143 }
144
145
146 func (k *Key) Close() {
147 k.slot.Close()
148 k.module.Close()
149 }
150
151
152 func (k *Key) Public() crypto.PublicKey {
153 return k.signer.Public()
154 }
155
156
157 func (k *Key) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
158 return k.signer.Sign(nil, digest, opts)
159 }
160
161
162 func (k *Key) Encrypt(plaintext []byte, opts any) ([]byte, error) {
163 if hash, ok := opts.(crypto.Hash); ok {
164 k.hash = hash
165 } else {
166 return nil, fmt.Errorf("Unsupported encrypt opts: %v", opts)
167 }
168 publicKey := k.Public()
169 _, ok := publicKey.(*rsa.PublicKey)
170 if ok {
171 return k.encryptRSA(plaintext)
172 }
173 _, ok = publicKey.(*ecdsa.PublicKey)
174 if ok {
175
176 return nil, errors.New("encrypt error: EC keys not yet supported")
177 }
178 return nil, errors.New("encrypt error: Unsupported key type")
179 }
180
181
182 func (k *Key) Decrypt(msg []byte, opts crypto.DecrypterOpts) ([]byte, error) {
183 if oaepOpts, ok := opts.(*rsa.OAEPOptions); ok {
184 k.hash = oaepOpts.Hash
185 } else {
186 return nil, fmt.Errorf("Unsupported DecrypterOpts: %v", opts)
187 }
188 if k.decrypter == nil {
189 return nil, fmt.Errorf("decrypt error: Decrypter is nil")
190 }
191 publicKey := k.Public()
192 _, ok := publicKey.(*rsa.PublicKey)
193 if ok {
194 return k.decryptRSAWithPKCS11(msg)
195 }
196 _, ok = publicKey.(*ecdsa.PublicKey)
197 if ok {
198
199 return nil, errors.New("decrypt error: EC keys not yet supported")
200 }
201 return nil, errors.New("decrypt error: Unsupported key type")
202 }
203
204 func (k *Key) encryptRSA(data []byte) ([]byte, error) {
205 publicKey := k.Public()
206 rsaPubKey := publicKey.(*rsa.PublicKey)
207 hash, err := cryptoHashToHash(k.hash)
208 if err != nil {
209 return nil, err
210 }
211 return rsa.EncryptOAEP(hash, rand.Reader, rsaPubKey, data, nil)
212 }
213
214 func (k *Key) decryptRSAWithPKCS11(encryptedData []byte) ([]byte, error) {
215 opts := &rsa.OAEPOptions{Hash: k.hash}
216 return k.decrypter.Decrypt(nil, encryptedData, opts)
217 }
218
219 func cryptoHashToHash(hash crypto.Hash) (hash.Hash, error) {
220 switch hash {
221 case crypto.SHA256:
222 return sha256.New(), nil
223 case crypto.SHA1:
224 return sha1.New(), nil
225 default:
226 return nil, errors.New("hash conversion error: Unsupported hash")
227 }
228 }
229
View as plain text