Source code for pycryptoki.misc

"""
PKCS11 Interface to the following functions:

* c_generate_random
* c_seed_random
* c_digest
* c_digestkey
* c_create_object
* c_set_ped_id (CA_ function)
* c_get_ped_id (CA_ function)
"""
from _ctypes import POINTER
from ctypes import create_string_buffer, cast, byref, string_at, c_ubyte

from six import integer_types

from pycryptoki.conversions import from_bytestring
from .attributes import Attributes, to_byte_array
from .common_utils import refresh_c_arrays, AutoCArray
from .cryptoki import C_GenerateRandom, CK_BYTE_PTR, CK_ULONG, \
    C_SeedRandom, C_DigestInit, C_DigestUpdate, C_DigestFinal, C_Digest, C_CreateObject, \
    CA_SetPedId, CK_SLOT_ID, CA_GetPedId, C_DigestKey
from .defines import CKR_OK
from .exceptions import make_error_handle_function
from .mechanism import parse_mechanism
from .sign_verify import do_multipart_sign_or_digest


[docs]def c_generate_random(h_session, length): """Generates a sequence of random numbers :param int h_session: Session handle :param int length: The length in bytes of the random number sequence :returns: (retcode, A string of random data) :rtype: tuple """ random_data = create_string_buffer(b"", length) data_ptr = cast(random_data, CK_BYTE_PTR) ret = C_GenerateRandom(h_session, data_ptr, CK_ULONG(length)) data = string_at(data_ptr, length) return ret, data
c_generate_random_ex = make_error_handle_function(c_generate_random)
[docs]def c_seed_random(h_session, seed): """Seeds the random number generator :param int h_session: Session handle :param bytes seed: A python string of some seed :returns: retcode :rtype: int """ seed_bytes = cast(create_string_buffer(seed), CK_BYTE_PTR) if isinstance(seed, (integer_types, float)): seed_length = seed else: seed_length = CK_ULONG(len(seed)) ret = C_SeedRandom(h_session, seed_bytes, seed_length) return ret
c_seed_random_ex = make_error_handle_function(c_seed_random)
[docs]def c_digest(h_session, data_to_digest, digest_flavor, mechanism=None, output_buffer=None): """Digests some data :param int h_session: Session handle :param bytes data_to_digest: The data to digest, either a string or a list of strings. If this is a list a multipart operation will be used :param int digest_flavor: The flavour of the mechanism to digest (MD2, SHA-1, HAS-160, SHA224, SHA256, SHA384, SHA512) :param mechanism: See the :py:func:`~pycryptoki.mechanism.parse_mechanism` function for possible values. If None will use digest flavor. :param list|int output_buffer: Integer or list of integers that specify a size of output buffer to use for an operation. By default will query with NULL pointer buffer to get required size of buffer. :returns: (retcode, a python string of the digested data) :rtype: tuple """ if mechanism is None: mech = parse_mechanism(digest_flavor) else: mech = parse_mechanism(mechanism) # Initialize Digestion ret = C_DigestInit(h_session, mech) if ret != CKR_OK: return ret, None # if a list is passed out do an digest operation on each string in the list, otherwise just # do one digest operation is_multi_part_operation = isinstance(data_to_digest, (list, tuple)) if is_multi_part_operation: ret, digested_python_string = do_multipart_sign_or_digest(h_session, C_DigestUpdate, C_DigestFinal, data_to_digest, output_buffer=output_buffer) else: # Get arguments c_data_to_digest, c_digest_data_len = to_byte_array(from_bytestring(data_to_digest)) c_data_to_digest = cast(c_data_to_digest, POINTER(c_ubyte)) if output_buffer is not None: size = CK_ULONG(output_buffer) digested_data = AutoCArray(ctype=c_ubyte, size=size) ret = C_Digest(h_session, c_data_to_digest, c_digest_data_len, digested_data.array, digested_data.size) else: digested_data = AutoCArray(ctype=c_ubyte) @refresh_c_arrays(1) def _digest(): """ Perform the digest operations """ return C_Digest(h_session, c_data_to_digest, c_digest_data_len, digested_data.array, digested_data.size) ret = _digest() if ret != CKR_OK: return ret, None # Convert Digested data into a python string digested_python_string = string_at(digested_data.array, digested_data.size.contents.value) return ret, digested_python_string
c_digest_ex = make_error_handle_function(c_digest)
[docs]def c_digestkey(h_session, h_key, digest_flavor, mechanism=None): """Digest a key :param int h_session: Session handle :param int h_key: Key to digest :param int digest_flavor: Digest flavor :param mechanism: See the :py:func:`~pycryptoki.mechanism.parse_mechanism` function for possible values. If None will use digest flavor. """ if mechanism is None: mech = parse_mechanism(digest_flavor) else: mech = parse_mechanism(mechanism) # Initialize Digestion ret = C_DigestInit(h_session, mech) if ret != CKR_OK: return ret ret = C_DigestKey(h_session, h_key) return ret
c_digestkey_ex = make_error_handle_function(c_digestkey)
[docs]def c_create_object(h_session, template): """Creates an object based on a given python template :param int h_session: Session handle :param dict template: The python template which the object will be based on :returns: (retcode, the handle of the object) :rtype: tuple """ c_template = Attributes(template).get_c_struct() new_object_handle = CK_ULONG() ret = C_CreateObject(h_session, c_template, CK_ULONG(len(template)), byref(new_object_handle)) return ret, new_object_handle.value
c_create_object_ex = make_error_handle_function(c_create_object)
[docs]def c_set_ped_id(slot, id): """Set the PED ID for the given slot. :param slot: slot number :param id: PED ID to use :returns: The result code """ ret = CA_SetPedId(CK_SLOT_ID(slot), CK_ULONG(id)) return ret
c_set_ped_id_ex = make_error_handle_function(c_set_ped_id)
[docs]def c_get_ped_id(slot): """Get the PED ID for the given slot. :param slot: slot number :returns: The result code and ID """ pedId = CK_ULONG() ret = CA_GetPedId(CK_SLOT_ID(slot), byref(pedId)) return ret, pedId.value
c_get_ped_id_ex = make_error_handle_function(c_get_ped_id)