1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 from __future__ import print_function
19
20 import PyKCS11.LowLevel
21 import os
22 import sys
23
24
25
26 CK_TRUE = PyKCS11.LowLevel.CK_TRUE
27 CK_FALSE = PyKCS11.LowLevel.CK_FALSE
28 CK_UNAVAILABLE_INFORMATION = PyKCS11.LowLevel.CK_UNAVAILABLE_INFORMATION
29 CK_EFFECTIVELY_INFINITE = PyKCS11.LowLevel.CK_EFFECTIVELY_INFINITE
30 CK_INVALID_HANDLE = PyKCS11.LowLevel.CK_INVALID_HANDLE
31
32 CKM = {}
33 CKR = {}
34 CKA = {}
35 CKO = {}
36 CKU = {}
37 CKK = {}
38 CKC = {}
39 CKF = {}
40 CKS = {}
41 CKG = {}
42 CKZ = {}
43
44
45 for x in PyKCS11.LowLevel.__dict__.keys():
46 if x[:4] == 'CKM_' \
47 or x[:4] == 'CKR_' \
48 or x[:4] == 'CKA_' \
49 or x[:4] == 'CKO_' \
50 or x[:4] == 'CKU_' \
51 or x[:4] == 'CKK_' \
52 or x[:4] == 'CKC_' \
53 or x[:4] == 'CKF_' \
54 or x[:4] == 'CKS_' \
55 or x[:4] == 'CKG_' \
56 or x[:4] == 'CKZ_':
57 a = "%s=PyKCS11.LowLevel.%s" % (x, x)
58 exec(a)
59 if x[3:] != "_VENDOR_DEFINED":
60 eval(x[:3])[eval(x)] = x
61 eval(x[:3])[x] = eval(x)
62
63
64 CKR[-3] = "Unknown format"
65 CKR[-2] = "Unkown PKCS#11 type"
66 CKR[-1] = "Load"
67
68
69 -class ckbytelist(PyKCS11.LowLevel.ckbytelist):
70 """
71 add a __repr__() method to the LowLevel equivalent
72 """
73
75
76 size = 0
77 if isinstance(data, int):
78 size = data
79 data = None
80
81 super(ckbytelist, self).__init__(size)
82
83
84 if data is None:
85 return
86
87
88 if isinstance(data, bytes):
89 self.reserve(len(data))
90 for x in data:
91 if sys.version_info[0] <= 2:
92
93 v = ord(x)
94 else:
95
96 v = x
97 self.append(v)
98
99
100 elif isinstance(data, str):
101 tmp = bytes(data, "utf-8")
102 self.reserve(len(tmp))
103 for x in tmp:
104 self.append(x)
105
106
107 elif isinstance(data, list) or isinstance(data, ckbytelist):
108 self.reserve(len(data))
109 for c in range(len(data)):
110 self.append(data[c])
111 else:
112 raise PyKCS11.PyKCS11Error(-3, text=type(data))
113
115 """
116 return the representation of a tuple
117 the __str__ method will use it also
118 """
119 rep = [elt for elt in self]
120 return repr(rep)
121
124 """
125 add a __repr__() method to the LowLevel equivalent
126 """
127
132
160
162 """
163 text representation of the object
164 """
165 dico = self.to_dict()
166 lines = list()
167 for key in sorted(dico.keys()):
168 lines.append("%s: %s" % (key, dico[key]))
169 return "\n".join(lines)
170
173 """
174 Base class for CK_* classes
175 """
176
177
178 flags_dict = dict()
179
180
181
182 fields = dict()
183
184 flags = 0
185
186 - def flags2text(self):
187 """
188 parse the L{self.flags} field and create a list of "CKF_*" strings
189 corresponding to bits set in flags
190
191 @return: a list of strings
192 @rtype: list
193 """
194 r = []
195 for v in self.flags_dict.keys():
196 if self.flags & v:
197 r.append(self.flags_dict[v])
198 return r
199
201 """
202 convert the fields of the object into a dictionnary
203 """
204 dico = dict()
205 for field in self.fields.keys():
206 if field == "flags":
207 dico[field] = self.flags2text()
208 else:
209 dico[field] = eval("self." + field)
210 return dico
211
213 """
214 text representation of the object
215 """
216 dico = self.to_dict()
217 lines = list()
218 for key in sorted(dico.keys()):
219 type = self.fields[key]
220 if type == "flags":
221 lines.append("%s: %s" % (key, ", ".join(dico[key])))
222 elif type == "pair":
223 lines.append("%s: " % key + "%d.%d" % dico[key])
224 else:
225 lines.append("%s: %s" % (key, dico[key]))
226 return "\n".join(lines)
227
230 """
231 matches the PKCS#11 CK_SLOT_INFO structure
232
233 @ivar slotDescription: blank padded
234 @type slotDescription: string
235 @ivar manufacturerID: blank padded
236 @type manufacturerID: string
237 @ivar flags: See L{flags2text}
238 @type flags: integer
239 @ivar hardwareVersion: 2 elements list
240 @type hardwareVersion: list
241 @ivar firmwareVersion: 2 elements list
242 @type firmwareVersion: list
243 """
244
245 flags_dict = {
246 CKF_TOKEN_PRESENT: "CKF_TOKEN_PRESENT",
247 CKF_REMOVABLE_DEVICE: "CKF_REMOVABLE_DEVICE",
248 CKF_HW_SLOT: "CKF_HW_SLOT"}
249
250 fields = {"slotDescription": "text",
251 "manufacturerID": "text",
252 "flags": "flags",
253 "hardwareVersion": "text",
254 "firmwareVersion": "text"}
255
258 """
259 matches the PKCS#11 CK_INFO structure
260
261 @ivar cryptokiVersion: Cryptoki interface version
262 @type cryptokiVersion: integer
263 @ivar manufacturerID: blank padded
264 @type manufacturerID: string
265 @ivar flags: must be zero
266 @type flags: integer
267 @ivar libraryDescription: blank padded
268 @type libraryDescription: string
269 @ivar libraryVersion: 2 elements list
270 @type libraryVersion: list
271 """
272
273 fields = {"cryptokiVersion": "pair",
274 "manufacturerID": "text",
275 "flags": "flags",
276 "libraryDescription": "text",
277 "libraryVersion": "pair"}
278
281 """
282 matches the PKCS#11 CK_SESSION_INFO structure
283
284 @ivar slotID: ID of the slot that interfaces with the token
285 @type slotID: integer
286 @ivar state: state of the session
287 @type state: integer
288 @ivar flags: bit flags that define the type of session
289 @type flags: integer
290 @ivar ulDeviceError: an error code defined by the cryptographic token
291 @type ulDeviceError: integer
292 """
293
294 flags_dict = {
295 CKF_RW_SESSION: "CKF_RW_SESSION",
296 CKF_SERIAL_SESSION: "CKF_SERIAL_SESSION",
297 }
298
299 - def state2text(self):
300 """
301 parse the L{self.state} field and return a "CKS_*" string
302 corresponding to the state
303
304 @return: a string
305 @rtype: string
306 """
307 return CKS[self.state]
308
309 fields = {"slotID": "text",
310 "state": "text",
311 "flags": "flags",
312 "ulDeviceError": "text"}
313
316 """
317 matches the PKCS#11 CK_TOKEN_INFO structure
318
319 @ivar label: blank padded
320 @type label: string
321 @ivar manufacturerID: blank padded
322 @type manufacturerID: string
323 @ivar model: string blank padded
324 @type model: string
325 @ivar serialNumber: string blank padded
326 @type serialNumber: string
327 @ivar flags:
328 @type flags: integer
329 @ivar ulMaxSessionCount:
330 @type ulMaxSessionCount: integer
331 @ivar ulSessionCount:
332 @type ulSessionCount: integer
333 @ivar ulMaxRwSessionCount:
334 @type ulMaxRwSessionCount: integer
335 @ivar ulRwSessionCount:
336 @type ulRwSessionCount: integer
337 @ivar ulMaxPinLen:
338 @type ulMaxPinLen: integer
339 @ivar ulMinPinLen:
340 @type ulMinPinLen: integer
341 @ivar ulTotalPublicMemory:
342 @type ulTotalPublicMemory: integer
343 @ivar ulFreePublicMemory:
344 @type ulFreePublicMemory: integer
345 @ivar ulTotalPrivateMemory:
346 @type ulTotalPrivateMemory: integer
347 @ivar ulFreePrivateMemory:
348 @type ulFreePrivateMemory: integer
349 @ivar hardwareVersion: 2 elements list
350 @type hardwareVersion: list
351 @ivar firmwareVersion: 2 elements list
352 @type firmwareVersion: list
353 @ivar utcTime: string
354 @type utcTime: string
355 """
356
357 flags_dict = {
358 CKF_RNG: "CKF_RNG",
359 CKF_WRITE_PROTECTED: "CKF_WRITE_PROTECTED",
360 CKF_LOGIN_REQUIRED: "CKF_LOGIN_REQUIRED",
361 CKF_USER_PIN_INITIALIZED: "CKF_USER_PIN_INITIALIZED",
362 CKF_RESTORE_KEY_NOT_NEEDED: "CKF_RESTORE_KEY_NOT_NEEDED",
363 CKF_CLOCK_ON_TOKEN: "CKF_CLOCK_ON_TOKEN",
364 CKF_PROTECTED_AUTHENTICATION_PATH: "CKF_PROTECTED_AUTHENTICATION_PATH",
365 CKF_DUAL_CRYPTO_OPERATIONS: "CKF_DUAL_CRYPTO_OPERATIONS",
366 CKF_TOKEN_INITIALIZED: "CKF_TOKEN_INITIALIZED",
367 CKF_SECONDARY_AUTHENTICATION: "CKF_SECONDARY_AUTHENTICATION",
368 CKF_USER_PIN_COUNT_LOW: "CKF_USER_PIN_COUNT_LOW",
369 CKF_USER_PIN_FINAL_TRY: "CKF_USER_PIN_FINAL_TRY",
370 CKF_USER_PIN_LOCKED: "CKF_USER_PIN_LOCKED",
371 CKF_USER_PIN_TO_BE_CHANGED: "CKF_USER_PIN_TO_BE_CHANGED",
372 CKF_SO_PIN_COUNT_LOW: "CKF_SO_PIN_COUNT_LOW",
373 CKF_SO_PIN_FINAL_TRY: "CKF_SO_PIN_FINAL_TRY",
374 CKF_SO_PIN_LOCKED: "CKF_SO_PIN_LOCKED",
375 CKF_SO_PIN_TO_BE_CHANGED: "CKF_SO_PIN_TO_BE_CHANGED",
376 }
377
378 fields = {"label": "text",
379 "manufacturerID": "text",
380 "model": "text",
381 "serialNumber": "text",
382 "flags": "flags",
383 "ulMaxSessionCount": "text",
384 "ulSessionCount": "text",
385 "ulMaxRwSessionCount": "text",
386 "ulRwSessionCount": "text",
387 "ulMaxPinLen": "text",
388 "ulMinPinLen": "text",
389 "ulTotalPublicMemory": "text",
390 "ulFreePublicMemory": "text",
391 "ulTotalPrivateMemory": "text",
392 "ulFreePrivateMemory": "text",
393 "hardwareVersion": "pair",
394 "firmwareVersion": "pair",
395 "utcTime": "text"}
396
399 """
400 matches the PKCS#11 CK_MECHANISM_INFO structure
401
402 @ivar ulMinKeySize: minimum size of the key
403 @type ulMinKeySize: integer
404 @ivar ulMaxKeySize: maximum size of the key
405 @type ulMaxKeySize: integer
406 @ivar flags: bit flags specifying mechanism capabilities
407 @type flags: integer
408 """
409
410 flags_dict = {
411 CKF_HW: "CKF_HW",
412 CKF_ENCRYPT: "CKF_ENCRYPT",
413 CKF_DECRYPT: "CKF_DECRYPT",
414 CKF_DIGEST: "CKF_DIGEST",
415 CKF_SIGN: "CKF_SIGN",
416 CKF_SIGN_RECOVER: "CKF_SIGN_RECOVER",
417 CKF_VERIFY: "CKF_VERIFY",
418 CKF_VERIFY_RECOVER: "CKF_VERIFY_RECOVER",
419 CKF_GENERATE: "CKF_GENERATE",
420 CKF_GENERATE_KEY_PAIR: "CKF_GENERATE_KEY_PAIR",
421 CKF_WRAP: "CKF_WRAP",
422 CKF_UNWRAP: "CKF_UNWRAP",
423 CKF_DERIVE: "CKF_DERIVE",
424 CKF_EXTENSION: "CKF_EXTENSION",
425 }
426
427 fields = {"ulMinKeySize": "text",
428 "ulMaxKeySize": "text",
429 "flags": "flags"}
430
433 """ define the possible PKCS#11 error codes """
434
438
440 """
441 The text representation of a PKCS#11 error is something like:
442 "CKR_DEVICE_ERROR (0x00000030)"
443 """
444 if (self.value < 0):
445 return CKR[self.value] + " (%s)" % self.text
446 else:
447 return CKR[self.value] + " (0x%08X)" % self.value
448
451 """ high level PKCS#11 binding """
452
455
462
463 - def load(self, pkcs11dll_filename=None, *init_string):
464 """
465 load a PKCS#11 library
466
467 @type pkcs11dll_filename: string
468 @param pkcs11dll_filename: the library name. If this parameter
469 is not set the environment variable PYKCS11LIB is used instead
470 @return: a L{PyKCS11Lib} object
471 @raise PyKCS11Error(-1): when the load fails
472 """
473 if pkcs11dll_filename is None:
474 pkcs11dll_filename = os.getenv("PYKCS11LIB")
475 if pkcs11dll_filename is None:
476 raise PyKCS11Error(-1, "No PKCS11 library specified (set PYKCS11LIB env variable)")
477 rv = self.lib.Load(pkcs11dll_filename)
478 if rv == 0:
479 raise PyKCS11Error(-1, pkcs11dll_filename)
480
482 """
483 C_InitToken
484
485 @param slot: slot number returned by L{getSlotList}
486 @type slot: integer
487 @param pin: SO's initial PIN
488 @param label: new label of the token
489 """
490 rv = self.lib.C_InitToken(slot, pin, label)
491 if rv != CKR_OK:
492 raise PyKCS11Error(rv)
493
512
514 """
515 C_GetSlotList
516
517 @param tokenPresent: L{False} (default) to list all slots,
518 L{True} to list only slots with present tokens
519 @type tokenPresent: bool
520 @return: a list of available slots
521 @rtype: list
522 """
523 slotList = PyKCS11.LowLevel.ckintlist()
524 rv = self.lib.C_GetSlotList(CK_TRUE if tokenPresent else CK_FALSE,
525 slotList)
526 if rv != CKR_OK:
527 raise PyKCS11Error(rv)
528
529 s = []
530 for x in range(len(slotList)):
531 s.append(slotList[x])
532 return s
533
555
607
625
636
660
683
685 """
686 C_WaitForSlotEvent
687
688 @param flags: 0 (default) or CKF_DONT_BLOCK
689 @type flags: integer
690 @return: slot
691 @rtype: integer
692 """
693 tmp = 0
694 (rv, slot) = self.lib.C_WaitForSlotEvent(flags, tmp)
695 if rv != CKR_OK:
696 raise PyKCS11Error(rv)
697
698 return slot
699
702 """Wraps CK_MECHANISM"""
703
704 - def __init__(self, mechanism, param=None):
705 """
706 @param mechanism: the mechanism to be used
707 @type mechanism: integer, any CKM_* value
708 @param param: data to be used as crypto operation parameter
709 (i.e. the IV for some algorithms)
710 @type param: string or list/tuple of bytes
711
712 @see: L{Session.decrypt}, L{Session.sign}
713 """
714 self._mech = PyKCS11.LowLevel.CK_MECHANISM()
715 self._mech.mechanism = mechanism
716 self._param = None
717 if param:
718 self._param = ckbytelist(param)
719 self._mech.pParameter = self._param
720 self._mech.ulParameterLen = len(param)
721
724
725 MechanismSHA1 = Mechanism(CKM_SHA_1, None)
726 MechanismRSAPKCS1 = Mechanism(CKM_RSA_PKCS, None)
727 MechanismRSAGENERATEKEYPAIR = Mechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, None)
728 MechanismECGENERATEKEYPAIR = Mechanism(CKM_EC_KEY_PAIR_GEN, None)
729 MechanismAESGENERATEKEY = Mechanism(CKM_AES_KEY_GEN, None)
733 """RSA OAEP Wrapping mechanism"""
734
735 - def __init__(self, hashAlg, mgf, label=None):
757
760
763 """RSA PSS Wrapping mechanism"""
764
765 - def __init__(self, hashAlg, mgf, sLen):
781
784
787 - def __init__(self, lib, session, mecha):
794
796 """
797 C_DigestUpdate
798
799 @param data: data to add to the digest
800 @type data: bytes or string
801 """
802 data1 = ckbytelist(data)
803 rv = self._lib.C_DigestUpdate(self._session, data1)
804 if rv != CKR_OK:
805 raise PyKCS11Error(rv)
806 return self
807
809 """
810 C_DigestKey
811
812 @param handle: key handle
813 @type handle: CK_OBJECT_HANDLE
814 """
815 rv = self._lib.C_DigestKey(self._session, handle)
816 if rv != CKR_OK:
817 raise PyKCS11Error(rv)
818 return self
819
837
840 """ Manage L{PyKCS11Lib.openSession} objects """
841
843 """
844 @param pykcs11: PyKCS11 library object
845 @type pykcs11: PyKCS11Lib
846 @param session: session handle
847 @type session: instance of CK_SESSION_HANDLE
848 """
849 if not isinstance(pykcs11, PyKCS11Lib):
850 raise TypeError("pykcs11 must be a PyKCS11Lib")
851 if not isinstance(session, LowLevel.CK_SESSION_HANDLE):
852 raise TypeError("session must be a CK_SESSION_HANDLE")
853
854
855 self.pykcs11 = pykcs11
856 self.session = session
857
858 @property
860 """
861 Get the low level lib of the owning PyKCS11Lib
862 """
863 return self.pykcs11.lib
864
872
890
892 """
893 C_Login
894
895 @param pin: the user's PIN or None for CKF_PROTECTED_AUTHENTICATION_PATH
896 @type pin: string
897 @param user_type: the user type. The default value is
898 CKU_USER. You may also use CKU_SO
899 @type user_type: integer
900 """
901 rv = self.lib.C_Login(self.session, user_type, pin)
902 if rv != CKR_OK:
903 raise PyKCS11Error(rv)
904
914
916 """
917 C_InitPIN
918
919 @param new_pin: new PIN
920 """
921 rv = self.lib.C_InitPIN(self.session, new_pin)
922 if rv != CKR_OK:
923 raise PyKCS11Error(rv)
924
925 - def setPin(self, old_pin, new_pin):
926 """
927 C_SetPIN
928
929 @param old_pin: old PIN
930 @param new_pin: new PIN
931 """
932 rv = self.lib.C_SetPIN(self.session, old_pin, new_pin)
933 if rv != CKR_OK:
934 raise PyKCS11Error(rv)
935
948
958
960 """
961 C_DigestInit/C_DigestUpdate/C_DigestKey/C_DigestFinal
962 @param mecha: the digesting mechanism to be used
963 @type mecha: L{Mechanism} instance or L{MechanismSHA1}
964 for CKM_SHA_1
965 @return: A L{DigestSession} object
966 @rtype: DigestSession
967 """
968 return DigestSession(self.lib, self.session, mecha)
969
971 """
972 C_DigestInit/C_Digest
973
974 @param data: the data to be digested
975 @type data: (binary) sring or list/tuple of bytes
976 @param mecha: the digesting mechanism to be used
977 @type mecha: L{Mechanism} instance or L{MechanismSHA1}
978 for CKM_SHA_1
979 @return: the computed digest
980 @rtype: list of bytes
981
982 @note: the returned value is an istance of L{ckbytelist}.
983 You can easly convert it to a binary string with::
984 bytes(ckbytelistDigest)
985 or, for Python 2::
986 ''.join(chr(i) for i in ckbytelistDigest)
987
988 """
989 digest = ckbytelist()
990 m = mecha.to_native()
991 data1 = ckbytelist(data)
992 rv = self.lib.C_DigestInit(self.session, m)
993 if rv != CKR_OK:
994 raise PyKCS11Error(rv)
995
996 rv = self.lib.C_Digest(self.session, data1, digest)
997 if rv != CKR_OK:
998 raise PyKCS11Error(rv)
999
1000 rv = self.lib.C_Digest(self.session, data1, digest)
1001 if rv != CKR_OK:
1002 raise PyKCS11Error(rv)
1003 return digest
1004
1006 """
1007 C_SignInit/C_Sign
1008
1009 @param key: a key handle, obtained calling L{findObjects}.
1010 @type key: integer
1011 @param data: the data to be signed
1012 @type data: (binary) string or list/tuple of bytes
1013 @param mecha: the signing mechanism to be used
1014 @type mecha: L{Mechanism} instance or L{MechanismRSAPKCS1}
1015 for CKM_RSA_PKCS
1016 @return: the computed signature
1017 @rtype: list of bytes
1018
1019 @note: the returned value is an instance of L{ckbytelist}.
1020 You can easly convert it to a binary string with::
1021 bytes(ckbytelistSignature)
1022 or, for Python 2::
1023 ''.join(chr(i) for i in ckbytelistSignature)
1024
1025 """
1026 m = mecha.to_native()
1027 signature = ckbytelist()
1028 data1 = ckbytelist(data)
1029 rv = self.lib.C_SignInit(self.session, m, key)
1030 if rv != CKR_OK:
1031 raise PyKCS11Error(rv)
1032
1033 rv = self.lib.C_Sign(self.session, data1, signature)
1034 if rv != CKR_OK:
1035 raise PyKCS11Error(rv)
1036
1037 rv = self.lib.C_Sign(self.session, data1, signature)
1038 if rv != CKR_OK:
1039 raise PyKCS11Error(rv)
1040 return signature
1041
1043 """
1044 C_VerifyInit/C_Verify
1045
1046 @param key: a key handle, obtained calling L{findObjects}.
1047 @type key: integer
1048 @param data: the data that was signed
1049 @type data: (binary) string or list/tuple of bytes
1050 @param signature: the signature to be verified
1051 @type signature: (binary) string or list/tuple of bytes
1052 @param mecha: the signing mechanism to be used
1053 @type mecha: L{Mechanism} instance or L{MechanismRSAPKCS1}
1054 for CKM_RSA_PKCS
1055 @return: True if signature is valid, False otherwise
1056 @rtype: bool
1057
1058 """
1059 m = mecha.to_native()
1060 data1 = ckbytelist(data)
1061 rv = self.lib.C_VerifyInit(self.session, m, key)
1062 if rv != CKR_OK:
1063 raise PyKCS11Error(rv)
1064 rv = self.lib.C_Verify(self.session, data1, signature)
1065 if rv == CKR_OK:
1066 return True
1067 elif rv == CKR_SIGNATURE_INVALID:
1068 return False
1069 else:
1070 raise PyKCS11Error(rv)
1071
1073 """
1074 C_EncryptInit/C_Encrypt
1075
1076 @param key: a key handle, obtained calling L{findObjects}.
1077 @type key: integer
1078 @param data: the data to be encrypted
1079 @type data: (binary) string or list/tuple of bytes
1080 @param mecha: the encryption mechanism to be used
1081 @type mecha: L{Mechanism} instance or L{MechanismRSAPKCS1}
1082 for CKM_RSA_PKCS
1083 @return: the encrypted data
1084 @rtype: list of bytes
1085
1086 @note: the returned value is an instance of L{ckbytelist}.
1087 You can easly convert it to a binary string with::
1088 bytes(ckbytelistEncrypted)
1089 or, for Python 2::
1090 ''.join(chr(i) for i in ckbytelistEncrypted)
1091
1092 """
1093 encrypted = ckbytelist()
1094 m = mecha.to_native()
1095 data1 = ckbytelist(data)
1096 rv = self.lib.C_EncryptInit(self.session, m, key)
1097 if rv != CKR_OK:
1098 raise PyKCS11Error(rv)
1099
1100 rv = self.lib.C_Encrypt(self.session, data1, encrypted)
1101 if rv != CKR_OK:
1102 raise PyKCS11Error(rv)
1103
1104 rv = self.lib.C_Encrypt(self.session, data1, encrypted)
1105 if rv != CKR_OK:
1106 raise PyKCS11Error(rv)
1107 return encrypted
1108
1110 """
1111 C_DecryptInit/C_Decrypt
1112
1113 @param key: a key handle, obtained calling L{findObjects}.
1114 @type key: integer
1115 @param data: the data to be decrypted
1116 @type data: (binary) string or list/tuple of bytes
1117 @param mecha: the decrypt mechanism to be used
1118 @type mecha: L{Mechanism} instance or L{MechanismRSAPKCS1}
1119 for CKM_RSA_PKCS
1120 @return: the decrypted data
1121 @rtype: list of bytes
1122
1123 @note: the returned value is an instance of L{ckbytelist}.
1124 You can easly convert it to a binary string with::
1125 bytes(ckbytelistData)
1126 or, for Python 2::
1127 ''.join(chr(i) for i in ckbytelistData)
1128
1129 """
1130 m = mecha.to_native()
1131 decrypted = ckbytelist()
1132 data1 = ckbytelist(data)
1133 rv = self.lib.C_DecryptInit(self.session, m, key)
1134 if rv != CKR_OK:
1135 raise PyKCS11Error(rv)
1136
1137 rv = self.lib.C_Decrypt(self.session, data1, decrypted)
1138 if rv != CKR_OK:
1139 raise PyKCS11Error(rv)
1140
1141 rv = self.lib.C_Decrypt(self.session, data1, decrypted)
1142 if rv != CKR_OK:
1143 raise PyKCS11Error(rv)
1144 return decrypted
1145
1147 """
1148 C_WrapKey
1149
1150 @param wrappingKey: a wrapping key handle
1151 @type wrappingKey: integer
1152 @param key: a handle of the key to be wrapped
1153 @type key: integer
1154 @param mecha: the encrypt mechanism to be used
1155 @type mecha: L{Mechanism} instance or L{MechanismRSAPKCS1}
1156 for CKM_RSA_PKCS
1157 @return: the wrapped key bytes
1158 @rtype: list of bytes
1159
1160 @note: the returned value is an instance of L{ckbytelist}.
1161 You can easily convert it to a binary string with::
1162 bytes(ckbytelistData)
1163 or, for Python 2::
1164 ''.join(chr(i) for i in ckbytelistData)
1165
1166 """
1167 wrapped = ckbytelist()
1168 native = mecha.to_native()
1169
1170 rv = self.lib.C_WrapKey(self.session, native, wrappingKey, key, wrapped)
1171 if rv != CKR_OK:
1172 raise PyKCS11Error(rv)
1173
1174 rv = self.lib.C_WrapKey(self.session, native, wrappingKey, key, wrapped)
1175 if rv != CKR_OK:
1176 raise PyKCS11Error(rv)
1177 return wrapped
1178
1180 """
1181 C_UnwrapKey
1182
1183 @param unwrappingKey: the unwrapping key handle
1184 @type unwrappingKey: integer
1185 @param wrappedKey: the bytes of the wrapped key
1186 @type wrappedKey: (binary) string or list/tuple of bytes
1187 @param template: template for the unwrapped key
1188 @param mecha: the decrypt mechanism to be used
1189 @type mecha: L{Mechanism} instance or L{MechanismRSAPKCS1}
1190 for CKM_RSA_PKCS
1191 @return: the unwrapped key object
1192 @rtype: integer
1193
1194 """
1195 m = mecha.to_native()
1196 data1 = ckbytelist(wrappedKey)
1197 handle = PyKCS11.LowLevel.CK_OBJECT_HANDLE()
1198 attrs = self._template2ckattrlist(template)
1199 rv = self.lib.C_UnwrapKey(self.session, m, unwrappingKey, data1, attrs, handle)
1200 if rv != CKR_OK:
1201 raise PyKCS11Error(rv)
1202 return handle
1203
1220
1222 """
1223 is the type a string value?
1224
1225 @param type: PKCS#11 type like CKA_LABEL
1226 @rtype: bool
1227 """
1228 if type in (CKA_LABEL,
1229 CKA_APPLICATION):
1230 return True
1231 return False
1232
1234 """
1235 is the type a boolean value?
1236
1237 @param type: PKCS#11 type like CKA_ALWAYS_SENSITIVE
1238 @rtype: bool
1239 """
1240 if type in (CKA_ALWAYS_SENSITIVE,
1241 CKA_DECRYPT,
1242 CKA_DERIVE,
1243 CKA_ENCRYPT,
1244 CKA_EXTRACTABLE,
1245 CKA_HAS_RESET,
1246 CKA_LOCAL,
1247 CKA_MODIFIABLE,
1248 CKA_NEVER_EXTRACTABLE,
1249 CKA_PRIVATE,
1250 CKA_RESET_ON_INIT,
1251 CKA_SECONDARY_AUTH,
1252 CKA_SENSITIVE,
1253 CKA_SIGN,
1254 CKA_SIGN_RECOVER,
1255 CKA_TOKEN,
1256 CKA_TRUSTED,
1257 CKA_UNWRAP,
1258 CKA_VERIFY,
1259 CKA_VERIFY_RECOVER,
1260 CKA_WRAP,
1261 CKA_WRAP_WITH_TRUSTED):
1262 return True
1263 return False
1264
1266 """
1267 is the type a byte array value?
1268
1269 @param type: PKCS#11 type like CKA_MODULUS
1270 @rtype: bool
1271 """
1272 return (not self.isBool(type)) and (not self.isString(type)) and (not self.isNum(type))
1273
1275 t = PyKCS11.LowLevel.ckattrlist(len(template))
1276 for x in range(len(template)):
1277 attr = template[x]
1278 if self.isNum(attr[0]):
1279 t[x].SetNum(attr[0], int(attr[1]))
1280 elif self.isString(attr[0]):
1281 t[x].SetString(attr[0], str(attr[1]))
1282 elif self.isBool(attr[0]):
1283 t[x].SetBool(attr[0], attr[1] == CK_TRUE)
1284 elif self.isBin(attr[0]):
1285 attrBin = attr[1]
1286 attrStr = attr[1]
1287 if isinstance(attr[1], int):
1288 attrStr = str(attr[1])
1289 if isinstance(attr[1], bytes):
1290 attrBin = ckbytelist(attrStr)
1291 t[x].SetBin(attr[0], attrBin)
1292 else:
1293 raise PyKCS11Error(-2)
1294 return t
1295
1297 """
1298 generate a secret key
1299
1300 @param template: template for the secret key
1301 @param mecha: mechanism to use
1302 @return: handle of the generated key
1303 @rtype: PyKCS11.LowLevel.CK_OBJECT_HANDLE
1304 """
1305 t = self._template2ckattrlist(template)
1306 ck_handle = PyKCS11.LowLevel.CK_OBJECT_HANDLE()
1307 m = mecha.to_native()
1308 rv = self.lib.C_GenerateKey(self.session, m, t, ck_handle)
1309 if rv != CKR_OK:
1310 raise PyKCS11Error(rv)
1311 return ck_handle
1312
1334
1372
1374 """
1375 C_GetAttributeValue
1376
1377 @param obj_id: object ID returned by L{findObjects}
1378 @type obj_id: integer
1379 @param attr: list of attributes
1380 @type attr: list
1381 @param allAsBinary: return all values as binary data; default is False.
1382 @type allAsBinary: Boolean
1383 @return: a list of values corresponding to the list of attributes
1384 @rtype: list
1385
1386 @see: L{getAttributeValue_fragmented}
1387
1388 @note: if allAsBinary is True the function do not convert results to
1389 Python types (i.e.: CKA_TOKEN to Bool, CKA_CLASS to int, ...).
1390
1391 Binary data is returned as L{ckbytelist} type, usable
1392 as a list containing only bytes.
1393 You can easly convert it to a binary string with::
1394 bytes(ckbytelistVariable)
1395 or, for Python 2::
1396 ''.join(chr(i) for i in ckbytelistVariable)
1397
1398 """
1399 valTemplate = PyKCS11.LowLevel.ckattrlist(len(attr))
1400 for x in range(len(attr)):
1401 valTemplate[x].SetType(attr[x])
1402
1403 rv = self.lib.C_GetAttributeValue(self.session, obj_id, valTemplate)
1404 if rv in (CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_SENSITIVE,
1405 CKR_ARGUMENTS_BAD):
1406 return self.getAttributeValue_fragmented(obj_id, attr, allAsBinary)
1407
1408 if rv != CKR_OK:
1409 raise PyKCS11Error(rv)
1410
1411 rv = self.lib.C_GetAttributeValue(self.session, obj_id, valTemplate)
1412 if rv != CKR_OK:
1413 raise PyKCS11Error(rv)
1414
1415 res = []
1416 for x in range(len(attr)):
1417 if (allAsBinary):
1418 res.append(valTemplate[x].GetBin())
1419 elif valTemplate[x].IsNum():
1420 res.append(valTemplate[x].GetNum())
1421 elif valTemplate[x].IsBool():
1422 res.append(valTemplate[x].GetBool())
1423 elif valTemplate[x].IsString():
1424 res.append(valTemplate[x].GetString())
1425 elif valTemplate[x].IsBin():
1426 res.append(valTemplate[x].GetBin())
1427 else:
1428 raise PyKCS11Error(-2)
1429
1430 return res
1431
1477
1479 """
1480 C_SeedRandom
1481
1482 @param seed: seed material
1483 @type seed: iterable
1484 """
1485 low_seed = ckbytelist(len(seed))
1486 for c in range(len(seed)):
1487 low_seed.append(seed[c])
1488 rv = self.lib.C_SeedRandom(self.session, low_seed)
1489 if rv != CKR_OK:
1490 raise PyKCS11Error(rv)
1491
1493 """
1494 C_GenerateRandom
1495
1496 @param size: number of random bytes to get
1497 @type size: integer
1498
1499 @note: the returned value is an instance of L{ckbytelist}.
1500 You can easly convert it to a binary string with::
1501 bytes(random)
1502 or, for Python 2::
1503 ''.join(chr(i) for i in random)
1504 """
1505 low_rand = ckbytelist(size)
1506 rv = self.lib.C_GenerateRandom(self.session, low_rand)
1507 if rv != CKR_OK:
1508 raise PyKCS11Error(rv)
1509 return low_rand
1510
1511 if __name__ == "__main__":
1512
1513 p = PyKCS11Lib()
1514 p.load()
1515
1516 print("getInfo")
1517 print(p.getInfo())
1518
1519 print()
1520 print("getSlotList")
1521 s = p.getSlotList()
1522 print("slots:", s)
1523 slot = s[0]
1524 print("using slot:", slot)
1525
1526 print()
1527 print("getSlotInfo")
1528 print(p.getSlotInfo(slot))
1529
1530 print()
1531 print("getTokenInfo")
1532 print(p.getTokenInfo(slot))
1533
1534 print()
1535 print("openSession")
1536 se = p.openSession(slot)
1537
1538 print()
1539 print("sessionInfo")
1540 print(se.getSessionInfo())
1541
1542 print()
1543 print("seedRandom")
1544 try:
1545 se.seedRandom([1, 2, 3, 4])
1546 except PyKCS11Error as e:
1547 print(e)
1548 print("generateRandom")
1549 print(se.generateRandom())
1550
1551 print()
1552 print("login")
1553 se.login(pin="0000")
1554
1555 print()
1556 print("sessionInfo")
1557 print(se.getSessionInfo())
1558
1559 print()
1560 print("findObjects")
1561 objs = se.findObjects([(CKA_CLASS, CKO_CERTIFICATE)])
1562 print("Nb objetcs:", len(objs))
1563 print(objs)
1564
1565 print()
1566 print("getAttributeValue")
1567 for o in objs:
1568 attr = se.getAttributeValue(o, [CKA_LABEL, CKA_CLASS])
1569 print(attr)
1570
1571 print()
1572 print("logout")
1573 se.logout()
1574
1575 print()
1576 print("closeSession")
1577 se.closeSession()
1578