diff --git a/kms-message/src/kms_kmip_reader_writer.c b/kms-message/src/kms_kmip_reader_writer.c index aea16657f..9a139d919 100644 --- a/kms-message/src/kms_kmip_reader_writer.c +++ b/kms-message/src/kms_kmip_reader_writer.c @@ -451,6 +451,7 @@ kmip_reader_find (kmip_reader_t *reader, if (read_tag == search_tag && read_type == type) { *pos = reader->pos; *length = read_length; + CHECK_REMAINING_BUFFER_AND_RET (compute_padded_length(read_length)); return true; } @@ -477,6 +478,10 @@ kmip_reader_find_and_recurse (kmip_reader_t *reader, kmip_tag_type_t tag) } reader->pos = 0; + + if (pos + compute_padded_length (length) > reader->len) { + return false; + } reader->ptr = reader->ptr + pos; reader->len = length; return true; diff --git a/kms-message/test/test_kmip_reader_writer.c b/kms-message/test/test_kmip_reader_writer.c index fa164a3b9..94d721806 100644 --- a/kms-message/test/test_kmip_reader_writer.c +++ b/kms-message/test/test_kmip_reader_writer.c @@ -443,6 +443,26 @@ kms_kmip_reader_find_and_recurse_test (void) free (data); } +void kms_kmip_reader_find_and_recurse_invalid_test (void); // -Wmissing-prototypes: for testing only. +void +kms_kmip_reader_find_and_recurse_invalid_test (void) +{ + uint8_t *data; + size_t datalen; + kmip_reader_t *reader; + + // Structure with overly large length: + data = hex_to_data ( + "42 00 20 | 01 | 00 00 00 FF", // Struct with bad length + &datalen); + + reader = kmip_reader_new (data, datalen); + // Expect error: + ASSERT (!kmip_reader_find_and_recurse (reader, KMIP_TAG_CompromiseDate)); + kmip_reader_destroy (reader); + free (data); +} + void kms_kmip_reader_find_and_read_enum_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_find_and_read_enum_test (void) diff --git a/kms-message/test/test_kms_request.c b/kms-message/test/test_kms_request.c index 7e696c9fd..9fdb34171 100644 --- a/kms-message/test/test_kms_request.c +++ b/kms-message/test/test_kms_request.c @@ -1216,6 +1216,7 @@ extern void kms_kmip_reader_test (void); extern void kms_kmip_reader_negative_int_test (void); extern void kms_kmip_reader_find_test (void); extern void kms_kmip_reader_find_and_recurse_test (void); +extern void kms_kmip_reader_find_and_recurse_invalid_test (void); extern void kms_kmip_reader_find_and_read_enum_test (void); extern void kms_kmip_reader_find_and_read_bytes_test (void); extern void kms_kmip_request_register_secretdata_test (void); @@ -1280,6 +1281,7 @@ main (int argc, char *argv[]) RUN_TEST (kms_kmip_reader_negative_int_test); RUN_TEST (kms_kmip_reader_test); RUN_TEST (kms_kmip_reader_find_and_recurse_test); + RUN_TEST (kms_kmip_reader_find_and_recurse_invalid_test); RUN_TEST (kms_kmip_reader_find_and_read_enum_test); RUN_TEST (kms_kmip_reader_find_and_read_bytes_test); RUN_TEST (kms_kmip_request_register_secretdata_test);