5959#include "../internal.h"
6060
6161// Forward declarations
62- static int asn1_parse2 (BIO * bp , const uint8_t * * pp , long len , int offset ,
62+ static int asn1_parse2 (BIO * bp , const uint8_t * * pp , long len , long offset ,
6363 int depth , int indent , int dump );
6464static int asn1_print_info (BIO * bp , int tag , int xclass , int constructed ,
6565 int indent );
6666static int asn1_parse_constructed_type (BIO * bp , const uint8_t * * current_pos ,
6767 const uint8_t * total_end ,
6868 const uint8_t * original_start ,
6969 long * object_len , int parse_flags ,
70- int offset , int depth , int indent ,
70+ long offset , int depth , int indent ,
7171 int dump );
7272static int asn1_parse_primitive_type (BIO * bp , const uint8_t * object_start ,
7373 const uint8_t * current_pos ,
74- long object_len , int header_len , int tag ,
74+ long object_len , long header_len , int tag ,
7575 int dump );
7676
7777const char * ASN1_tag2str (int tag ) {
@@ -177,14 +177,18 @@ static int asn1_parse_constructed_type(BIO *bp, const uint8_t **current_pos,
177177 const uint8_t * total_end ,
178178 const uint8_t * original_start ,
179179 long * object_len , int parse_flags ,
180- int offset , int depth , int indent ,
180+ long offset , int depth , int indent ,
181181 int dump ) {
182182 GUARD_PTR (bp );
183183 GUARD_PTR (current_pos );
184184 GUARD_PTR (total_end );
185185 GUARD_PTR (original_start );
186186 GUARD_PTR (object_len );
187187
188+ if (offset < 0 || depth < 0 || indent < 0 ) {
189+ return 0 ;
190+ }
191+
188192 const uint8_t * start_pos = * current_pos ;
189193
190194 if (BIO_write (bp , "\n" , 1 ) <= 0 ) {
@@ -275,6 +279,10 @@ static int asn1_parse_boolean_type(BIO *bp, const uint8_t *data, long len,
275279 GUARD_PTR (data );
276280 GUARD_PTR (dump_as_hex );
277281
282+ if (len < 0 ) {
283+ return 0 ;
284+ }
285+
278286 if (len != 1 ) {
279287 if (BIO_puts (bp , ":BAD BOOLEAN" ) <= 0 ) {
280288 return 0 ;
@@ -295,6 +303,10 @@ static int asn1_parse_octet_string_type(BIO *bp, const uint8_t *data, long len,
295303 GUARD_PTR (data );
296304 GUARD_PTR (newline_printed );
297305
306+ if (len < 0 ) {
307+ return 0 ;
308+ }
309+
298310 const unsigned char * parse_pos = data ;
299311 int return_code = 0 ;
300312 int dump_indent = 6 ;
@@ -305,7 +317,7 @@ static int asn1_parse_octet_string_type(BIO *bp, const uint8_t *data, long len,
305317 int printable = 1 ;
306318 parse_pos = octet_string -> data ;
307319
308- // Test whether the octet string is printable
320+ // Test whether the octet string is printable (i.e. ASCII)
309321 for (int i = 0 ; i < octet_string -> length ; i ++ ) {
310322 if (((parse_pos [i ] < ' ' ) && (parse_pos [i ] != '\n' ) &&
311323 (parse_pos [i ] != '\r' ) && (parse_pos [i ] != '\t' )) ||
@@ -364,6 +376,10 @@ static int asn1_parse_integer_type(BIO *bp, const uint8_t *object_start,
364376 GUARD_PTR (object_start );
365377 GUARD_PTR (dump_as_hex );
366378
379+ if (object_len < 0 || header_len < 0 ) {
380+ return 0 ;
381+ }
382+
367383 const uint8_t * parse_pos = object_start ;
368384 int return_code = 0 ;
369385
@@ -409,6 +425,10 @@ static int asn1_parse_enumerated_type(BIO *bp, const uint8_t *object_start,
409425 GUARD_PTR (object_start );
410426 GUARD_PTR (dump_as_hex );
411427
428+ if (object_len < 0 || header_len < 0 ) {
429+ return 0 ;
430+ }
431+
412432 const uint8_t * parse_pos = object_start ;
413433 int return_code = 0 ;
414434
@@ -456,7 +476,11 @@ static int asn1_parse_hex_dump(BIO *bp, const uint8_t *object_start,
456476 GUARD_PTR (current_pos );
457477 GUARD_PTR (newline_printed );
458478
459- int dump_indent = 6 ;
479+ if (object_len < 0 || header_len < 0 ) {
480+ return 0 ;
481+ }
482+
483+ const int dump_indent = 6 ;
460484
461485 if (object_len > 0 && dump ) {
462486 if (!* newline_printed ) {
@@ -477,6 +501,10 @@ static int asn1_parse_hex_dump(BIO *bp, const uint8_t *object_start,
477501// Helper function to output hex data when dump_as_hex flag is set
478502static int asn1_output_hex_data (BIO * bp , const uint8_t * object_start ,
479503 long object_len , int header_len ) {
504+ if (object_len < 0 || header_len < 0 ) {
505+ return 0 ;
506+ }
507+
480508 const uint8_t * hex_data = object_start + header_len ;
481509
482510 if (BIO_puts (bp , ":[" ) <= 0 ) {
@@ -496,16 +524,20 @@ static int asn1_output_hex_data(BIO *bp, const uint8_t *object_start,
496524// Refactored main function to parse primitive ASN.1 types
497525static int asn1_parse_primitive_type (BIO * bp , const uint8_t * object_start ,
498526 const uint8_t * current_pos ,
499- long object_len , int header_len , int tag ,
527+ long object_len , long header_len , int tag ,
500528 int dump ) {
501- int newline_printed = 0 ;
502- int dump_as_hex = 0 ;
503- int result = 0 ;
504-
505529 GUARD_PTR (bp );
506530 GUARD_PTR (object_start );
507531 GUARD_PTR (current_pos );
508532
533+ if (object_len < 0 || header_len < 0 ) {
534+ return 0 ;
535+ }
536+
537+ int newline_printed = 0 ;
538+ int dump_as_hex = 0 ;
539+ int result = 0 ;
540+
509541 // Handle different primitive types
510542 if ((tag == V_ASN1_PRINTABLESTRING ) || (tag == V_ASN1_T61STRING ) ||
511543 (tag == V_ASN1_IA5STRING ) || (tag == V_ASN1_VISIBLESTRING ) ||
@@ -554,13 +586,17 @@ static int asn1_parse_primitive_type(BIO *bp, const uint8_t *object_start,
554586 return 1 ;
555587}
556588
557- static int asn1_parse2 (BIO * bp , const uint8_t * * pp , long length , int offset ,
589+ static int asn1_parse2 (BIO * bp , const uint8_t * * pp , long length , long offset ,
558590 int depth , int indent , int dump ) {
559591 GUARD_PTR (bp );
560592 GUARD_PTR (pp );
561593
594+ if (length < 0 || offset < 0 || depth < 0 || indent < 0 ) {
595+ return 0 ;
596+ }
597+
562598 const uint8_t * current_pos , * total_end , * object_start ;
563- long object_length = 0 ;
599+ long content_length = 0 ;
564600 int tag , xclass , return_value = 0 ;
565601 int header_length = 0 , parse_flags = 0 ;
566602
@@ -574,7 +610,7 @@ static int asn1_parse2(BIO *bp, const uint8_t **pp, long length, int offset,
574610 while (length > 0 ) {
575611 object_start = current_pos ;
576612 parse_flags =
577- ASN1_get_object (& current_pos , & object_length , & tag , & xclass , length );
613+ ASN1_get_object (& current_pos , & content_length , & tag , & xclass , length );
578614 if (parse_flags & 0x80 ) {
579615 if (BIO_write (bp , "Error in encoding\n" , 18 ) <= 0 ) {
580616 goto end ;
@@ -595,7 +631,7 @@ static int asn1_parse2(BIO *bp, const uint8_t **pp, long length, int offset,
595631
596632 if (parse_flags != (V_ASN1_CONSTRUCTED | 1 )) {
597633 if (BIO_printf (bp , "d=%-2d hl=%ld l=%4ld " , depth , (long )header_length ,
598- object_length ) <= 0 ) {
634+ content_length ) <= 0 ) {
599635 goto end ;
600636 }
601637 } else {
@@ -608,34 +644,34 @@ static int asn1_parse2(BIO *bp, const uint8_t **pp, long length, int offset,
608644 goto end ;
609645 }
610646 if (parse_flags & V_ASN1_CONSTRUCTED ) {
611- if (object_length > length ) {
647+ if (content_length > length ) {
612648 BIO_printf (bp , "length is greater than %ld\n" , length );
613649 return_value = 0 ;
614650 goto end ;
615651 }
616652 if (!asn1_parse_constructed_type (bp , & current_pos , total_end , * pp ,
617- & object_length , parse_flags , offset ,
653+ & content_length , parse_flags , offset ,
618654 depth , indent , dump )) {
619655 return_value = 0 ;
620656 goto end ;
621657 }
622658 } else if (xclass != 0 ) {
623- current_pos += object_length ;
659+ current_pos += content_length ;
624660 if (BIO_write (bp , "\n" , 1 ) <= 0 ) {
625661 goto end ;
626662 }
627663 } else {
628664 if (!asn1_parse_primitive_type (bp , object_start , current_pos ,
629- object_length , header_length , tag , dump )) {
665+ content_length , header_length , tag , dump )) {
630666 goto end ;
631667 }
632- current_pos += object_length ;
668+ current_pos += content_length ;
633669 if ((tag == V_ASN1_EOC ) && (xclass == 0 )) {
634670 return_value = 2 ; /* End of sequence */
635671 goto end ;
636672 }
637673 }
638- length -= object_length ;
674+ length -= content_length ;
639675 }
640676 return_value = 1 ;
641677end :
0 commit comments