aboutsummaryrefslogtreecommitdiff
path: root/rpc_pkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpc_pkey.c')
-rw-r--r--rpc_pkey.c213
1 files changed, 110 insertions, 103 deletions
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
};
/*