aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cryptech/libhal.py20
-rw-r--r--hal.h13
-rw-r--r--hal_internal.h14
-rw-r--r--hashsig.c35
-rw-r--r--rpc_api.c20
-rw-r--r--rpc_client.c66
-rw-r--r--rpc_pkey.c104
-rw-r--r--rpc_server.c60
-rw-r--r--utils/pkey.c104
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
diff --git a/hal.h b/hal.h
index 43ea6a0..1a08690 100644
--- a/hal.h
+++ b/hal.h
@@ -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,
diff --git a/hashsig.c b/hashsig.c
index f55558d..cd00224 100644
--- a/hashsig.c
+++ b/hashsig.c
@@ -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)
{
diff --git a/rpc_api.c b/rpc_api.c
index 97c8e99..155cb30 100644
--- a/rpc_api.c
+++ b/rpc_api.c
@@ -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 */
diff --git a/rpc_pkey.c b/rpc_pkey.c
index b44eb54..67732ad 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -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;