summaryrefslogtreecommitdiff
path: root/src/ltc/pk/asn1
diff options
context:
space:
mode:
authorKarel Miko <karel.miko@gmail.com>2018-10-04 20:13:36 +0200
committerKarel Miko <karel.miko@gmail.com>2018-10-04 20:13:36 +0200
commitc14794b6f61e93a6716b75c4547b554033612e07 (patch)
tree6ae18006485245a855abcef838752b0ed6324e1f /src/ltc/pk/asn1
parent3bf90f7e79623e5f5f610fa683032811115b1553 (diff)
libtomcrypt update
Diffstat (limited to 'src/ltc/pk/asn1')
-rw-r--r--src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c9
-rw-r--r--src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c4
-rw-r--r--src/ltc/pk/asn1/oid/pk_get_oid.c45
-rw-r--r--src/ltc/pk/asn1/oid/pk_oid_cmp.c54
-rw-r--r--src/ltc/pk/asn1/oid/pk_oid_str.c90
-rw-r--r--src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c107
-rw-r--r--src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c10
-rw-r--r--src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c13
8 files changed, 318 insertions, 14 deletions
diff --git a/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c
index f4978627..23dcf770 100644
--- a/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c
+++ b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c
@@ -71,8 +71,13 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle
y++;
} else {
if (y == 0) {
- words[0] = t / 40;
- words[1] = t % 40;
+ if (t <= 79) {
+ words[0] = t / 40;
+ words[1] = t % 40;
+ } else {
+ words[0] = 2;
+ words[1] = t - 80;
+ }
y = 2;
} else {
words[y++] = t;
diff --git a/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c
index cc22a3c9..e6cff37a 100644
--- a/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c
+++ b/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c
@@ -48,8 +48,8 @@ int der_length_object_identifier(const unsigned long *words, unsigned long nword
return CRYPT_INVALID_ARG;
}
- /* word1 = 0,1,2,3 and word2 0..39 */
- if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) {
+ /* word1 = 0,1,2 and word2 0..39 */
+ if (words[0] > 2 || (words[0] < 2 && words[1] > 39)) {
return CRYPT_INVALID_ARG;
}
diff --git a/src/ltc/pk/asn1/oid/pk_get_oid.c b/src/ltc/pk/asn1/oid/pk_get_oid.c
new file mode 100644
index 00000000..529cf66a
--- /dev/null
+++ b/src/ltc/pk/asn1/oid/pk_get_oid.c
@@ -0,0 +1,45 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+#ifdef LTC_DER
+
+typedef struct {
+ enum ltc_oid_id id;
+ const char* oid;
+} oid_table_entry;
+
+static const oid_table_entry pka_oids[] = {
+ { PKA_RSA, "1.2.840.113549.1.1.1" },
+ { PKA_DSA, "1.2.840.10040.4.1" },
+ { PKA_EC, "1.2.840.10045.2.1" },
+ { PKA_EC_PRIMEF, "1.2.840.10045.1.1" },
+};
+
+/*
+ Returns the OID requested.
+ @return CRYPT_OK if valid
+*/
+int pk_get_oid(enum ltc_oid_id id, const char **st)
+{
+ unsigned int i;
+ LTC_ARGCHK(st != NULL);
+ for (i = 0; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) {
+ if (pka_oids[i].id == id) {
+ *st = pka_oids[i].oid;
+ return CRYPT_OK;
+ }
+ }
+ return CRYPT_INVALID_ARG;
+}
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/ltc/pk/asn1/oid/pk_oid_cmp.c b/src/ltc/pk/asn1/oid/pk_oid_cmp.c
new file mode 100644
index 00000000..5e3f1207
--- /dev/null
+++ b/src/ltc/pk/asn1/oid/pk_oid_cmp.c
@@ -0,0 +1,54 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+#ifdef LTC_DER
+
+/*
+ Compare an OID string to an array of `unsigned long`.
+ @return CRYPT_OK if equal
+*/
+int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size)
+{
+ unsigned long i;
+ char tmp[256] = { 0 };
+ int err;
+
+ if (o1 == NULL || o2 == NULL) return CRYPT_ERROR;
+
+ i = sizeof(tmp);
+ if ((err = pk_oid_num_to_str(o2, o2size, tmp, &i)) != CRYPT_OK) {
+ return err;
+ }
+
+ if (XSTRCMP(o1, tmp) != 0) {
+ return CRYPT_PK_INVALID_TYPE;
+ }
+
+ return CRYPT_OK;
+}
+
+/*
+ Compare an OID string to an OID element decoded from ASN.1.
+ @return CRYPT_OK if equal
+*/
+int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2)
+{
+ if (o1 == NULL || o2 == NULL) return CRYPT_ERROR;
+
+ if (o2->type != LTC_ASN1_OBJECT_IDENTIFIER) return CRYPT_INVALID_ARG;
+
+ return pk_oid_cmp_with_ulong(o1, o2->data, o2->size);
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/ltc/pk/asn1/oid/pk_oid_str.c b/src/ltc/pk/asn1/oid/pk_oid_str.c
new file mode 100644
index 00000000..afe6a1e8
--- /dev/null
+++ b/src/ltc/pk/asn1/oid/pk_oid_str.c
@@ -0,0 +1,90 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "tomcrypt_private.h"
+
+int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen)
+{
+ unsigned long i, j, limit, OID_len, oid_j;
+
+ LTC_ARGCHK(oidlen != NULL);
+
+ limit = *oidlen;
+ *oidlen = 0; /* make sure that we return zero oidlen on error */
+ for (i = 0; i < limit; i++) oid[i] = 0;
+
+ if (OID == NULL) return CRYPT_OK;
+
+ OID_len = strlen(OID);
+ if (OID_len == 0) return CRYPT_OK;
+
+ for (i = 0, j = 0; i < OID_len; i++) {
+ if (OID[i] == '.') {
+ if (++j >= limit) continue;
+ }
+ else if ((OID[i] >= '0') && (OID[i] <= '9')) {
+ if ((j >= limit) || (oid == NULL)) continue;
+ oid_j = oid[j];
+ oid[j] = oid[j] * 10 + (OID[i] - '0');
+ if (oid[j] < oid_j) return CRYPT_OVERFLOW;
+ }
+ else {
+ return CRYPT_ERROR;
+ }
+ }
+ if (j == 0) return CRYPT_ERROR;
+ if (j >= limit) {
+ *oidlen = j;
+ return CRYPT_BUFFER_OVERFLOW;
+ }
+ *oidlen = j + 1;
+ return CRYPT_OK;
+}
+
+int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen)
+{
+ int i;
+ unsigned long j, k;
+ char tmp[256] = { 0 };
+
+ LTC_ARGCHK(oid != NULL);
+ LTC_ARGCHK(OID != NULL);
+ LTC_ARGCHK(outlen != NULL);
+
+ for (i = oidlen - 1, k = 0; i >= 0; i--) {
+ j = oid[i];
+ if (j == 0) {
+ tmp[k] = '0';
+ if (++k >= sizeof(tmp)) return CRYPT_ERROR;
+ }
+ else {
+ while (j > 0) {
+ tmp[k] = '0' + (j % 10);
+ if (++k >= sizeof(tmp)) return CRYPT_ERROR;
+ j /= 10;
+ }
+ }
+ if (i > 0) {
+ tmp[k] = '.';
+ if (++k >= sizeof(tmp)) return CRYPT_ERROR;
+ }
+ }
+ if (*outlen < k + 1) {
+ *outlen = k + 1;
+ return CRYPT_BUFFER_OVERFLOW;
+ }
+ for (j = 0; j < k; j++) OID[j] = tmp[k - j - 1];
+ OID[k] = '\0';
+ *outlen = k; /* the length without terminating NUL byte */
+ return CRYPT_OK;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c b/src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c
new file mode 100644
index 00000000..eef2f410
--- /dev/null
+++ b/src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c
@@ -0,0 +1,107 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+#ifdef LTC_PKCS_8
+
+/**
+ PKCS#8 decrypt if necessary & flexi-decode
+
+ @param in Pointer to the ASN.1 encoded input data
+ @param inlen Length of the input data
+ @param pwd Pointer to the password that was used when encrypting
+ @param pwdlen Length of the password
+ @param decoded_list Pointer to a pointer for the flexi-decoded list
+ @return CRYPT_OK on success
+*/
+int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
+ const void *pwd, unsigned long pwdlen,
+ ltc_asn1_list **decoded_list)
+{
+ unsigned long len = inlen;
+ unsigned long dec_size;
+ unsigned char *dec_data = NULL;
+ ltc_asn1_list *l = NULL;
+ int err;
+
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(decoded_list != NULL);
+
+ *decoded_list = NULL;
+ if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) {
+ /* the following "if" detects whether it is encrypted or not */
+ /* PKCS8 Setup
+ * 0:d=0 hl=4 l= 380 cons: SEQUENCE
+ * 4:d=1 hl=2 l= 78 cons: SEQUENCE
+ * 6:d=2 hl=2 l= 9 prim: OBJECT :OID indicating PBES1 or PBES2 (== *lalgoid)
+ * 17:d=2 hl=2 l= 65 cons: SEQUENCE
+ * Stuff in between is dependent on whether it's PBES1 or PBES2
+ * 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data)
+ */
+ if (l->type == LTC_ASN1_SEQUENCE &&
+ LTC_ASN1_IS_TYPE(l->child, LTC_ASN1_SEQUENCE) &&
+ LTC_ASN1_IS_TYPE(l->child->child, LTC_ASN1_OBJECT_IDENTIFIER) &&
+ LTC_ASN1_IS_TYPE(l->child->child->next, LTC_ASN1_SEQUENCE) &&
+ LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) {
+ ltc_asn1_list *lalgoid = l->child->child;
+ pbes_arg pbes;
+
+ XMEMSET(&pbes, 0, sizeof(pbes));
+
+ if (pbes1_extract(lalgoid, &pbes) == CRYPT_OK) {
+ /* Successfully extracted PBES1 parameters */
+ } else if (pbes2_extract(lalgoid, &pbes) == CRYPT_OK) {
+ /* Successfully extracted PBES2 parameters */
+ } else {
+ /* unsupported encryption */
+ err = CRYPT_INVALID_PACKET;
+ goto LBL_DONE;
+ }
+
+ pbes.enc_data = l->child->next;
+ pbes.pwd = pwd;
+ pbes.pwdlen = pwdlen;
+
+ dec_size = pbes.enc_data->size;
+ if ((dec_data = XMALLOC(dec_size)) == NULL) {
+ err = CRYPT_MEM;
+ goto LBL_DONE;
+ }
+
+ if ((err = pbes_decrypt(&pbes, dec_data, &dec_size)) != CRYPT_OK) goto LBL_DONE;
+
+ der_free_sequence_flexi(l);
+ l = NULL;
+ err = der_decode_sequence_flexi(dec_data, &dec_size, &l);
+ if (err != CRYPT_OK) goto LBL_DONE;
+ *decoded_list = l;
+ }
+ else {
+ /* not encrypted */
+ err = CRYPT_OK;
+ *decoded_list = l;
+ }
+ /* Set l to NULL so it won't be free'd */
+ l = NULL;
+ }
+
+LBL_DONE:
+ if (l) der_free_sequence_flexi(l);
+ if (dec_data) {
+ zeromem(dec_data, dec_size);
+ XFREE(dec_data);
+ }
+ return err;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c
index ba51f292..bd84e7c7 100644
--- a/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c
+++ b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c
@@ -43,7 +43,7 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i
{
int err;
unsigned long len, alg_id_num;
- oid_st oid;
+ const char* oid;
unsigned char *tmpbuf;
unsigned long tmpoid[16];
ltc_asn1_list alg_id[2];
@@ -92,11 +92,9 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i
*parameters_len = alg_id[1].size;
}
- if ((alg_id[0].size != oid.OIDlen) ||
- XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0])) != 0) {
- /* OID mismatch */
- err = CRYPT_PK_INVALID_TYPE;
- goto LBL_ERR;
+ if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
+ /* OID mismatch */
+ goto LBL_ERR;
}
len = subject_pubkey[1].size/8;
diff --git a/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c
index bb29fed8..c9607b1c 100644
--- a/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c
+++ b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c
@@ -43,17 +43,22 @@ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outle
{
int err;
ltc_asn1_list alg_id[2];
- oid_st oid;
+ const char *OID;
+ unsigned long oid[16], oidlen;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
- err = pk_get_oid(algorithm, &oid);
- if (err != CRYPT_OK) {
+ if ((err = pk_get_oid(algorithm, &OID)) != CRYPT_OK) {
return err;
}
- LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen);
+ oidlen = sizeof(oid)/sizeof(oid[0]);
+ if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
+ return err;
+ }
+
+ LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len);
return der_encode_sequence_multi(out, outlen,