aboutsummaryrefslogtreecommitdiff
path: root/rpc_server.c
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2019-11-06 14:34:00 -0500
committerPaul Selkirk <paul@psgd.org>2019-11-06 14:34:00 -0500
commit323bc8ade3eae73174961bbf604257a1b099fe55 (patch)
tree1559cea03677438ca9a7cb0313b65aa0cfb8f7b5 /rpc_server.c
parent9e6edd6082cc8d501e2b062983ed58b01ef677d7 (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_server.c')
-rw-r--r--rpc_server.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/rpc_server.c b/rpc_server.c
index 9598413..aa7e936 100644
--- a/rpc_server.c
+++ b/rpc_server.c
@@ -776,6 +776,60 @@ static hal_error_t pkey_import(const uint8_t **iptr, const uint8_t * const ilimi
return err;
}
+static hal_error_t pkey_export_raw(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
+{
+ hal_client_handle_t client;
+ hal_pkey_handle_t pkey;
+ size_t der_len;
+ uint32_t der_max;
+ uint8_t *optr_orig = *optr;
+ hal_error_t err;
+
+ check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &der_max));
+
+ if (nargs(1) + pad(der_max) > (uint32_t)(olimit - *optr))
+ return HAL_ERROR_RPC_PACKET_OVERFLOW;
+
+ uint8_t der[der_max];
+
+ check(hal_rpc_pkey_export_raw(pkey, der, &der_len, sizeof(der)));
+
+ if ((err = hal_xdr_encode_variable_opaque(optr, olimit, der, der_len)) != HAL_OK)
+ *optr = optr_orig;
+
+ return err;
+}
+
+static hal_error_t pkey_import_raw(const uint8_t **iptr, const uint8_t * const ilimit,
+ uint8_t **optr, const uint8_t * const olimit)
+{
+ hal_client_handle_t client;
+ hal_session_handle_t session;
+ hal_pkey_handle_t pkey;
+ hal_uuid_t name;
+ const uint8_t *der;
+ size_t der_len;
+ uint8_t *optr_orig = *optr;
+ hal_key_flags_t flags;
+ hal_error_t err;
+
+ check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+ check(hal_xdr_decode_int(iptr, ilimit, &session.handle));
+ check(hal_xdr_decode_variable_opaque_ptr(iptr, ilimit, &der, &der_len));
+ check(hal_xdr_decode_int(iptr, ilimit, &flags));
+
+ check(hal_rpc_pkey_import_raw(client, session, &pkey, &name, der, der_len, flags));
+
+ if ((err = hal_xdr_encode_int(optr, olimit, pkey.handle)) != HAL_OK ||
+ (err = hal_xdr_encode_variable_opaque(optr, olimit, name.uuid, sizeof(name.uuid))) != HAL_OK)
+ *optr = optr_orig;
+
+ return err;
+}
+
hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen,
uint8_t * const obuf, size_t * const olen)
@@ -890,6 +944,12 @@ hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ile
case RPC_FUNC_PKEY_IMPORT:
handler = pkey_import;
break;
+ case RPC_FUNC_PKEY_EXPORT_RAW:
+ handler = pkey_export_raw;
+ break;
+ case RPC_FUNC_PKEY_IMPORT_RAW:
+ handler = pkey_import_raw;
+ break;
}
if (handler)