Skip to content

Commit c4eaf71

Browse files
authored
MONGOCRYPT-910 validate HTTP sizes (#1173)
1 parent 15f89a3 commit c4eaf71

3 files changed

Lines changed: 57 additions & 6 deletions

File tree

kms-message/src/hexlify.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "kms_message_private.h"
2222

23+
#include <limits.h>
2324
#include <stdint.h>
2425
#include <stdio.h>
2526
#include <stdlib.h>
@@ -50,8 +51,8 @@ unhexlify (const char *in, size_t len)
5051
{
5152
int i;
5253
int byte;
53-
int total = 0;
54-
int multiplier = 1;
54+
int64_t total = 0;
55+
int64_t multiplier = 1;
5556

5657
for (i = (int) len - 1; i >= 0; i--) {
5758
char c = *(in + i);
@@ -66,8 +67,11 @@ unhexlify (const char *in, size_t len)
6667
return -1;
6768
}
6869

69-
total += byte * multiplier;
70+
total += (int64_t) byte * multiplier;
71+
if (total > INT_MAX) {
72+
return -1;
73+
}
7074
multiplier *= 16;
7175
}
72-
return total;
76+
return (int) total;
7377
}

kms-message/src/kms_response_parser.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ _parse_line (kms_response_parser_t *parser, int end)
234234
/* if we have *not* read the Content-Length yet, check. */
235235
if (parser->content_length == -1 &&
236236
strcmp (key->str, "Content-Length") == 0) {
237-
if (!_parse_int (val->str, &parser->content_length)) {
237+
if (!_parse_int (val->str, &parser->content_length) || parser->content_length > KMS_PARSER_MAX_RESPONSE_LEN || parser->content_length < 0) {
238238
KMS_ERROR (parser, "Could not parse Content-Length header.");
239239
kms_request_str_destroy (key);
240240
kms_request_str_destroy (val);
@@ -258,7 +258,7 @@ _parse_line (kms_response_parser_t *parser, int end)
258258
} else if (parser->state == PARSING_CHUNK_LENGTH) {
259259
int result = 0;
260260

261-
if (!_parse_hex_from_view (raw + i, end - i, &result)) {
261+
if (!_parse_hex_from_view (raw + i, end - i, &result) || result > KMS_PARSER_MAX_RESPONSE_LEN || result < 0) {
262262
KMS_ERROR (parser, "Failed to parse hex chunk length.");
263263
return PARSING_DONE;
264264
}
@@ -297,6 +297,9 @@ kms_response_parser_feed (kms_response_parser_t *parser,
297297
/* find the next \r\n. */
298298
if (curr && strncmp (raw->str + (curr - 1), "\r\n", 2) == 0) {
299299
parser->state = _parse_line (parser, curr - 1);
300+
if (parser->failed) {
301+
return false;
302+
}
300303
parser->start = curr + 1;
301304
}
302305
curr++;

test/data/kms-tests.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,49 @@
293293
"{\"KeyId\": \"arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0\", \"CiphertextBlob\": \"A\"}"
294294
],
295295
"expect": "Failed to base64 decode"
296+
},
297+
{
298+
"description": "Chunked transfer with INT_MAX chunk size (MONGOCRYPT-910)",
299+
"ctx": [
300+
"datakey",
301+
"decrypt",
302+
"azure_oauth_datakey",
303+
"azure_oauth_decrypt",
304+
"azure_datakey",
305+
"azure_decrypt",
306+
"gcp_oauth_datakey",
307+
"gcp_oauth_decrypt",
308+
"gcp_datakey",
309+
"gcp_decrypt"
310+
],
311+
"http_reply": [
312+
"HTTP/1.1 200 OK\r\n",
313+
"Transfer-Encoding: chunked\r\n",
314+
"\r\n",
315+
"7fffffff\r\nX"
316+
],
317+
"expect": "Failed to parse hex chunk length"
318+
},
319+
{
320+
"description": "Content-Length too large",
321+
"ctx": [
322+
"datakey",
323+
"decrypt",
324+
"azure_oauth_datakey",
325+
"azure_oauth_decrypt",
326+
"azure_datakey",
327+
"azure_decrypt",
328+
"gcp_oauth_datakey",
329+
"gcp_oauth_decrypt",
330+
"gcp_datakey",
331+
"gcp_decrypt"
332+
],
333+
"http_reply": [
334+
"HTTP/1.1 200 OK\r\n",
335+
"Content-Length: 123123123\r\n",
336+
"\r\n",
337+
"{}"
338+
],
339+
"expect": "Could not parse Content-Length"
296340
}
297341
]

0 commit comments

Comments
 (0)