aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2017-05-04 02:33:40 -0400
committerRob Austein <sra@hactrn.net>2017-05-04 02:33:40 -0400
commit0cc1b0a7b5605d86d8a8639651987e25fdb3bdc9 (patch)
tree9560dbda984b8ece29f2018e3bff143fa4f5ce97
parentce8ba928172071dc89cc1fc0520f840211bbfa0d (diff)
Support using C_GetFunctionList() instead of library symbols.
The Python ctypes library allows us direct access to the public symbols of a shared library, so we never bothered to implement support for using the dispatch vector returned by C_GetFunctionList(). Well, it turns out that there are useful debugging tools like pkcs11-spy which require the dispatch vector support, so refactor to add it.
-rw-r--r--cryptech/py11/__init__.py109
-rw-r--r--cryptech/py11/exceptions.py5
-rw-r--r--cryptech/py11/prototypes.py85
-rw-r--r--cryptech/py11/types.py92
4 files changed, 160 insertions, 131 deletions
diff --git a/cryptech/py11/__init__.py b/cryptech/py11/__init__.py
index 46b62d6..fb9af7e 100644
--- a/cryptech/py11/__init__.py
+++ b/cryptech/py11/__init__.py
@@ -11,7 +11,6 @@ from .exceptions import *
from .types import *
from .constants import *
from .attributes import *
-from .prototypes import *
class PKCS11 (object):
@@ -44,20 +43,37 @@ class PKCS11 (object):
raw PKCS #11 API, which map the API into something a bit more Pythonic.
"""
+ # Whether to use C_GetFunctionList() instead of dynamic link symbols.
+ use_C_GetFunctionList = False
+
def __init__(self, so_name = "libpkcs11.so"):
self.so_name = so_name
self.so = CDLL(so_name)
- def raise_on_failure(rv):
- if rv != CKR_OK:
- raise CKR_Exception.ckr_map[rv]
- for name, args in Prototypes.iteritems():
- func = getattr(self.so, name)
- func.restype = raise_on_failure
- func.argtypes = args
+ self.d = type("Dispatch", (object,), {})()
+ for name, args in Prototypes:
+ try:
+ func = getattr(self.so, name)
+ except AttributeError:
+ self.use_C_GetFunctionList = True
+ else:
+ func.restype = CK_RV
+ func.argtypes = args
+ func.errcheck = CKR_Exception.raise_on_failure
+ setattr(self.d, name, func)
+ if self.use_C_GetFunctionList:
+ functions = CK_FUNCTION_LIST_PTR()
+ self.so.C_GetFunctionList(byref(functions))
+ for name, args in Prototypes:
+ func = getattr(functions.contents, name)
+ func.errcheck = CKR_Exception.raise_on_failure
+ setattr(self.d, name, func)
self.adb = AttributeDB()
def __getattr__(self, name):
- return getattr(self.so, name)
+ try:
+ return getattr(self.d, name)
+ except AttributeError:
+ return getattr(self.so, name)
def C_GetFunctionList(self):
return self
@@ -65,7 +81,7 @@ class PKCS11 (object):
@property
def version(self):
info = CK_INFO()
- self.so.C_GetInfo(byref(info))
+ self.d.C_GetInfo(byref(info))
return info.cryptokiVersion
# Be very careful if you try to provide your own locking functions.
@@ -81,52 +97,53 @@ class PKCS11 (object):
def C_Initialize(self, flags = 0, create_mutex = None, destroy_mutex = None, lock_mutex = None, unlock_mutex = None):
if flags == 0 and create_mutex is None and destroy_mutex is None and lock_mutex is None and unlock_mutex is None:
self._C_Initialize_args = None
- self.so.C_Initialize(None)
+ self.d.C_Initialize(None)
else:
create_mutex = CK_CREATEMUTEX() if create_mutex is None else CK_CREATEMUTEX(create_mutex)
destroy_mutex = CK_DESTROYMUTEX() if destroy_mutex is None else CK_DESTROYMUTEX(destroy_mutex)
lock_mutex = CK_LOCKMUTEX() if lock_mutex is None else CK_LOCKMUTEX(lock_mutex)
unlock_mutex = CK_UNLOCKMUTEX() if unlock_mutex is None else CK_UNLOCKMUTEX(unlock_mutex)
- self._C_Initialize_args = CK_C_INITIALIZE_ARGS(create_mutex, destroy_mutex, lock_mutex, unlock_mutex, flags, None)
- self.so.C_Initialize(cast(byref(self._C_Initialize_args), CK_VOID_PTR))
+ self._C_Initialize_args = CK_C_INITIALIZE_ARGS(create_mutex, destroy_mutex,
+ lock_mutex, unlock_mutex, flags, None)
+ self.d.C_Initialize(cast(byref(self._C_Initialize_args), CK_VOID_PTR))
def C_Finalize(self):
- self.so.C_Finalize(None)
+ self.d.C_Finalize(None)
self._C_Initialize_args = None
def C_GetSlotList(self):
count = CK_ULONG()
- self.so.C_GetSlotList(CK_TRUE, None, byref(count))
+ self.d.C_GetSlotList(CK_TRUE, None, byref(count))
slots = (CK_SLOT_ID * count.value)()
- self.so.C_GetSlotList(CK_TRUE, slots, byref(count))
+ self.d.C_GetSlotList(CK_TRUE, slots, byref(count))
return tuple(slots[i] for i in xrange(count.value))
def C_GetTokenInfo(self, slot_id):
token_info = CK_TOKEN_INFO()
- self.so.C_GetTokenInfo(slot_id, byref(token_info))
+ self.d.C_GetTokenInfo(slot_id, byref(token_info))
return token_info
def C_OpenSession(self, slot, flags = CKF_RW_SESSION, application = None, notify = CK_NOTIFY()):
flags |= CKF_SERIAL_SESSION
handle = CK_SESSION_HANDLE()
- self.so.C_OpenSession(slot, flags, application, notify, byref(handle))
+ self.d.C_OpenSession(slot, flags, application, notify, byref(handle))
return handle.value
def C_GenerateRandom(self, session, n):
buffer = create_string_buffer(n)
- self.so.C_GenerateRandom(session, buffer, sizeof(buffer))
+ self.d.C_GenerateRandom(session, buffer, sizeof(buffer))
return buffer.raw
def C_Login(self, session, user, pin):
- self.so.C_Login(session, user, pin, len(pin))
+ self.d.C_Login(session, user, pin, len(pin))
def C_GetAttributeValue(self, session_handle, object_handle, *attributes):
if len(attributes) == 1 and isinstance(attributes[0], (list, tuple)):
attributes = attributes[0]
template = self.adb.getvalue_create_template(attributes)
- self.so.C_GetAttributeValue(session_handle, object_handle, template, len(template))
+ self.d.C_GetAttributeValue(session_handle, object_handle, template, len(template))
self.adb.getvalue_allocate_template(template)
- self.so.C_GetAttributeValue(session_handle, object_handle, template, len(template))
+ self.d.C_GetAttributeValue(session_handle, object_handle, template, len(template))
return self.adb.from_ctypes(template)
def C_FindObjectsInit(self, session, template = None, **kwargs):
@@ -134,15 +151,15 @@ class PKCS11 (object):
assert not template
template = kwargs
if template:
- self.so.C_FindObjectsInit(session, self.adb.to_ctypes(template), len(template))
+ self.d.C_FindObjectsInit(session, self.adb.to_ctypes(template), len(template))
else:
- self.so.C_FindObjectsInit(session, None, 0)
+ self.d.C_FindObjectsInit(session, None, 0)
def C_FindObjects(self, session, chunk_size = 10):
objects = (CK_OBJECT_HANDLE * chunk_size)()
count = CK_ULONG(1)
while count.value > 0:
- self.so.C_FindObjects(session, objects, len(objects), byref(count))
+ self.d.C_FindObjects(session, objects, len(objects), byref(count))
for i in xrange(count.value):
yield objects[i]
@@ -194,45 +211,45 @@ class PKCS11 (object):
mechanism = CK_MECHANISM(mechanism_type, None, 0)
public_handle = CK_OBJECT_HANDLE()
private_handle = CK_OBJECT_HANDLE()
- self.so.C_GenerateKeyPair(session, byref(mechanism),
- public_template, len(public_template),
- private_template, len(private_template),
- byref(public_handle), byref(private_handle))
+ self.d.C_GenerateKeyPair(session, byref(mechanism),
+ public_template, len(public_template),
+ private_template, len(private_template),
+ byref(public_handle), byref(private_handle))
return public_handle.value, private_handle.value
def C_SignInit(self, session, mechanism_type, private_key):
mechanism = CK_MECHANISM(mechanism_type, None, 0)
- self.so.C_SignInit(session, byref(mechanism), private_key)
+ self.d.C_SignInit(session, byref(mechanism), private_key)
def C_Sign(self, session, data):
n = CK_ULONG()
- self.so.C_Sign(session, data, len(data), None, byref(n))
+ self.d.C_Sign(session, data, len(data), None, byref(n))
sig = create_string_buffer(n.value)
- self.so.C_Sign(session, data, len(data), sig, byref(n))
+ self.d.C_Sign(session, data, len(data), sig, byref(n))
return sig.raw
def C_SignUpdate(self, session, data):
- self.so.C_SignUpdate(session, data, len(data))
+ self.d.C_SignUpdate(session, data, len(data))
def C_SignFinal(self, session):
n = CK_ULONG()
- self.so.C_SignFinal(session, None, byref(n))
+ self.d.C_SignFinal(session, None, byref(n))
sig = create_string_buffer(n.value)
- self.so.C_SignFinal(session, sig, byref(n))
+ self.d.C_SignFinal(session, sig, byref(n))
return sig.raw
def C_VerifyInit(self, session, mechanism_type, public_key):
mechanism = CK_MECHANISM(mechanism_type, None, 0)
- self.so.C_VerifyInit(session, byref(mechanism), public_key)
+ self.d.C_VerifyInit(session, byref(mechanism), public_key)
def C_Verify(self, session, data, signature):
- self.so.C_Verify(session, data, len(data), signature, len(signature))
+ self.d.C_Verify(session, data, len(data), signature, len(signature))
def C_VerifyUpdate(self, session, data):
- self.so.C_VerifyUpdate(session, data, len(data))
+ self.d.C_VerifyUpdate(session, data, len(data))
def C_VerifyFinal(self, session, signature):
- self.so.C_VerifyFinal(session, signature, len(signature))
+ self.d.C_VerifyFinal(session, signature, len(signature))
def C_CreateObject(self, session, template = None, **kwargs):
if kwargs:
@@ -240,28 +257,28 @@ class PKCS11 (object):
template = kwargs
template = self.adb.to_ctypes(template)
handle = CK_OBJECT_HANDLE()
- self.so.C_CreateObject(session, template, len(template), byref(handle))
+ self.d.C_CreateObject(session, template, len(template), byref(handle))
return handle.value
def C_DigestInit(self, session, mechanism_type):
mechanism = CK_MECHANISM(mechanism_type, None, 0)
- self.so.C_DigestInit(session, byref(mechanism))
+ self.d.C_DigestInit(session, byref(mechanism))
def C_Digest(self, session, data):
n = CK_ULONG()
- self.so.C_Digest(session, data, len(data), None, byref(n))
+ self.d.C_Digest(session, data, len(data), None, byref(n))
hash = create_string_buffer(n.value)
- self.so.C_Digest(session, data, len(data), hash, byref(n))
+ self.d.C_Digest(session, data, len(data), hash, byref(n))
return hash.raw
def C_DigestUpdate(self, session, data):
- self.so.C_DigestUpdate(session, data, len(data))
+ self.d.C_DigestUpdate(session, data, len(data))
def C_DigestFinal(self, session):
n = CK_ULONG()
- self.so.C_DigestFinal(session, None, byref(n))
+ self.d.C_DigestFinal(session, None, byref(n))
hash = create_string_buffer(n.value)
- self.so.C_DigestFinal(session, hash, byref(n))
+ self.d.C_DigestFinal(session, hash, byref(n))
return hash.raw
__all__ = ["PKCS11"]
diff --git a/cryptech/py11/exceptions.py b/cryptech/py11/exceptions.py
index 7f86fe4..9512cda 100644
--- a/cryptech/py11/exceptions.py
+++ b/cryptech/py11/exceptions.py
@@ -28,6 +28,11 @@ class CKR_Exception(Exception):
def __int__(self):
return self.ckr_code
+ @classmethod
+ def raise_on_failure(cls, rv, func, *args):
+ if rv != CKR_OK:
+ raise cls.ckr_map[rv]
+
CKR_OK = 0x00000000
class CKR_CANCEL (CKR_Exception): ckr_code = 0x00000001
diff --git a/cryptech/py11/prototypes.py b/cryptech/py11/prototypes.py
deleted file mode 100644
index 7951515..0000000
--- a/cryptech/py11/prototypes.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# An attempt at a Python interface to PKCS 11 using the scary ctypes
-# module from the Python standard library.
-
-from ctypes import *
-from .types import *
-
-# Prototypes for the PKCS #11 public functions.
-#
-# We don't bother implementing C_GetFunctionList(), because it would
-# be extremely tedious and it's not all that useful to us in Python.
-# Instead, we emulate its behavior in the PKCS11 class.
-
-Prototypes = dict(
- C_Initialize = [CK_VOID_PTR],
- C_Finalize = [CK_VOID_PTR],
- C_GetInfo = [CK_INFO_PTR],
-# C_GetFunctionList = [CK_FUNCTION_LIST_PTR_PTR],
- C_GetSlotList = [CK_BBOOL, CK_SLOT_ID_PTR, CK_ULONG_PTR],
- C_GetSlotInfo = [CK_SLOT_ID, CK_SLOT_INFO_PTR],
- C_GetTokenInfo = [CK_SLOT_ID, CK_TOKEN_INFO_PTR],
- C_GetMechanismList = [CK_SLOT_ID, CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR],
- C_GetMechanismInfo = [CK_SLOT_ID, CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR],
- C_InitToken = [CK_SLOT_ID, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR],
- C_InitPIN = [CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG],
- C_SetPIN = [CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR, CK_ULONG],
- C_OpenSession = [CK_SLOT_ID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY, CK_SESSION_HANDLE_PTR],
- C_CloseSession = [CK_SESSION_HANDLE],
- C_CloseAllSessions = [CK_SLOT_ID],
- C_GetSessionInfo = [CK_SESSION_HANDLE, CK_SESSION_INFO_PTR],
- C_GetOperationState = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR],
- C_SetOperationState = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE],
- C_Login = [CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG],
- C_Logout = [CK_SESSION_HANDLE],
- C_CreateObject = [CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR],
- C_CopyObject = [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR],
- C_DestroyObject = [CK_SESSION_HANDLE, CK_OBJECT_HANDLE],
- C_GetObjectSize = [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR],
- C_GetAttributeValue = [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG],
- C_SetAttributeValue = [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG],
- C_FindObjectsInit = [CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG],
- C_FindObjects = [CK_SESSION_HANDLE, CK_OBJECT_HANDLE_PTR, CK_ULONG, CK_ULONG_PTR],
- C_FindObjectsFinal = [CK_SESSION_HANDLE],
- C_EncryptInit = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE],
- C_Encrypt = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_EncryptUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_EncryptFinal = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DecryptInit = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE],
- C_Decrypt = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DecryptUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DecryptFinal = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DigestInit = [CK_SESSION_HANDLE, CK_MECHANISM_PTR],
- C_Digest = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DigestUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG],
- C_DigestKey = [CK_SESSION_HANDLE, CK_OBJECT_HANDLE],
- C_DigestFinal = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR],
- C_SignInit = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE],
- C_Sign = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_SignUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG],
- C_SignFinal = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR],
- C_SignRecoverInit = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE],
- C_SignRecover = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_VerifyInit = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE],
- C_Verify = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG],
- C_VerifyUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG],
- C_VerifyFinal = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG],
- C_VerifyRecoverInit = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE],
- C_VerifyRecover = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DigestEncryptUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DecryptDigestUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_SignEncryptUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_DecryptVerifyUpdate = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR],
- C_GenerateKey = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR],
- C_GenerateKeyPair = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG,
- CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR],
- C_WrapKey = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE,
- CK_BYTE_PTR, CK_ULONG_PTR],
- C_UnwrapKey = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG,
- CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR],
- C_DeriveKey = [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG,
- CK_OBJECT_HANDLE_PTR],
- C_SeedRandom = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG],
- C_GenerateRandom = [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG],
- C_GetFunctionStatus = [CK_SESSION_HANDLE],
- C_CancelFunction = [CK_SESSION_HANDLE],
- C_WaitForSlotEvent = [CK_FLAGS, CK_SLOT_ID_PTR, CK_VOID_PTR])
diff --git a/cryptech/py11/types.py b/cryptech/py11/types.py
index 4d0b279..1b233e7 100644
--- a/cryptech/py11/types.py
+++ b/cryptech/py11/types.py
@@ -2,6 +2,8 @@
# module from the Python standard library.
from ctypes import *
+from .types import *
+from .exceptions import *
# This code is derived from the RSA PKCS #11 C header files, which say:
#
@@ -178,3 +180,93 @@ class CK_C_INITIALIZE_ARGS (Structure):
("pReserved", CK_VOID_PTR)]
CK_C_INITIALIZE_ARGS_PTR = POINTER(CK_C_INITIALIZE_ARGS)
+
+# Prototypes for the PKCS #11 public functions.
+#
+# These used to be a separate module, but the forward references
+# needed to implement CK_FUNCTION_LIST are enough fun without adding a
+# gratuitous Python module loop too.
+
+class CK_FUNCTION_LIST (Structure):
+ pass
+
+CK_FUNCTION_LIST_PTR = POINTER(CK_FUNCTION_LIST)
+CK_FUNCTION_LIST_PTR_PTR = POINTER(CK_FUNCTION_LIST_PTR)
+
+Prototypes = (
+ ("C_Initialize", [CK_VOID_PTR]),
+ ("C_Finalize", [CK_VOID_PTR]),
+ ("C_GetInfo", [CK_INFO_PTR]),
+ ("C_GetFunctionList", [CK_FUNCTION_LIST_PTR_PTR]),
+ ("C_GetSlotList", [CK_BBOOL, CK_SLOT_ID_PTR, CK_ULONG_PTR]),
+ ("C_GetSlotInfo", [CK_SLOT_ID, CK_SLOT_INFO_PTR]),
+ ("C_GetTokenInfo", [CK_SLOT_ID, CK_TOKEN_INFO_PTR]),
+ ("C_GetMechanismList", [CK_SLOT_ID, CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR]),
+ ("C_GetMechanismInfo", [CK_SLOT_ID, CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR]),
+ ("C_InitToken", [CK_SLOT_ID, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR]),
+ ("C_InitPIN", [CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG]),
+ ("C_SetPIN", [CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR, CK_ULONG]),
+ ("C_OpenSession", [CK_SLOT_ID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY, CK_SESSION_HANDLE_PTR]),
+ ("C_CloseSession", [CK_SESSION_HANDLE]),
+ ("C_CloseAllSessions", [CK_SLOT_ID]),
+ ("C_GetSessionInfo", [CK_SESSION_HANDLE, CK_SESSION_INFO_PTR]),
+ ("C_GetOperationState", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_SetOperationState", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE]),
+ ("C_Login", [CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG]),
+ ("C_Logout", [CK_SESSION_HANDLE]),
+ ("C_CreateObject", [CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR]),
+ ("C_CopyObject", [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR]),
+ ("C_DestroyObject", [CK_SESSION_HANDLE, CK_OBJECT_HANDLE]),
+ ("C_GetObjectSize", [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR]),
+ ("C_GetAttributeValue", [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG]),
+ ("C_SetAttributeValue", [CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG]),
+ ("C_FindObjectsInit", [CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG]),
+ ("C_FindObjects", [CK_SESSION_HANDLE, CK_OBJECT_HANDLE_PTR, CK_ULONG, CK_ULONG_PTR]),
+ ("C_FindObjectsFinal", [CK_SESSION_HANDLE]),
+ ("C_EncryptInit", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE]),
+ ("C_Encrypt", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_EncryptUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_EncryptFinal", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DecryptInit", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE]),
+ ("C_Decrypt", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DecryptUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DecryptFinal", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DigestInit", [CK_SESSION_HANDLE, CK_MECHANISM_PTR]),
+ ("C_Digest", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DigestUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG]),
+ ("C_DigestKey", [CK_SESSION_HANDLE, CK_OBJECT_HANDLE]),
+ ("C_DigestFinal", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_SignInit", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE]),
+ ("C_Sign", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_SignUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG]),
+ ("C_SignFinal", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_SignRecoverInit", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE]),
+ ("C_SignRecover", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_VerifyInit", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE]),
+ ("C_Verify", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG]),
+ ("C_VerifyUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG]),
+ ("C_VerifyFinal", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG]),
+ ("C_VerifyRecoverInit", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE]),
+ ("C_VerifyRecover", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DigestEncryptUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DecryptDigestUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_SignEncryptUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_DecryptVerifyUpdate", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_GenerateKey", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR]),
+ ("C_GenerateKeyPair", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG,
+ CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR]),
+ ("C_WrapKey", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE,
+ CK_BYTE_PTR, CK_ULONG_PTR]),
+ ("C_UnwrapKey", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG,
+ CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR]),
+ ("C_DeriveKey", [CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG,
+ CK_OBJECT_HANDLE_PTR]),
+ ("C_SeedRandom", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG]),
+ ("C_GenerateRandom", [CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG]),
+ ("C_GetFunctionStatus", [CK_SESSION_HANDLE]),
+ ("C_CancelFunction", [CK_SESSION_HANDLE]),
+ ("C_WaitForSlotEvent", [CK_FLAGS, CK_SLOT_ID_PTR, CK_VOID_PTR]))
+
+CK_FUNCTION_LIST._fields_ = ([("version", CK_VERSION)] +
+ [(_name, CFUNCTYPE(*([CK_RV] + _args)))
+ for _name, _args in Prototypes])