@@ -11111,6 +11111,8 @@ enum mg_tls_hs_state {
11111
11111
11112
11112
// Server state machine:
11113
11113
MG_TLS_STATE_SERVER_START, // Wait for ClientHello
11114
+ MG_TLS_STATE_SERVER_WAIT_CERT, // Wait for Certificate
11115
+ MG_TLS_STATE_SERVER_WAIT_CV, // Wait for CertificateVerify
11114
11116
MG_TLS_STATE_SERVER_NEGOTIATED, // Wait for Finish
11115
11117
MG_TLS_STATE_SERVER_CONNECTED // Done
11116
11118
};
@@ -11146,14 +11148,15 @@ struct tls_data {
11146
11148
uint8_t x25519_cli[32]; // client X25519 key between the handshake states
11147
11149
uint8_t x25519_sec[32]; // x25519 secret between the handshake states
11148
11150
11149
- int skip_verification; // perform checks on server certificate?
11150
- int cert_requested; // client received a CertificateRequest?
11151
+ bool skip_verification; // do not perform checks on server certificate
11152
+ bool cert_requested; // client received a CertificateRequest
11153
+ bool is_twoway; // server is configured to authenticate clients
11151
11154
struct mg_str cert_der; // certificate in DER format
11152
11155
struct mg_str ca_der; // CA certificate
11153
11156
uint8_t ec_key[32]; // EC private key
11154
- char hostname[254]; // server hostname (client extension)
11157
+ char hostname[254]; // matching hostname
11155
11158
11156
- int is_ec_pubkey; // EC or RSA?
11159
+ bool is_ec_pubkey; // EC or RSA
11157
11160
uint8_t pubkey[512 + 16]; // server EC (64) or RSA (512+exp) public key to
11158
11161
// verify cert
11159
11162
size_t pubkeysz; // size of the server public key
@@ -11599,18 +11602,18 @@ static int mg_tls_recv_record(struct mg_connection *c) {
11599
11602
}
11600
11603
11601
11604
static void mg_tls_calc_cert_verify_hash(struct mg_connection *c,
11602
- uint8_t hash[32], int is_client) {
11605
+ uint8_t hash[32], bool is_client) {
11603
11606
struct tls_data *tls = (struct tls_data *) c->tls;
11604
- uint8_t server_context[34] = "TLS 1.3, server CertificateVerify";
11605
- uint8_t client_context[34] = "TLS 1.3, client CertificateVerify";
11606
11607
uint8_t sig_content[130];
11607
11608
mg_sha256_ctx sha256;
11608
11609
11609
11610
memset(sig_content, 0x20, 64);
11610
11611
if (is_client) {
11611
- memmove(sig_content + 64, client_context, sizeof(client_context));
11612
+ uint8_t client_context[34] = "TLS 1.3, client CertificateVerify";
11613
+ memcpy(sig_content + 64, client_context, sizeof(client_context));
11612
11614
} else {
11613
- memmove(sig_content + 64, server_context, sizeof(server_context));
11615
+ uint8_t server_context[34] = "TLS 1.3, server CertificateVerify";
11616
+ memcpy(sig_content + 64, server_context, sizeof(server_context));
11614
11617
}
11615
11618
11616
11619
memmove(&sha256, &tls->sha256, sizeof(mg_sha256_ctx));
@@ -11752,17 +11755,46 @@ static void mg_tls_server_send_ext(struct mg_connection *c) {
11752
11755
mg_tls_encrypt(c, ext, sizeof(ext), MG_TLS_HANDSHAKE);
11753
11756
}
11754
11757
11755
- static void mg_tls_server_send_cert(struct mg_connection *c) {
11758
+ // signature algorithms we actually support:
11759
+ // rsa_pkcs1_sha256, rsa_pss_rsae_sha256 and ecdsa_secp256r1_sha256
11760
+ static const uint8_t secp256r1_sig_algs[12] = {
11761
+ 0x00, 0x0d, 0x00, 0x08, 0x00, 0x06, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01,
11762
+ };
11763
+
11764
+ static void mg_tls_server_send_cert_request(struct mg_connection *c) {
11765
+ struct tls_data *tls = (struct tls_data *) c->tls;
11766
+ size_t n = sizeof(secp256r1_sig_algs) + 6;
11767
+ uint8_t *req = (uint8_t *) mg_calloc(1, 13 + n);
11768
+ if (req == NULL) {
11769
+ mg_error(c, "tls cert req oom");
11770
+ return;
11771
+ }
11772
+ req[0] = MG_TLS_CERTIFICATE_REQUEST; // handshake header
11773
+ MG_STORE_BE24(req + 1, n + 9);
11774
+ req[4] = 0; // context length
11775
+ MG_STORE_BE16(req + 5, n); // extensions length
11776
+ MG_STORE_BE16(req + 7, 13); // "signature algorithms"
11777
+ MG_STORE_BE16(req + 9, sizeof(secp256r1_sig_algs) + 2); // length
11778
+ MG_STORE_BE16(
11779
+ req + 11,
11780
+ sizeof(secp256r1_sig_algs)); // signature hash algorithms length
11781
+ memcpy(req + 13, (uint8_t *) secp256r1_sig_algs, sizeof(secp256r1_sig_algs));
11782
+ mg_sha256_update(&tls->sha256, req, 13 + n);
11783
+ mg_tls_encrypt(c, req, 13 + n, MG_TLS_HANDSHAKE);
11784
+ mg_free(req);
11785
+ }
11786
+
11787
+ static void mg_tls_send_cert(struct mg_connection *c, bool is_client) {
11756
11788
struct tls_data *tls = (struct tls_data *) c->tls;
11757
- int send_ca = !c-> is_client && tls->ca_der.len > 0;
11758
- // server DER certificate + CA (optional)
11789
+ int send_ca = !is_client && tls->ca_der.len > 0;
11790
+ // DER certificate + CA (server optional)
11759
11791
size_t n = tls->cert_der.len + (send_ca ? tls->ca_der.len + 5 : 0);
11760
11792
uint8_t *cert = (uint8_t *) mg_calloc(1, 13 + n);
11761
11793
if (cert == NULL) {
11762
11794
mg_error(c, "tls cert oom");
11763
11795
return;
11764
11796
}
11765
- cert[0] = 0x0b ; // handshake header
11797
+ cert[0] = MG_TLS_CERTIFICATE ; // handshake header
11766
11798
MG_STORE_BE24(cert + 1, n + 9);
11767
11799
cert[4] = 0; // request context
11768
11800
MG_STORE_BE24(cert + 5, n + 5); // 3 bytes: cert (s) length
@@ -11805,7 +11837,7 @@ static void finish_SHA256(const MG_UECC_HashContext *base,
11805
11837
mg_sha256_final(hash_result, &c->ctx);
11806
11838
}
11807
11839
11808
- static void mg_tls_send_cert_verify(struct mg_connection *c, int is_client) {
11840
+ static void mg_tls_send_cert_verify(struct mg_connection *c, bool is_client) {
11809
11841
struct tls_data *tls = (struct tls_data *) c->tls;
11810
11842
// server certificate verify packet
11811
11843
uint8_t verify[82] = {0x0f, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00};
@@ -11882,12 +11914,9 @@ static void mg_tls_client_send_hello(struct mg_connection *c) {
11882
11914
11883
11915
uint8_t x25519_pub[X25519_BYTES];
11884
11916
11885
- // signature algorithms we actually support:
11886
- // rsa_pkcs1_sha256, rsa_pss_rsae_sha256 and ecdsa_secp256r1_sha256
11887
- uint8_t secp256r1_sig_algs[12] = {
11888
- 0x00, 0x0d, 0x00, 0x08, 0x00, 0x06, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01,
11889
- };
11890
- // all popular signature algorithms (if we don't care about verification)
11917
+ // - "signature algorithms we actually support", see above
11918
+ // uint8_t secp256r1_sig_algs[]
11919
+ // - all popular signature algorithms (if we don't care about verification)
11891
11920
uint8_t all_sig_algs[34] = {
11892
11921
0x00, 0x0d, 0x00, 0x1e, 0x00, 0x1c, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03,
11893
11922
0x08, 0x07, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0a, 0x08, 0x0b, 0x08, 0x04,
@@ -11931,7 +11960,8 @@ static void mg_tls_client_send_hello(struct mg_connection *c) {
11931
11960
const char *hostname = tls->hostname;
11932
11961
size_t hostnamesz = strlen(tls->hostname);
11933
11962
size_t hostname_extsz = hostnamesz ? hostnamesz + 9 : 0;
11934
- uint8_t *sig_alg = tls->skip_verification ? all_sig_algs : secp256r1_sig_algs;
11963
+ uint8_t *sig_alg =
11964
+ tls->skip_verification ? all_sig_algs : (uint8_t *) secp256r1_sig_algs;
11935
11965
size_t sig_alg_sz = tls->skip_verification ? sizeof(all_sig_algs)
11936
11966
: sizeof(secp256r1_sig_algs);
11937
11967
@@ -12306,7 +12336,7 @@ static int mg_tls_verify_cert_cn(struct mg_der_tlv *subj, const char *host) {
12306
12336
return matched;
12307
12337
}
12308
12338
12309
- static int mg_tls_client_recv_cert (struct mg_connection *c) {
12339
+ static int mg_tls_recv_cert (struct mg_connection *c, bool is_client ) {
12310
12340
struct tls_data *tls = (struct tls_data *) c->tls;
12311
12341
unsigned char *recv_buf;
12312
12342
@@ -12324,7 +12354,8 @@ static int mg_tls_client_recv_cert(struct mg_connection *c) {
12324
12354
}
12325
12355
12326
12356
if (recv_buf[0] != MG_TLS_CERTIFICATE) {
12327
- mg_error(c, "expected server certificate but got msg 0x%02x", recv_buf[0]);
12357
+ mg_error(c, "expected %s certificate but got msg 0x%02x",
12358
+ is_client ? "server" : "client", recv_buf[0]);
12328
12359
return -1;
12329
12360
}
12330
12361
@@ -12334,7 +12365,7 @@ static int mg_tls_client_recv_cert(struct mg_connection *c) {
12334
12365
}
12335
12366
12336
12367
{
12337
- // Normally, there are 2-3 certs in a chain
12368
+ // Normally, there are 2-3 certs in a chain (when is_client)
12338
12369
struct mg_tls_cert certs[8];
12339
12370
int certnum = 0;
12340
12371
uint32_t full_cert_chain_len = MG_LOAD_BE24(recv_buf + 1);
@@ -12379,9 +12410,10 @@ static int mg_tls_client_recv_cert(struct mg_connection *c) {
12379
12410
}
12380
12411
12381
12412
if (ci == certs) {
12382
- // First certificate in the chain is peer cert, check SAN and store
12383
- // public key for further CertVerify step
12384
- if (mg_tls_verify_cert_san(cert, certsz, tls->hostname) <= 0 &&
12413
+ // First certificate in the chain is peer cert, check SAN if requested,
12414
+ // and store public key for further CertVerify step
12415
+ if (tls->hostname != NULL && *tls->hostname != '\0' &&
12416
+ mg_tls_verify_cert_san(cert, certsz, tls->hostname) <= 0 &&
12385
12417
mg_tls_verify_cert_cn(&ci->subj, tls->hostname) <= 0) {
12386
12418
mg_error(c, "failed to verify hostname");
12387
12419
return -1;
@@ -12412,28 +12444,28 @@ static int mg_tls_client_recv_cert(struct mg_connection *c) {
12412
12444
!mg_tls_verify_cert_signature(&certs[certnum - 1], &ca)) {
12413
12445
mg_error(c, "failed to verify CA");
12414
12446
return -1;
12415
- } else {
12447
+ } else if (is_client) {
12416
12448
MG_VERBOSE(
12417
12449
("CA was not in the chain, but verification with builtin CA "
12418
12450
"passed"));
12419
12451
}
12420
12452
}
12421
12453
}
12422
12454
mg_tls_drop_message(c);
12423
- mg_tls_calc_cert_verify_hash(c, tls->sighash, 0 );
12455
+ mg_tls_calc_cert_verify_hash(c, tls->sighash, !is_client );
12424
12456
return 0;
12425
12457
}
12426
12458
12427
- static int mg_tls_client_recv_cert_verify (struct mg_connection *c) {
12459
+ static int mg_tls_recv_cert_verify (struct mg_connection *c) {
12428
12460
struct tls_data *tls = (struct tls_data *) c->tls;
12429
12461
unsigned char *recv_buf;
12430
12462
if (mg_tls_recv_record(c) < 0) {
12431
12463
return -1;
12432
12464
}
12433
12465
recv_buf = &c->rtls.buf[tls->recv_offset];
12434
12466
if (recv_buf[0] != MG_TLS_CERTIFICATE_VERIFY) {
12435
- mg_error(c, "expected server certificate verify but got msg 0x%02x",
12436
- recv_buf[0]);
12467
+ mg_error(c, "expected %s certificate verify but got msg 0x%02x",
12468
+ c->is_client ? "server" : "client", recv_buf[0]);
12437
12469
return -1;
12438
12470
}
12439
12471
if (tls->recv_len < 8) {
@@ -12442,7 +12474,7 @@ static int mg_tls_client_recv_cert_verify(struct mg_connection *c) {
12442
12474
return -1;
12443
12475
}
12444
12476
12445
- // Ignore CertificateVerify is strict checks are not required
12477
+ // Ignore CertificateVerify if strict checks are not required
12446
12478
if (tls->skip_verification) {
12447
12479
mg_tls_drop_message(c);
12448
12480
return 0;
@@ -12573,13 +12605,13 @@ static void mg_tls_client_handshake(struct mg_connection *c) {
12573
12605
tls->state = MG_TLS_STATE_CLIENT_WAIT_CERT;
12574
12606
// Fallthrough
12575
12607
case MG_TLS_STATE_CLIENT_WAIT_CERT:
12576
- if (mg_tls_client_recv_cert(c ) < 0) {
12608
+ if (mg_tls_recv_cert(c, true ) < 0) {
12577
12609
break;
12578
12610
}
12579
12611
tls->state = MG_TLS_STATE_CLIENT_WAIT_CV;
12580
12612
// Fallthrough
12581
12613
case MG_TLS_STATE_CLIENT_WAIT_CV:
12582
- if (mg_tls_client_recv_cert_verify (c) < 0) {
12614
+ if (mg_tls_recv_cert_verify (c) < 0) {
12583
12615
break;
12584
12616
}
12585
12617
tls->state = MG_TLS_STATE_CLIENT_WAIT_FINISH;
@@ -12588,28 +12620,19 @@ static void mg_tls_client_handshake(struct mg_connection *c) {
12588
12620
if (mg_tls_client_recv_finish(c) < 0) {
12589
12621
break;
12590
12622
}
12591
- if (tls->cert_requested) {
12592
- /* for mTLS we should generate application keys at this point
12593
- * but then restore handshake keys and continue with
12594
- * the rest of the handshake */
12595
- struct tls_enc app_keys;
12596
- struct tls_enc hs_keys = tls->enc;
12597
- mg_tls_generate_application_keys(c);
12598
- app_keys = tls->enc;
12599
- tls->enc = hs_keys;
12600
- mg_tls_server_send_cert(c);
12601
- mg_tls_send_cert_verify(c, 1);
12602
- mg_tls_client_send_finish(c);
12603
- tls->enc = app_keys;
12604
- } else {
12605
- mg_tls_client_send_finish(c);
12606
- mg_tls_generate_application_keys(c);
12623
+ if (tls->cert_requested && tls->cert_der.len > 0) { // two-way auth
12624
+ mg_tls_send_cert(c, true);
12625
+ mg_tls_send_cert_verify(c, true);
12607
12626
}
12627
+ mg_tls_client_send_finish(c);
12628
+ mg_tls_generate_application_keys(c);
12608
12629
tls->state = MG_TLS_STATE_CLIENT_CONNECTED;
12609
12630
c->is_tls_hs = 0;
12610
12631
mg_call(c, MG_EV_TLS_HS, NULL);
12611
12632
break;
12612
- default: mg_error(c, "unexpected client state: %d", tls->state); break;
12633
+ default:
12634
+ mg_error(c, "unexpected client state: %d", tls->state);
12635
+ break;
12613
12636
}
12614
12637
}
12615
12638
@@ -12623,9 +12646,14 @@ static void mg_tls_server_handshake(struct mg_connection *c) {
12623
12646
mg_tls_server_send_hello(c);
12624
12647
mg_tls_generate_handshake_keys(c);
12625
12648
mg_tls_server_send_ext(c);
12626
- mg_tls_server_send_cert(c);
12627
- mg_tls_send_cert_verify(c, 0);
12649
+ if (tls->is_twoway) mg_tls_server_send_cert_request(c);
12650
+ mg_tls_send_cert(c, false);
12651
+ mg_tls_send_cert_verify(c, false);
12628
12652
mg_tls_server_send_finish(c);
12653
+ if (tls->is_twoway) {
12654
+ tls->state = MG_TLS_STATE_SERVER_WAIT_CERT;
12655
+ break;
12656
+ }
12629
12657
tls->state = MG_TLS_STATE_SERVER_NEGOTIATED;
12630
12658
// fallthrough
12631
12659
case MG_TLS_STATE_SERVER_NEGOTIATED:
@@ -12636,7 +12664,17 @@ static void mg_tls_server_handshake(struct mg_connection *c) {
12636
12664
tls->state = MG_TLS_STATE_SERVER_CONNECTED;
12637
12665
c->is_tls_hs = 0;
12638
12666
return;
12639
- default: mg_error(c, "unexpected server state: %d", tls->state); break;
12667
+ case MG_TLS_STATE_SERVER_WAIT_CERT:
12668
+ if (mg_tls_recv_cert(c, false) < 0) break;
12669
+ tls->state = MG_TLS_STATE_SERVER_WAIT_CV;
12670
+ // Fallthrough
12671
+ case MG_TLS_STATE_SERVER_WAIT_CV:
12672
+ if (mg_tls_recv_cert_verify(c) < 0) break;
12673
+ tls->state = MG_TLS_STATE_SERVER_NEGOTIATED;
12674
+ break;
12675
+ default:
12676
+ mg_error(c, "unexpected server state: %d", tls->state);
12677
+ break;
12640
12678
}
12641
12679
}
12642
12680
@@ -12723,6 +12761,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
12723
12761
MG_ERROR(("Failed to load certificate"));
12724
12762
return;
12725
12763
}
12764
+ if (!c->is_client) tls->is_twoway = true; // server + CA: two-way auth
12726
12765
}
12727
12766
12728
12767
if (opts->cert.buf == NULL) {
0 commit comments