Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions kms-message/src/kms_kmip_response_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ kms_kmip_response_parser_feed (kms_kmip_response_parser_t *parser,
const uint8_t *buf,
uint32_t len)
{
// As a precaution, limit the maximum size KMS response:
if (len > KMS_PARSER_MAX_RESPONSE_LEN || parser->buf->len > KMS_PARSER_MAX_RESPONSE_LEN - len) {
KMS_ERROR (parser, "KMS response too large");
return false;
}

kms_request_str_append_chars (parser->buf, (char *) buf, len);
parser->bytes_fed += len;

Expand Down
2 changes: 2 additions & 0 deletions kms-message/src/kms_message/kms_response_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
extern "C" {
#endif

#define KMS_PARSER_MAX_RESPONSE_LEN 16 * 1024 * 1024 /* 16 MiB */

typedef struct _kms_response_parser_t kms_response_parser_t;

KMS_MSG_EXPORT (kms_response_parser_t *)
Expand Down
6 changes: 6 additions & 0 deletions kms-message/src/kms_response_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ kms_response_parser_feed (kms_response_parser_t *parser,
return kms_kmip_response_parser_feed (parser->kmip, buf, len);
}

// As a precaution, limit the maximum size KMS response:
if (len > KMS_PARSER_MAX_RESPONSE_LEN || raw->len > KMS_PARSER_MAX_RESPONSE_LEN - len) {
KMS_ERROR (parser, "KMS response too large");
return false;
}

curr = (int) raw->len;
kms_request_str_append_chars (raw, (char *) buf, len);
/* process the new data appended. */
Expand Down
50 changes: 50 additions & 0 deletions kms-message/test/test_kms_kmip_response_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,53 @@ kms_kmip_response_parser_notenough_test (void)
kms_response_parser_destroy (parser);
free (data);
}


void kms_response_parser_response_too_big_test (void); // -Wmissing-prototypes: for testing only.
void
kms_response_parser_response_too_big_test (void)
{
uint8_t *data = (uint8_t*) malloc(KMS_PARSER_MAX_RESPONSE_LEN); // 16 MiB
memset(data, 0, KMS_PARSER_MAX_RESPONSE_LEN);

// Test HTTP parser:
{
kms_response_parser_t *parser = kms_response_parser_new ();

// Feed max length:
{
bool ok = kms_response_parser_feed (parser, data, KMS_PARSER_MAX_RESPONSE_LEN);
ASSERT (ok);
}

// Feed one more byte:
{
bool ok = kms_response_parser_feed (parser, data, 1);
ASSERT_PARSER_ERROR (parser, "KMS response too large");
ASSERT (!ok);
}

kms_response_parser_destroy (parser);
}

// Test KMIP parser:
{
kms_response_parser_t *parser = kms_kmip_response_parser_new (NULL);

// Feed max length:
{
bool ok = kms_response_parser_feed (parser, data, KMS_PARSER_MAX_RESPONSE_LEN);
ASSERT (ok);
}

// Feed one more byte:
{
bool ok = kms_response_parser_feed (parser, data, 1);
ASSERT_PARSER_ERROR (parser, "KMS response too large");
ASSERT (!ok);
}

kms_response_parser_destroy (parser);
}
free (data);
}
2 changes: 2 additions & 0 deletions kms-message/test/test_kms_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,7 @@ extern void kms_kmip_response_get_secretdata_notfound_test (void);
extern void kms_kmip_response_parser_reuse_test (void);
extern void kms_kmip_response_parser_excess_test (void);
extern void kms_kmip_response_parser_notenough_test (void);
extern void kms_response_parser_response_too_big_test (void);

int
main (int argc, char *argv[])
Expand Down Expand Up @@ -1296,6 +1297,7 @@ main (int argc, char *argv[])
RUN_TEST (kms_kmip_response_parser_reuse_test);
RUN_TEST (kms_kmip_response_parser_excess_test);
RUN_TEST (kms_kmip_response_parser_notenough_test);
RUN_TEST (kms_response_parser_response_too_big_test);
RUN_TEST (test_request_newlines);
RUN_TEST (test_kms_util);

Expand Down