From 4fd9d1186efed0de8e3ae1d1e2fa5a0e5c46c2fb Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Mon, 2 Dec 2019 15:38:58 -0500 Subject: After some thought, I'd rather make raw export/import a sub-function of key export/import (kekek = none, kek_len = 0), rather than separate RPCs. --- rpc_pkey.c | 213 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 110 insertions(+), 103 deletions(-) (limited to 'rpc_pkey.c') diff --git a/rpc_pkey.c b/rpc_pkey.c index 67732ad..3f2b5f5 100644 --- a/rpc_pkey.c +++ b/rpc_pkey.c @@ -1287,11 +1287,70 @@ static hal_error_t pkey_local_get_attributes(const hal_pkey_handle_t pkey, attributes_buffer, attributes_buffer_len); } +static hal_error_t pkey_local_export_raw(const hal_pkey_handle_t pkey_handle, + uint8_t *pkcs8, size_t *pkcs8_len, const size_t pkcs8_max) +{ + hal_assert(pkcs8 != NULL && pkcs8_len != NULL); + + uint8_t kek[KEK_LENGTH]; + size_t kek_len; + hal_error_t err; + size_t len; + + hal_pkey_slot_t * const pkey = find_handle(pkey_handle); + + if (pkey == NULL) + return HAL_ERROR_KEY_NOT_FOUND; + + if ((pkey->flags & HAL_KEY_FLAG_EXPORTABLE) == 0) + return HAL_ERROR_FORBIDDEN; + + if (pkcs8_max < HAL_KS_WRAPPED_KEYSIZE) + return HAL_ERROR_RESULT_TOO_LONG; + + if ((err = ks_fetch_from_flags(pkey, pkcs8, &len, pkcs8_max)) != HAL_OK) + goto fail; + + /* if hashsig, update internal parameters and disable further use */ + if (pkey->type == HAL_KEY_TYPE_HASHSIG_PRIVATE) { + if ((err = hal_hashsig_export_raw(&pkey->name, pkcs8, &len, pkcs8_max)) != HAL_OK) + goto fail; + pkey->flags &= ~HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE; + } + + if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) != HAL_OK) + goto fail; + + *pkcs8_len = pkcs8_max; + if ((err = hal_aes_keywrap(NULL, kek, KEK_LENGTH, pkcs8, len, pkcs8, pkcs8_len)) != HAL_OK) + goto fail; + + if ((err = hal_asn1_encode_pkcs8_encryptedprivatekeyinfo(hal_asn1_oid_aesKeyWrap, + hal_asn1_oid_aesKeyWrap_len, + pkcs8, *pkcs8_len, + pkcs8, pkcs8_len, pkcs8_max)) != HAL_OK) + goto fail; + + return HAL_OK; + + fail: + memset(pkcs8, 0, pkcs8_max); + memset(kek, 0, sizeof(kek)); + *pkcs8_len = 0; + return err; +} + static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle, const hal_pkey_handle_t kekek_handle, uint8_t *pkcs8, size_t *pkcs8_len, const size_t pkcs8_max, uint8_t *kek, size_t *kek_len, const size_t kek_max) { + if (kekek_handle.handle == HAL_HANDLE_NONE) { + if (kek_len != NULL) + *kek_len = 0; + return pkey_local_export_raw(pkey_handle, pkcs8, pkcs8_len, pkcs8_max); + } + hal_assert(pkcs8 != NULL && pkcs8_len != NULL && kek != NULL && kek_len != NULL && kek_max > KEK_LENGTH); uint8_t rsabuf[hal_rsa_key_t_size]; @@ -1385,6 +1444,53 @@ static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle, return err; } +static hal_error_t pkey_local_import_raw(const hal_client_handle_t client, + const hal_session_handle_t session, + hal_pkey_handle_t *pkey, + hal_uuid_t *name, + const uint8_t * const pkcs8, const size_t pkcs8_len, + const hal_key_flags_t flags) +{ + hal_assert(pkey != NULL && name != NULL && pkcs8 != NULL); + + uint8_t kek[KEK_LENGTH], der[HAL_KS_WRAPPED_KEYSIZE]; + size_t der_len, oid_len, data_len, kek_len; + const uint8_t *oid, *data; + hal_error_t err; + + if ((err = hal_asn1_decode_pkcs8_encryptedprivatekeyinfo(&oid, &oid_len, &data, &data_len, + pkcs8, pkcs8_len)) != HAL_OK) + goto fail; + + if (oid_len != hal_asn1_oid_aesKeyWrap_len || + memcmp(oid, hal_asn1_oid_aesKeyWrap, oid_len) != 0 || + data_len > sizeof(der)) { + err = HAL_ERROR_ASN1_PARSE_FAILED; + goto fail; + } + + if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) != HAL_OK) + goto fail; + + der_len = sizeof(der); + if ((err = hal_aes_keyunwrap(NULL, kek, kek_len, data, data_len, der, &der_len)) != HAL_OK) + goto fail; + + hal_key_type_t type; + hal_curve_name_t curve; + if ((err = hal_asn1_guess_key_type(&type, &curve, der, der_len)) == HAL_OK && + type == HAL_KEY_TYPE_HASHSIG_PRIVATE && + (err = hal_hashsig_import(der, der_len, flags)) != HAL_OK) + goto fail; + + err = hal_rpc_pkey_load(client, session, pkey, name, der, der_len, flags); + + fail: + memset(kek, 0, sizeof(kek)); + memset(der, 0, sizeof(der)); + return err; +} + static hal_error_t pkey_local_import(const hal_client_handle_t client, const hal_session_handle_t session, hal_pkey_handle_t *pkey, @@ -1394,6 +1500,9 @@ static hal_error_t pkey_local_import(const hal_client_handle_t client, const uint8_t * const kek_, const size_t kek_len, const hal_key_flags_t flags) { + if (kekek_handle.handle == HAL_HANDLE_NONE) + return pkey_local_import_raw(client, session, pkey, name, pkcs8, pkcs8_len, flags); + hal_assert(pkey != NULL && name != NULL && pkcs8 != NULL && kek_ != NULL && kek_len > 2); uint8_t kek[KEK_LENGTH], rsabuf[hal_rsa_key_t_size], der[HAL_KS_WRAPPED_KEYSIZE], *d; @@ -1474,106 +1583,6 @@ static hal_error_t pkey_local_import(const hal_client_handle_t client, return err; } -static hal_error_t pkey_local_export_raw(const hal_pkey_handle_t pkey_handle, - uint8_t *pkcs8, size_t *pkcs8_len, const size_t pkcs8_max) -{ - hal_assert(pkcs8 != NULL && pkcs8_len != NULL); - - uint8_t kek[KEK_LENGTH]; - size_t kek_len; - hal_error_t err; - size_t len; - - hal_pkey_slot_t * const pkey = find_handle(pkey_handle); - - if (pkey == NULL) - return HAL_ERROR_KEY_NOT_FOUND; - - if ((pkey->flags & HAL_KEY_FLAG_EXPORTABLE) == 0) - return HAL_ERROR_FORBIDDEN; - - if (pkcs8_max < HAL_KS_WRAPPED_KEYSIZE) - return HAL_ERROR_RESULT_TOO_LONG; - - if ((err = ks_fetch_from_flags(pkey, pkcs8, &len, pkcs8_max)) != HAL_OK) - goto fail; - - /* if hashsig, update internal parameters and disable further use */ - if (pkey->type == HAL_KEY_TYPE_HASHSIG_PRIVATE) { - if ((err = hal_hashsig_export_raw(&pkey->name, pkcs8, &len, pkcs8_max)) != HAL_OK) - goto fail; - pkey->flags &= ~HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE; - } - - if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) != HAL_OK) - goto fail; - - *pkcs8_len = pkcs8_max; - if ((err = hal_aes_keywrap(NULL, kek, KEK_LENGTH, pkcs8, len, pkcs8, pkcs8_len)) != HAL_OK) - goto fail; - - if ((err = hal_asn1_encode_pkcs8_encryptedprivatekeyinfo(hal_asn1_oid_aesKeyWrap, - hal_asn1_oid_aesKeyWrap_len, - pkcs8, *pkcs8_len, - pkcs8, pkcs8_len, pkcs8_max)) != HAL_OK) - goto fail; - - return HAL_OK; - - fail: - memset(pkcs8, 0, pkcs8_max); - memset(kek, 0, sizeof(kek)); - *pkcs8_len = 0; - return err; -} - -static hal_error_t pkey_local_import_raw(const hal_client_handle_t client, - const hal_session_handle_t session, - hal_pkey_handle_t *pkey, - hal_uuid_t *name, - const uint8_t * const pkcs8, const size_t pkcs8_len, - const hal_key_flags_t flags) -{ - hal_assert(pkey != NULL && name != NULL && pkcs8 != NULL); - - uint8_t kek[KEK_LENGTH], der[HAL_KS_WRAPPED_KEYSIZE]; - size_t der_len, oid_len, data_len, kek_len; - const uint8_t *oid, *data; - hal_error_t err; - - if ((err = hal_asn1_decode_pkcs8_encryptedprivatekeyinfo(&oid, &oid_len, &data, &data_len, - pkcs8, pkcs8_len)) != HAL_OK) - goto fail; - - if (oid_len != hal_asn1_oid_aesKeyWrap_len || - memcmp(oid, hal_asn1_oid_aesKeyWrap, oid_len) != 0 || - data_len > sizeof(der)) { - err = HAL_ERROR_ASN1_PARSE_FAILED; - goto fail; - } - - if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) != HAL_OK) - goto fail; - - der_len = sizeof(der); - if ((err = hal_aes_keyunwrap(NULL, kek, kek_len, data, data_len, der, &der_len)) != HAL_OK) - goto fail; - - hal_key_type_t type; - hal_curve_name_t curve; - if ((err = hal_asn1_guess_key_type(&type, &curve, der, der_len)) == HAL_OK && - type == HAL_KEY_TYPE_HASHSIG_PRIVATE && - (err = hal_hashsig_import(der, der_len, flags)) != HAL_OK) - goto fail; - - err = hal_rpc_pkey_load(client, session, pkey, name, der, der_len, flags); - - fail: - memset(kek, 0, sizeof(kek)); - memset(der, 0, sizeof(der)); - return err; -} - const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch = { .load = pkey_local_load, .open = pkey_local_open, @@ -1593,9 +1602,7 @@ const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch = { .set_attributes = pkey_local_set_attributes, .get_attributes = pkey_local_get_attributes, .export = pkey_local_export, - .import = pkey_local_import, - .export_raw = pkey_local_export_raw, - .import_raw = pkey_local_import_raw + .import = pkey_local_import }; /* -- cgit v1.2.3