diff options
author | Paul Selkirk <paul@psgd.org> | 2019-11-06 14:34:00 -0500 |
---|---|---|
committer | Paul Selkirk <paul@psgd.org> | 2019-11-06 14:34:00 -0500 |
commit | 323bc8ade3eae73174961bbf604257a1b099fe55 (patch) | |
tree | 1559cea03677438ca9a7cb0313b65aa0cfb8f7b5 /rpc_client.c | |
parent | 9e6edd6082cc8d501e2b062983ed58b01ef677d7 (diff) |
Export/import "raw" keys for external storage.
Exported keys are wrapped with the MKM KEK, not a transit KEK, and can
only be imported back to the same HSM.
The idea is to support operators who have more keys than will fit on the
HSM, so they will cycle keys into and out of the HSM as needed.
NOTE that hashsig is, as always, special. The hashsig key has an internal
index that is updated on every signature. To prevent a hashsig key from
being re-imported with an old index (which would compromise the security
of the key), the hashsig key is disabled on export, and must be deleted
from the HSM before being re-imported.
Diffstat (limited to 'rpc_client.c')
-rw-r--r-- | rpc_client.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/rpc_client.c b/rpc_client.c index c9ac9b7..face70f 100644 --- a/rpc_client.c +++ b/rpc_client.c @@ -1018,6 +1018,64 @@ static hal_error_t pkey_remote_import(const hal_client_handle_t client, return rpc_ret; } +static hal_error_t pkey_remote_export_raw(const hal_pkey_handle_t pkey, + uint8_t *der, size_t *der_len, const size_t der_max) +{ + uint8_t outbuf[nargs(4)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[nargs(3) + pad(der_max)]; + const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + hal_client_handle_t dummy_client = {0}; + hal_error_t rpc_ret; + + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_EXPORT_RAW)); + check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(&optr, olimit, der_max)); + check(hal_rpc_send(outbuf, optr - outbuf)); + + check(read_matching_packet(RPC_FUNC_PKEY_EXPORT_RAW, inbuf, sizeof(inbuf), &iptr, &ilimit)); + + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(hal_xdr_decode_variable_opaque(&iptr, ilimit, der, der_len, der_max)); + } + return rpc_ret; +} + +static hal_error_t pkey_remote_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 der, const size_t der_len, + const hal_key_flags_t flags) +{ + uint8_t outbuf[nargs(5) + pad(der_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[nargs(5) + pad(sizeof(name->uuid))]; + const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t name_len; + hal_error_t rpc_ret; + + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_IMPORT_RAW)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_variable_opaque(&optr, olimit, der, der_len)); + check(hal_xdr_encode_int(&optr, olimit, flags)); + check(hal_rpc_send(outbuf, optr - outbuf)); + + check(read_matching_packet(RPC_FUNC_PKEY_IMPORT_RAW, inbuf, sizeof(inbuf), &iptr, &ilimit)); + + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); + + if (rpc_ret == HAL_OK) { + check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle)); + check(hal_xdr_decode_variable_opaque(&iptr, ilimit, name->uuid, &name_len, sizeof(name->uuid))); + if (name_len != sizeof(name->uuid)) + return HAL_ERROR_KEY_NAME_TOO_LONG; + } + + return rpc_ret; +} + #if RPC_CLIENT == RPC_CLIENT_MIXED /* @@ -1149,7 +1207,9 @@ const hal_rpc_pkey_dispatch_t hal_rpc_remote_pkey_dispatch = { .set_attributes = pkey_remote_set_attributes, .get_attributes = pkey_remote_get_attributes, .export = pkey_remote_export, - .import = pkey_remote_import + .import = pkey_remote_import, + .export_raw = pkey_remote_export_raw, + .import_raw = pkey_remote_import_raw }; #if RPC_CLIENT == RPC_CLIENT_MIXED @@ -1172,7 +1232,9 @@ const hal_rpc_pkey_dispatch_t hal_rpc_mixed_pkey_dispatch = { .set_attributes = pkey_remote_set_attributes, .get_attributes = pkey_remote_get_attributes, .export = pkey_remote_export, - .import = pkey_remote_import + .import = pkey_remote_import, + .export_raw = pkey_remote_export_raw, + .import_raw = pkey_remote_import_raw }; #endif /* RPC_CLIENT == RPC_CLIENT_MIXED */ |