Skip to content

Commit 719d297

Browse files
committed
Merge pull request #373 from libtom/fix/der-recursion-limit
implement DER recursion limit (cherry picked from commit af67321)
1 parent 3249dcb commit 719d297

6 files changed

Lines changed: 47 additions & 1 deletion

File tree

src/headers/tomcrypt_custom.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,13 @@
472472
#endif
473473
#endif
474474

475+
#if defined(LTC_DER)
476+
#ifndef LTC_DER_MAX_RECURSION
477+
/* Maximum recursion limit when processing nested ASN.1 types. */
478+
#define LTC_DER_MAX_RECURSION 30
479+
#endif
480+
#endif
481+
475482
#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT)
476483
/* Include the MPI functionality? (required by the PK algorithms) */
477484
#define LTC_MPI

src/misc/crypt/crypt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ const char *crypt_build_settings =
398398
#endif
399399
#if defined(LTC_DER)
400400
" DER "
401+
" " NAME_VALUE(LTC_DER_MAX_RECURSION) " "
401402
#endif
402403
#if defined(LTC_PKCS_1)
403404
" PKCS#1 "

src/misc/crypt/crypt_constants.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ static const crypt_constant _crypt_constants[] = {
111111

112112
#ifdef LTC_DER
113113
/* DER handling */
114+
{"LTC_DER", 1},
114115
_C_STRINGIFY(LTC_ASN1_EOL),
115116
_C_STRINGIFY(LTC_ASN1_BOOLEAN),
116117
_C_STRINGIFY(LTC_ASN1_INTEGER),
@@ -132,6 +133,9 @@ static const crypt_constant _crypt_constants[] = {
132133
_C_STRINGIFY(LTC_ASN1_CONSTRUCTED),
133134
_C_STRINGIFY(LTC_ASN1_CONTEXT_SPECIFIC),
134135
_C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME),
136+
_C_STRINGIFY(LTC_DER_MAX_RECURSION),
137+
#else
138+
{"LTC_DER", 0},
135139
#endif
136140

137141
#ifdef LTC_CTR_MODE

src/pk/asn1/der/sequence/der_decode_sequence_flexi.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static int _new_element(ltc_asn1_list **l)
7979
*/
8080
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
8181
{
82-
ltc_asn1_list *l;
82+
ltc_asn1_list *l, *t;
8383
unsigned long err, type, len, totlen, data_offset;
8484
void *realloc_tmp;
8585

@@ -407,6 +407,17 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
407407
l->child->parent = l;
408408
}
409409

410+
t = l;
411+
len_len = 0;
412+
while((t != NULL) && (t->child != NULL)) {
413+
len_len++;
414+
t = t->child;
415+
}
416+
if (len_len > LTC_DER_MAX_RECURSION) {
417+
err = CRYPT_PK_ASN1_ERROR;
418+
goto error;
419+
}
420+
410421
break;
411422

412423
case 0x80: /* Context-specific */

tests/common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ extern prng_state yarrow_prng;
1616
#ifdef LTC_VERBOSE
1717
#define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
1818
#define DOX(x, str) do { fprintf(stderr, "%s - %s:\n", #x, (str)); run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
19+
#define SHOULD_FAIL(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
1920
#else
2021
#define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
2122
#define DOX(x, str) do { run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
23+
#define SHOULD_FAIL(x) do { run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
2224
#endif
2325

2426
void run_cmd(int res, int line, const char *file, const char *cmd, const char *algorithm);

tests/der_test.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,25 @@ static int der_choice_test(void)
10941094
}
10951095

10961096

1097+
static void _der_recursion_limit(void)
1098+
{
1099+
int failed = 0;
1100+
unsigned int n;
1101+
unsigned long integer = 123, s;
1102+
ltc_asn1_list seqs[LTC_DER_MAX_RECURSION + 2], dummy[1], *flexi;
1103+
unsigned char buf[2048];
1104+
LTC_SET_ASN1(dummy, 0, LTC_ASN1_SHORT_INTEGER, &integer, 1);
1105+
LTC_SET_ASN1(seqs, LTC_DER_MAX_RECURSION + 1, LTC_ASN1_SEQUENCE, dummy, 1);
1106+
for (n = 0; n < LTC_DER_MAX_RECURSION + 1; ++n) {
1107+
LTC_SET_ASN1(seqs, LTC_DER_MAX_RECURSION - n, LTC_ASN1_SEQUENCE, &seqs[LTC_DER_MAX_RECURSION - n + 1], 1);
1108+
}
1109+
s = sizeof(buf);
1110+
DO(der_encode_sequence(seqs, 1, buf, &s));
1111+
DO(der_decode_sequence(buf, s, seqs, 1));
1112+
SHOULD_FAIL(der_decode_sequence_flexi(buf, &s, &flexi));
1113+
if (failed) exit(EXIT_FAILURE);
1114+
}
1115+
10971116
int der_test(void)
10981117
{
10991118
unsigned long x, y, z, zz, oid[2][32];
@@ -1126,6 +1145,8 @@ int der_test(void)
11261145
unsigned char utf8_buf[32];
11271146
wchar_t utf8_out[32];
11281147

1148+
1149+
_der_recursion_limit();
11291150
der_cacert_test();
11301151

11311152
DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL));

0 commit comments

Comments
 (0)