# An attempt at a Python interface to PKCS 11 using the scary ctypes # module from the Python standard library. from ctypes import * # This code is derived from the RSA PKCS #11 C header files, which say: # # License to copy and use this software is granted provided that it is # identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface # (Cryptoki)" in all material mentioning or referencing this software. # # License is also granted to make and use derivative works provided that # such works are identified as "derived from the RSA Security Inc. PKCS #11 # Cryptographic Token Interface (Cryptoki)" in all material mentioning or # referencing the derived work. # # RSA Security Inc. makes no representations concerning either the # merchantability of this software or the suitability of this software for # any particular purpose. It is provided "as is" without express or implied # warranty of any kind. # This is not a complete set of PKCS #11 types, because the full set # with all the optional mechanisms is tediously long and each # structure type requires hand conversion. Goal at the moment is to # cover stuff we care about in the base specification. Add other # mechanism-specific stuff later as needed. # Mapping beween C and Python at the lowest level isn't perfect # because characters are integer types in C while they're strings in # Python. It looks like we want the string handling in most cases # other than CK_BBOOL and CK_VERSION, map lowest-level PKCS #11 types # accordingly. CK_BYTE = c_char CK_CHAR = CK_BYTE CK_UTF8CHAR = CK_BYTE CK_BBOOL = c_ubyte CK_ULONG = c_ulong CK_LONG = c_long CK_FLAGS = CK_ULONG CK_VOID_PTR = POINTER(c_char) CK_BYTE_PTR = POINTER(CK_BYTE) CK_CHAR_PTR = POINTER(CK_CHAR) CK_UTF8CHAR_PTR = POINTER(CK_UTF8CHAR) CK_ULONG_PTR = POINTER(CK_ULONG) CK_VOID_PTR_PTR = POINTER(CK_VOID_PTR) class CK_VERSION (Structure): _fields_ = [("major", c_ubyte), ("minor", c_ubyte)] CK_VERSION_PTR = POINTER(CK_VERSION) class CK_INFO (Structure): _fields_ = [("cryptokiVersion", CK_VERSION), ("manufacturerID", CK_UTF8CHAR * 32), ("flags", CK_FLAGS), ("libraryDescription", CK_UTF8CHAR * 32), ("libraryVersion", CK_VERSION)] CK_INFO_PTR = POINTER(CK_INFO) CK_NOTIFICATION = CK_ULONG CK_SLOT_ID = CK_ULONG CK_SLOT_ID_PTR = POINTER(CK_SLOT_ID) class CK_SLOT_INFO (Structure): _fields_ = [("slotDescription", CK_UTF8CHAR * 64), ("manufacturerID", CK_UTF8CHAR * 32), ("flags", CK_FLAGS), ("hardwareVersion", CK_VERSION), ("firmwareVersion", CK_VERSION)] CK_SLOT_INFO_PTR = POINTER(CK_SLOT_INFO) class CK_TOKEN_INFO (Structure): _fields_ = [("label", CK_UTF8CHAR * 32), ("manufacturerID", CK_UTF8CHAR * 32), ("model", CK_UTF8CHAR * 16), ("serialNumber", CK_CHAR * 16), ("flags", CK_FLAGS), ("ulMaxSessionCount", CK_ULONG), ("ulSessionCount", CK_ULONG), ("ulMaxRwSessionCount", CK_ULONG), ("ulRwSessionCount", CK_ULONG), ("ulMaxPinLen", CK_ULONG), ("ulMinPinLen", CK_ULONG), ("ulTotalPublicMemory", CK_ULONG), ("ulFreePublicMemory", CK_ULONG), ("ulTotalPrivateMemory", CK_ULONG), ("ulFreePrivateMemory", CK_ULONG), ("hardwareVersion", CK_VERSION), ("firmwareVersion", CK_VERSION), ("utcTime", CK_CHAR * 16)] CK_TOKEN_INFO_PTR = POINTER(CK_TOKEN_INFO) CK_SESSION_HANDLE = CK_ULONG CK_SESSION_HANDLE_PTR = POINTER(CK_SESSION_HANDLE) CK_USER_TYPE = CK_ULONG CK_STATE = CK_ULONG class CK_SESSION_INFO (Structure): _fields_ = [("slotID", CK_SLOT_ID), ("state", CK_STATE), ("flags", CK_FLAGS), ("ulDeviceError", CK_ULONG)] CK_SESSION_INFO_PTR = POINTER(CK_SESSION_INFO) CK_OBJECT_HANDLE = CK_ULONG CK_OBJECT_HANDLE_PTR = POINTER(CK_OBJECT_HANDLE) CK_OBJECT_CLASS = CK_ULONG CK_OBJECT_CLASS_PTR = POINTER(CK_OBJECT_CLASS) CK_HW_FEATURE_TYPE = CK_ULONG CK_KEY_TYPE = CK_ULONG CK_CERTIFICATE_TYPE = CK_ULONG CK_ATTRIBUTE_TYPE = CK_ULONG class CK_ATTRIBUTE (Structure): _fields_ = [("type", CK_ATTRIBUTE_TYPE), ("pValue", CK_VOID_PTR), ("ulValueLen", CK_ULONG)] CK_ATTRIBUTE_PTR = POINTER(CK_ATTRIBUTE) class CK_DATE (Structure): _fields_ = [("year", CK_CHAR * 4), ("month", CK_CHAR * 2), ("day", CK_CHAR * 2)] CK_MECHANISM_TYPE = CK_ULONG CK_MECHANISM_TYPE_PTR = POINTER(CK_MECHANISM_TYPE) class CK_MECHANISM (Structure): _fields_ = [("mechanism", CK_MECHANISM_TYPE), ("pParameter", CK_VOID_PTR), ("ulParameterLen", CK_ULONG)] CK_MECHANISM_PTR = POINTER(CK_MECHANISM) class CK_MECHANISM_INFO (Structure): _fields_ = [("ulMinKeySize", CK_ULONG), ("ulMaxKeySize", CK_ULONG), ("flags", CK_FLAGS)] CK_MECHANISM_INFO_PTR = POINTER(CK_MECHANISM_INFO) CK_RV = CK_ULONG CK_NOTIFY = CFUNCTYPE(CK_RV, CK_SESSION_HANDLE, CK_NOTIFICATION, CK_VOID_PTR) CK_CREATEMUTEX = CFUNCTYPE(CK_RV, CK_VOID_PTR_PTR) CK_DESTROYMUTEX = CFUNCTYPE(CK_RV, CK_VOID_PTR) CK_LOCKMUTEX = CFUNCTYPE(CK_RV, CK_VOID_PTR) CK_UNLOCKMUTEX = CFUNCTYPE(CK_RV, CK_VOID_PTR) class CK_C_INITIALIZE_ARGS (Structure): _fields_ = [("CreateMutex", CK_CREATEMUTEX), ("DestroyMutex", CK_DESTROYMUTEX), ("LockMutex", CK_LOCKMUTEX), ("UnlockMutex", CK_UNLOCKMUTEX), ("flags", CK_FLAGS), ("pReserved", CK_VOID_PTR)] CK_C_INITIALIZE_ARGS_PTR = POINTER(CK_C_INITIALIZE_ARGS)