Skip to content

Commit

Permalink
deps: cherry-pick akamai/openssl/commit/a6282c566d88db11300c82abc3c84…
Browse files Browse the repository at this point in the history
…a4e2e9ea568

Original Commit Message:

  Some cleanup for the main QUIC changes

  Try to reduce unneeded whitespace changes and wrap new code to 80 columns.
  Reword documentation to attempt to improve clarity.
  Add some more sanity checks and clarifying comments to the code.
  Update referenced I-D versions.

PR-URL: #34033
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
  • Loading branch information
kaduk authored and jasnell committed Jun 24, 2020
1 parent 8a9763a commit 74cbfd3
Show file tree
Hide file tree
Showing 18 changed files with 166 additions and 111 deletions.
43 changes: 24 additions & 19 deletions deps/openssl/openssl/doc/man3/SSL_CTX_set_quic_method.pod
Expand Up @@ -63,22 +63,25 @@ SSL_quic_max_handshake_flight_len() returns the maximum number of bytes
that may be received at the given encryption level. This function should be
used to limit buffering in the QUIC implementation.

See https://tools.ietf.org/html/draft-ietf-quic-transport-16#section-4.4.
See https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-4.

SSL_quic_read_level() returns the current read encryption level.

SSL_quic_write_level() returns the current write encryption level.

SSL_provide_quic_data() provides data from QUIC at a particular encryption
level B<level>. It is an error to call this function outside of the handshake
or with an encryption level other than the current read level. It returns one
on success and zero on error.
SSL_provide_quic_data() is used to provide data from QUIC CRYPTO frames to the
state machine, at a particular encryption level B<level>. It is an error to
call this function outside of the handshake or with an encryption level other
than the current read level. The application must buffer and consolidate any
frames with less than four bytes of content. It returns one on success and
zero on error.

SSL_process_quic_post_handshake() processes any data that QUIC has provided
after the handshake has completed. This includes NewSessionTicket messages
sent by the server.

SSL_is_quic() indicates whether a connection uses QUIC.
SSL_is_quic() indicates whether a connection uses QUIC. A given B<SSL>
or B<SSL_CTX> can only be used with QUIC or TLS, but not both.

=head1 NOTES

Expand All @@ -89,11 +92,11 @@ functions allow a QUIC implementation to serve as the underlying transport as
described in draft-ietf-quic-tls.

When configured for QUIC, SSL_do_handshake() will drive the handshake as
before, but it will not use the configured B<BIO>. It will call functions on
B<SSL_QUIC_METHOD> to configure secrets and send data. If data is needed from
the peer, it will return B<SSL_ERROR_WANT_READ>. When received, the caller
should call SSL_provide_quic_data() and then SSL_do_handshake() to continue
the handshake. After the handshake is complete, the caller should call
before, but it will not use the configured B<BIO>. It will call functions from
the configured B<SSL_QUIC_METHOD> to configure secrets and send data. If data
is needed from the peer, it will return B<SSL_ERROR_WANT_READ>. When received,
the caller should call SSL_provide_quic_data() and then SSL_do_handshake() to
continue the handshake. After the handshake is complete, the caller should call
SSL_provide_quic_data() for any post-handshake data, followed by
SSL_process_quic_post_handshake() to process it. It is an error to call
SSL_read()/SSL_read_ex() and SSL_write()/SSL_write_ex() in QUIC.
Expand All @@ -105,19 +108,20 @@ pass the active write level to add_handshake_data() when writing data. Callers
can use SSL_quic_write_level() to query the active write level when
generating their own errors.

See https://tools.ietf.org/html/draft-ietf-quic-tls-15#section-4.1 for more
See https://tools.ietf.org/html/draft-ietf-quic-tls-27#section-4.1 for more
details.

To avoid DoS attacks, the QUIC implementation must limit the amount of data
being queued up. The implementation can call
SSL_quic_max_handshake_flight_len() to get the maximum buffer length at each
encryption level.

draft-ietf-quic-tls defines a new TLS extension quic_transport_parameters
draft-ietf-quic-tls defines a new TLS extension "quic_transport_parameters"
used by QUIC for each endpoint to unilaterally declare its supported
transport parameters. draft-ietf-quic-transport (section 7.4) defines the
contents of that extension (a TransportParameters struct) and describes how
to handle it and its semantic meaning.
transport parameters. The contents of the extension are specified in
https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-18 (as
a sequence of tag/length/value parameters) along with the interpretation of the
various parameters and the rules for their processing.

OpenSSL handles this extension as an opaque byte string. The caller is
responsible for serializing and parsing it.
Expand Down Expand Up @@ -205,10 +209,11 @@ SSL_process_quic_post_handshake()
return 1 on success, and 0 on error.

SSL_quic_read_level() and SSL_quic_write_level() return the current
encryption level as B<OSSL_ENCRYPTION_LEVEL> (B<enum ssl_encryption_level_t>).
encryption level as an B<OSSL_ENCRYPTION_LEVEL>
(B<enum ssl_encryption_level_t>).

SSL_quic_max_handshake_flight_len() returns the maximum length of a flight
for a given encryption level.
SSL_quic_max_handshake_flight_len() returns the maximum length in bytes of a
flight for a given encryption level.

SSL_is_quic() returns 1 if QUIC is being used, 0 if not.

Expand Down
4 changes: 2 additions & 2 deletions deps/openssl/openssl/include/openssl/ssl.h
Expand Up @@ -2473,10 +2473,10 @@ __owur int SSL_process_quic_post_handshake(SSL *ssl);

__owur int SSL_is_quic(SSL *ssl);

# endif

int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *c);

# endif

# ifdef __cplusplus
}
# endif
Expand Down
4 changes: 3 additions & 1 deletion deps/openssl/openssl/include/openssl/sslerr.h
Expand Up @@ -11,7 +11,9 @@
#ifndef HEADER_SSLERR_H
# define HEADER_SSLERR_H

# include <openssl/symhacks.h>
# ifndef HEADER_SYMHACKS_H
# include <openssl/symhacks.h>
# endif

# ifdef __cplusplus
extern "C"
Expand Down
2 changes: 1 addition & 1 deletion deps/openssl/openssl/include/openssl/tls1.h
Expand Up @@ -148,7 +148,7 @@ extern "C" {
/* Temporary extension type */
# define TLSEXT_TYPE_renegotiate 0xff01

/* ExtensionType value from draft-ietf-quic-tls-13 */
/* ExtensionType value from draft-ietf-quic-tls-27 */
# define TLSEXT_TYPE_quic_transport_parameters 0xffa5

# ifndef OPENSSL_NO_NEXTPROTONEG
Expand Down
7 changes: 5 additions & 2 deletions deps/openssl/openssl/ssl/build.info
Expand Up @@ -12,5 +12,8 @@ SOURCE[../libssl]=\
ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \
bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \
record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
statem/statem.c record/ssl3_record_tls13.c \
ssl_quic.c statem/statem_quic.c
statem/statem.c record/ssl3_record_tls13.c

IF[{- !$disabled{quic} -}]
SOURCE[../libssl]=ssl_quic.c statem/statem_quic.c
ENDIF
2 changes: 2 additions & 0 deletions deps/openssl/openssl/ssl/ssl_ciph.c
Expand Up @@ -2163,6 +2163,7 @@ int ssl_cert_is_disabled(size_t idx)
return 0;
}

#ifndef OPENSSL_NO_QUIC
int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *c)
{
switch (c->algorithm2 & (0xFF << TLS1_PRF_DGST_SHIFT)) {
Expand Down Expand Up @@ -2194,3 +2195,4 @@ int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *c)
}
return NID_undef;
}
#endif
2 changes: 1 addition & 1 deletion deps/openssl/openssl/ssl/ssl_lib.c
Expand Up @@ -3982,7 +3982,7 @@ EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx)

const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
{
if (s->session != NULL)
if ((s->session != NULL) && (s->session->cipher != NULL))
return s->session->cipher;
return NULL;
}
Expand Down
3 changes: 1 addition & 2 deletions deps/openssl/openssl/ssl/ssl_local.h
Expand Up @@ -1086,6 +1086,7 @@ struct quic_data_st {
OSSL_ENCRYPTION_LEVEL level;
size_t offset;
size_t length;
/* char data[]; should be here but C90 VLAs not allowed here */
};
typedef struct quic_data_st QUIC_DATA;
int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level);
Expand Down Expand Up @@ -1561,8 +1562,6 @@ typedef struct tls_group_info_st {
# define TLS_CURVE_CHAR2 0x1
# define TLS_CURVE_CUSTOM 0x2

typedef struct cert_pkey_st CERT_PKEY;

/*
* Structure containing table entry of certificate info corresponding to
* CERT_PKEY entries
Expand Down
45 changes: 21 additions & 24 deletions deps/openssl/openssl/ssl/ssl_quic.c
Expand Up @@ -11,10 +11,6 @@
#include "internal/cryptlib.h"
#include "internal/refcount.h"

#ifdef OPENSSL_NO_QUIC
NON_EMPTY_TRANSLATION_UNIT
#else

int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params,
size_t params_len)
{
Expand Down Expand Up @@ -109,10 +105,10 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level,
return 0;
}

/* Split the QUIC messages up, if necessary */
/* Split on handshake message boundaries, if necessary */
while (len > 0) {
QUIC_DATA *qd;
const uint8_t *p = data + 1;
const uint8_t *p;

/* Check for an incomplete block */
qd = ssl->quic_input_data_tail;
Expand All @@ -130,6 +126,12 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level,
}
}

if (len < SSL3_HM_HEADER_LENGTH) {
SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_BAD_LENGTH);
return 0;
}
/* TLS Handshake message header has 1-byte type and 3-byte length */
p = data + 1;
n2l3(p, l);
l += SSL3_HM_HEADER_LENGTH;

Expand Down Expand Up @@ -163,31 +165,17 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level,

int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method)
{
switch (ctx->method->version) {
case DTLS1_VERSION:
case DTLS1_2_VERSION:
case DTLS_ANY_VERSION:
case DTLS1_BAD_VER:
if (ctx->method->version != TLS_ANY_VERSION)
return 0;
default:
break;
}
ctx->quic_method = quic_method;
ctx->options &= ~SSL_OP_ENABLE_MIDDLEBOX_COMPAT;
return 1;
}

int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method)
{
switch (ssl->method->version) {
case DTLS1_VERSION:
case DTLS1_2_VERSION:
case DTLS_ANY_VERSION:
case DTLS1_BAD_VER:
if (ssl->method->version != TLS_ANY_VERSION)
return 0;
default:
break;
}
ssl->quic_method = quic_method;
ssl->options &= ~SSL_OP_ENABLE_MIDDLEBOX_COMPAT;
return 1;
Expand Down Expand Up @@ -225,6 +213,12 @@ int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level)
/* May not have selected cipher, yet */
const SSL_CIPHER *c = NULL;

/*
* It probably doesn't make sense to use an (external) PSK session,
* but in theory some kinds of external session caches could be
* implemented using it, so allow psksession to be used as well as
* the regular session.
*/
if (ssl->session != NULL)
c = SSL_SESSION_get0_cipher(ssl->session);
else if (ssl->psksession != NULL)
Expand Down Expand Up @@ -268,6 +262,11 @@ int SSL_process_quic_post_handshake(SSL *ssl)
return 0;
}

/*
* This is always safe (we are sure to be at a record boundary) because
* SSL_read()/SSL_write() are never used for QUIC connections -- the
* application data is handled at the QUIC layer instead.
*/
ossl_statem_set_in_init(ssl, 1);
ret = ssl->handshake_func(ssl);
ossl_statem_set_in_init(ssl, 0);
Expand All @@ -281,5 +280,3 @@ int SSL_is_quic(SSL* ssl)
{
return SSL_IS_QUIC(ssl);
}

#endif
5 changes: 3 additions & 2 deletions deps/openssl/openssl/ssl/statem/extensions_clnt.c
Expand Up @@ -1936,7 +1936,7 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context,
#ifndef OPENSSL_NO_QUIC
/*
* QUIC server must send 0xFFFFFFFF or it's a PROTOCOL_VIOLATION
* per draft-ietf-quic-tls-24 S4.5
* per draft-ietf-quic-tls-27 S4.5
*/
if (s->quic_method != NULL && max_early_data != 0xFFFFFFFF) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_EARLY_DATA,
Expand Down Expand Up @@ -2045,7 +2045,8 @@ int tls_parse_stoc_quic_transport_params(SSL *s, PACKET *pkt, unsigned int conte
&s->ext.peer_quic_transport_params,
&s->ext.peer_quic_transport_params_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PARSE_STOC_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR);
SSL_F_TLS_PARSE_STOC_QUIC_TRANSPORT_PARAMS,
ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
Expand Down
8 changes: 5 additions & 3 deletions deps/openssl/openssl/ssl/statem/extensions_srvr.c
Expand Up @@ -1316,7 +1316,8 @@ int tls_parse_ctos_quic_transport_params(SSL *s, PACKET *pkt, unsigned int conte
&s->ext.peer_quic_transport_params,
&s->ext.peer_quic_transport_params_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PARSE_CTOS_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR);
SSL_F_TLS_PARSE_CTOS_QUIC_TRANSPORT_PARAMS,
ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
Expand Down Expand Up @@ -1952,7 +1953,7 @@ EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt,
return EXT_RETURN_NOT_SENT;

#ifndef OPENSSL_NO_QUIC
/* QUIC server must always send 0xFFFFFFFF, per draft-ietf-quic-tls-24 S4.5 */
/* QUIC server must always send 0xFFFFFFFF, per draft-ietf-quic-tls-27 S4.5 */
if (s->quic_method != NULL)
max_early_data = 0xFFFFFFFF;
#endif
Expand Down Expand Up @@ -2016,7 +2017,8 @@ EXT_RETURN tls_construct_stoc_quic_transport_params(SSL *s, WPACKET *pkt,
|| !WPACKET_sub_memcpy_u16(pkt, s->ext.quic_transport_params,
s->ext.quic_transport_params_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_STOC_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR);
SSL_F_TLS_CONSTRUCT_STOC_QUIC_TRANSPORT_PARAMS,
ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}

Expand Down
2 changes: 1 addition & 1 deletion deps/openssl/openssl/ssl/statem/statem.c
Expand Up @@ -577,6 +577,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
ret = dtls_get_message(s, &mt, &len);
#ifndef OPENSSL_NO_QUIC
} else if (SSL_IS_QUIC(s)) {
/* QUIC behaves like DTLS -- all in one go. */
ret = quic_get_message(s, &mt, &len);
#endif
} else {
Expand Down Expand Up @@ -907,7 +908,6 @@ int statem_flush(SSL *s)
#ifndef OPENSSL_NO_QUIC
if (SSL_IS_QUIC(s)) {
if (!s->quic_method->flush_flight(s)) {
/* NOTE: BIO_flush() does not generate an error */
SSLerr(SSL_F_STATEM_FLUSH, ERR_R_INTERNAL_ERROR);
return 0;
}
Expand Down
27 changes: 16 additions & 11 deletions deps/openssl/openssl/ssl/statem/statem_lib.c
Expand Up @@ -42,23 +42,29 @@ int ssl3_do_write(SSL *s, int type)
{
int ret;
size_t written = 0;

#ifndef OPENSSL_NO_QUIC
if (SSL_IS_QUIC(s) && type == SSL3_RT_HANDSHAKE) {
ret = s->quic_method->add_handshake_data(s, s->quic_write_level,
(const uint8_t*)&s->init_buf->data[s->init_off],
s->init_num);
if (!ret) {
ret = -1;
/* QUIC can't sent anything out sice the above failed */
SSLerr(SSL_F_SSL3_DO_WRITE, SSL_R_INTERNAL_ERROR);
if (SSL_IS_QUIC(s)) {
if (type == SSL3_RT_HANDSHAKE) {
ret = s->quic_method->add_handshake_data(s, s->quic_write_level,
(const uint8_t*)&s->init_buf->data[s->init_off],
s->init_num);
if (!ret) {
ret = -1;
/* QUIC can't sent anything out sice the above failed */
SSLerr(SSL_F_SSL3_DO_WRITE, SSL_R_INTERNAL_ERROR);
} else {
written = s->init_num;
}
} else {
written = s->init_num;
/* QUIC doesn't use ChangeCipherSpec */
ret = -1;
SSLerr(SSL_F_SSL3_DO_WRITE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
}
} else
#endif
ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off],
s->init_num, &written);

if (ret < 0)
return -1;
if (type == SSL3_RT_HANDSHAKE)
Expand Down Expand Up @@ -1171,7 +1177,6 @@ int tls_get_message_header(SSL *s, int *mt)

do {
while (s->init_num < SSL3_HM_HEADER_LENGTH) {
/* QUIC: either create a special ssl_read_bytes... or if/else this */
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type,
&p[s->init_num],
SSL3_HM_HEADER_LENGTH - s->init_num,
Expand Down
2 changes: 2 additions & 0 deletions deps/openssl/openssl/ssl/statem/statem_local.h
Expand Up @@ -93,7 +93,9 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst);
__owur int tls_get_message_header(SSL *s, int *mt);
__owur int tls_get_message_body(SSL *s, size_t *len);
__owur int dtls_get_message(SSL *s, int *mt, size_t *len);
#ifndef OPENSSL_NO_QUIC
__owur int quic_get_message(SSL *s, int *mt, size_t *len);
#endif

/* Message construction and processing functions */
__owur int tls_process_initial_server_flight(SSL *s);
Expand Down

0 comments on commit 74cbfd3

Please sign in to comment.