diff options
author | Karel Miko <karel.miko@gmail.com> | 2018-10-04 20:13:36 +0200 |
---|---|---|
committer | Karel Miko <karel.miko@gmail.com> | 2018-10-04 20:13:36 +0200 |
commit | c14794b6f61e93a6716b75c4547b554033612e07 (patch) | |
tree | 6ae18006485245a855abcef838752b0ed6324e1f /src/ltc/pk/asn1 | |
parent | 3bf90f7e79623e5f5f610fa683032811115b1553 (diff) |
libtomcrypt update
Diffstat (limited to 'src/ltc/pk/asn1')
-rw-r--r-- | src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c | 9 | ||||
-rw-r--r-- | src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c | 4 | ||||
-rw-r--r-- | src/ltc/pk/asn1/oid/pk_get_oid.c | 45 | ||||
-rw-r--r-- | src/ltc/pk/asn1/oid/pk_oid_cmp.c | 54 | ||||
-rw-r--r-- | src/ltc/pk/asn1/oid/pk_oid_str.c | 90 | ||||
-rw-r--r-- | src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c | 107 | ||||
-rw-r--r-- | src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c | 10 | ||||
-rw-r--r-- | src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c | 13 |
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, |