• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LudovicRousseau / PyKCS11 / 12855273166

19 Jan 2025 04:26PM UTC coverage: 86.678% (-0.008%) from 86.686%
12855273166

push

github

LudovicRousseau
test_derive: document test_deriveKey_CKM_EXTRACT_KEY_FROM_KEY

2993 of 3453 relevant lines covered (86.68%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.17
/test/test_wrap.py
1
import unittest
1✔
2

3
from PyKCS11 import PyKCS11
1✔
4

5

6
class TestUtil(unittest.TestCase):
1✔
7
    def setUp(self):
1✔
8
        self.pkcs11 = PyKCS11.PyKCS11Lib()
1✔
9
        self.pkcs11.load()
1✔
10

11
        # get SoftHSM major version
12
        self.SoftHSMversion = self.pkcs11.getInfo().libraryVersion[0]
1✔
13

14
        self.slot = self.pkcs11.getSlotList(tokenPresent=True)[0]
1✔
15
        self.session = self.pkcs11.openSession(
1✔
16
            self.slot, PyKCS11.CKF_SERIAL_SESSION | PyKCS11.CKF_RW_SESSION
17
        )
18
        self.session.login("1234")
1✔
19

20
    def tearDown(self):
1✔
21
        self.session.logout()
1✔
22
        self.pkcs11.closeAllSessions(self.slot)
1✔
23
        del self.pkcs11
1✔
24

25
    def test_wrapKey(self):
1✔
26
        keyID = (0x01,)
1✔
27
        AESKeyTemplate = [
1✔
28
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_SECRET_KEY),
29
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_AES),
30
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
31
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
32
            (PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
33
            (PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
34
            (PyKCS11.CKA_SIGN, PyKCS11.CK_FALSE),
35
            (PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_TRUE),
36
            (PyKCS11.CKA_VERIFY, PyKCS11.CK_FALSE),
37
            (PyKCS11.CKA_VALUE_LEN, 32),
38
            (PyKCS11.CKA_LABEL, "TestAESKey"),
39
            (PyKCS11.CKA_ID, keyID),
40
        ]
41

42
        if self.SoftHSMversion < 2:
1✔
43
            self.skipTest("generateKey() only supported by SoftHSM >= 2")
×
44

45
        self.wrapKey = self.session.generateKey(AESKeyTemplate)
1✔
46
        self.assertIsNotNone(self.wrapKey)
1✔
47

48
        keyID = (0x02,)
1✔
49
        # make the key extractable
50
        AESKeyTemplate.append((PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_TRUE))
1✔
51

52
        self.AESKey = self.session.generateKey(AESKeyTemplate)
1✔
53
        self.assertIsNotNone(self.AESKey)
1✔
54

55
        # buffer of 32 bytes 0x42
56
        DataIn = [42] * 32
1✔
57

58
        mechanism = PyKCS11.Mechanism(PyKCS11.CKM_AES_ECB)
1✔
59
        DataOut = self.session.encrypt(self.AESKey, DataIn, mechanism)
1✔
60
        # print("DataOut", DataOut)
61

62
        DataCheck = self.session.decrypt(self.AESKey, DataOut, mechanism)
1✔
63
        # print("DataCheck:", DataCheck)
64

65
        # check we can encrypt/decrypt with the AES key
66
        self.assertSequenceEqual(DataIn, DataCheck)
1✔
67

68
        # wrap using CKM_AES_KEY_WRAP
69
        mechanismWrap = PyKCS11.Mechanism(PyKCS11.CKM_AES_KEY_WRAP)
1✔
70
        wrapped = self.session.wrapKey(self.wrapKey, self.AESKey, mechanismWrap)
1✔
71
        self.assertIsNotNone(wrapped)
1✔
72

73
        # destroy the original key
74
        self.session.destroyObject(self.AESKey)
1✔
75

76
        # unwrap
77
        template = [
1✔
78
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_SECRET_KEY),
79
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_AES),
80
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
81
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
82
            (PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
83
            (PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
84
            (PyKCS11.CKA_SIGN, PyKCS11.CK_FALSE),
85
            (PyKCS11.CKA_VERIFY, PyKCS11.CK_FALSE),
86
        ]
87
        unwrapped = self.session.unwrapKey(
1✔
88
            self.wrapKey, wrapped, template, mechanismWrap
89
        )
90
        self.assertIsNotNone(unwrapped)
1✔
91

92
        DataCheck = self.session.decrypt(unwrapped, DataOut, mechanism)
1✔
93
        # print("DataCheck:", DataCheck)
94

95
        # check we can decrypt with the unwrapped AES key
96
        self.assertSequenceEqual(DataIn, DataCheck)
1✔
97

98
        # cleanup
99
        self.session.destroyObject(unwrapped)
1✔
100

101
        self.session.destroyObject(self.wrapKey)
1✔
102

103
    def test_wrapKey_OAEP(self):
1✔
104
        if self.SoftHSMversion < 2:
1✔
105
            self.skipTest("generateKey() only supported by SoftHSM >= 2")
×
106

107
        keyID = (0x22,)
1✔
108
        pubTemplate = [
1✔
109
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_PUBLIC_KEY),
110
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
111
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
112
            (PyKCS11.CKA_MODULUS_BITS, 0x0400),
113
            (PyKCS11.CKA_PUBLIC_EXPONENT, (0x01, 0x00, 0x01)),
114
            (PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
115
            (PyKCS11.CKA_VERIFY, PyKCS11.CK_TRUE),
116
            (PyKCS11.CKA_VERIFY_RECOVER, PyKCS11.CK_TRUE),
117
            (PyKCS11.CKA_WRAP, PyKCS11.CK_TRUE),
118
            (PyKCS11.CKA_LABEL, "My Public Key"),
119
            (PyKCS11.CKA_ID, keyID),
120
        ]
121

122
        privTemplate = [
1✔
123
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY),
124
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
125
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_TRUE),
126
            (PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
127
            (PyKCS11.CKA_SIGN, PyKCS11.CK_TRUE),
128
            (PyKCS11.CKA_SIGN_RECOVER, PyKCS11.CK_TRUE),
129
            (PyKCS11.CKA_UNWRAP, PyKCS11.CK_TRUE),
130
            (PyKCS11.CKA_ID, keyID),
131
        ]
132

133
        self.pubKey, self.privKey = self.session.generateKeyPair(
1✔
134
            pubTemplate, privTemplate
135
        )
136
        self.assertIsNotNone(self.pubKey)
1✔
137
        self.assertIsNotNone(self.privKey)
1✔
138

139
        keyID = (0x02,)
1✔
140
        AESKeyTemplate = [
1✔
141
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_SECRET_KEY),
142
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_AES),
143
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
144
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
145
            (PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
146
            (PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
147
            (PyKCS11.CKA_SIGN, PyKCS11.CK_FALSE),
148
            (PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_TRUE),
149
            (PyKCS11.CKA_VERIFY, PyKCS11.CK_FALSE),
150
            (PyKCS11.CKA_VALUE_LEN, 32),
151
            (PyKCS11.CKA_LABEL, "TestAESKey"),
152
            (PyKCS11.CKA_ID, keyID),
153
        ]
154

155
        # make the key extractable
156
        AESKeyTemplate.append((PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_TRUE))
1✔
157

158
        self.AESKey = self.session.generateKey(AESKeyTemplate)
1✔
159
        self.assertIsNotNone(self.AESKey)
1✔
160

161
        # buffer of 32 bytes 0x42
162
        DataIn = [42] * 32
1✔
163

164
        mechanism = PyKCS11.Mechanism(PyKCS11.CKM_AES_ECB)
1✔
165
        DataOut = self.session.encrypt(self.AESKey, DataIn, mechanism)
1✔
166
        # print("DataOut", DataOut)
167

168
        DataCheck = self.session.decrypt(self.AESKey, DataOut, mechanism)
1✔
169
        # print("DataCheck:", DataCheck)
170

171
        # check we can encrypt/decrypt with the AES key
172
        self.assertSequenceEqual(DataIn, DataCheck)
1✔
173

174
        # wrap using CKM_RSA_PKCS_OAEP + CKG_MGF1_SHA1
175
        mechanismWrap = PyKCS11.RSAOAEPMechanism(
1✔
176
            PyKCS11.CKM_SHA_1, PyKCS11.CKG_MGF1_SHA1
177
        )
178
        wrapped = self.session.wrapKey(self.pubKey, self.AESKey, mechanismWrap)
1✔
179
        self.assertIsNotNone(wrapped)
1✔
180

181
        # destroy the original key
182
        self.session.destroyObject(self.AESKey)
1✔
183

184
        # unwrap
185
        template = [
1✔
186
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_SECRET_KEY),
187
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_AES),
188
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
189
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
190
            (PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
191
            (PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
192
            (PyKCS11.CKA_SIGN, PyKCS11.CK_FALSE),
193
            (PyKCS11.CKA_VERIFY, PyKCS11.CK_FALSE),
194
        ]
195
        unwrapped = self.session.unwrapKey(
1✔
196
            self.privKey, wrapped, template, mechanismWrap
197
        )
198
        self.assertIsNotNone(unwrapped)
1✔
199

200
        DataCheck = self.session.decrypt(unwrapped, DataOut, mechanism)
1✔
201
        # print("DataCheck:", DataCheck)
202

203
        # check we can decrypt with the unwrapped AES key
204
        self.assertSequenceEqual(DataIn, DataCheck)
1✔
205

206
        # cleanup
207
        self.session.destroyObject(unwrapped)
1✔
208

209
        self.session.destroyObject(self.pubKey)
1✔
210
        self.session.destroyObject(self.privKey)
1✔
211

212
    def test_wrapKey_UNWRAP_TEMPLATE(self):
1✔
213
        keyID = (0x01,)
1✔
214
        pubTemplate = [
1✔
215
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_PUBLIC_KEY),
216
            (PyKCS11.CKA_LABEL, "RSA Public Key"),
217
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_RSA),
218
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
219
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_TRUE),
220
            (PyKCS11.CKA_VERIFY, PyKCS11.CK_TRUE),
221
            (PyKCS11.CKA_MODULUS_BITS, 2048),
222
            (PyKCS11.CKA_PUBLIC_EXPONENT, (0x01, 0x00, 0x01)),
223
            (PyKCS11.CKA_ID, keyID),
224
            (PyKCS11.CKA_WRAP, PyKCS11.CK_TRUE),
225
        ]
226

227
        unwrap_template = [
1✔
228
            (PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_FALSE),
229
        ]
230

231
        privTemplate = [
1✔
232
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY),
233
            (PyKCS11.CKA_LABEL, "RSA Private Key"),
234
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_RSA),
235
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
236
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_TRUE),
237
            (PyKCS11.CKA_SIGN, PyKCS11.CK_TRUE),
238
            (PyKCS11.CKA_ID, keyID),
239
            (PyKCS11.CKA_UNWRAP, PyKCS11.CK_TRUE),
240
            (PyKCS11.CKA_UNWRAP_TEMPLATE, unwrap_template),
241
        ]
242

243
        if self.SoftHSMversion < 2:
1✔
244
            self.skipTest("generateKey() only supported by SoftHSM >= 2")
×
245

246
        self.pubKey, self.privKey = self.session.generateKeyPair(
1✔
247
            pubTemplate, privTemplate
248
        )
249
        self.assertIsNotNone(self.pubKey)
1✔
250
        self.assertIsNotNone(self.privKey)
1✔
251

252
        keyID = (0x02,)
1✔
253
        AESKeyTemplate = [
1✔
254
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_SECRET_KEY),
255
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_AES),
256
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
257
            (PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
258
            (PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
259
            (PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
260
            (PyKCS11.CKA_SIGN, PyKCS11.CK_FALSE),
261
            (PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_TRUE),
262
            (PyKCS11.CKA_VERIFY, PyKCS11.CK_FALSE),
263
            (PyKCS11.CKA_VALUE_LEN, 32),
264
            (PyKCS11.CKA_LABEL, "TestAESKey"),
265
            (PyKCS11.CKA_ID, keyID),
266
        ]
267

268
        # make the key extractable
269
        AESKeyTemplate.append((PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_TRUE))
1✔
270

271
        self.AESKey = self.session.generateKey(AESKeyTemplate)
1✔
272
        self.assertIsNotNone(self.AESKey)
1✔
273

274
        # buffer of 32 bytes 0x42
275
        DataIn = [42] * 32
1✔
276

277
        mechanism = PyKCS11.Mechanism(PyKCS11.CKM_AES_ECB)
1✔
278
        DataOut = self.session.encrypt(self.AESKey, DataIn, mechanism)
1✔
279
        # print("DataOut", DataOut)
280

281
        DataCheck = self.session.decrypt(self.AESKey, DataOut, mechanism)
1✔
282
        # print("DataCheck:", DataCheck)
283

284
        # check we can encrypt/decrypt with the AES key
285
        self.assertSequenceEqual(DataIn, DataCheck)
1✔
286

287
        # wrap
288
        mechanismWrap = PyKCS11.RSAOAEPMechanism(
1✔
289
            PyKCS11.CKM_SHA_1, PyKCS11.CKG_MGF1_SHA1
290
        )
291
        wrapped = self.session.wrapKey(self.pubKey, self.AESKey, mechanismWrap)
1✔
292
        self.assertIsNotNone(wrapped)
1✔
293

294
        # destroy the original key
295
        self.session.destroyObject(self.AESKey)
1✔
296

297
        # unwrap
298
        template = [
1✔
299
            (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
300
            (PyKCS11.CKA_CLASS, PyKCS11.CKO_SECRET_KEY),
301
            (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_AES),
302
            (PyKCS11.CKA_EXTRACTABLE, PyKCS11.CK_FALSE),
303
        ]
304
        unwrapped = self.session.unwrapKey(
1✔
305
            self.privKey, wrapped, template, mechanismWrap
306
        )
307
        self.assertIsNotNone(unwrapped)
1✔
308

309
        DataCheck = self.session.decrypt(unwrapped, DataOut, mechanism)
1✔
310
        # print("DataCheck:", DataCheck)
311

312
        # check we can decrypt with the unwrapped AES key
313
        self.assertSequenceEqual(DataIn, DataCheck)
1✔
314

315
        attributes = self.session.getAttributeValue(
1✔
316
            unwrapped, [PyKCS11.CKA_EXTRACTABLE]
317
        )
318
        self.assertSequenceEqual(attributes, [False])
1✔
319

320
        # cleanup
321
        self.session.destroyObject(unwrapped)
1✔
322

323
        self.session.destroyObject(self.pubKey)
1✔
324
        self.session.destroyObject(self.privKey)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc