aboutsummaryrefslogblamecommitdiff
path: root/cryptech/py11/types.py
blob: 1b233e79d654347c933894f7f7f595aef031b751 (plain) (tree)
1
2
3
4
5
6



                                                                    

                         















































































































































































                                                                                                           

























































































                                                                                                                       
# 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 *
from .exceptions 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)

# 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])