aboutsummaryrefslogtreecommitdiff
path: root/asn1.c
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2017-04-05 23:59:53 -0400
committerRob Austein <sra@hactrn.net>2017-04-05 23:59:53 -0400
commitfb4933fd6e42a661603b3249e3a0f95b003303b6 (patch)
tree8a1129086fabfd7952785e82195a1f4c5bfd36fd /asn1.c
parent34d240a491d0a5ccf2b9bf0f6cda8109d05f72ce (diff)
First cut at key backup code. Not tested yet.
Still missing Python script to drive backup process, and need to do something about setting the EXPORTABLE key flag for this to be useful.
Diffstat (limited to 'asn1.c')
-rw-r--r--asn1.c83
1 files changed, 72 insertions, 11 deletions
diff --git a/asn1.c b/asn1.c
index 1d7e628..3ca8fc8 100644
--- a/asn1.c
+++ b/asn1.c
@@ -52,7 +52,7 @@
#include <assert.h>
#include "hal.h"
-
+#include "hal_internal.h"
#include "asn1_internal.h"
#define INIT_FP_INT {{{0}}}
@@ -67,6 +67,16 @@ const size_t hal_asn1_oid_rsaEncryption_len = sizeof(hal_asn1_oid_rsaEncryption
const uint8_t hal_asn1_oid_ecPublicKey[] = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 };
const size_t hal_asn1_oid_ecPublicKey_len = sizeof(hal_asn1_oid_ecPublicKey);
+#if KEK_LENGTH == (bitsToBytes(128))
+const uint8_t hal_asn1_oid_aesKeyWrap[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x08 };
+const size_t hal_asn1_oid_aesKeyWrap_len = sizeof(hal_asn1_oid_aesKeyWrap);
+#endif
+
+#if KEK_LENGTH == (bitsToBytes(256))
+const uint8_t hal_asn1_oid_aesKeyWrap[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x30 };
+const size_t hal_asn1_oid_aesKeyWrap_len = sizeof(hal_asn1_oid_aesKeyWrap);
+#endif
+
/*
* Encode tag and length fields of an ASN.1 object.
*
@@ -482,8 +492,7 @@ hal_error_t hal_asn1_decode_spki(const uint8_t **alg_oid, size_t *alg_oid_len,
const uint8_t **pubkey, size_t *pubkey_len,
const uint8_t *const der, const size_t der_len)
{
- if (alg_oid == NULL || alg_oid_len == NULL || curve_oid == NULL || curve_oid_len == NULL ||
- pubkey == NULL || pubkey_len == NULL || der == NULL)
+ if (der == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
const uint8_t * const der_end = der + der_len;
@@ -510,12 +519,16 @@ hal_error_t hal_asn1_decode_spki(const uint8_t **alg_oid, size_t *alg_oid_len,
d += hlen;
if (vlen > algid_end - d)
return HAL_ERROR_ASN1_PARSE_FAILED;
- *alg_oid = d;
- *alg_oid_len = vlen;
+ if (alg_oid != NULL)
+ *alg_oid = d;
+ if (alg_oid_len != NULL)
+ *alg_oid_len = vlen;
d += vlen;
- *curve_oid = NULL;
- *curve_oid_len = 0;
+ if (curve_oid != NULL)
+ *curve_oid = NULL;
+ if (curve_oid_len != NULL)
+ *curve_oid_len = 0;
if (d < algid_end) {
switch (*d) {
@@ -526,8 +539,10 @@ hal_error_t hal_asn1_decode_spki(const uint8_t **alg_oid, size_t *alg_oid_len,
d += hlen;
if (vlen > algid_end - d)
return HAL_ERROR_ASN1_PARSE_FAILED;
- *curve_oid = d;
- *curve_oid_len = vlen;
+ if (curve_oid != NULL)
+ *curve_oid = d;
+ if (curve_oid_len != NULL)
+ *curve_oid_len = vlen;
d += vlen;
break;
@@ -551,8 +566,11 @@ hal_error_t hal_asn1_decode_spki(const uint8_t **alg_oid, size_t *alg_oid_len,
d += hlen;
if (vlen >= algid_end - d || vlen == 0 || *d != 0x00)
return HAL_ERROR_ASN1_PARSE_FAILED;
- *pubkey = ++d;
- *pubkey_len = --vlen;
+ ++d; --vlen;
+ if (pubkey != NULL)
+ *pubkey = d;
+ if (pubkey_len != NULL)
+ *pubkey_len = vlen;
d += vlen;
if (d != der_end)
@@ -721,6 +739,49 @@ hal_error_t hal_asn1_decode_pkcs8_encryptedprivatekeyinfo(const uint8_t **alg_oi
}
/*
+ * Attempt to guess what kind of key we're looking at.
+ */
+
+hal_error_t hal_asn1_guess_key_type(hal_key_type_t *type,
+ hal_curve_name_t *curve,
+ const uint8_t *const der, const size_t der_len)
+{
+ if (type == NULL || curve == NULL || der == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ const uint8_t *alg_oid, *curve_oid;
+ size_t alg_oid_len, curve_oid_len;
+ hal_error_t err;
+ int public = 0;
+
+ err = hal_asn1_decode_pkcs8_privatekeyinfo(&alg_oid, &alg_oid_len, &curve_oid, &curve_oid_len, NULL, 0, der, der_len);
+
+ if (err == HAL_ERROR_ASN1_PARSE_FAILED &&
+ (err = hal_asn1_decode_spki(&alg_oid, &alg_oid_len, &curve_oid, &curve_oid_len, NULL, 0, der, der_len)) == HAL_OK)
+ public = 1;
+
+ if (err != HAL_OK)
+ return err;
+
+ if (alg_oid_len == hal_asn1_oid_rsaEncryption_len && memcmp(alg_oid, hal_asn1_oid_rsaEncryption, alg_oid_len) == 0) {
+ *type = public ? HAL_KEY_TYPE_RSA_PUBLIC : HAL_KEY_TYPE_RSA_PRIVATE;
+ *curve = HAL_CURVE_NONE;
+ return HAL_OK;
+ }
+
+ if (alg_oid_len == hal_asn1_oid_ecPublicKey_len && memcmp(alg_oid, hal_asn1_oid_ecPublicKey, alg_oid_len) == 0) {
+ *type = public ? HAL_KEY_TYPE_EC_PUBLIC : HAL_KEY_TYPE_EC_PRIVATE;
+ if ((err = hal_ecdsa_oid_to_curve(curve, curve_oid, curve_oid_len)) != HAL_OK)
+ *curve = HAL_CURVE_NONE;
+ return err;
+ }
+
+ *type = HAL_KEY_TYPE_NONE;
+ *curve = HAL_CURVE_NONE;
+ return HAL_ERROR_UNSUPPORTED_KEY;
+}
+
+/*
* Local variables:
* indent-tabs-mode: nil
* End: