@@ -8145,7 +8145,9 @@ bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
81458145 size_t i = 0, j = 0, ni = 0, nj = 0;
81468146 if (caps) caps->buf = NULL, caps->len = 0;
81478147 while (i < p.len || j < s.len) {
8148- if (i < p.len && j < s.len && (p.buf[i] == '?' || s.buf[j] == p.buf[i])) {
8148+ if (i < p.len && j < s.len &&
8149+ (p.buf[i] == '?' ||
8150+ (p.buf[i] != '*' && p.buf[i] != '#' && s.buf[j] == p.buf[i]))) {
81498151 if (caps == NULL) {
81508152 } else if (p.buf[i] == '?') {
81518153 caps->buf = &s.buf[j], caps->len = 1; // Finalize `?` cap
@@ -8188,10 +8190,10 @@ bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char sep) {
81888190
81898191bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) {
81908192 size_t i = 0, ndigits = 0;
8191- uint64_t max = val_len == sizeof(uint8_t) ? 0xFF
8193+ uint64_t max = val_len == sizeof(uint8_t) ? 0xFF
81928194 : val_len == sizeof(uint16_t) ? 0xFFFF
81938195 : val_len == sizeof(uint32_t) ? 0xFFFFFFFF
8194- : (uint64_t) ~0;
8196+ : (uint64_t) ~0;
81958197 uint64_t result = 0;
81968198 if (max == (uint64_t) ~0 && val_len != sizeof(uint64_t)) return false;
81978199 if (base == 0 && str.len >= 2) {
@@ -8207,7 +8209,7 @@ bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) {
82078209 case 2:
82088210 while (i < str.len && (str.buf[i] == '0' || str.buf[i] == '1')) {
82098211 uint64_t digit = (uint64_t) (str.buf[i] - '0');
8210- if (result > max/ 2) return false; // Overflow
8212+ if (result > max / 2) return false; // Overflow
82118213 result *= 2;
82128214 if (result > max - digit) return false; // Overflow
82138215 result += digit;
@@ -8217,12 +8219,12 @@ bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) {
82178219 case 10:
82188220 while (i < str.len && str.buf[i] >= '0' && str.buf[i] <= '9') {
82198221 uint64_t digit = (uint64_t) (str.buf[i] - '0');
8220- if (result > max/ 10) return false; // Overflow
8222+ if (result > max / 10) return false; // Overflow
82218223 result *= 10;
82228224 if (result > max - digit) return false; // Overflow
82238225 result += digit;
82248226 i++, ndigits++;
8225- }
8227+ }
82268228 break;
82278229 case 16:
82288230 while (i < str.len) {
@@ -8232,7 +8234,7 @@ bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) {
82328234 : (c >= 'a' && c <= 'f') ? (uint64_t) (c - 'W')
82338235 : (uint64_t) ~0;
82348236 if (digit == (uint64_t) ~0) break;
8235- if (result > max/ 16) return false; // Overflow
8237+ if (result > max / 16) return false; // Overflow
82368238 result *= 16;
82378239 if (result > max - digit) return false; // Overflow
82388240 result += digit;
@@ -9651,13 +9653,15 @@ static void mg_tls_drop_record(struct mg_connection *c) {
96519653static void mg_tls_drop_message(struct mg_connection *c) {
96529654 uint32_t len;
96539655 struct tls_data *tls = (struct tls_data *) c->tls;
9654- if (tls->recv.len == 0) {
9656+ if (tls->recv.len == 0) return;
9657+ len = MG_LOAD_BE24(tls->recv.buf + 1) + TLS_MSGHDR_SIZE;
9658+ if (tls->recv.len < len) {
9659+ mg_error(c, "wrong size");
96559660 return;
96569661 }
9657- len = MG_LOAD_BE24(tls->recv.buf + 1);
9658- mg_sha256_update(&tls->sha256, tls->recv.buf, len + TLS_MSGHDR_SIZE);
9659- tls->recv.buf += len + TLS_MSGHDR_SIZE;
9660- tls->recv.len -= len + TLS_MSGHDR_SIZE;
9662+ mg_sha256_update(&tls->sha256, tls->recv.buf, len);
9663+ tls->recv.buf += len;
9664+ tls->recv.len -= len;
96619665 if (tls->recv.len == 0) {
96629666 mg_tls_drop_record(c);
96639667 }
@@ -9918,6 +9922,10 @@ static int mg_tls_recv_record(struct mg_connection *c) {
99189922 free(dec);
99199923 }
99209924#else
9925+ if (msgsz < 16) {
9926+ mg_error(c, "wrong size");
9927+ return -1;
9928+ }
99219929 mg_aes_gcm_decrypt(msg, msg, msgsz - 16, key, 16, nonce, sizeof(nonce));
99229930#endif
99239931 r = msgsz - 16 - 1;
@@ -9981,8 +9989,10 @@ static int mg_tls_server_recv_hello(struct mg_connection *c) {
99819989 MG_INFO(("bad session id len"));
99829990 }
99839991 cipher_suites_len = MG_LOAD_BE16(rio->buf + 44 + session_id_len);
9992+ if (cipher_suites_len > (rio->len - 46 - session_id_len)) goto fail;
99849993 ext_len = MG_LOAD_BE16(rio->buf + 48 + session_id_len + cipher_suites_len);
99859994 ext = rio->buf + 50 + session_id_len + cipher_suites_len;
9995+ if (ext_len > (rio->len - 52 - session_id_len - cipher_suites_len)) goto fail;
99869996 for (j = 0; j < ext_len;) {
99879997 uint16_t k;
99889998 uint16_t key_exchange_len;
@@ -9993,10 +10003,14 @@ static int mg_tls_server_recv_hello(struct mg_connection *c) {
999310003 j += (uint16_t) (n + 4);
999410004 continue;
999510005 }
9996- key_exchange_len = MG_LOAD_BE16(ext + j + 5 );
10006+ key_exchange_len = MG_LOAD_BE16(ext + j + 4 );
999710007 key_exchange = ext + j + 6;
10008+ if (key_exchange_len >
10009+ rio->len - (uint16_t) ((size_t) key_exchange - (size_t) rio->buf) - 2)
10010+ goto fail;
999810011 for (k = 0; k < key_exchange_len;) {
999910012 uint16_t m = MG_LOAD_BE16(key_exchange + k + 2);
10013+ if (m > (key_exchange_len - k - 4)) goto fail;
1000010014 if (m == 32 && key_exchange[k] == 0x00 && key_exchange[k + 1] == 0x1d) {
1000110015 memmove(tls->x25519_cli, key_exchange + k + 4, m);
1000210016 mg_tls_drop_record(c);
@@ -10006,6 +10020,7 @@ static int mg_tls_server_recv_hello(struct mg_connection *c) {
1000610020 }
1000710021 j += (uint16_t) (n + 4);
1000810022 }
10023+ fail:
1000910024 mg_error(c, "bad client hello");
1001010025 return -1;
1001110026}
@@ -10324,13 +10339,15 @@ static int mg_tls_client_recv_hello(struct mg_connection *c) {
1032410339
1032510340 ext_len = MG_LOAD_BE16(rio->buf + 5 + 39 + 32 + 3);
1032610341 ext = rio->buf + 5 + 39 + 32 + 3 + 2;
10342+ if (ext_len > (rio->len - (5 + 39 + 32 + 3 + 2))) goto fail;
1032710343
1032810344 for (j = 0; j < ext_len;) {
1032910345 uint16_t ext_type = MG_LOAD_BE16(ext + j);
1033010346 uint16_t ext_len2 = MG_LOAD_BE16(ext + j + 2);
1033110347 uint16_t group;
1033210348 uint8_t *key_exchange;
1033310349 uint16_t key_exchange_len;
10350+ if (ext_len2 > (ext_len - j - 4)) goto fail;
1033410351 if (ext_type != 0x0033) { // not a key share extension, ignore
1033510352 j += (uint16_t) (ext_len2 + 4);
1033610353 continue;
@@ -10353,6 +10370,7 @@ static int mg_tls_client_recv_hello(struct mg_connection *c) {
1035310370 mg_tls_generate_handshake_keys(c);
1035410371 return 0;
1035510372 }
10373+ fail:
1035610374 mg_error(c, "bad client hello");
1035710375 return -1;
1035810376}
@@ -10663,7 +10681,7 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label,
1066310681 size_t n = 0, m = 0;
1066410682 char *s;
1066510683 const char *c;
10666- struct mg_str caps[5];
10684+ struct mg_str caps[6]; // number of wildcards + 1
1066710685 if (!mg_match(pem, mg_str("#-----BEGIN #-----#-----END #-----#"), caps)) {
1066810686 *der = mg_strdup(pem);
1066910687 return 0;
@@ -10713,6 +10731,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
1071310731 if (opts->name.len > 0) {
1071410732 if (opts->name.len >= sizeof(tls->hostname) - 1) {
1071510733 mg_error(c, "hostname too long");
10734+ return;
1071610735 }
1071710736 strncpy((char *) tls->hostname, opts->name.buf, sizeof(tls->hostname) - 1);
1071810737 tls->hostname[opts->name.len] = 0;
0 commit comments