Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions extern/load_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static P11_HANDLE* p11_open(PyObject *path_str) {
result = (P11_HANDLE*) PyMem_Malloc(sizeof(P11_HANDLE));
result->lib_handle = handle;
result->get_function_list_ptr = ptr;
result->get_interface_ptr = GetProcAddress(handle, "C_GetInterface");
}
}
return result;
Expand Down Expand Up @@ -85,6 +86,7 @@ static P11_HANDLE* p11_open(PyObject *path_str) {
result = (P11_HANDLE*) PyMem_Malloc(sizeof(P11_HANDLE));
result->lib_handle = handle;
result->get_function_list_ptr = ptr;
result->get_interface_ptr = dlsym(handle, "C_GetInterface");
}
}
return result;
Expand Down
3 changes: 2 additions & 1 deletion extern/load_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ typedef void *LIB_HANDLE;
#ifndef P11_HANDLE
typedef struct P11_HANDLE {
LIB_HANDLE lib_handle;
void * get_function_list_ptr;
void *get_function_list_ptr;
void *get_interface_ptr; /* C_GetInterface direct export; NULL for v2.0 libs */
} P11_HANDLE;
#endif

Expand Down
165 changes: 165 additions & 0 deletions pkcs11/_pkcs11.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ cdef extern from '../extern/cryptoki.h':
CK_ULONG ulContextDataLen
CK_BYTE *pContextData

ctypedef struct CK_INTERFACE:
CK_UTF8CHAR *pInterfaceName
void *pFunctionList
CK_FLAGS flags

cdef struct CK_FUNCTION_LIST:
CK_VERSION version
## pointers to library functions are stored here
Expand Down Expand Up @@ -600,10 +605,170 @@ cdef extern from '../extern/cryptoki.h':
CK_SLOT_ID *slot,
void *pRserved) nogil


cdef struct CK_FUNCTION_LIST_3_0:
CK_RV C_GetInterfaceList(CK_INTERFACE *pInterfacesList,
CK_ULONG *pulCount) nogil

CK_RV C_GetInterface(CK_UTF8CHAR *pInterfaceName,
CK_VERSION *pVersion,
CK_INTERFACE **ppInterface,
CK_FLAGS flags) nogil

CK_RV C_LoginUser(CK_SESSION_HANDLE hSession,
CK_USER_TYPE userType,
CK_UTF8CHAR *pPin,
CK_ULONG ulPinLen,
CK_UTF8CHAR *pUsername,
CK_ULONG ulUsernameLen) nogil

CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession,
CK_FLAGS flags) nogil

CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM *pMechanism,
CK_OBJECT_HANDLE hKey) nogil

CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pAssociatedData,
CK_ULONG ulAssociatedDataLen,
CK_BYTE *pPlaintext,
CK_ULONG ulPlaintextLen,
CK_BYTE *pCiphertext,
CK_ULONG *pulCiphertextLen) nogil

CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pAssociatedData,
CK_ULONG ulAssociatedDataLen) nogil

CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pPlaintextPart,
CK_ULONG ulPlaintextPartLen,
CK_BYTE *pCiphertextPart,
CK_ULONG *pulCiphertextPartLen,
CK_FLAGS flags) nogil

CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession) nogil

CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM *pMechanism,
CK_OBJECT_HANDLE hKey) nogil

CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pAssociatedData,
CK_ULONG ulAssociatedDataLen,
CK_BYTE *pCiphertext,
CK_ULONG ulCiphertextLen,
CK_BYTE *pPlaintext,
CK_ULONG *pulPlaintextLen) nogil

CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pAssociatedData,
CK_ULONG ulAssociatedDataLen) nogil

CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pCiphertextPart,
CK_ULONG ulCiphertextPartLen,

CK_ULONG *pulPlaintextPartLen,
CK_FLAGS flags) nogil

CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession) nogil

CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM *pMechanism,
CK_OBJECT_HANDLE hKey) nogil

CK_RV C_SignMessage(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pData,
CK_ULONG ulDataLen,
CK_BYTE *pSignature,
CK_ULONG *pulSignatureLen) nogil

CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen) nogil

CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pData,
CK_ULONG ulDataLen,
CK_BYTE *pSignature,
CK_ULONG *pulSignatureLen) nogil

CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession) nogil

CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM *pMechanism,
CK_OBJECT_HANDLE hKey) nogil

CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pData,
CK_ULONG ulDataLen,
CK_BYTE *pSignature,
CK_ULONG ulSignatureLen) nogil

CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen) nogil

CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession,
void *pParameter,
CK_ULONG ulParameterLen,
CK_BYTE *pData,
CK_ULONG ulDataLen,
CK_BYTE *pSignature,
CK_ULONG ulSignatureLen) nogil

CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession) nogil


cdef struct CK_FUNCTION_LIST_3_2:
CK_RV C_EncapsulateKey(CK_SESSION_HANDLE session,
CK_MECHANISM *mechanism,
CK_OBJECT_HANDLE public_key,
CK_ATTRIBUTE *template,
CK_ULONG count,
CK_BYTE *ciphertext,
CK_ULONG *ciphertext_len,
CK_OBJECT_HANDLE *key) nogil
CK_RV C_DecapsulateKey(CK_SESSION_HANDLE session,
CK_MECHANISM *mechanism,
CK_OBJECT_HANDLE private_key,
CK_ATTRIBUTE *template,
CK_ULONG count,
CK_BYTE *ciphertext,
CK_ULONG ciphertext_len,
CK_OBJECT_HANDLE *key) nogil

# The only external API call that must be defined in a PKCS#11 library
# All other APIs are taken from the CK_FUNCTION_LIST table
ctypedef CK_RV (*C_GetFunctionList_ptr) (CK_FUNCTION_LIST **) nogil

ctypedef CK_RV (*C_GetInterface_ptr)(
CK_UTF8CHAR *pInterfaceName,
CK_VERSION *pVersion,
CK_INTERFACE **ppInterface,
CK_FLAGS flags
) nogil

ctypedef CK_RV (*KeyOperationInit) (
CK_SESSION_HANDLE session,
CK_MECHANISM *mechanism,
Expand Down
35 changes: 32 additions & 3 deletions pkcs11/_pkcs11.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ cdef class lib(HasFuncList)

cdef class HasFuncList:
cdef CK_FUNCTION_LIST *funclist
cdef CK_FUNCTION_LIST_3_0 *funclist30
cdef CK_FUNCTION_LIST_3_2 *funclist32

def __cinit__(self, *args, **kwargs):
self.funclist = NULL
self.funclist30 = NULL
self.funclist32 = NULL


cdef assertRV(rv) with gil:
Expand Down Expand Up @@ -451,6 +455,8 @@ cdef class Token(HasFuncList, types.Token):

cdef Token token = Token.__new__(Token)
token.funclist = slot.funclist
token.funclist30 = slot.funclist30
token.funclist32 = slot.funclist32
token.slot = slot
token.label = _CK_UTF8CHAR_to_str(label)
token.serial = serial_number.rstrip()
Expand Down Expand Up @@ -870,6 +876,8 @@ cdef class Session(HasFuncList, types.Session):
cdef Session session = Session.__new__(Session)

session.funclist = token.funclist
session.funclist30 = token.funclist30
session.funclist32 = token.funclist32
session.token = token

session.handle = handle
Expand Down Expand Up @@ -1960,6 +1968,7 @@ _CLASS_MAP = {
cdef extern from "../extern/load_module.c":
ctypedef struct P11_HANDLE:
void *get_function_list_ptr
void *get_interface_ptr

object p11_error()
P11_HANDLE* p11_open(object path_str)
Expand Down Expand Up @@ -2063,6 +2072,25 @@ cdef class lib(HasFuncList):
self._cryptoki_version = info.cryptokiVersion
self._library_version = info.libraryVersion

# Prefer v3.2, fall back to v3.0. PKCS#11 3.0+ libraries export
# C_GetInterface as a direct symbol; older libraries leave it absent.
cdef C_GetInterface_ptr get_interface
cdef CK_INTERFACE *iface
cdef CK_VERSION ver
if self._p11_handle.get_interface_ptr != NULL:
get_interface = <C_GetInterface_ptr>self._p11_handle.get_interface_ptr
ver.major = 3
ver.minor = 2
retval = get_interface(<CK_UTF8CHAR*>"PKCS 11", &ver, &iface, 0)
if retval == CKR_OK and iface != NULL:
self.funclist32 = <CK_FUNCTION_LIST_3_2*>iface.pFunctionList
else:
ver.major = 3
ver.minor = 0
retval = get_interface(<CK_UTF8CHAR*>"PKCS 11", &ver, &iface, 0)
if retval == CKR_OK and iface != NULL:
self.funclist30 = <CK_FUNCTION_LIST_3_0*>iface.pFunctionList

@property
def library_version(self):
"""Hardware version (:class:`tuple`)."""
Expand Down Expand Up @@ -2117,9 +2145,10 @@ cdef class lib(HasFuncList):
retval = self.funclist.C_GetSlotInfo(slot_id, &info)
assertRV(retval)

slots.append(
Slot.make(self.funclist, slot_id, info, self._cryptoki_version)
)
slot = Slot.make(self.funclist, slot_id, info, self._cryptoki_version)
slot.funclist30 = self.funclist30
slot.funclist32 = self.funclist32
slots.append(slot)

return slots

Expand Down
Loading