Skip to content

Commit

Permalink
Merge pull request #19 from ThalesGroup/merge_jun_2020
Browse files Browse the repository at this point in the history
Merge Jun 2020
  • Loading branch information
astraw38 authored Jun 8, 2020
2 parents 8457650 + 254d2d4 commit 863acf7
Show file tree
Hide file tree
Showing 70 changed files with 3,946 additions and 1,557 deletions.
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
# The short X.Y version.
version = "2.5"
# The full version, including alpha/beta/rc tags.
release = "2.5.4"
release = "2.5.11"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 2 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ It's highly recommended that you have the `PKCS11 <https://www.cryptsoft.com/pkc
handy, as pycryptoki uses that as the underlying C interface. Session management, object management,
and other concepts are unchanged from PKCS11.

See :ref:`usertypes` for the mapping of Luna users to PKCS11 constants.

.. code-block:: python
from pycryptoki.default_templates import *
Expand Down
30 changes: 30 additions & 0 deletions docs/problems.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,33 @@ number of parts in the operation::

For a multi-part operation that returns data in the ``C_*Final`` function, the output buffer will be
equivalent to the largest buffer size specified in the output_buffer list.


.. _usertypes:

Luna & PKCS11 User types
------------------------

Following is a table showing the mapping between Luna user types & their PKCS11 constant equivalents

Note that the user type is context-dependent -- some users are only valid on the Admin partition,
and some are only valid on a User partition, and some are dual-use.


+----------------------------+----------------------------+-----------------+
| Luna User | PKCS11 User | Partition |
+============================+============================+=================+
| Security Officer | CKU_SO | Admin Partition |
+----------------------------+----------------------------+-----------------+
| Administrator | CKU_USER | Admin Partition |
+----------------------------+----------------------------+-----------------+
| Auditor | CKU_AUDIT | Admin Partition |
+----------------------------+----------------------------+-----------------+
| Partition Security Officer | CKU_SO | User Partition |
+----------------------------+----------------------------+-----------------+
| Crypto Officer | CKU_USER | User Partition |
+----------------------------+----------------------------+-----------------+
| Crypto User | CKU_LIMITED_USER | User Partition |
+----------------------------+----------------------------+-----------------+
| Limited Crypto Officer | CKU_LIMITED_CRYPTO_OFFICER | User Partition |
+----------------------------+----------------------------+-----------------+
24 changes: 16 additions & 8 deletions pycryptoki/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@
)
from functools import wraps

from six import (b, string_types, integer_types, binary_type)
from pycryptoki.conversions import (from_bytestring, from_hex, to_bytestring)
from .cryptoki import (CK_ATTRIBUTE, CK_BBOOL, CK_ATTRIBUTE_TYPE, CK_ULONG, CK_BYTE, CK_CHAR,
CK_KEY_STATUS)
from .defines import (CKA_EKM_UID, CKA_GENERIC_1, CKA_GENERIC_2, CKA_GENERIC_3)
from six import b, string_types, integer_types, binary_type
from pycryptoki.conversions import from_bytestring, from_hex, to_bytestring
from .cryptoki import (
CK_ATTRIBUTE,
CK_BBOOL,
CK_ATTRIBUTE_TYPE,
CK_ULONG,
CK_BYTE,
CK_CHAR,
CK_KEY_STATUS,
)
from .defines import CKA_EKM_UID, CKA_GENERIC_1, CKA_GENERIC_2, CKA_GENERIC_3
from .defines import (
CKA_USAGE_LIMIT,
CKA_USAGE_COUNT,
Expand Down Expand Up @@ -85,7 +92,7 @@
CKA_VALUE,
CKA_BYTES_REMAINING,
CKA_FAILED_KEY_AUTH_COUNT,
CKA_KEY_STATUS
CKA_KEY_STATUS,
)

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -251,6 +258,7 @@ def to_pka_key_status(val, reverse=False):

return to_byte_array(val, reverse)


@ret_type(CK_BYTE)
def to_byte_array(val, reverse=False):
"""Converts an arbitrarily sized integer, list, or byte array
Expand Down Expand Up @@ -402,8 +410,8 @@ def to_sub_attributes(val, reverse=False):
# Dict
CKA_UNWRAP_TEMPLATE: to_sub_attributes,
CKA_DERIVE_TEMPLATE: to_sub_attributes,
#pka
CKA_KEY_STATUS: to_pka_key_status
# pka
CKA_KEY_STATUS: to_pka_key_status,
}
)

Expand Down
10 changes: 7 additions & 3 deletions pycryptoki/audit_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ def ca_init_audit(slot, audit_pin, audit_label):
:param audit_label:
"""
if audit_pin == '':
if audit_pin == "":
ret = CA_InitAudit(CK_SLOT_ID(slot), None, CK_ULONG(0), cast(audit_label, CK_CHAR_PTR))
else:
ret = CA_InitAudit(CK_SLOT_ID(slot), cast(audit_pin, CK_CHAR_PTR), CK_ULONG(len(audit_pin)),
cast(audit_label, CK_CHAR_PTR))
ret = CA_InitAudit(
CK_SLOT_ID(slot),
cast(audit_pin, CK_CHAR_PTR),
CK_ULONG(len(audit_pin)),
cast(audit_label, CK_CHAR_PTR),
)
return ret


Expand Down
160 changes: 101 additions & 59 deletions pycryptoki/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,50 @@
from ctypes import byref, c_ulong

from .common_utils import AutoCArray, refresh_c_arrays
from .cryptoki import CA_OpenSecureToken, CA_CloseSecureToken, CA_Extract, CA_Insert, \
CK_ULONG, \
CA_SIMExtract, CK_BYTE, string_at, create_string_buffer, POINTER, cast, pointer, \
CK_BYTE_PTR, c_ubyte, CA_SIMInsert, CA_SIMMultiSign
from .defines import (CKA_SIM_NO_AUTHORIZATION, CKA_SIM_PASSWORD, CKA_SIM_CHALLENGE,
CKA_SIM_SECURE_PORT, CKA_SIM_PORTABLE_NO_AUTHORIZATION,
CKA_SIM_PORTABLE_PASSWORD, CKA_SIM_PORTABLE_CHALLENGE,
CKA_SIM_PORTABLE_SECURE_PORT, CKR_OK)
from .cryptoki import (
CA_OpenSecureToken,
CA_CloseSecureToken,
CA_Extract,
CA_Insert,
CK_ULONG,
CA_SIMExtract,
CK_BYTE,
string_at,
create_string_buffer,
POINTER,
cast,
pointer,
CK_BYTE_PTR,
c_ubyte,
CA_SIMInsert,
CA_SIMMultiSign,
)
from .defines import (
CKA_SIM_NO_AUTHORIZATION,
CKA_SIM_PASSWORD,
CKA_SIM_CHALLENGE,
CKA_SIM_SECURE_PORT,
CKA_SIM_PORTABLE_NO_AUTHORIZATION,
CKA_SIM_PORTABLE_PASSWORD,
CKA_SIM_PORTABLE_CHALLENGE,
CKA_SIM_PORTABLE_SECURE_PORT,
CKR_OK,
)
from .exceptions import make_error_handle_function
from .mechanism import parse_mechanism

logger = logging.getLogger(__name__)

SIM_AUTH_FORMS = (CKA_SIM_NO_AUTHORIZATION,
CKA_SIM_PASSWORD,
CKA_SIM_CHALLENGE,
CKA_SIM_SECURE_PORT,
CKA_SIM_PORTABLE_NO_AUTHORIZATION,
CKA_SIM_PORTABLE_PASSWORD,
CKA_SIM_PORTABLE_CHALLENGE,
CKA_SIM_PORTABLE_SECURE_PORT)
SIM_AUTH_FORMS = (
CKA_SIM_NO_AUTHORIZATION,
CKA_SIM_PASSWORD,
CKA_SIM_CHALLENGE,
CKA_SIM_SECURE_PORT,
CKA_SIM_PORTABLE_NO_AUTHORIZATION,
CKA_SIM_PORTABLE_PASSWORD,
CKA_SIM_PORTABLE_CHALLENGE,
CKA_SIM_PORTABLE_SECURE_PORT,
)


def ca_open_secure_token(h_session, storage_path, dev_ID, mode):
Expand All @@ -39,8 +62,9 @@ def ca_open_secure_token(h_session, storage_path, dev_ID, mode):
"""
number_of_elems = CK_ULONG(0)
ph_ID = CK_ULONG(0)
ret = CA_OpenSecureToken(h_session, storage_path, dev_ID, mode, byref(number_of_elems),
byref(ph_ID))
ret = CA_OpenSecureToken(
h_session, storage_path, dev_ID, mode, byref(number_of_elems), byref(ph_ID)
)

return ret, number_of_elems.value, ph_ID.value

Expand Down Expand Up @@ -95,8 +119,9 @@ def ca_insert(h_session, mechanism):
ca_insert_ex = make_error_handle_function(ca_insert)


def ca_sim_extract(h_session, key_handles, authform, auth_secrets=None, subset_size=0,
delete_after_extract=False):
def ca_sim_extract(
h_session, key_handles, authform, auth_secrets=None, subset_size=0, delete_after_extract=False
):
"""
Extract multiple keys to a wrapped blob. The returned blob can then be written into
a file.
Expand All @@ -118,9 +143,10 @@ def ca_sim_extract(h_session, key_handles, authform, auth_secrets=None, subset_s
auth_secrets = []

auth_secret_sizes = AutoCArray(data=[c_ulong(len(x)) for x in auth_secrets])
c_auth_secrets = AutoCArray(data=[cast(pointer(create_string_buffer(x, len(x))),
CK_BYTE_PTR) for x in auth_secrets],
ctype=POINTER(CK_BYTE))
c_auth_secrets = AutoCArray(
data=[cast(pointer(create_string_buffer(x, len(x))), CK_BYTE_PTR) for x in auth_secrets],
ctype=POINTER(CK_BYTE),
)
c_key_handles = AutoCArray(key_handles)
blob_data = AutoCArray(ctype=c_ubyte)

Expand All @@ -130,13 +156,19 @@ def extract():
Closure to allow us to get the size of the blob_data.
"""
blobarr, bloblen = blob_data.array, blob_data.size
return CA_SIMExtract(h_session,
len(c_key_handles), c_key_handles.array,
CK_ULONG(len(auth_secrets)), CK_ULONG(subset_size),
authform,
auth_secret_sizes.array, c_auth_secrets.array,
delete_after_extract,
bloblen, blobarr)
return CA_SIMExtract(
h_session,
len(c_key_handles),
c_key_handles.array,
CK_ULONG(len(auth_secrets)),
CK_ULONG(subset_size),
authform,
auth_secret_sizes.array,
c_auth_secrets.array,
delete_after_extract,
bloblen,
blobarr,
)

ret = extract()
if ret == 0:
Expand Down Expand Up @@ -166,9 +198,10 @@ def ca_sim_insert(h_session, blob_data, authform, auth_secrets=None):
auth_secrets = []

auth_secret_sizes = AutoCArray(data=[c_ulong(len(x)) for x in auth_secrets])
c_auth_secrets = AutoCArray(data=[cast(create_string_buffer(x, len(x)), CK_BYTE_PTR)
for x in auth_secrets],
ctype=POINTER(CK_BYTE))
c_auth_secrets = AutoCArray(
data=[cast(create_string_buffer(x, len(x)), CK_BYTE_PTR) for x in auth_secrets],
ctype=POINTER(CK_BYTE),
)
c_key_handles = AutoCArray()
c_blob_data = create_string_buffer(blob_data, len(blob_data))

Expand All @@ -178,11 +211,17 @@ def insert():
Closure to allow us to get the size of the blob_data.
"""
key_array, key_array_len = c_key_handles.array, c_key_handles.size
return CA_SIMInsert(h_session,
CK_ULONG(len(auth_secrets)), authform,
auth_secret_sizes.array, c_auth_secrets.array,
len(blob_data), cast(c_blob_data, POINTER(CK_BYTE)),
key_array_len, key_array)
return CA_SIMInsert(
h_session,
CK_ULONG(len(auth_secrets)),
authform,
auth_secret_sizes.array,
c_auth_secrets.array,
len(blob_data),
cast(c_blob_data, POINTER(CK_BYTE)),
key_array_len,
key_array,
)

ret = insert()
if ret == 0:
Expand Down Expand Up @@ -219,9 +258,10 @@ def ca_sim_multisign(h_session, blob_data, data_to_sign, mechanism, authform, au
c_mechanism = parse_mechanism(mechanism)

auth_secret_sizes = AutoCArray(data=[c_ulong(len(x)) for x in auth_secrets])
c_auth_secrets = AutoCArray(data=[cast(create_string_buffer(x, len(x)),
CK_BYTE_PTR) for x in auth_secrets],
ctype=POINTER(CK_BYTE))
c_auth_secrets = AutoCArray(
data=[cast(create_string_buffer(x, len(x)), CK_BYTE_PTR) for x in auth_secrets],
ctype=POINTER(CK_BYTE),
)
c_blob_data = create_string_buffer(blob_data, len(blob_data))

# Output array of signatures (array of pointers
Expand All @@ -234,26 +274,28 @@ def ca_sim_multisign(h_session, blob_data, data_to_sign, mechanism, authform, au

# Input data sizes
data_lens = AutoCArray([len(x) for x in data_to_sign])
data_buffers = [cast(create_string_buffer(chunk, len(chunk)), CK_BYTE_PTR)
for chunk in data_to_sign]
data_buffers = [
cast(create_string_buffer(chunk, len(chunk)), CK_BYTE_PTR) for chunk in data_to_sign
]

# Input data to sign -- array of pointers
input_data = AutoCArray(ctype=CK_BYTE_PTR,
data=data_buffers)

ret = CA_SIMMultiSign(h_session,
byref(c_mechanism),
CK_ULONG(len(auth_secrets)),
authform,
auth_secret_sizes.array,
c_auth_secrets.array,
len(blob_data),
cast(c_blob_data, CK_BYTE_PTR),
len(data_to_sign),
data_lens.array,
input_data.array,
signature_lens,
signatures)
input_data = AutoCArray(ctype=CK_BYTE_PTR, data=data_buffers)

ret = CA_SIMMultiSign(
h_session,
byref(c_mechanism),
CK_ULONG(len(auth_secrets)),
authform,
auth_secret_sizes.array,
c_auth_secrets.array,
len(blob_data),
cast(c_blob_data, CK_BYTE_PTR),
len(data_to_sign),
data_lens.array,
input_data.array,
signature_lens,
signatures,
)
py_sigs = []
if ret == CKR_OK:
for sig, sig_len in zip(signatures, signature_lens):
Expand Down
29 changes: 21 additions & 8 deletions pycryptoki/ca_extensions/derive_wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@
LOG = logging.getLogger(__name__)


def ca_derive_key_and_wrap(h_session, derive_mechanism, h_base_key, derive_template,
wrapping_key, wrap_mechanism, output_buffer=2048):
def ca_derive_key_and_wrap(
h_session,
derive_mechanism,
h_base_key,
derive_template,
wrapping_key,
wrap_mechanism,
output_buffer=2048,
):
"""
Derive a key from the base key and wrap it off the HSM using the wrapping key
Expand All @@ -39,13 +46,19 @@ def ca_derive_key_and_wrap(h_session, derive_mechanism, h_base_key, derive_templ
# derive key and wrap function requires the size and in that way is
# inconsistent with wrap function
size = CK_ULONG(output_buffer)
wrapped_key = AutoCArray(ctype=c_ubyte,
size=size)
wrapped_key = AutoCArray(ctype=c_ubyte, size=size)

ret = CA_DeriveKeyAndWrap(h_session, derive_mech, CK_OBJECT_HANDLE(h_base_key),
c_template, CK_ULONG(len(derive_template)),
wrap_mech, CK_OBJECT_HANDLE(wrapping_key),
wrapped_key.array, wrapped_key.size)
ret = CA_DeriveKeyAndWrap(
h_session,
derive_mech,
CK_OBJECT_HANDLE(h_base_key),
c_template,
CK_ULONG(len(derive_template)),
wrap_mech,
CK_OBJECT_HANDLE(wrapping_key),
wrapped_key.array,
wrapped_key.size,
)

if ret != CKR_OK:
return ret, None
Expand Down
Loading

0 comments on commit 863acf7

Please sign in to comment.