mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
Make built-in TLS play fair to TCP
Handshake functions in Mongoose TLS assumed data was being fully sent after calling mg_io_send(). This was in fact the case with the usual 1460-bytes MSS, but not with the default 536-bytes MSS. This PR removes all those calls from individual handshake functions, actual send is done at the main handshake function, keeping track of the amount of data sent, and so handling small MTUs/MSSs and possible MG_IO_WAITs when running over a socket layer.
This commit is contained in:
parent
a321c2d096
commit
fadf28adb4
25
mongoose.c
25
mongoose.c
@ -4745,7 +4745,7 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||
return NULL;
|
||||
}
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
s->dmss = 1460; // TODO(scaprile): 536; // assume default, RFC-9293 3.7.1
|
||||
s->dmss = 536; // assume default, RFC-9293 3.7.1
|
||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||
settmout(c, MIP_TTYPE_KEEPALIVE);
|
||||
@ -10864,12 +10864,12 @@ enum mg_tls_hs_state {
|
||||
MG_TLS_STATE_CLIENT_WAIT_EE, // Wait for EncryptedExtensions
|
||||
MG_TLS_STATE_CLIENT_WAIT_CERT, // Wait for Certificate
|
||||
MG_TLS_STATE_CLIENT_WAIT_CV, // Wait for CertificateVerify
|
||||
MG_TLS_STATE_CLIENT_WAIT_FINISHED, // Wait for Finished
|
||||
MG_TLS_STATE_CLIENT_WAIT_FINISH, // Wait for Finish
|
||||
MG_TLS_STATE_CLIENT_CONNECTED, // Done
|
||||
|
||||
// Server state machine:
|
||||
MG_TLS_STATE_SERVER_START, // Wait for ClientHello
|
||||
MG_TLS_STATE_SERVER_NEGOTIATED, // Wait for Finished
|
||||
MG_TLS_STATE_SERVER_NEGOTIATED, // Wait for Finish
|
||||
MG_TLS_STATE_SERVER_CONNECTED // Done
|
||||
};
|
||||
|
||||
@ -11599,7 +11599,6 @@ static void mg_tls_send_cert_verify(struct mg_connection *c, int is_client) {
|
||||
|
||||
static void mg_tls_server_send_finish(struct mg_connection *c) {
|
||||
struct tls_data *tls = (struct tls_data *) c->tls;
|
||||
struct mg_iobuf *wio = &tls->send;
|
||||
mg_sha256_ctx sha256;
|
||||
uint8_t hash[32];
|
||||
uint8_t finish[36] = {0x14, 0, 0, 32};
|
||||
@ -11607,9 +11606,6 @@ static void mg_tls_server_send_finish(struct mg_connection *c) {
|
||||
mg_sha256_final(hash, &sha256);
|
||||
mg_hmac_sha256(finish + 4, tls->enc.server_finished_key, 32, hash, 32);
|
||||
mg_tls_encrypt(c, finish, sizeof(finish), MG_TLS_HANDSHAKE);
|
||||
mg_io_send(c, wio->buf, wio->len);
|
||||
wio->len = 0;
|
||||
|
||||
mg_sha256_update(&tls->sha256, finish, sizeof(finish));
|
||||
}
|
||||
|
||||
@ -11734,8 +11730,6 @@ static void mg_tls_client_send_hello(struct mg_connection *c) {
|
||||
|
||||
// change cipher message
|
||||
mg_iobuf_add(wio, wio->len, (const char *) "\x14\x03\x03\x00\x01\x01", 6);
|
||||
mg_io_send(c, wio->buf, wio->len);
|
||||
wio->len = 0;
|
||||
}
|
||||
|
||||
static int mg_tls_client_recv_hello(struct mg_connection *c) {
|
||||
@ -12284,7 +12278,6 @@ static int mg_tls_client_recv_finish(struct mg_connection *c) {
|
||||
|
||||
static void mg_tls_client_send_finish(struct mg_connection *c) {
|
||||
struct tls_data *tls = (struct tls_data *) c->tls;
|
||||
struct mg_iobuf *wio = &tls->send;
|
||||
mg_sha256_ctx sha256;
|
||||
uint8_t hash[32];
|
||||
uint8_t finish[36] = {0x14, 0, 0, 32};
|
||||
@ -12292,8 +12285,6 @@ static void mg_tls_client_send_finish(struct mg_connection *c) {
|
||||
mg_sha256_final(hash, &sha256);
|
||||
mg_hmac_sha256(finish + 4, tls->enc.client_finished_key, 32, hash, 32);
|
||||
mg_tls_encrypt(c, finish, sizeof(finish), MG_TLS_HANDSHAKE);
|
||||
mg_io_send(c, wio->buf, wio->len);
|
||||
wio->len = 0;
|
||||
}
|
||||
|
||||
static void mg_tls_client_handshake(struct mg_connection *c) {
|
||||
@ -12325,9 +12316,9 @@ static void mg_tls_client_handshake(struct mg_connection *c) {
|
||||
if (mg_tls_client_recv_cert_verify(c) < 0) {
|
||||
break;
|
||||
}
|
||||
tls->state = MG_TLS_STATE_CLIENT_WAIT_FINISHED;
|
||||
tls->state = MG_TLS_STATE_CLIENT_WAIT_FINISH;
|
||||
// Fallthrough
|
||||
case MG_TLS_STATE_CLIENT_WAIT_FINISHED:
|
||||
case MG_TLS_STATE_CLIENT_WAIT_FINISH:
|
||||
if (mg_tls_client_recv_finish(c) < 0) {
|
||||
break;
|
||||
}
|
||||
@ -12388,11 +12379,17 @@ static void mg_tls_server_handshake(struct mg_connection *c) {
|
||||
}
|
||||
|
||||
void mg_tls_handshake(struct mg_connection *c) {
|
||||
struct tls_data *tls = (struct tls_data *) c->tls;
|
||||
long n;
|
||||
if (c->is_client) {
|
||||
mg_tls_client_handshake(c);
|
||||
} else {
|
||||
mg_tls_server_handshake(c);
|
||||
}
|
||||
while (tls->send.len > 0 &&
|
||||
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
|
||||
mg_iobuf_del(&tls->send, 0, (size_t) n);
|
||||
}
|
||||
}
|
||||
|
||||
static int mg_parse_pem(const struct mg_str pem, const struct mg_str label,
|
||||
|
@ -580,7 +580,7 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||
return NULL;
|
||||
}
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
s->dmss = 1460; // TODO(scaprile): 536; // assume default, RFC-9293 3.7.1
|
||||
s->dmss = 536; // assume default, RFC-9293 3.7.1
|
||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||
settmout(c, MIP_TTYPE_KEEPALIVE);
|
||||
|
@ -39,12 +39,12 @@ enum mg_tls_hs_state {
|
||||
MG_TLS_STATE_CLIENT_WAIT_EE, // Wait for EncryptedExtensions
|
||||
MG_TLS_STATE_CLIENT_WAIT_CERT, // Wait for Certificate
|
||||
MG_TLS_STATE_CLIENT_WAIT_CV, // Wait for CertificateVerify
|
||||
MG_TLS_STATE_CLIENT_WAIT_FINISHED, // Wait for Finished
|
||||
MG_TLS_STATE_CLIENT_WAIT_FINISH, // Wait for Finish
|
||||
MG_TLS_STATE_CLIENT_CONNECTED, // Done
|
||||
|
||||
// Server state machine:
|
||||
MG_TLS_STATE_SERVER_START, // Wait for ClientHello
|
||||
MG_TLS_STATE_SERVER_NEGOTIATED, // Wait for Finished
|
||||
MG_TLS_STATE_SERVER_NEGOTIATED, // Wait for Finish
|
||||
MG_TLS_STATE_SERVER_CONNECTED // Done
|
||||
};
|
||||
|
||||
@ -774,7 +774,6 @@ static void mg_tls_send_cert_verify(struct mg_connection *c, int is_client) {
|
||||
|
||||
static void mg_tls_server_send_finish(struct mg_connection *c) {
|
||||
struct tls_data *tls = (struct tls_data *) c->tls;
|
||||
struct mg_iobuf *wio = &tls->send;
|
||||
mg_sha256_ctx sha256;
|
||||
uint8_t hash[32];
|
||||
uint8_t finish[36] = {0x14, 0, 0, 32};
|
||||
@ -782,9 +781,6 @@ static void mg_tls_server_send_finish(struct mg_connection *c) {
|
||||
mg_sha256_final(hash, &sha256);
|
||||
mg_hmac_sha256(finish + 4, tls->enc.server_finished_key, 32, hash, 32);
|
||||
mg_tls_encrypt(c, finish, sizeof(finish), MG_TLS_HANDSHAKE);
|
||||
mg_io_send(c, wio->buf, wio->len);
|
||||
wio->len = 0;
|
||||
|
||||
mg_sha256_update(&tls->sha256, finish, sizeof(finish));
|
||||
}
|
||||
|
||||
@ -909,8 +905,6 @@ static void mg_tls_client_send_hello(struct mg_connection *c) {
|
||||
|
||||
// change cipher message
|
||||
mg_iobuf_add(wio, wio->len, (const char *) "\x14\x03\x03\x00\x01\x01", 6);
|
||||
mg_io_send(c, wio->buf, wio->len);
|
||||
wio->len = 0;
|
||||
}
|
||||
|
||||
static int mg_tls_client_recv_hello(struct mg_connection *c) {
|
||||
@ -1459,7 +1453,6 @@ static int mg_tls_client_recv_finish(struct mg_connection *c) {
|
||||
|
||||
static void mg_tls_client_send_finish(struct mg_connection *c) {
|
||||
struct tls_data *tls = (struct tls_data *) c->tls;
|
||||
struct mg_iobuf *wio = &tls->send;
|
||||
mg_sha256_ctx sha256;
|
||||
uint8_t hash[32];
|
||||
uint8_t finish[36] = {0x14, 0, 0, 32};
|
||||
@ -1467,8 +1460,6 @@ static void mg_tls_client_send_finish(struct mg_connection *c) {
|
||||
mg_sha256_final(hash, &sha256);
|
||||
mg_hmac_sha256(finish + 4, tls->enc.client_finished_key, 32, hash, 32);
|
||||
mg_tls_encrypt(c, finish, sizeof(finish), MG_TLS_HANDSHAKE);
|
||||
mg_io_send(c, wio->buf, wio->len);
|
||||
wio->len = 0;
|
||||
}
|
||||
|
||||
static void mg_tls_client_handshake(struct mg_connection *c) {
|
||||
@ -1500,9 +1491,9 @@ static void mg_tls_client_handshake(struct mg_connection *c) {
|
||||
if (mg_tls_client_recv_cert_verify(c) < 0) {
|
||||
break;
|
||||
}
|
||||
tls->state = MG_TLS_STATE_CLIENT_WAIT_FINISHED;
|
||||
tls->state = MG_TLS_STATE_CLIENT_WAIT_FINISH;
|
||||
// Fallthrough
|
||||
case MG_TLS_STATE_CLIENT_WAIT_FINISHED:
|
||||
case MG_TLS_STATE_CLIENT_WAIT_FINISH:
|
||||
if (mg_tls_client_recv_finish(c) < 0) {
|
||||
break;
|
||||
}
|
||||
@ -1563,11 +1554,17 @@ static void mg_tls_server_handshake(struct mg_connection *c) {
|
||||
}
|
||||
|
||||
void mg_tls_handshake(struct mg_connection *c) {
|
||||
struct tls_data *tls = (struct tls_data *) c->tls;
|
||||
long n;
|
||||
if (c->is_client) {
|
||||
mg_tls_client_handshake(c);
|
||||
} else {
|
||||
mg_tls_server_handshake(c);
|
||||
}
|
||||
while (tls->send.len > 0 &&
|
||||
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
|
||||
mg_iobuf_del(&tls->send, 0, (size_t) n);
|
||||
}
|
||||
}
|
||||
|
||||
static int mg_parse_pem(const struct mg_str pem, const struct mg_str label,
|
||||
|
Loading…
Reference in New Issue
Block a user