"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "barbican/plugin/crypto/pkcs11.py" between
barbican-11.0.0.tar.gz and barbican-12.0.0.tar.gz

About: OpenStack Barbican is the OpenStack Key Manager service. It provides secure storage, provisioning and management of secret data.
The "Wallaby" series (latest release).

pkcs11.py  (barbican-11.0.0):pkcs11.py  (barbican-12.0.0)
skipping to change at line 30 skipping to change at line 30
from barbican.common import exception from barbican.common import exception
from barbican.common import utils from barbican.common import utils
from barbican import i18n as u from barbican import i18n as u
LOG = utils.getLogger(__name__) LOG = utils.getLogger(__name__)
Attribute = collections.namedtuple("Attribute", ["type", "value"]) Attribute = collections.namedtuple("Attribute", ["type", "value"])
CKAttributes = collections.namedtuple("CKAttributes", ["template", "cffivals"]) CKAttributes = collections.namedtuple("CKAttributes", ["template", "cffivals"])
CKMechanism = collections.namedtuple("CKMechanism", ["mech", "cffivals"]) CKMechanism = collections.namedtuple("CKMechanism", ["mech", "cffivals"])
Token = collections.namedtuple("Token", ["slot_id", "label", "serial_number"])
CKR_OK = 0 CKR_OK = 0
CKR_CRYPTOKI_ALREADY_INITIALIZED = 0x00000191
CK_TRUE = 1
CKF_RW_SESSION = (1 << 1) CKF_RW_SESSION = (1 << 1)
CKF_SERIAL_SESSION = (1 << 2) CKF_SERIAL_SESSION = (1 << 2)
CKF_OS_LOCKING_OK = 0x02
CKU_SO = 0 CKU_SO = 0
CKU_USER = 1 CKU_USER = 1
CKS_RO_PUBLIC_SESSION = 0 CKS_RO_PUBLIC_SESSION = 0
CKS_RO_USER_FUNCTIONS = 1 CKS_RO_USER_FUNCTIONS = 1
CKS_RW_PUBLIC_SESSION = 2 CKS_RW_PUBLIC_SESSION = 2
CKS_RW_USER_FUNCTIONS = 3 CKS_RW_USER_FUNCTIONS = 3
CKO_SECRET_KEY = 4 CKO_SECRET_KEY = 4
CKK_AES = 0x1f CKK_AES = 0x1f
skipping to change at line 265 skipping to change at line 269
0x1a0: 'CKR_MUTEX_BAD', 0x1a0: 'CKR_MUTEX_BAD',
0x1a1: 'CKR_MUTEX_NOT_LOCKED', 0x1a1: 'CKR_MUTEX_NOT_LOCKED',
0x200: 'CKR_FUNCTION_REJECTED', 0x200: 'CKR_FUNCTION_REJECTED',
1 << 31: 'CKR_VENDOR_DEFINED' 1 << 31: 'CKR_VENDOR_DEFINED'
} }
def build_ffi(): def build_ffi():
ffi = cffi.FFI() ffi = cffi.FFI()
ffi.cdef(textwrap.dedent(""" ffi.cdef(textwrap.dedent("""
typedef unsigned char CK_BYTE; typedef unsigned char CK_BYTE;
typedef CK_BYTE CK_CHAR;
typedef CK_BYTE CK_UTF8CHAR;
typedef CK_BYTE CK_BBOOL;
typedef unsigned long CK_ULONG; typedef unsigned long CK_ULONG;
typedef unsigned long CK_RV; typedef unsigned long CK_RV;
typedef unsigned long CK_SESSION_HANDLE; typedef unsigned long CK_SESSION_HANDLE;
typedef unsigned long CK_OBJECT_HANDLE; typedef unsigned long CK_OBJECT_HANDLE;
typedef unsigned long CK_SLOT_ID; typedef unsigned long CK_SLOT_ID;
typedef CK_SLOT_ID * CK_SLOT_ID_PTR;
typedef unsigned long CK_FLAGS; typedef unsigned long CK_FLAGS;
typedef unsigned long CK_STATE; typedef unsigned long CK_STATE;
typedef unsigned long CK_USER_TYPE; typedef unsigned long CK_USER_TYPE;
typedef unsigned char * CK_UTF8CHAR_PTR; typedef unsigned char * CK_UTF8CHAR_PTR;
typedef void * CK_VOID_PTR;
typedef CK_VOID_PTR * CK_VOID_PTR_PTR;
typedef ... *CK_NOTIFY; typedef ... *CK_NOTIFY;
typedef unsigned long ck_attribute_type_t; typedef unsigned long ck_attribute_type_t;
struct ck_attribute { struct ck_attribute {
ck_attribute_type_t type; ck_attribute_type_t type;
void *value; void *value;
unsigned long value_len; unsigned long value_len;
}; };
typedef struct ck_attribute CK_ATTRIBUTE; typedef struct ck_attribute CK_ATTRIBUTE;
typedef CK_ATTRIBUTE *CK_ATTRIBUTE_PTR; typedef CK_ATTRIBUTE *CK_ATTRIBUTE_PTR;
typedef CK_RV (*CK_CREATEMUTEX)(CK_VOID_PTR_PTR);
typedef CK_RV (*CK_DESTROYMUTEX)(CK_VOID_PTR);
typedef CK_RV (*CK_LOCKMUTEX)(CK_VOID_PTR);
typedef CK_RV (*CK_UNLOCKMUTEX)(CK_VOID_PTR);
typedef struct CK_C_INITIALIZE_ARGS {
CK_CREATEMUTEX CreateMutex;
CK_DESTROYMUTEX DestroyMutex;
CK_LOCKMUTEX LockMutex;
CK_UNLOCKMUTEX UnlockMutex;
CK_FLAGS flags;
CK_VOID_PTR pReserved;
} CK_C_INITIALIZE_ARGS;
typedef unsigned long ck_mechanism_type_t; typedef unsigned long ck_mechanism_type_t;
struct ck_mechanism { struct ck_mechanism {
ck_mechanism_type_t mechanism; ck_mechanism_type_t mechanism;
void *parameter; void *parameter;
unsigned long parameter_len; unsigned long parameter_len;
}; };
typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism CK_MECHANISM;
typedef CK_MECHANISM *CK_MECHANISM_PTR; typedef CK_MECHANISM *CK_MECHANISM_PTR;
typedef CK_BYTE *CK_BYTE_PTR; typedef CK_BYTE *CK_BYTE_PTR;
typedef CK_ULONG *CK_ULONG_PTR; typedef CK_ULONG *CK_ULONG_PTR;
typedef struct CK_VERSION {
CK_BYTE major;
CK_BYTE minor;
} CK_VERSION;
typedef struct CK_SLOT_INFO {
CK_UTF8CHAR slotDescription[64];
CK_UTF8CHAR manufacturerID[32];
CK_FLAGS flags;
CK_VERSION hardwareVersion;
CK_VERSION firmwareVersion;
} CK_SLOT_INFO;
typedef CK_SLOT_INFO * CK_SLOT_INFO_PTR;
typedef struct CK_TOKEN_INFO {
CK_UTF8CHAR label[32];
CK_UTF8CHAR manufacturerID[32];
CK_UTF8CHAR model[16];
CK_CHAR serialNumber[16];
CK_FLAGS flags;
CK_ULONG 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_VERSION hardwareVersion;
CK_VERSION firmwareVersion;
CK_CHAR utcTime[16];
} CK_TOKEN_INFO;
typedef CK_TOKEN_INFO * CK_TOKEN_INFO_PTR;
typedef struct ck_session_info { typedef struct ck_session_info {
CK_SLOT_ID slot_id; CK_SLOT_ID slot_id;
CK_STATE state; CK_STATE state;
CK_FLAGS flags; CK_FLAGS flags;
unsigned long device_error; unsigned long device_error;
} CK_SESSION_INFO; } CK_SESSION_INFO;
typedef CK_SESSION_INFO *CK_SESSION_INFO_PTR; typedef CK_SESSION_INFO *CK_SESSION_INFO_PTR;
typedef struct CK_AES_GCM_PARAMS { typedef struct CK_AES_GCM_PARAMS {
char * pIv; char * pIv;
skipping to change at line 323 skipping to change at line 385
# FUNCTIONS # FUNCTIONS
ffi.cdef(textwrap.dedent(""" ffi.cdef(textwrap.dedent("""
CK_RV C_Initialize(void *); CK_RV C_Initialize(void *);
CK_RV C_Finalize(void *); CK_RV C_Finalize(void *);
CK_RV C_OpenSession(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY, CK_RV C_OpenSession(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY,
CK_SESSION_HANDLE *); CK_SESSION_HANDLE *);
CK_RV C_CloseSession(CK_SESSION_HANDLE); CK_RV C_CloseSession(CK_SESSION_HANDLE);
CK_RV C_GetSessionInfo(CK_SESSION_HANDLE, CK_SESSION_INFO_PTR); CK_RV C_GetSessionInfo(CK_SESSION_HANDLE, CK_SESSION_INFO_PTR);
CK_RV C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_RV C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR,
CK_ULONG); CK_ULONG);
CK_RV C_GetSlotList(CK_BBOOL, CK_SLOT_ID_PTR, CK_ULONG_PTR);
CK_RV C_GetSlotInfo(CK_SLOT_ID, CK_SLOT_INFO_PTR);
CK_RV C_GetTokenInfo(CK_SLOT_ID, CK_TOKEN_INFO_PTR);
CK_RV C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_RV C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
CK_ATTRIBUTE *, CK_ULONG); CK_ATTRIBUTE *, CK_ULONG);
CK_RV C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_RV C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
CK_ATTRIBUTE *, CK_ULONG); CK_ATTRIBUTE *, CK_ULONG);
CK_RV C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); CK_RV C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG); CK_RV C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG);
CK_RV C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_ULONG, CK_RV C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_ULONG,
CK_ULONG *); CK_ULONG *);
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE); CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE);
CK_RV C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_ATTRIBUTE *, CK_RV C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_ATTRIBUTE *,
skipping to change at line 366 skipping to change at line 431
CK_RV C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG); CK_RV C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG);
""")) """))
return ffi return ffi
class PKCS11(object): class PKCS11(object):
def __init__(self, library_path, login_passphrase, rw_session, slot_id, def __init__(self, library_path, login_passphrase, rw_session, slot_id,
encryption_mechanism=None, encryption_mechanism=None,
ffi=None, algorithm=None, ffi=None, algorithm=None,
seed_random_buffer=None, seed_random_buffer=None,
generate_iv=None, always_set_cka_sensitive=None, generate_iv=None, always_set_cka_sensitive=None,
hmac_keywrap_mechanism='CKM_SHA256_HMAC'): hmac_keywrap_mechanism='CKM_SHA256_HMAC',
token_serial_number=None,
token_labels=None,
os_locking_ok=False):
if algorithm: if algorithm:
LOG.warning("WARNING: Using deprecated 'algorithm' argument.") LOG.warning("WARNING: Using deprecated 'algorithm' argument.")
encryption_mechanism = encryption_mechanism or algorithm encryption_mechanism = encryption_mechanism or algorithm
if encryption_mechanism not in _ENCRYPTION_MECHANISMS: if encryption_mechanism not in _ENCRYPTION_MECHANISMS:
raise ValueError("Invalid encryption_mechanism.") raise ValueError("Invalid encryption_mechanism.")
self.encrypt_mech = _ENCRYPTION_MECHANISMS[encryption_mechanism] self.encrypt_mech = _ENCRYPTION_MECHANISMS[encryption_mechanism]
self.encrypt = getattr( self.encrypt = getattr(
self, self,
'_{}_encrypt'.format(encryption_mechanism) '_{}_encrypt'.format(encryption_mechanism)
) )
if hmac_keywrap_mechanism not in _KEY_WRAP_MECHANISMS: if hmac_keywrap_mechanism not in _KEY_WRAP_MECHANISMS:
raise ValueError("Invalid HMAC keywrap mechanism") raise ValueError("Invalid HMAC keywrap mechanism")
self.ffi = ffi or build_ffi() self.ffi = ffi or build_ffi()
self.lib = self.ffi.dlopen(library_path) self.lib = self.ffi.dlopen(library_path)
rv = self.lib.C_Initialize(self.ffi.NULL)
if os_locking_ok:
init_arg_pt = self.ffi.new("CK_C_INITIALIZE_ARGS *")
init_arg_pt.flags = CKF_OS_LOCKING_OK
else:
init_arg_pt = self.ffi.NULL
rv = self.lib.C_Initialize(init_arg_pt)
self._check_error(rv) self._check_error(rv)
# Session options # Session options
self.login_passphrase = _to_bytes(login_passphrase) self.login_passphrase = _to_bytes(login_passphrase)
self.rw_session = rw_session self.rw_session = rw_session
self.slot_id = slot_id self.slot_id = self._get_slot_id(
token_serial_number,
token_labels,
slot_id)
# Algorithm options # Algorithm options
self.algorithm = CKM_NAMES[encryption_mechanism] self.algorithm = CKM_NAMES[encryption_mechanism]
self.blocksize = 16 self.blocksize = 16
self.noncesize = 12 self.noncesize = 12
self.gcmtagsize = 16 self.gcmtagsize = 16
self.generate_iv = generate_iv self.generate_iv = generate_iv
self.always_set_cka_sensitive = always_set_cka_sensitive self.always_set_cka_sensitive = always_set_cka_sensitive
self.hmac_keywrap_mechanism = CKM_NAMES[hmac_keywrap_mechanism] self.hmac_keywrap_mechanism = CKM_NAMES[hmac_keywrap_mechanism]
# Validate configuration and RNG # Validate configuration and RNG
session = self.get_session() session = self.get_session()
if seed_random_buffer is not None: if seed_random_buffer is not None:
self._seed_random(session, seed_random_buffer) self._seed_random(session, seed_random_buffer)
self._rng_self_test(session) self._rng_self_test(session)
self.return_session(session) self.return_session(session)
LOG.debug("Connected to PCKS#11 Token in Slot %s", self.slot_id)
def _get_slot_id(self, token_serial_number, token_labels, slot_id):
# First find out how many slots with tokens are available
slots_ptr = self.ffi.new("CK_ULONG_PTR")
rv = self.lib.C_GetSlotList(CK_TRUE, self.ffi.NULL, slots_ptr)
self._check_error(rv)
# Next get the Slot IDs for each of the available slots
slot_ids_ptr = self.ffi.new("CK_SLOT_ID[{}]".format(slots_ptr[0]))
rv = self.lib.C_GetSlotList(CK_TRUE, slot_ids_ptr, slots_ptr)
self._check_error(rv)
# Gather details from each token
tokens = list()
for id in slot_ids_ptr:
token_info_ptr = self.ffi.new("CK_TOKEN_INFO_PTR")
rv = self.lib.C_GetTokenInfo(id, token_info_ptr)
self._check_error(rv)
token = Token(
id,
self.ffi.string(token_info_ptr.label).decode("UTF-8").strip(),
self.ffi.string(
token_info_ptr.serialNumber
).decode("UTF-8").strip()
)
LOG.debug("Slot %s: label: %s sn: %s",
token.slot_id,
token.label,
token.serial_number)
tokens.append(token)
# Matching serial number gets highest priority
if token_serial_number:
for token in tokens:
if token.serial_number == token_serial_number:
LOG.debug("Found token sn: %s in slot %s",
token.serial_number,
token.slot_id)
if token_labels:
LOG.warning(
"Ignoring token_labels: %s from barbican.conf",
token_labels
)
if slot_id:
LOG.warning("Ignoring slot_id: %s from barbican.conf",
slot_id)
return token.slot_id
raise ValueError("Token Serial Number not found.")
# Label match is next, raises an error if there's not exactly one match
if token_labels:
for token in tokens:
if token.label in token_labels:
LOG.debug("Found token label: %s in slot %s", token.label,
token.slot_id)
if slot_id:
LOG.warning("Ignoring slot_id: %s from barbican.conf",
slot_id)
return token.slot_id
raise ValueError("Token Labels not found.")
# If we got this far, slot_id was the only param given, so we return it
return slot_id
def get_session(self): def get_session(self):
session = self._open_session(self.slot_id) session = self._open_session(self.slot_id)
# Get session info to check user state # Get session info to check user state
session_info = self._get_session_info(session) session_info = self._get_session_info(session)
if session_info.state in (CKS_RO_PUBLIC_SESSION, if session_info.state in (CKS_RO_PUBLIC_SESSION,
CKS_RW_PUBLIC_SESSION): CKS_RW_PUBLIC_SESSION):
# Login public sessions # Login public sessions
self._login(self.login_passphrase, session) self._login(self.login_passphrase, session)
return session return session
skipping to change at line 719 skipping to change at line 861
def destroy_object(self, obj_handle, session): def destroy_object(self, obj_handle, session):
rv = self.lib.C_DestroyObject(session, obj_handle) rv = self.lib.C_DestroyObject(session, obj_handle)
self._check_error(rv) self._check_error(rv)
def finalize(self): def finalize(self):
rv = self.lib.C_Finalize(self.ffi.NULL) rv = self.lib.C_Finalize(self.ffi.NULL)
self._check_error(rv) self._check_error(rv)
def _check_error(self, value): def _check_error(self, value):
if value != CKR_OK: if value != CKR_OK and value != CKR_CRYPTOKI_ALREADY_INITIALIZED:
code = ERROR_CODES.get(value, 'CKR_????') code = ERROR_CODES.get(value, 'CKR_????')
hex_code = "{hex} {code}".format(hex=hex(value), code=code) hex_code = "{hex} {code}".format(hex=hex(value), code=code)
if code == 'CKR_TOKEN_NOT_PRESENT': if code == 'CKR_TOKEN_NOT_PRESENT':
raise exception.P11CryptoTokenException(slot_id=self.slot_id) raise exception.P11CryptoTokenException(slot_id=self.slot_id)
raise exception.P11CryptoPluginException(u._( raise exception.P11CryptoPluginException(u._(
"HSM returned response code: {code}").format(code=hex_code)) "HSM returned response code: {code}").format(code=hex_code))
def _seed_random(self, session, seed_random_buffer): def _seed_random(self, session, seed_random_buffer):
 End of changes. 14 change blocks. 
4 lines changed or deleted 146 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)