@@ -4968,10 +4968,8 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) {
49684968 // if not already running, setup a timer to send an ACK later
49694969 if (s->ttype != MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_ACK);
49704970 }
4971- if (c->is_tls && c->is_tls_hs) {
4972- mg_tls_handshake(c);
4973- } else if (c->is_tls) {
4974- handle_tls_recv(c);
4971+ if (c->is_tls) {
4972+ c->is_tls_hs ? mg_tls_handshake(c) : handle_tls_recv(c);
49754973 } else {
49764974 // Plain text connection, data is already in c->recv, trigger MG_EV_READ
49774975 mg_call(c, MG_EV_READ, &pkt->pay.len);
@@ -5592,7 +5590,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
55925590 mg_tls_pending(c), c->rtls.len));
55935591 // order is important, TLS conn close with > 1 record in buffer (below)
55945592 if (is_tls && (c->rtls.len > 0 || mg_tls_pending(c) > 0))
5595- handle_tls_recv(c);
5593+ c->is_tls_hs ? mg_tls_handshake(c) : handle_tls_recv(c);
55965594 if (can_write(c)) write_conn(c);
55975595 if (is_tls && c->send.len == 0) mg_tls_flush(c);
55985596 if (c->is_draining && c->send.len == 0 && s->ttype != MIP_TTYPE_FIN)
@@ -11164,7 +11162,8 @@ struct tls_data {
1116411162 size_t pubkeysz; // size of the server public key
1116511163 uint8_t sighash[32]; // calculated signature verification hash
1116611164
11167- struct tls_enc enc;
11165+ struct tls_enc enc; // actual keys in use at this time
11166+ struct tls_enc app_keys; // storage during two-way auth handshake
1116811167};
1116911168
1117011169#define TLS_RECHDR_SIZE 5 // 1 byte type, 2 bytes version, 2 bytes length
@@ -11554,8 +11553,7 @@ static int mg_tls_recv_record(struct mg_connection *c) {
1155411553 }
1155511554 if (rio->buf[0] == MG_TLS_APP_DATA) {
1155611555 break;
11557- } else if (rio->buf[0] ==
11558- MG_TLS_CHANGE_CIPHER) { // Skip ChangeCipher messages
11556+ } else if (rio->buf[0] == MG_TLS_CHANGE_CIPHER) { // skip CCS
1155911557 mg_tls_drop_record(c);
1156011558 } else if (rio->buf[0] == MG_TLS_ALERT) { // Skip Alerts
1156111559 MG_INFO(("TLS ALERT packet received"));
@@ -11764,29 +11762,28 @@ static void mg_tls_server_send_ext(struct mg_connection *c) {
1176411762// signature algorithms we actually support:
1176511763// rsa_pkcs1_sha256, rsa_pss_rsae_sha256 and ecdsa_secp256r1_sha256
1176611764static const uint8_t secp256r1_sig_algs[12] = {
11767- 0x00, 0x0d, 0x00, 0x08, 0x00, 0x06, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01,
11765+ 0x00, 0x0d, 0x00, 0x08, 0x00, 0x06, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01
1176811766};
1176911767
1177011768static void mg_tls_server_send_cert_request(struct mg_connection *c) {
1177111769 struct tls_data *tls = (struct tls_data *) c->tls;
11772- size_t n = sizeof(secp256r1_sig_algs) + 6;
11773- uint8_t *req = (uint8_t *) mg_calloc(1, 13 + n);
11770+ uint8_t *req = (uint8_t *) mg_calloc(1, 13 + sizeof(secp256r1_sig_algs));
1177411771 if (req == NULL) {
1177511772 mg_error(c, "tls cert req oom");
1177611773 return;
1177711774 }
1177811775 req[0] = MG_TLS_CERTIFICATE_REQUEST; // handshake header
11779- MG_STORE_BE24(req + 1, n + 9 );
11780- req[4] = 0; // context length
11781- MG_STORE_BE16(req + 5, n); // extensions length
11776+ MG_STORE_BE24(req + 1, 9 + sizeof(secp256r1_sig_algs) );
11777+ req[4] = 0; // context length
11778+ MG_STORE_BE16(req + 5, 6 + sizeof(secp256r1_sig_algs)); // extensions length
1178211779 MG_STORE_BE16(req + 7, 13); // "signature algorithms"
11783- MG_STORE_BE16(req + 9, sizeof(secp256r1_sig_algs) + 2 ); // length
11780+ MG_STORE_BE16(req + 9, 2 + sizeof(secp256r1_sig_algs)); // length
1178411781 MG_STORE_BE16(
1178511782 req + 11,
1178611783 sizeof(secp256r1_sig_algs)); // signature hash algorithms length
1178711784 memcpy(req + 13, (uint8_t *) secp256r1_sig_algs, sizeof(secp256r1_sig_algs));
11788- mg_sha256_update(&tls->sha256, req, 13 + n );
11789- mg_tls_encrypt(c, req, 13 + n , MG_TLS_HANDSHAKE);
11785+ mg_sha256_update(&tls->sha256, req, 13 + sizeof(secp256r1_sig_algs) );
11786+ mg_tls_encrypt(c, req, 13 + sizeof(secp256r1_sig_algs) , MG_TLS_HANDSHAKE);
1179011787 mg_free(req);
1179111788}
1179211789
@@ -12259,7 +12256,8 @@ static int mg_tls_parse_cert_der(void *buf, size_t dersz,
1225912256}
1226012257
1226112258static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
12262- const char *server_name) {
12259+ const char *server_name,
12260+ struct mg_addr *server_ip) {
1226312261 struct mg_der_tlv root, field, name;
1226412262 if (mg_der_parse((uint8_t *) der, dersz, &root) < 0) {
1226512263 MG_ERROR(("failed to parse certificate"));
@@ -12274,12 +12272,16 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
1227412272 return -1;
1227512273 }
1227612274 while (mg_der_next(&field, &name) > 0) {
12277- MG_DEBUG(("Found SAN: %.*s", name.len, name.value));
12278- if (mg_match(mg_str(server_name), mg_str_n((char *) name.value, name.len),
12279- NULL)) {
12280- // Found SAN that matches the host name
12281- return 1;
12282- }
12275+ if (name.type == 0x87 && name.len == 4) { // this is an IPv4 address
12276+ MG_DEBUG(("Found SAN, IP: %M", mg_print_ip4, name.value));
12277+ if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->ip4)
12278+ return 1; // and matches the one we're connected to
12279+ } else { // this is a text SAN
12280+ MG_DEBUG(("Found SAN, (%u): %.*s", name.type, name.len, name.value));
12281+ if (mg_match(mg_str(server_name), mg_str_n((char *) name.value, name.len),
12282+ NULL))
12283+ return 1; // and matches the host name
12284+ } // TODO(): add IPv6 comparison, more items ?
1228312285 }
1228412286 return -1;
1228512287}
@@ -12419,7 +12421,7 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) {
1241912421 // First certificate in the chain is peer cert, check SAN if requested,
1242012422 // and store public key for further CertVerify step
1242112423 if (tls->hostname[0] != '\0' &&
12422- mg_tls_verify_cert_san(cert, certsz, tls->hostname) <= 0 &&
12424+ mg_tls_verify_cert_san(cert, certsz, tls->hostname, &c->rem ) <= 0 &&
1242312425 mg_tls_verify_cert_cn(&ci->subj, tls->hostname) <= 0) {
1242412426 mg_error(c, "failed to verify hostname");
1242512427 return -1;
@@ -12627,11 +12629,19 @@ static void mg_tls_client_handshake(struct mg_connection *c) {
1262712629 break;
1262812630 }
1262912631 if (tls->cert_requested && tls->cert_der.len > 0) { // two-way auth
12632+ // generate application keys at this point, keep using handshake keys
12633+ struct tls_enc hs_keys = tls->enc;
12634+ mg_tls_generate_application_keys(c);
12635+ tls->app_keys = tls->enc;
12636+ tls->enc = hs_keys;
1263012637 mg_tls_send_cert(c, true);
1263112638 mg_tls_send_cert_verify(c, true);
12639+ mg_tls_client_send_finish(c);
12640+ tls->enc = tls->app_keys;
12641+ } else {
12642+ mg_tls_client_send_finish(c);
12643+ mg_tls_generate_application_keys(c);
1263212644 }
12633- mg_tls_client_send_finish(c);
12634- mg_tls_generate_application_keys(c);
1263512645 tls->state = MG_TLS_STATE_CLIENT_CONNECTED;
1263612646 c->is_tls_hs = 0;
1263712647 mg_call(c, MG_EV_TLS_HS, NULL);
@@ -12657,6 +12667,11 @@ static void mg_tls_server_handshake(struct mg_connection *c) {
1265712667 mg_tls_send_cert_verify(c, false);
1265812668 mg_tls_server_send_finish(c);
1265912669 if (tls->is_twoway) {
12670+ // generate application keys at this point, keep using handshake keys
12671+ struct tls_enc hs_keys = tls->enc;
12672+ mg_tls_generate_application_keys(c);
12673+ tls->app_keys = tls->enc;
12674+ tls->enc = hs_keys;
1266012675 tls->state = MG_TLS_STATE_SERVER_WAIT_CERT;
1266112676 break;
1266212677 }
@@ -12666,7 +12681,11 @@ static void mg_tls_server_handshake(struct mg_connection *c) {
1266612681 if (mg_tls_server_recv_finish(c) < 0) {
1266712682 return;
1266812683 }
12669- mg_tls_generate_application_keys(c);
12684+ if (tls->is_twoway) { // use previously generated keys
12685+ tls->enc = tls->app_keys;
12686+ } else { // generate keys now
12687+ mg_tls_generate_application_keys(c);
12688+ }
1267012689 tls->state = MG_TLS_STATE_SERVER_CONNECTED;
1267112690 c->is_tls_hs = 0;
1267212691 return;
0 commit comments