From 690fd61a0cf2b4b51ee64811656692eb644d2918 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 Aug 2024 17:51:01 +0200 Subject: sm: More improvements for PKCS#12 parsing for latest IVBB changes. * common/tlv.h (TLV_PARSER_FLAG_T5793): New. (tlv_parser_new): New macro. Rename function with an underscore. (tlv_next_with_flag): New. * common/tlv-parser.c (struct tlv_parser_s): Remove const from buffer. Add fields crammed, lasttlv, and origoff. Remove bufferlist ands ist definition. (dump_to_file): New but disabled debug helper. (parse_tag): Print more info on error. (_tlv_parser_new): Add args lasttlv and LNO. Take a copy of the data. (_tlv_parser_release): Free the copy of the buffer and return the recorded TLV object from tlv_parser_new. (_tlv_peek, tlv_parser_peek, _tlv_parser_peek_null): Remove. (_tlv_push): Record crammed length. (_tlv_pop): Restore crammed length. (_tlv_parser_next): Add arg flags. More debug output. Handle cramming here. Take care of cramming here. (tlv_expect_object): Simplify to adjust for changes in _tlv_parser_next. (tlv_expect_octet_string): Remove arg encapsulates. Adjust for changes in _tlv_parser_next. Change all allers. (tlv_expect_null): New. (cram_octet_string): Rewrite. (need_octet_string_cramming): Remove. * sm/minip12.c (dump_to_file): New. Enablein debug mode and if a envvar ist set. Replace all explict but disabled dumping to call this function. (parse_bag_encrypted_data): Replace tlv_peek_null and a peeking for an optional SET by non-peeking code. (parse_cert_bag): Ditto. (parse_shrouded_key_bag): Replace tlv_peek_null by non-peeking code. (parse_bag_encrypted_data): Use the new TLV_PARSER_FLAG_T5793 to enable the Mozilla workaround. (parse_bag_encrypted_data): Replace the 'renewed_tlv' code by the new tlv_parser_release semantics. (parse_shrouded_key_bag): Ditto. (parse_shrouded_key_bag): Create a new context instead of using the former encapsulated mechanism for tlv_expect_octet_string. (parse_bag_data): Ditto. (p12_parse): Ditto. -- GnuPG-bug-id: 7213 Fixing this took way too long; I should have earlier explained the code to a co-hacker to find the problem myself in my code by this. --- common/tlv.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'common/tlv.h') diff --git a/common/tlv.h b/common/tlv.h index 3136195a5..cfd615003 100644 --- a/common/tlv.h +++ b/common/tlv.h @@ -150,18 +150,17 @@ size_t get_tlv_length (int class, int tag, int constructed, size_t length); /*-- tlv-parser.c --*/ +#define TLV_PARSER_FLAG_T5793 1 /* Enable workaround for Mozilla bug. */ -tlv_parser_t tlv_parser_new (const unsigned char *buffer, size_t bufsize, - int verbosity); -void tlv_parser_release (tlv_parser_t tlv); +tlv_parser_t _tlv_parser_new (const unsigned char *buffer, size_t bufsize, + int verbosity, tlv_parser_t lasttlv, int lno); +tlv_parser_t _tlv_parser_release (tlv_parser_t tlv, int lno); void _tlv_parser_dump_tag (const char *text, int lno, tlv_parser_t tlv); void _tlv_parser_dump_state (const char *text, const char *text2, int lno, tlv_parser_t tlv); -int _tlv_parser_peek (tlv_parser_t tlv, int class, int tag); -int _tlv_parser_peek_null (tlv_parser_t tlv); -gpg_error_t _tlv_parser_next (tlv_parser_t tlv, int lno); +gpg_error_t _tlv_parser_next (tlv_parser_t tlv, unsigned int flags, int lno); unsigned int tlv_parser_level (tlv_parser_t tlv); size_t tlv_parser_offset (tlv_parser_t tlv); @@ -178,7 +177,7 @@ gpg_error_t tlv_expect_set (tlv_parser_t tlv); gpg_error_t tlv_expect_object (tlv_parser_t tlv, int class, int tag, unsigned char const **r_data, size_t *r_datalen); -gpg_error_t tlv_expect_octet_string (tlv_parser_t tlv, int encapsulates, +gpg_error_t tlv_expect_octet_string (tlv_parser_t tlv, unsigned char const **r_data, size_t *r_datalen); gpg_error_t tlv_expect_integer (tlv_parser_t tlv, int *r_value); @@ -189,19 +188,20 @@ gpg_error_t tlv_expect_mpinteger (tlv_parser_t tlv, int ignore_zero, gpg_error_t tlv_expect_object_id (tlv_parser_t tlv, unsigned char const **r_oid, size_t *r_oidlen); +gpg_error_t tlv_expect_null (tlv_parser_t tlv); /* Easier to use wrapper around parse_ber_header. */ gpg_error_t tlv_parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti); /* Convenience macro and macros to include the line number. */ +#define tlv_parser_new(a,b,c,d) _tlv_parser_new ((a),(b),(c),(d), __LINE__) +#define tlv_parser_release(a) _tlv_parser_release ((a), __LINE__) #define tlv_parser_dump_tag(a,b) _tlv_parser_dump_tag ((a),__LINE__,(b)) #define tlv_parser_dump_state(a,b,c) \ _tlv_parser_dump_state ((a),(b),__LINE__,(c)) -#define tlv_peek(a,b,c) _tlv_parser_peek ((a),(b),(c)) -#define tlv_peek_null(a) _tlv_parser_peek_null ((a)) -#define tlv_next(a) _tlv_parser_next ((a), __LINE__) - +#define tlv_next(a) _tlv_parser_next ((a),0, __LINE__) +#define tlv_next_with_flag(a,b) _tlv_parser_next ((a),(b), __LINE__) #endif /* SCD_TLV_H */ -- cgit v1.2.3