diff options
-rw-r--r-- | cryptech/libhal.py | 20 | ||||
-rw-r--r-- | hal.h | 13 | ||||
-rw-r--r-- | hal_internal.h | 14 | ||||
-rw-r--r-- | hashsig.c | 35 | ||||
-rw-r--r-- | rpc_api.c | 20 | ||||
-rw-r--r-- | rpc_client.c | 66 | ||||
-rw-r--r-- | rpc_pkey.c | 104 | ||||
-rw-r--r-- | rpc_server.c | 60 | ||||
-rw-r--r-- | utils/pkey.c | 104 |
9 files changed, 394 insertions, 42 deletions
diff --git a/cryptech/libhal.py b/cryptech/libhal.py index 647dbd6..1899102 100644 --- a/cryptech/libhal.py +++ b/cryptech/libhal.py @@ -191,6 +191,8 @@ RPCFunc.define(''' RPC_FUNC_PKEY_EXPORT, RPC_FUNC_PKEY_IMPORT, RPC_FUNC_PKEY_GENERATE_HASHSIG, + RPC_FUNC_PKEY_EXPORT_RAW, + RPC_FUNC_PKEY_IMPORT_RAW, ''') class HALDigestAlgorithm(Enum): pass @@ -434,6 +436,12 @@ class PKey(Handle): def import_pkey(self, pkcs8, kek, flags = 0): return self.hsm.pkey_import(kekek = self, pkcs8 = pkcs8, kek = kek, flags = flags) + def export_raw_pkey(self, pkey): + return self.hsm.pkey_export_raw(pkey = pkey, der_max = 5480) + + def import_raw_pkey(self, der, flags = 0): + return self.hsm.pkey_import_raw(der = der, flags = flags) + class ContextManagedUnpacker(xdrlib.Unpacker): def __enter__(self): @@ -710,3 +718,15 @@ class HSM(object): pkey = PKey(self, r.unpack_uint(), UUID(bytes = r.unpack_bytes())) logger.debug("Imported pkey %s", pkey.uuid) return pkey + + def pkey_export_raw(self, pkey, der_max = 2560): + with self.rpc(RPC_FUNC_PKEY_EXPORT_RAW, pkey, der_max) as r: + der = r.unpack_bytes(), r.unpack_bytes() + logger.debug("Exported raw pkey %s", pkey.uuid) + return der + + def pkey_import_raw(self, der, flags = 0, client = 0, session = 0): + with self.rpc(RPC_FUNC_PKEY_IMPORT_RAW, session, der, flags, client = client) as r: + pkey = PKey(self, r.unpack_uint(), UUID(bytes = r.unpack_bytes())) + logger.debug("Imported raw pkey %s", pkey.uuid) + return pkey @@ -893,6 +893,9 @@ extern hal_error_t hal_rpc_pkey_export(const hal_pkey_handle_t pkey, uint8_t *pkcs8, size_t *pkcs8_len, const size_t pkcs8_max, uint8_t *kek, size_t *kek_len, const size_t kek_max); +extern hal_error_t hal_rpc_pkey_export_raw(const hal_pkey_handle_t pkey, + uint8_t *pkcs8, size_t *pkcs8_len, const size_t pkcs8_max); + extern hal_error_t hal_rpc_pkey_import(const hal_client_handle_t client, const hal_session_handle_t session, hal_pkey_handle_t *pkey, @@ -902,6 +905,13 @@ extern hal_error_t hal_rpc_pkey_import(const hal_client_handle_t client, const uint8_t * const kek, const size_t kek_len, const hal_key_flags_t flags); +extern hal_error_t hal_rpc_pkey_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); + extern hal_error_t hal_rpc_client_init(void); extern hal_error_t hal_rpc_client_close(void); @@ -1005,6 +1015,9 @@ extern hal_error_t hal_hashsig_ks_init(void); extern hal_error_t hal_hashsig_export(const hal_uuid_t * const name, uint8_t *der, size_t *der_len, const size_t der_max); +extern hal_error_t hal_hashsig_export_raw(const hal_uuid_t * const name, + uint8_t *der, size_t *der_len, const size_t der_max); + extern hal_error_t hal_hashsig_import(const uint8_t *der, const size_t der_len, const hal_key_flags_t flags); diff --git a/hal_internal.h b/hal_internal.h index 15f4c79..1885595 100644 --- a/hal_internal.h +++ b/hal_internal.h @@ -380,6 +380,16 @@ typedef struct { const uint8_t * const kek, const size_t kek_len, const hal_key_flags_t flags); + hal_error_t (*export_raw)(const hal_pkey_handle_t pkey_handle, + uint8_t *der, size_t *der_len, const size_t der_max); + + hal_error_t (*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); + } hal_rpc_pkey_dispatch_t; @@ -662,9 +672,11 @@ typedef enum { RPC_FUNC_PKEY_EXPORT, RPC_FUNC_PKEY_IMPORT, RPC_FUNC_PKEY_GENERATE_HASHSIG, + RPC_FUNC_PKEY_EXPORT_RAW, + RPC_FUNC_PKEY_IMPORT_RAW, } rpc_func_num_t; -#define RPC_VERSION 0x01010100 /* 1.1.1.0 */ +#define RPC_VERSION 0x01010200 /* 1.1.2.0 */ /* * RPC client locality. These have to be defines rather than an enum, @@ -2100,6 +2100,41 @@ err_out: return err; } +hal_error_t hal_hashsig_export_raw(const hal_uuid_t * const name, uint8_t *der, size_t *der_len, const size_t der_max) +{ + hal_error_t err; + hal_hashsig_key_t keybuf, *tmp_key = &keybuf, *hss_key; + + if ((err = hal_hashsig_private_key_from_der(&hss_key, &keybuf, sizeof(keybuf), der, *der_len)) != HAL_OK) + goto err_out; + if (hss_key == tmp_key) { + err = HAL_ERROR_KEY_NOT_FOUND; /* or IMPOSSIBLE? */ + goto err_out; + } + + /* adjust exported q */ + hss_key->q_start = hss_key->lms_keys[0].q; + + /* store updated hss_key + * toggle HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE to disable further use + */ + hal_pkey_slot_t slot = { + .type = HAL_KEY_TYPE_HASHSIG_PRIVATE, + .name = *name, + .flags = HAL_KEY_FLAG_TOKEN | HAL_KEY_FLAG_EXPORTABLE + }; + if ((err = hal_hashsig_private_key_to_der(hss_key, der, der_len, der_max)) != HAL_OK || + (err = hal_ks_rewrite_der(hal_ks_token, &slot, der, *der_len)) != HAL_OK) + goto err_out; + + /* return with updated der */ + +err_out: + memset(&keybuf, 0, sizeof(keybuf)); + hss_key = NULL; + return err; +} + hal_error_t hal_hashsig_import(const uint8_t *der, const size_t der_len, const hal_key_flags_t flags) { @@ -432,6 +432,26 @@ hal_error_t hal_rpc_pkey_import(const hal_client_handle_t client, return hal_rpc_pkey_dispatch->import(client, session, pkey, name, kekek, pkcs8, pkcs8_len, kek, kek_len, flags); } +hal_error_t hal_rpc_pkey_export_raw(const hal_pkey_handle_t pkey, + uint8_t *der, size_t *der_len, const size_t der_max) +{ + if (der == NULL || der_len == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + return hal_rpc_pkey_dispatch->export_raw(pkey, der, der_len, der_max); +} + +hal_error_t hal_rpc_pkey_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) +{ + if (pkey == NULL || name == NULL || der == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + return hal_rpc_pkey_dispatch->import_raw(client, session, pkey, name, der, der_len, flags); +} + /* * Local variables: * indent-tabs-mode: nil 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 */ @@ -1474,6 +1474,106 @@ 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, @@ -1493,7 +1593,9 @@ 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 + .import = pkey_local_import, + .export_raw = pkey_local_export_raw, + .import_raw = pkey_local_import_raw }; /* 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) diff --git a/utils/pkey.c b/utils/pkey.c index 76c1bf7..efd360d 100644 --- a/utils/pkey.c +++ b/utils/pkey.c @@ -62,8 +62,8 @@ * list [-t type] * sign [-h (hash)] [-k keyname] [-m msgfile] [-s sigfile] [-n iterations] * verify [-h (hash)] [-k keyname] [-m msgfile] [-s sigfile] - * export [-k keyname] [-K kekekfile] [-o outfile] - * import [-K kekekfile] [-i infile] [-x (exportable)] [-v (volatile keystore)] + * export [-k keyname] [-r (raw) | -K kekekfile] [-o outfile] + * import [-r (raw) | -K kekekfile] [-i infile] [-x (exportable)] [-v (volatile keystore)] * delete [-k keyname] ... */ @@ -166,7 +166,7 @@ static int file_write(const char * const fn, const void * const buf, const size_ if (fclose(fp) != 0) lose("Error closing %s: %s\n", fn, strerror(errno)); - if (secret && chmod(fn, S_IRUSR) != 0) + if (secret && chmod(fn, S_IRUSR|S_IWUSR) != 0) lose("Error chmod'ing %s: %s\n", fn, strerror(errno)); return 0; @@ -799,6 +799,8 @@ done: m, mlen, sig, &sig_len, sizeof(sig))) != HAL_OK) { if (i > 0 && err == HAL_ERROR_HASHSIG_KEY_EXHAUSTED) break; + else if (n == 1) + lose("Error signing: %s\n", hal_error_string(err)); else lose("Error signing (%d): %s\n", i, hal_error_string(err)); } @@ -923,14 +925,15 @@ fail: static int pkey_export(int argc, char *argv[]) { - char usage[] = "Usage: export [-k keyname] [-K kekekfile] [-o outfile]"; + char usage[] = "Usage: export [-k keyname] [-r | -K kekekfile] [-o outfile]"; hal_pkey_handle_t kekek_handle = {HAL_HANDLE_NONE}; char *kekek_fn = NULL; char *out_fn = NULL; + int raw = 0; int opt; - while ((opt = getopt(argc, argv, "-k:K:o:")) != -1) { + while ((opt = getopt(argc, argv, "-k:K:o:r")) != -1) { switch (opt) { case 1: /* found the next command */ @@ -947,6 +950,9 @@ static int pkey_export(int argc, char *argv[]) case 'o': out_fn = optarg; break; + case 'r': + raw = 1; + break; default: puts(usage); return -1; @@ -960,7 +966,7 @@ done: return -1; } - if (kekek_fn == NULL) { + if (!raw && kekek_fn == NULL) { printf("export: missing kekek\n"); puts(usage); return -1; @@ -975,34 +981,43 @@ done: out_fn = key_name; } - if (pkey_load(kekek_fn, &kekek_handle) != 0) + if (!raw && pkey_load(kekek_fn, &kekek_handle) != 0) goto fail; uint8_t der[HAL_KS_WRAPPED_KEYSIZE]; size_t der_len; uint8_t kek[HAL_KS_WRAPPED_KEYSIZE]; size_t kek_len; - if ((err = hal_rpc_pkey_export(key_handle, kekek_handle, - der, &der_len, sizeof(der), - kek, &kek_len, sizeof(kek))) != HAL_OK) - lose("Error exporting private key: %s\n", hal_error_string(err)); + if (!raw) { + if ((err = hal_rpc_pkey_export(key_handle, kekek_handle, + der, &der_len, sizeof(der), + kek, &kek_len, sizeof(kek))) != HAL_OK) + lose("Error exporting private key: %s\n", hal_error_string(err)); + } + else { + if ((err = hal_rpc_pkey_export_raw(key_handle, + der, &der_len, sizeof(der))) != HAL_OK) + lose("Error exporting private key: %s\n", hal_error_string(err)); + } char fn[strlen(out_fn) + 5]; strcpy(fn, out_fn); strcat(fn, ".der"); if (file_write(fn, der, der_len, 1) != 0) goto fail; - strcpy(fn, out_fn); strcat(fn, ".kek"); - if (file_write(fn, kek, kek_len, 1) != 0) - goto fail; + if (!raw) { + strcpy(fn, out_fn); strcat(fn, ".kek"); + if (file_write(fn, kek, kek_len, 1) != 0) + goto fail; - if ((err = hal_rpc_pkey_delete(kekek_handle)) != HAL_OK) - lose("Could not delete key: %s\n", hal_error_string(err)); + if ((err = hal_rpc_pkey_delete(kekek_handle)) != HAL_OK) + lose("Could not delete key: %s\n", hal_error_string(err)); + } } return 0; fail: - if (kekek_handle.handle != HAL_HANDLE_NONE) + if (!raw && kekek_handle.handle != HAL_HANDLE_NONE) (void)hal_rpc_pkey_delete(kekek_handle); return -1; @@ -1010,14 +1025,15 @@ fail: static int pkey_import(int argc, char *argv[]) { - char usage[] = "Usage: import [-K kekekfile] [-i infile] [-x (exportable)] [-v (volatile keystore)]"; + char usage[] = "Usage: import [-r | -K kekekfile] [-i infile] [-x (exportable)] [-v (volatile keystore)]"; hal_pkey_handle_t kekek_handle = {HAL_HANDLE_NONE}; char *kekek_fn = NULL; char *in_fn = NULL; + int raw = 0; int opt; - while ((opt = getopt(argc, argv, "-K:i:xv")) != -1) { + while ((opt = getopt(argc, argv, "-K:i:xvr")) != -1) { switch (opt) { case 1: /* found the next command */ @@ -1036,6 +1052,9 @@ static int pkey_import(int argc, char *argv[]) case 'v': flags &= ~HAL_KEY_FLAG_TOKEN; break; + case 'r': + raw = 1; + break; default: puts(usage); return -1; @@ -1043,7 +1062,7 @@ static int pkey_import(int argc, char *argv[]) } done: - if (kekek_fn == NULL) { + if (!raw && kekek_fn == NULL) { printf("export: missing kekek\n"); puts(usage); return -1; @@ -1055,10 +1074,11 @@ done: return -1; } - if (pkey_load(kekek_fn, &kekek_handle) != 0) + if (!raw && pkey_load(kekek_fn, &kekek_handle) != 0) goto fail; { + hal_error_t err; char fn[strlen(in_fn) + 5]; strcpy(fn, in_fn); strcat(fn, ".der"); size_t der_len = file_size(fn); @@ -1068,36 +1088,44 @@ done: if (file_read(fn, der, &der_len, sizeof(der)) != 0) goto fail; - strcpy(fn, in_fn); strcat(fn, ".kek"); - size_t kek_len = file_size(fn); - if (kek_len == SIZE_MAX) - goto fail; - uint8_t kek[kek_len]; - if (file_read(fn, kek, &kek_len, sizeof(kek)) != 0) - goto fail; + if (!raw) { + strcpy(fn, in_fn); strcat(fn, ".kek"); + size_t kek_len = file_size(fn); + if (kek_len == SIZE_MAX) + goto fail; + uint8_t kek[kek_len]; + if (file_read(fn, kek, &kek_len, sizeof(kek)) != 0) + goto fail; - hal_error_t err; - if ((err = hal_rpc_pkey_import(client, session, - &key_handle, &key_uuid, - kekek_handle, - der, der_len, - kek, kek_len, - flags)) != HAL_OK) - lose("Error importing private key: %s\n", hal_error_string(err)); + if ((err = hal_rpc_pkey_import(client, session, + &key_handle, &key_uuid, + kekek_handle, + der, der_len, + kek, kek_len, + flags)) != HAL_OK) + lose("Error importing private key: %s\n", hal_error_string(err)); + } + else { + if ((err = hal_rpc_pkey_import_raw(client, session, + &key_handle, &key_uuid, + der, der_len, + flags)) != HAL_OK) + lose("Error importing private key: %s\n", hal_error_string(err)); + } char name_str[HAL_UUID_TEXT_SIZE]; if ((err = hal_uuid_format(&key_uuid, name_str, sizeof(name_str))) != HAL_OK) lose("Error formatting private key name: %s\n", hal_error_string(err)); printf("New private key name: %s\n", name_str); - if ((err = hal_rpc_pkey_delete(kekek_handle)) != HAL_OK) + if (!raw && (err = hal_rpc_pkey_delete(kekek_handle)) != HAL_OK) lose("Could not delete key: %s\n", hal_error_string(err)); } return 0; fail: - if (kekek_handle.handle != HAL_HANDLE_NONE) + if (!raw && kekek_handle.handle != HAL_HANDLE_NONE) (void)hal_rpc_pkey_delete(kekek_handle); return -1; |