diff options
-rw-r--r-- | deps/openssl/openssl/ssl/ssl_local.h | 2 | ||||
-rw-r--r-- | deps/openssl/openssl/ssl/ssl_quic.c | 104 |
2 files changed, 76 insertions, 30 deletions
diff --git a/deps/openssl/openssl/ssl/ssl_local.h b/deps/openssl/openssl/ssl/ssl_local.h index fa61ec838c1..6277fa02c8e 100644 --- a/deps/openssl/openssl/ssl/ssl_local.h +++ b/deps/openssl/openssl/ssl/ssl_local.h @@ -1410,6 +1410,8 @@ struct ssl_st { OSSL_ENCRYPTION_LEVEL quic_write_level; QUIC_DATA *quic_input_data_head; QUIC_DATA *quic_input_data_tail; + uint8_t quic_msg_hd[SSL3_HM_HEADER_LENGTH]; + size_t quic_msg_hd_offset; const SSL_QUIC_METHOD *quic_method; #endif /* diff --git a/deps/openssl/openssl/ssl/ssl_quic.c b/deps/openssl/openssl/ssl/ssl_quic.c index 339414ded02..bcf4657e912 100644 --- a/deps/openssl/openssl/ssl/ssl_quic.c +++ b/deps/openssl/openssl/ssl/ssl_quic.c @@ -93,6 +93,7 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, { size_t l; uint8_t mt; + QUIC_DATA *qd; if (!SSL_IS_QUIC(ssl)) { SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -106,35 +107,65 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, return 0; } - /* Split on handshake message boundaries, if necessary */ - while (len > 0) { - QUIC_DATA *qd; - const uint8_t *p; + if (len == 0) { + return 1; + } - /* Check for an incomplete block */ - qd = ssl->quic_input_data_tail; - if (qd != NULL) { - l = qd->length - qd->offset; - if (l != 0) { - /* we still need to copy `l` bytes into the last data block */ - if (l > len) - l = len; - memcpy((char*)(qd+1) + qd->offset, data, l); - qd->offset += l; - len -= l; - data += l; - continue; - } + /* Check for an incomplete block */ + qd = ssl->quic_input_data_tail; + if (qd != NULL) { + l = qd->length - qd->offset; + if (l != 0) { + /* we still need to copy `l` bytes into the last data block */ + if (l > len) + l = len; + memcpy((char *)(qd + 1) + qd->offset, data, l); + qd->offset += l; + len -= l; + data += l; } + } - if (len < SSL3_HM_HEADER_LENGTH) { - SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_BAD_LENGTH); - return 0; + /* Split the QUIC messages up, if necessary */ + while (len > 0) { + const uint8_t *p; + uint8_t *dst; + + if (ssl->quic_msg_hd_offset != 0) { + /* If we have already buffered premature message header, + try to add new data to it to form complete message + header. */ + size_t nread = + SSL3_HM_HEADER_LENGTH - ssl->quic_msg_hd_offset; + + if (len < nread) + nread = len; + memcpy(ssl->quic_msg_hd + ssl->quic_msg_hd_offset, data, nread); + ssl->quic_msg_hd_offset += nread; + + if (ssl->quic_msg_hd_offset < SSL3_HM_HEADER_LENGTH) { + /* We still have premature message header. */ + break; + } + data += nread; + len -= nread; + /* TLS Handshake message header has 1-byte type and 3-byte length */ + mt = *ssl->quic_msg_hd; + p = ssl->quic_msg_hd + 1; + n2l3(p, l); + } else if (len < SSL3_HM_HEADER_LENGTH) { + /* We don't get complete message header. Just buffer the + received data and wait for the next data to arrive. */ + memcpy(ssl->quic_msg_hd, data, len); + ssl->quic_msg_hd_offset += len; + break; + } else { + /* We have complete message header in data. */ + /* TLS Handshake message header has 1-byte type and 3-byte length */ + mt = *data; + p = data + 1; + n2l3(p, l); } - /* TLS Handshake message header has 1-byte type and 3-byte length */ - mt = *data; - p = data + 1; - n2l3(p, l); l += SSL3_HM_HEADER_LENGTH; if (mt == SSL3_MT_KEY_UPDATE) { SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_UNEXPECTED_MESSAGE); @@ -150,12 +181,23 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, qd->next = NULL; qd->length = l; qd->level = level; - /* partial data received? */ - if (l > len) - l = len; - qd->offset = l; - memcpy((void*)(qd + 1), data, l); + dst = (uint8_t *)(qd + 1); + if (ssl->quic_msg_hd_offset) { + memcpy(dst, ssl->quic_msg_hd, ssl->quic_msg_hd_offset); + dst += ssl->quic_msg_hd_offset; + l -= SSL3_HM_HEADER_LENGTH; + if (l > len) + l = len; + qd->offset = SSL3_HM_HEADER_LENGTH + l; + memcpy(dst, data, l); + } else { + /* partial data received? */ + if (l > len) + l = len; + qd->offset = l; + memcpy(dst, data, l); + } if (ssl->quic_input_data_tail != NULL) ssl->quic_input_data_tail->next = qd; else @@ -164,6 +206,8 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, data += l; len -= l; + + ssl->quic_msg_hd_offset = 0; } return 1; |