@@ -39,11 +39,12 @@ static int _new_element(ltc_asn1_list **l)
3939 @param in The input buffer
4040 @param inlen [in/out] The length of the input buffer and on output the amount of decoded data
4141 @param out [out] A pointer to the linked list
42+ @param depth The depth/level of decoding recursion we've already reached
4243 @return CRYPT_OK on success.
4344*/
44- int der_decode_sequence_flexi (const unsigned char * in , unsigned long * inlen , ltc_asn1_list * * out )
45+ static int _der_decode_sequence_flexi (const unsigned char * in , unsigned long * inlen , ltc_asn1_list * * out , unsigned long depth )
4546{
46- ltc_asn1_list * l , * t ;
47+ ltc_asn1_list * l ;
4748 unsigned long err , identifier , len , totlen , data_offset , id_len , len_len ;
4849 void * realloc_tmp ;
4950
@@ -428,6 +429,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
428429 }
429430 }
430431
432+ /* check that we don't go over the recursion limit */
433+ if (depth > LTC_DER_MAX_RECURSION ) {
434+ err = CRYPT_PK_ASN1_ERROR ;
435+ goto error ;
436+ }
437+
431438 if ((l -> data = XMALLOC (len )) == NULL ) {
432439 err = CRYPT_MEM ;
433440 goto error ;
@@ -446,7 +453,7 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
446453 len_len = len ;
447454
448455 /* Sequence elements go as child */
449- if ((err = der_decode_sequence_flexi (in , & len , & (l -> child ))) != CRYPT_OK ) {
456+ if ((err = _der_decode_sequence_flexi (in , & len , & (l -> child ), depth + 1 )) != CRYPT_OK ) {
450457 goto error ;
451458 }
452459 if (len_len != len ) {
@@ -463,17 +470,6 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
463470 l -> child -> parent = l ;
464471 }
465472
466- t = l ;
467- len_len = 0 ;
468- while ((t != NULL ) && (t -> child != NULL )) {
469- len_len ++ ;
470- t = t -> child ;
471- }
472- if (len_len > LTC_DER_MAX_RECURSION ) {
473- err = CRYPT_PK_ASN1_ERROR ;
474- goto error ;
475- }
476-
477473 break ;
478474
479475 case 0x80 : /* Context-specific */
@@ -535,6 +531,18 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
535531 return err ;
536532}
537533
534+ /**
535+ ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
536+ @param in The input buffer
537+ @param inlen [in/out] The length of the input buffer and on output the amount of decoded data
538+ @param out [out] A pointer to the linked list
539+ @return CRYPT_OK on success.
540+ */
541+ int der_decode_sequence_flexi (const unsigned char * in , unsigned long * inlen , ltc_asn1_list * * out )
542+ {
543+ return _der_decode_sequence_flexi (in , inlen , out , 0 );
544+ }
545+
538546#endif
539547
540548
0 commit comments