def keys(auth_session): """ Fixture containing keys""" keys = {} try: for key_gen in set(param[1] for param in PARAM_LIST): template = get_default_key_template(key_gen) ret, key_handle = c_generate_key(auth_session, key_gen, template) ret2, wrap_handle = c_generate_key(auth_session, key_gen, template) if ret == CKR_OK and ret2 == CKR_OK: keys[key_gen] = key_handle, wrap_handle elif ret2 != CKR_OK: keys[key_gen] = key_handle, None logger.info( "Failed to generate key: {}\nReturn code: {}".format( key_gen, ret2)) elif ret != CKR_OK: keys[key_gen] = None, wrap_handle logger.info( "Failed to generate key: {}\nReturn code: {}".format( key_gen, ret)) else: logger.info( "Failed to generate key: {}\nReturn code: {}".format( key_gen, ret)) yield keys finally: for key, wrap in keys.values(): if key is not None: c_destroy_object(auth_session, key) if wrap is not None: c_destroy_object(auth_session, wrap)
def test_derive_key(self, key_type, d_type): """ Test derive key for using parametrized hash :param key_type: Key-gen mechanism :param d_type: Hash mech """ key_template = get_default_key_template(key_type) h_base_key = c_generate_key_ex(self.h_session, key_type, key_template) mech = NullMech(d_type).to_c_mech() derived_key_template = key_template.copy() del derived_key_template[CKA_VALUE_LEN] ret, h_derived_key = c_derive_key(self.h_session, h_base_key, key_template, mechanism=mech) try: self.verify_ret(ret, CKR_OK) verify_object_attributes(self.h_session, h_derived_key, key_template) finally: if h_base_key: c_destroy_object(self.h_session, h_base_key) if h_derived_key: c_destroy_object(self.h_session, h_derived_key)
def test_too_long_length_derives(self, key_type, d_type, valid_mechanisms): """ Verify that trying to derive a key that is too long for the given derivation function will return CKR_KEY_SIZE_RANGE :param key_type: :param d_type: """ if key_type not in valid_mechanisms: pytest.skip("Not a valid mechanism on this product") key_template = get_session_template(get_default_key_template(key_type)) h_base_key = c_generate_key_ex(self.h_session, key_type, key_template) mech = NullMech(d_type).to_c_mech() derived_key_template = key_template.copy() del derived_key_template[CKA_VALUE_LEN] ret, h_derived_key = c_derive_key(self.h_session, h_base_key, key_template, mechanism=mech) try: self.verify_ret(ret, CKR_KEY_SIZE_RANGE) finally: if h_base_key: c_destroy_object(self.h_session, h_base_key) if h_derived_key: c_destroy_object(self.h_session, h_derived_key)
def test_derive_dukpt_ipek(self, valid_mechanisms): """ Test derive key for the new dukpt ipek mechanism """ if CKM_DES2_DUKPT_IPEK not in valid_mechanisms: pytest.skip( 'This test is only valid for FWs that support CKM_DES2_DUKPT_IPEK' ) key_template = get_session_template( get_default_key_template(CKM_DES2_KEY_GEN)) ret, h_base_key = c_generate_key(self.h_session, CKM_DES2_KEY_GEN, key_template) mech = StringDataDerivationMechanism(mech_type=CKM_DES2_DUKPT_IPEK, params={ 'data': 0xffff9876543210e00000 }).to_c_mech() derived_key_template = key_template.copy() del derived_key_template[CKA_VALUE_LEN] derived_key_template[CKA_LABEL] = b"DUKPT IPEK" ret, h_derived_key = c_derive_key(self.h_session, h_base_key, derived_key_template, mechanism=mech) try: self.verify_ret(ret, CKR_OK) verify_object_attributes(self.h_session, h_derived_key, derived_key_template) finally: if h_base_key: c_destroy_object(self.h_session, h_base_key) if h_derived_key: c_destroy_object(self.h_session, h_derived_key)
def test_long_length_derive_key(self, key_type, d_type, valid_mechanisms): """ Test deriving a key :param key_type: key generation mechanism :param d_type: derive mechanism """ key_template = get_session_template(get_default_key_template(key_type)) if key_type not in valid_mechanisms: pytest.skip("Not a valid mechanism on this product") h_base_key = c_generate_key_ex(self.h_session, key_type, key_template) mech = NullMech(d_type).to_c_mech() derived_key_template = key_template.copy() del derived_key_template[CKA_VALUE_LEN] ret, h_derived_key = c_derive_key(self.h_session, h_base_key, key_template, mechanism=mech) try: self.verify_ret(ret, CKR_OK) verify_object_attributes(self.h_session, h_derived_key, key_template) finally: if h_base_key: c_destroy_object(self.h_session, h_base_key) if h_derived_key: c_destroy_object(self.h_session, h_derived_key)
def test_wrap_unwrap_key(self, mech, k_type, keys): """ Test key wrapping :param mech: encryption mech :param k_type: key gen mech :param keys: keys fixture """ temp = get_default_key_template(k_type) unwrap_temp = self.generate_unwrap_temp(k_type) extra_p = EXTRA_PARAM[mech] h_key, h_wrap_key = keys[k_type] if h_key is None or h_wrap_key is None: pytest.skip("No valid key found for {}".format(LOOKUP[mech][0])) # Wrap the key wrap_mech = {"mech_type": mech, "params": extra_p} ret, wrapped_key = c_wrap_key(self.h_session, h_wrap_key, h_key, mechanism=wrap_mech) self.verify_ret(ret, CKR_OK) h_unwrapped_key = None try: # Unwrap the Key ret, h_unwrapped_key = c_unwrap_key(self.h_session, h_wrap_key, wrapped_key, unwrap_temp, mechanism=wrap_mech) self.verify_ret(ret, CKR_OK) # Verify all of the attributes against the originally generated attributes verify_object_attributes(self.h_session, h_unwrapped_key, temp) finally: if h_unwrapped_key: c_destroy_object(self.h_session, h_unwrapped_key)
def asym_key(auth_session, usage_set): """ Generate a key pair & set the USAGE limit by some method (on creation or c_setattr, or both) :return: private key handle """ usage_type, limit = usage_set pubtemp, privtemp = get_default_key_pair_template( CKM_RSA_PKCS_KEY_PAIR_GEN) usage_template = {CKA_USAGE_LIMIT: limit} if usage_type in ("create", "both", "create_then_use"): privtemp.update(usage_template) pubkey, privkey = c_generate_key_pair_ex(auth_session, CKM_RSA_PKCS_KEY_PAIR_GEN, get_session_template(pubtemp), get_session_template(privtemp)) try: if usage_type == "create_then_use": with open(_get_data_file('sha1pkcs_plain.der'), 'rb') as df: data = df.read() c_sign_ex(auth_session, privkey, data, CKM_RSA_PKCS) if usage_type in ("setattr", "both", "create_then_use"): c_set_attribute_value_ex(auth_session, privkey, usage_template) yield privkey finally: c_destroy_object(auth_session, pubkey) c_destroy_object(auth_session, privkey)
def sym_key_params(request, auth_session, usage_set): """ Generate a key, setting the usage limit by the method described in ``usage_set`` Return that key handle. """ usage_type, limit = usage_set key_gen, mechanism = request.param key_template = get_session_template(get_default_key_template(key_gen)) usage_template = {CKA_USAGE_LIMIT: limit} if usage_type in ("create", "both", "create_then_use"): key_template.update(usage_template) h_key = c_generate_key_ex(auth_session, mechanism=key_gen, template=key_template) try: if usage_type in ("create_then_use", ): c_encrypt_ex(auth_session, h_key, b'a' * 2048, mechanism={"mech_type": mechanism}) if usage_type in ("setattr", "both", "create_then_use"): c_set_attribute_value_ex(auth_session, h_key, usage_template) yield SymParams(h_key, mechanism) finally: c_destroy_object(auth_session, h_key)
def test_destroymultipleobjects(self): """ Test deletion of multiple keys Tested by RSA key pair """ key_type, pub_key_temp, priv_key_temp = pair_params( CKM_RSA_PKCS_KEY_PAIR_GEN) session_pub_template = get_session_template(pub_key_temp) session_priv_template = get_session_template(priv_key_temp) ret, pub_key, prv_key = c_generate_key_pair(self.h_session, key_type, session_pub_template, session_priv_template) try: ret = ca_destroy_multiple_objects_ex(self.h_session, [pub_key, prv_key]) self.verify_ret(ret, CKR_OK) for templ in (session_pub_template, session_priv_template): objs = c_find_objects_ex(self.h_session, templ, 1) assert len(objs) == 0 except Exception: for key in (pub_key, prv_key): c_destroy_object(self.h_session, key)
def test_encrypt_wrap_unwrap_decrypt_key(self, mech, k_type, keys): """ Test that encrypt/decrypt works with wrapped keys :param mech: encryption mech :param k_type: key gen mech :param keys: keys fixture """ unwrap_temp = self.generate_unwrap_temp(k_type) h_key, h_wrap_key = keys[k_type] extra_p = EXTRA_PARAM[mech] if h_key is None or h_wrap_key is None: pytest.skip("No valid key found for {}".format(LOOKUP[mech][0])) # Encrypt some data data_to_encrypt = b"a" * 512 enc_mech = {"mech_type": mech} ret, encrypted_data = c_encrypt(self.h_session, h_key, data_to_encrypt, mechanism=enc_mech) self.verify_ret(ret, CKR_OK) # Wrap the key wrap_mech = {"mech_type": mech, "params": extra_p} ret, wrapped_key = c_wrap_key(self.h_session, h_wrap_key, h_key, mechanism=wrap_mech) self.verify_ret(ret, CKR_OK) h_unwrapped_key = None try: # Unwrap the Key ret, h_unwrapped_key = c_unwrap_key(self.h_session, h_wrap_key, wrapped_key, unwrap_temp, mechanism=wrap_mech) self.verify_ret(ret, CKR_OK) # Decrypt the data ret, decrypted_string = c_decrypt(self.h_session, h_unwrapped_key, encrypted_data, mechanism=enc_mech) self.verify_ret(ret, CKR_OK) assert decrypted_string == data_to_encrypt, \ "The decrypted data should be the same as the data that was encrypted. " \ "Instead found " + str(decrypted_string) finally: if h_unwrapped_key: c_destroy_object(self.h_session, h_unwrapped_key)
def test_ca_get_object_handle(self): """ Testing the function CA_GetObjectHandle :return: """ h_object = c_create_object_ex(self.h_session, DATA_TEMPLATE) try: object_uid = c_get_attribute_value_ex(self.h_session, h_object, {CKA_OUID: None})[CKA_OUID] object_handle = ca_get_object_handle_ex(self.admin_slot, self.h_session, object_uid) assert h_object == object_handle finally: c_destroy_object(self.h_session, h_object)
def test_generate_key(self, key_type, valid_mechanisms): """ Test generation of keys for sym. crypto systems :param key_type: key generation mechanism """ key_template = get_session_template(get_default_key_template(key_type)) ret, key_handle = c_generate_key(self.h_session, key_type, key_template) try: if key_type not in valid_mechanisms: self.verify_ret(ret, CKR_MECHANISM_INVALID) else: self.verify_ret(ret, CKR_OK) self.verify_key_len(key_handle, key_handle) finally: c_destroy_object(self.h_session, key_handle)
def test_modifyusagecount(self, command_type): """Test modify usage count :param command_type: """ key_handle = c_generate_key_ex( self.h_session, CKM_DES_KEY_GEN, get_session_template(CKM_DES_KEY_GEN_TEMP)) try: ret = ca_modifyusagecount(self.h_session, key_handle, command_type, 0) assert ret == CKR_OK, \ "Return code should be " + ret_vals_dictionary[CKR_OK] + \ " not " + ret_vals_dictionary[ret] finally: c_destroy_object(self.h_session, key_handle)
def test_generate_ecdsa_key_pairs(self, curve_type): """ Test generate ECDSA key pairs :param curve_type: """ CKM_ECDSA_KEY_PAIR_GEN_PUBTEMP[CKA_ECDSA_PARAMS] = curve_list[ curve_type] ret, public_key_handle, private_key_handle = c_generate_key_pair( self.h_session, CKM_ECDSA_KEY_PAIR_GEN, CKM_ECDSA_KEY_PAIR_GEN_PUBTEMP, CKM_ECDSA_KEY_PAIR_GEN_PRIVTEMP) try: self.verify_ret(ret, CKR_OK) self.verify_key_len(public_key_handle, private_key_handle) finally: if public_key_handle: c_destroy_object(self.h_session, public_key_handle) if private_key_handle: c_destroy_object(self.h_session, private_key_handle)
def sym_keys(auth_session): """ Fixture containing all sym. keys """ keys = {} try: for key_type in SYM_KEYS: template = get_session_template(get_default_key_template(key_type)) ret, key_handle = c_generate_key(auth_session, key_type, template) if ret == CKR_OK: keys[key_type] = key_handle else: logger.info( "Failed to generate key: {}\nReturn code: {}".format( key_type, ret)) yield keys finally: for handle in keys.values(): c_destroy_object(auth_session, handle)
def test_generate_key_pair(self, key_type, pub_key_temp, prv_key_temp, valid_mechanisms): """ Test generation of key pairs for asym. crypto systems :param key_type: key generation mechanism :param pub_key_temp: public key template :param prv_key_temp: private key template """ ret, pub_key, prv_key = c_generate_key_pair(self.h_session, key_type, get_session_template(pub_key_temp), get_session_template(prv_key_temp)) try: if key_type not in valid_mechanisms: self.verify_ret(ret, CKR_MECHANISM_INVALID) else: self.verify_ret(ret, CKR_OK) self.verify_key_len(pub_key, prv_key) finally: c_destroy_object(self.h_session, prv_key) c_destroy_object(self.h_session, pub_key)
def asym_keys(auth_session): """ Fixture containing all asym. keys """ keys = {} try: for params in ASYM_PARAMS: key_type, pub_temp, prv_temp, _ = params ret, pub_key, prv_key = c_generate_key_pair( auth_session, key_type, pub_temp, prv_temp) if ret == CKR_OK: keys[key_type] = (pub_key, prv_key) else: logger.info( "Failed to generate key: {}\nReturn code: {}".format( key_type, ret)) yield keys finally: for pub_key, prv_key in keys.values(): c_destroy_object(auth_session, pub_key) c_destroy_object(auth_session, prv_key)
def asym_keys(auth_session): """ Fixture containing all asym. keys """ keys = {} try: for key_type in ASYM_TABLE.values(): pub_temp, prv_temp = get_default_key_pair_template(key_type) ret, pub_key, prv_key = c_generate_key_pair( auth_session, key_type, pub_temp, prv_temp) if ret == CKR_OK: keys[key_type] = (pub_key, prv_key) else: logger.info("Failed to generate key: %s\nReturn code: %s", key_type, ret) yield keys finally: for pub_key, prv_key in keys.values(): c_destroy_object(auth_session, pub_key) c_destroy_object(auth_session, prv_key)
def test_generate_ecdsa_key_pairs(self, curve_type): """ Test generate ECDSA key pairs :param curve_type: """ pub_temp = CKM_ECDSA_KEY_PAIR_GEN_PUBTEMP.copy() pub_temp[CKA_ECDSA_PARAMS] = curve_list[curve_type] data = c_generate_key_pair( self.h_session, CKM_ECDSA_KEY_PAIR_GEN, get_session_template(pub_temp), get_session_template(CKM_ECDSA_KEY_PAIR_GEN_PRIVTEMP)) ret, public_key_handle, private_key_handle = data try: self.verify_ret(ret, CKR_OK) self.verify_key_len(public_key_handle, private_key_handle) finally: if public_key_handle: c_destroy_object(self.h_session, public_key_handle) if private_key_handle: c_destroy_object(self.h_session, private_key_handle)
def test_data_create(self): """Tests C_CreateObject with a data template and verifies the object's attributes """ template = get_session_template(DATA_TEMPLATE) h_object = c_create_object_ex(self.h_session, template) try: desired_attrs = {x: None for x in template.keys()} attr = c_get_attribute_value_ex(self.h_session, h_object, template=desired_attrs) # CKA_VALUE in the template is a list of ints, but is returned as a single hex string. # Let's try to convert it back to the list of ints. value = attr[CKA_VALUE] attr[CKA_VALUE] = [ int(value[x:x + 2], 16) for x in range(0, len(value), 2) ] assert attr == template finally: c_destroy_object(self.h_session, h_object)
def partition_clearer(auth_session): """ Autoused fixture to make sure the active session is cleared from all created objects. :param auth_session: :return: """ yield try: # Use a blank template so we can grab everything. template = Attributes({}).get_c_struct() objects = c_find_objects_ex(auth_session, template, 1000) for handle in objects: ret = c_destroy_object(auth_session, handle) if ret != CKR_OK: LOG.info("Failed to destroy object w/ handle %s", handle) except LunaException: LOG.exception("Failed to destroy all objects created on this session")
def test_x9_key_derive(self, auth_session, curve_type): """ Test we can do X9 key derivation """ derived_key2 = derived_key1 = pub_key1 = pub_key2 = prv_key2 = prv_key1 = None derived_template = { CKA_CLASS: CKO_SECRET_KEY, CKA_KEY_TYPE: CKK_DES, CKA_ENCRYPT: True, CKA_DECRYPT: True, CKA_PRIVATE: True, CKA_SENSITIVE: True } pub_temp, priv_temp = get_default_key_pair_template( CKM_ECDSA_KEY_PAIR_GEN) priv_temp = get_session_template(priv_temp) pub_temp = get_session_template(pub_temp) pub_temp[CKA_ECDSA_PARAMS] = curve_list[curve_type] pub_key1, prv_key1 = c_generate_key_pair_ex(auth_session, CKM_ECDSA_KEY_PAIR_GEN, pbkey_template=pub_temp, prkey_template=priv_temp) try: pub_key2, prv_key2 = c_generate_key_pair_ex( auth_session, CKM_ECDSA_KEY_PAIR_GEN, pbkey_template=pub_temp, prkey_template=priv_temp) pub_key1_raw = c_get_attribute_value_ex( auth_session, pub_key1, {CKA_EC_POINT: None})[CKA_EC_POINT] pub_key2_raw = c_get_attribute_value_ex( auth_session, pub_key2, {CKA_EC_POINT: None})[CKA_EC_POINT] derived_key1 = c_derive_key_ex(auth_session, h_base_key=prv_key2, template=derived_template, mechanism={ "mech_type": CKM_ECDH1_DERIVE, "params": { "kdf": CKD_NULL, "sharedData": None, "publicData": pub_key1_raw } }) derived_key2 = c_derive_key_ex(auth_session, h_base_key=prv_key1, template=derived_template, mechanism={ "mech_type": CKM_ECDH1_DERIVE, "params": { "kdf": CKD_NULL, "sharedData": None, "publicData": pub_key2_raw } }) cipher_data = c_encrypt_ex(auth_session, derived_key1, data=DATA, mechanism=CKM_DES_ECB) restored_text = c_decrypt_ex(auth_session, derived_key2, cipher_data, mechanism=CKM_DES_ECB) assert DATA == restored_text.rstrip(b'\x00') finally: for key in (pub_key1, prv_key1, pub_key2, prv_key2, derived_key1, derived_key2): if key: c_destroy_object(auth_session, key)