Copyright (C) 2004 Midori (http:/www.paipai.net/)
Verbatim copying and distribution of this entire article are permitted worldwide,
without royalty, in any medium, provided this notice, and the copyright notice,
are preserved.
Contents:
This wrapper has been generated with the help of the SWIG compiler, a wrapper
generator.
Just differences from original PKCS#11 API are documented.
Anything not documented here can be found on the PKCS#11
specification.
Please don't think about this documentation as a replacement for the PKCS#11
manual :)
The PKCS#11 API is very C oriented,
so a C++ wrapper over the original PKCS#11 API has been created
This C++ wrapper exports the interface of
some PKCS#11 function in a
more "Python oriented" way (using stl collections, that are well
wrapped by SWIG and are easy to use with Python because are very
similar to Lists
and Tuples).
The C++ has been chosen as wrapping language because SWIG supports it very
well.
This document ISN'T A PKCS#11 API reference replacement.
You NEED to know most of the PKCS#11
API you need if you want to use PyKCS11.
The PKCS#11 reference contained in
this document just shows differences between PyKCS11 and the original
PKCS#11 API.
Please don't ask us how to use the PKCS#11 API, consult instead the
original RSA PKCS#11 documentation:
http://www.rsasecurity.com/rsalabs
http://www.rsasecurity.com/rsalabs/node.asp?id=2133
ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf
1) Since most PKCS#11 structures are read only, strings
located inside such a structure (i.e. a fixed length string padded
with space character, not null
terminated) is not accessed directly, but
using an accessor function named GetTheOriginalNameOfTheStringVar(),
that convert the PKCS#11 padded string to a Python string.
Example:
typedef struct CK_INFO {
CK_VERSION cryptokiVersion;
unsigned char manufacturerID[32];
unsigned long flags;
unsigned char libraryDescription[32];
CK_VERSION libraryVersion;
} CK_INFO;
The manufacturerID field is accessed using the GetManufacturerID()
method of a CK_INFO instance.
The libraryDescription field is accessed using the
GetLibraryDescription() method of a CK_INFO instance.
ckInfo = PyKCS11.CK_INFO()
...
print "Manufacturer is: ", ckInfo.GetManufacturerID()
2) Any string input parameter passed as
array/length pair is wrapped as
Python string
In example, the C_Login function:
C_Login's original prototype: C_Login(CK_SESSION_HANDLE hSession, CK_CHAR*
pPin, CK_ULONG ulPinLen)
C_Login's prototype in PyKCS11: C_Login(CK_SESSION_HANDLE hSession, String Pin)
So in a Python script:
p11Lib = PyKCS11.CPKCS11Lib()
# ... other P11 calls ...
Pin = "123456"
rv = p11Lib.C_Login(PyKCS11.CKU_USER, Pin)
print "C_Login returned ", rv
3) All input and output bytes array parameters are
passed as
ckbytelist
type, instead of array/length pair.
The ckbytelist
is much like a Python list.
The PKCS#11 API uses a convention to retrieve unknown length data;
usually this convention is leaved unchanged (an exception
is the C_GetSlotList function).
Why that? This wrapper does not have the purpose to simplify
the usage of the PKCS#11 API inside Python. It just is a tool to
call the PKCS#11 in the way you would do using C (that is, the
extension is designed to be a PKCS#11 testing tool to create
test script in a simpler way).
So, to retrieve unknown length byte array you should create an empty ckbytelist object; then
you should call the PKCS#11 function a first time:
this first call just returns the data length; now
you should call the function again using exactly same parameters
to retrieve actual data.
4) PKCS#11 Templates (CK_ATTRIBUTE arrays)
are passed as ckattrlist type. The ckattrlist is
much like a Python list.
ckattrlist is a list of CK_ATTRIBUTE_SMART structures,
a CK_ATTRIBUTE extension; CK_ATTRIBUTE_SMART has
some helper method that let you
set and get values using Python basic types.
Additional notes about the C_GetAttributeValue()
function, the only one that uses attribute templates as output.
This function should be called twice, once to know the values' length and another
time to retrieve actual values.
5) PKCS#11 wrapped functions returns the PKCS#11 error codes unchanged. No exceptions are thrown while a PKCS#11 error is returned, you should check return value for errors exactly as you would do in C.
6) All PKCS#11 defines (return codes, attribute types, mechanism types, etc) are declared as constants in the PyKCS11 module. The name of each constant is exactly the C define name (i.e. CKR_OK, CKA_LABEL, CKM_RSA_PKCS, CKU_USER, etc.)
PyKCS11 is composed by 2 Python modules, _PyKCS11.dll (or
.so, or any other Dynamic Library extension your OS uses) and PyKCS11.py.
_PyKCS11.dll is the native code wrapper, a native
Python module that calls the PKCS#11 API. PyKCS11.py is
a pure-Python helper module that just encapsulates _PyKCS11.dll functions
inside nice Python objects (that is, _PyKCS11.dll interface
is not object oriented, while PyKCS11.py does).
To call PyKCS11, you should place_PyKCS11.dll and PyKCS11.py files
inside the Python's libraries folder or in the script folder, then you should
import the PyKCS11 module in your script, i.e. like this:
import PyKCS11
PyKCS11 module defines some custom data type, used i.e. to return session
and object handles, list of slots and binary data.
There is also a group of wrappers for all PKCS#11 structures, such as
CK_SESSION_INFO.
ck[...]list |
The ck[...]list types are used
by PyKCS11 to
receive or return collections of data. i.e. the ckintlist is
used to get
or pass list of numeric values, while ckbytelist is
just like a byte array and is used to pass or get binary data. Example 1: Example 2: There is also some other method, as size() and clear(). Usually you don't need to call that methods while using this types with PyKCS11, so they are not documented (you can see them in the PyKCS11.py file) |
ckintlist | A list of numeric values. Is used to pass or get lists
of numeric value; i.e. is used by C_GetSlotList() to return a list
of available slots (as a list of SlotIDs). |
ckbytelist | Represents an array of bytes; is used every time a binary buffer should
be passed to a PKCS#11 function. Can be used as a list, so you can
iterate on it like this: Note: to avoid the double call mechanism you can use the ckintlist's method reserve(new_list_len) or you can specify an initial length when you create the ckintlist instance: ToBeSignedBuffer = PyKCS11.ckbytelist(1024) |
ckattrlist | Represents an array of CK_ATTRIBUTE_SMART objects. Is used every time a PKCS#11 Template is involved. The C_GetAttributeValue() function is the only one that use this type as output. |
CK_ATTRIBUTE_SMART | Is an extension for the PKCS#11 structure CK_ATTRIBUTE.
The CK_ATTRIBUTE structure (se
also PKCS#11 templates) is widely used in the PKCS#11 API to
set or
get Object's
attributes or while creating objects or generating keys. A CK_ATTRIBUTE
can contain any type of value as internally it is stored ad a
byte array. |
CK_VERSION | See the PKCS#11 API reference |
CK_INFO | The manufacturerID and libraryDescription fields can be accessed using GetManufacturerID() and GetLibraryVersion() methods. For more details about this structure please consult the PKCS#11 API reference. |
CK_SLOT_INFO | The manufacturerID, slotDescription, hardwareVersion and firmwareVersion fields can be accessed using GetManufacturerID(), GetSlotDescription(), GetHardwareVersion() and GetFirmwareVersion() methods. For more details about this structure please consult the PKCS#11 API reference. |
CK_TOKEN_INFO | The manufacturerID, model and firmwareVersion fields can be accessed using GetManufacturerID(), GetModel() and GetFirmwareVersion() methods. For more details about this structure please consult the PKCS#11 API reference. |
CK_SESSION_INFO | See the PKCS#11 API reference |
CK_DATE | The year, month and day fields can be accessed using GetYear(), GetMonth() and GetDay() methods. For more details about this structure please consult the PKCS#11 API reference. |
CK_MECHANISM | See the PKCS#11 API reference |
CK_MECHANISM_INFO | See the PKCS#11 API reference |
CK_ATTRIBUTE_SMART Methods:
Reset() | Make the object instance empty: reset the value and the type |
ResetValue() | Just make the value empty, leaving the type unchanged. |
Reserve(numeric len) | Allocates enough space to store a number of bytes specified in the len parameter. |
GetType() | Returns the Attribute Type (look for CK_ATTRIBUTE_TYPE in the PKCS#11 API Reference) |
SetType() | Set the Attribute Type |
GetLen() | Get the Attribute size expressed in bytes |
IsString() | Returns true if the value contained is a string (the type contained is detected using the Attribute Type value) |
IsBool() | Returns true if the value contained is boolean (the type contained is detected using the Attribute Type value) |
IsNum() | Returns true if the value contained is numeric (the type contained is detected using the Attribute Type value) |
IsBin() | Returns true if the value contained isn't boolean, string or numeric (equivalent to not IsNum() and not IsBool() and not IsString() ) |
GetString() | Returns the contained value as string (no conversion is performed: if the value contained is not a PKCS#11 string, invalid data may be returned) |
SetString(string new_value) | Set the Attribute value to the string new_value |
GetNum() | Returns the contained value as Numeric. Note that if the Attribute doesn't contains a numeric value, always 0 is returned. |
SetNum(numeric new_value) | Set the Attribute value to the numeric new_value |
GetBool() | Returns the contained value as Boolean. Note that if the Attribute doesn't contains a Boolean value, always false is returned. |
SetBool() | Set the Attribute value to the boolean new_value |
GetBin() | Return the raw Attribute Value, as a tuple of byte (returns a ckbytelist object) |
SetBin(list/tuple new_value) | Set the Attribute value to the raw new_value. The new_value should be a list or tuple |
CPKCS11Lib represents a PKCS#11 library instance. It almost exposes the complete PKCS#11 interface and some additional methods as Load() and Unload().
Example of use:
import PyKCS11
p11Lib = PyKCS11.CPKCS11Lib() # creates a CPKCS11Lib instance
lib_path = "PKCS11Lib.dll"
info = PyKCS11.CK_INFO() # creates a CK_INFO instance
slotInfo = PyKCS11.CK_SLOT_INFO() # creates a CK_SLOT_INFO instance
slotList = PyKCS11.ckintlist() # creates a ckintlist instance to store the
SlotList
rv = p11Lib.Load(lib_path,
1)
print "Load():", rv
rv = p11Lib.C_GetInfo(info)
print "C_GetInfo():", rv
print "manufacturerID:", info.GetManufacturerID()
del info
rv = p11Lib.C_GetSlotList(0, slotList)
print "C_GetSlotList():", rv
print "\tAvailable Slots: " + str(len(slotList))
bool CPKCS11Lib.Load(string szLib, bool bAutoCallInitialize)
Loads a PKCS#11 Library.
szLib | The library to load (name or full path) |
bAutoCallInitialize | Automatically calls C_Initialize(), if needed |
Returns | True if the load succeeded |
Unloads a PKCS#11 Library.
Returns | Nothing |
Example of use:
import PyKCS11
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
...
if bLoadResult: p11.Unload()
Abstract of what follows: PKCS#11 API is not designed to be used by different modules that runs inside a single process, if that modules doesn't are aware of each other presence!
PyKCS11 is able to load same PKCS#11 Library more than
once in a transparent
way if you pass the bAutoCallInitialize parameter as true.
PKCS#11 API says that the C_Initialize()
MUST be called only
once by
a single process; if you call it more than once, an error is reported;
but this is not the problem.
Problems begins when C_Finalize() is called!
The library became unusable when C_Finalize()
is called, so if you load same library more than once
the C_Finalize() MUST be called only when
there is no more code that needs to use the Library.
So, if you call the Load() method using the bAutoCallInitialize parameter
set to true, the C_Finalize() is called only when the last CPKCS11Lib instance
is deleted.
Some issue still exists:
CK_RV CPKCS11Lib.C_Initialize()
Initializes the loaded library. Doesn't take any parameter (the
original PKCS#11 takes void* parameter; NULL will be passed to the PKCS#11
library)
CK_RV CPKCS11Lib.C_Finalize()
Finalize the loaded library. Doesn't take any parameter (the
original PKCS#11 takes void* parameter; NULL will be passed to the PKCS#11
library)
CK_RV CPKCS11Lib.C_GetInfo(CK_INFO Info)
Get Library information. Can be used to detect if the library is
Initialized (CKR_CRYPTOKI_NOT_INITIALIZED is returned if C_Initialize
needs to be called)
Takes a CK_INFO instance as parameter.
Example of use:
import PyKCS11
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
info = PyKCS11.CK_INFO()
rv = p11.C_GetInfo(info)
CK_RV CPKCS11Lib.C_GetSlotList (bool TokenPresent, ckintlist slotList)
Get a list of available slots. The list is placed inside the
slotList parameter. The function
can be called passing a slotList instance
of any length: it would be resized to contain the actual slot
list size (this is an exception to the normal behavior)
slotList parameter is used
instead of the pair CK_SLOT_ID* pSlotList and CK_UNLOG
uCount PKCS#11 original parameters.
Example of use:
import PyKCS11
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
slotList = PyKCS11.ckintlist()
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
print "C_GetSlotList():", rv
print "\tAvailable Slots: " + str(len(slotList))
CK_RV CPKCS11Lib.C_GetSlotInfo ( int slotID, CK_SLOT_INFO pInfo )
Get information about a slot. Accept a slot id (see C_GetSlotList()
function, a value contained in the slotList parameter),
and a CK_SLOT_INFO instance.
Example of use:
import PyKCS11
SlotInfos = PyKCS11.CK_SLOT_INFO()
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
print "C_GetSlotList():", rv
print "\tAvailable Slots: " + str(len(slotList))
rv = p11.C_GetSlotInfo(slotList[0], SlotInfos)
print "\tSlot ", slotList[0], " name:", SlotInfos.GetSlotDescription()
CK_RV CPKCS11Lib.C_GetTokenInfo ( int slotID, CK_Token_INFO Info )
Get information about a Token placed in a slot. Accept a slot id (see C_GetSlotList()
function, a value contained in the slotList parameter),
and a CK_TOKEN_INFO instance.
Example of use:
import PyKCS11
TokenInfos = PyKCS11.CK_TOKEN_INFO()
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
print "C_GetSlotList():", rv
print "\tAvailable Slots: " + str(len(slotList))
rv = p11.C_GetTokenInfo(slotList[0], TokenInfos)
print "\tSlot ", slotList[0], " name:", TokenInfos.GetSlotDescription()
CK_RV CPKCS11Lib.C_InitToken(int slotID, string Pin, string Label)
Initialize a Token. Accept a slot id (see C_GetSlotList()
function, a value contained in the slotList parameter),
a Pin and a token Label.
The original PKCS#11 function takes a pair "CK_CHAR* pPin, CK_ULONG
uPunLen", that became a Python string, passed as Pin parameter;
and another parameter "CK_CHAR Label[32]", a fixed length string
padded with the blanks (ASCII space character, 0x20), that became a Python
string
passed as Label parameter. Label length
can be between 0 and 32.
CK_RV CPKCS11Lib.C_InitPIN (CK_SESSION_HANDLE hSession, string Pin)
Initialize or reset the user Pin. Accept a session handle as first parameter
(hSession), and a new Pin.
The
original PKCS#11 function takes a pair "CK_CHAR* pPin, CK_ULONG
uPunLen", that became a Python string, passed as Pin parameter.
CK_RV CPKCS11Lib.C_SetPIN (CK_SESSION_HANDLE hSession, string OldPin,
string NewPin )
Changes a Pin. Accept a session handle as first
parameter (hSession) and the strings OldPin and
the
NewPin.
The original PKCS#11 function takes a pair "CK_CHAR* pOldPin, CK_ULONG
uOldPunLen", that became a Python string, passed as OldPin parameter;
and takes a pair "CK_CHAR* pNewPin, CK_ULONG
uNewPunLen", that became a Python string, passed as NewPin parameter.
CK_RV CPKCS11Lib.C_OpenSession (int slotID, int flags, CK_SESSION_HANDLE newhSession )
Open a new session on a Token. In the original prototype the newhSession parameter was a CK_SESSION_HANDLE pointer.
CK_RV CPKCS11Lib.C_CloseSession( CK_SESSION_HANDLE hSession )
Closes a session opened using C_OpenSession.
CK_RV CPKCS11Lib.C_CloseAllSessions ( int slotID )
Closes all session opened on a Token.
CK_RV CPKCS11Lib.C_Login (CK_SESSION_HANDLE hSession, int userType, string Pin )
Login a user on all sessions open on a Token. Accept a session handle obtained calling the C_OpenSession function, the type of user to login and the Pin to use.
CK_RV CPKCS11Lib.C_Logout ( CK_SESSION_HANDLE hSession )
Logout all sessions open on a Token. Accept a session handle obtained calling the C_OpenSession.
CK_RV CPKCS11Lib.C_GetSessionInfo ( CK_SESSION_HANDLE hSession, CK_SESSION_INFO Info )
Get some information about the specified session and copy them in the Info
object. In the original prototype the Info was
a CK_SESSION_INFO pointer.
Example of use:
import PyKCS11
TokenInfos = PyKCS11.CK_TOKEN_INFO()
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
session = PyKCS11.CK_SESSION_HANDLE()
sessionInfo = PyKCS11.CK_SESSION_INFO()
rv = p11.C_OpenSession(slotList[0], PyKCS11.CKF_SERIAL_SESSION,
session)
rv = p11.C_Login(session,
PyKCS11.CKU_USER,
"123456")
rv = p11.C_GetSessionInfo(session,
sessionInfo)
rv = p11.C_Logout(session)
rv = p11.C_CloseSession(
CK_RV CPKCS11Lib.C_CreateObject ( CK_SESSION_HANDLE hSession, vectorattr Template, CK_OBJECT_HANDLE outhObject )
This method can be used to create a new object. The Object template (that
is, object's attributes) is passed using the Template argument,
while the object handle is placed in the outhObject argument.
In the original prototype, Template was
a pair of arguments: a CK_TEMPLATE array and a numeric length of array,
while outhObject was
a CK_OBJECT_HANDLE pointer.
Template is a vectorattr object type, a list
of CK_ATTRIBUTE_SMART objects.
Example of use:
import PyKCS11
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
session = PyKCS11.CK_SESSION_HANDLE()
sessionInfo = PyKCS11.CK_SESSION_INFO()
rv = p11.C_OpenSession(slotList[0], PyKCS11.CKF_SERIAL_SESSION,
session)
rv = p11.C_Login(session,
PyKCS11.CKU_USER, "123456")
objTemplate = PyKCS11.vectorattr(4)
objValues = PyKCS11.vectorattr(2)
newObjValues = PyKCS11.vectorattr(1)
hObject = PyKCS11.CK_OBJECT_HANDLE()
objTemplate(0).SetBool(PyKCS11.CKA_TOKEN, 1)
objTemplate(1).SetNum(PyKCS11.CKA_CLASS, PyKCS11.CKO_DATA)
objTemplate(2).SetString(PyKCS11.CKA_LABEL, "TestDataObject")
objTemplate(3).SetString(PyKCS11.CKA_VALUE, "This is a sample Data Object")
rv = p11.C_CreateObject(session,
objTemplate, hObject)
objValues(0).SetType(PyKCS11.CKA_MODIFIABLE)
objValues(1).SetType(PyKCS11.CKA_PRIVATE)
rv = p11.C_GetAttributeValue(session, hObject,
objValues) # first call: just get sizes
rv = p11.C_GetAttributeValue(session,
hObject, objValues) # second call: get actual data
newObjValues(0).SetString(PyKCS11.CKA_APPLICATION, "Test")
rv = p11.C_SetAttributeValue(session, hObject, newObjValues)
rv = p11.C_DestroyObject(session, hObject)
rv = p11.C_Logout(session)
rv = p11.C_CloseSession(session)
CK_RV CPKCS11Lib.C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
This function destroys an object. You specify the object to destroy passing
an object handle previously obtained by C_FindObjects()
or any object creation function, such as C_CreateObject().
Example of use: see C_CreateObject().
CK_RV CPKCS11Lib.C_GetObjectSize (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, int outulSize)
Return the size of an object. The object's size is returned in the outulSize argument. In
the original prototype the outulSize was
a pointer to an unsigned long.
Example of use: see C_CreateObject().
CK_RV CPKCS11Lib.C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, vectorattr outTemplate)
Get object's attributes. outTemplate is
a vectorattr object type, a list
of CK_ATTRIBUTE_SMART objects. In the original
prototype outTemplate was a pair of arguments:
a CK_TEMPLATE array and a numeric length of that array.
Example of use: see C_CreateObject().
CK_RV CPKCS11Lib.C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, vectorattr Template )
Assign new values to object's attributes. Template is
a vectorattr object type, a list of CK_ATTRIBUTE_SMART objects.
In the original prototype outTemplate was
a pair of arguments: a CK_TEMPLATE array and a numeric length of that
array.
Example of use: see C_CreateObject().
CK_RV CPKCS11Lib.C_FindObjectsInit( CK_SESSION_HANDLE hSession, vectorattr Template )
Begin a search on a session using Template as search filter. In the original prototype Template was a pair of arguments: a CK_TEMPLATE array and a numeric length of that array.
Example of use:
import PyKCS11
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
session = PyKCS11.CK_SESSION_HANDLE()
rv = p11.C_OpenSession(slotList[0], PyKCS11.CKF_SERIAL_SESSION, session)
rv = p11.C_Login(session, PyKCS11.CKU_USER, "123456")
SearchResult = PyKCS11.ckintlist(10)
searchTemplate = PyKCS11.vectorattr(2)
searchTemplate[0].SetBool(PyKCS11.CKA_TOKEN, 1)
searchTemplate[1].SetNum(PyKCS11.CKA_CLASS, PyKCS11.CKO_CERTIFICATE)
rv = p11.C_FindObjectsInit(session, searchTemplate)
rv = p11.C_FindObjects(session, SearchResult)
rv = p11.C_FindObjectsFinal(session)
for x in SearchResult:
print "object " + hex(x)
valTemplate = PyKCS11.ckattrlist(1)
valTemplate[0].SetType(PyKCS11.CKA_LABEL)
rv = p11.C_GetAttributeValue(session,
x, valTemplate)
print "CKA_LABEL: ", valTemplate[0].GetString()
CK_RV CPKCS11Lib.C_FindObjects( CK_SESSION_HANDLE hSession, ckintlist outObjectsList )
Continue a search operation started by C_FindObjectsInit() on a session. Returns a list of object handles in the outObjectsList argument. In the original prototype outObjectsList was a pair of arguments: an array of CK_OBJECT_HANDLE and a numeric length of that array.
Example of use: see C_FindObjectsInit().
CK_RV CPKCS11Lib.C_FindObjectsFinal( CK_SESSION_HANDLE hSession )
Ends a search started on a session by C_FindObjectsInit().
Example of use: see C_FindObjectsInit().
CK_RV CPKCS11Lib.C_GenerateKeyPair(
CK_SESSION_HANDLE hSession, CK_MECHANISM Mechanism,
ckattrlist PublicKeyTemplate, ckattrlist PrivateKeyTemplate,
CK_OBJECT_HANDLE outhPublicKey,
CK_OBJECT_HANDLE outhPrivateKey )
Generate a new key pair using the specified templates for private and public
keys. The generated object handles are placed in outhPublicKey and
outhPrivateKey.
In the original prototype PublicKeyTemplate/PrivateKeyTemplate was a
pair of arguments: an array of CK_ATTRIBUTE and a numeric length of
that array. While outhPublicKey/outhPrivateKey was
a CK_OBJECT_HANDLE pointer.
Example of use: the use of this function is very similar to C_CreateObject().
CK_RV CPKCS11Lib.C_SignInit( CK_SESSION_HANDLE hSession, CK_MECHANISM Mechanism, CK_OBJECT_HANDLE hKey )
Start a signature on a session using the specified key.
Example of use: see C_Sign().
CK_RV CPKCS11Lib.C_Sign( CK_SESSION_HANDLE hSession, ckbytelist inData, ckbytelist outSignature )
Perform a signature operation. inData contains
the data to sign; after a successful call outSignature should
contain the signed data.
In the original prototype inData was
a pair of arguments: an array of CK_BYTE and a numeric length of that array;
while outSignature was another pair of
arguments: an array of CK_BYTE and a numeric length of that array used
to pass array
size and to get actual data length.
Example of use:
import PyKCS11
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
session = PyKCS11.CK_SESSION_HANDLE()
rv = p11.C_OpenSession(slotList[0], PyKCS11.CKF_SERIAL_SESSION,
session)
rv = p11.C_Login(session, PyKCS11.CKU_USER, "123456")
SearchResult = PyKCS11.ckintlist(10)
searchTemplate = PyKCS11.vectorattr(2)
searchTemplate[0].SetBool(PyKCS11.CKA_TOKEN, 1)
searchTemplate[1].SetNum(PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY)
rv = p11.C_FindObjectsInit(session, searchTemplate)
rv = p11.C_FindObjects(session, SearchResult)
rv = p11.C_FindObjectsFinal(session)
DataToSign = PyKCS11.ckbytelist(5)
Signature = PyKCS11.ckbytelist()
DataToSign[0] = 1
DataToSign[1] = 2
DataToSign[2] = 3
DataToSign[3] = 4
DataToSign[4] = 5
Mechanism = PyKCS11.CK_MECHANISM()
Mechanism.mechanism = PyKCS11.CKM_RSA_PKCS
for x in SearchResult:
rv = p11.C_SignInit(session, Mechanism, x)
rv = p11.C_Sign(session, DataToSign, Signature) # first
call get size
rv = p11.C_Sign(session, DataToSign, Signature) # second
call get the signature
CK_RV CPKCS11Lib.C_DecryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM Mechanism, CK_OBJECT_HANDLE hKey)
Start a decryption on a session using the specified key.
Example of use: see C_Decrypt().
CK_RV CPKCS11Lib.C_Decrypt ( CK_SESSION_HANDLE hSession, ckbytelist inEncryptedData, ckbytelist outData )
Perform a decryption on the specified session. inEncryptedData is
the data to decrypt, outData is where the
decrypted data would be placed.
In the original prototype inEncryptedData was
a pair of arguments: an array of CK_BYTE and a numeric length of that array;
while outData was
another pair of arguments: an array of CK_BYTE and a numeric
length of that array used to pass array size and to get actual data length.
Example of use:
import PyKCS11
p11 = PyKCS11.CPKCS11Lib() #create a lib instance
bLoadResult = p11.Load("p11lib.dll", true) #load a lib and calls C_Initialize.
rv = p11.C_GetSlotList(0, slotList)
session = PyKCS11.CK_SESSION_HANDLE()
rv = p11.C_OpenSession(slotList[0], PyKCS11.CKF_SERIAL_SESSION, session)
rv = p11.C_Login(session, PyKCS11.CKU_USER, "123456")
SearchResult = PyKCS11.ckintlist(10)
searchTemplate = PyKCS11.vectorattr(2)
searchTemplate[0].SetBool(PyKCS11.CKA_TOKEN, 1)
searchTemplate[1].SetNum(PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY)
rv = p11.C_FindObjectsInit(session, searchTemplate)
rv = p11.C_FindObjects(session, SearchResult)
rv = p11.C_FindObjectsFinal(session)
DataToDecrypt =
PyKCS11.ckbytelist(128)
DecryptedData = PyKCS11.ckbytelist()
# ... fill the
DataToDecrypt variable
Mechanism = PyKCS11.CK_MECHANISM()
Mechanism.mechanism = PyKCS11.CKM_RSA_PKCS
for x in SearchResult:
rv = p11.C_DecryptInit(session, Mechanism, x)
rv = p11.C_Decrypt(session, DataToDecrypt, DecryptedData) #
first call get the size
rv = p11.C_Decrypt(session, DataToDecrypt, DecryptedData) #
second call get the data
CK_RV CPKCS11Lib.C_EncryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM Mechanism,
CK_OBJECT_HANDLE hKey )
Start an encryption on a session using the specified key.
Example of use: see C_Encrypt().
CK_RV CPKCS11Lib.C_Encrypt ( CK_SESSION_HANDLE hSession, ckbytelist inData, ckbytelist outEncryptedData )
Perform an encryption on the specified session. inData is
the data to decrypt, outEncryptedData is where
the decrypted data would be placed.
In the original prototype inData was
a pair of arguments: an array of CK_BYTE and a numeric length of that array;
while outEncryptedData was another pair of arguments:
an array of CK_BYTE and a numeric length of that array used to pass array size
and to get actual data length.
Example of use: the usage is very similar to C_Encrypt().
This reference ends here.
We think that the above documentation is enough
to understand how to use all function of this wrapper; if you
need to know how to use other methods, please see the basic
principles used to create this wrapper and the official PKCS#11 manual
from RSA.
Copyright (C) 2004 Midori (http:/www.paipai.net/)
Verbatim copying and distribution of this entire article are permitted worldwide,
without royalty, in any medium, provided this notice, and the copyright notice,
are preserved.