mirror of
https://github.com/openssl/openssl.git
synced 2025-03-01 19:28:10 +08:00
NewSessionTickets with an early_data extension must have a valid max value
The max_early_data value must be 0xffffffff if the extension is present in a NewSessionTicket message in QUIC. Otherwise it is a PROTOCOL_VIOLATION. Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21686)
This commit is contained in:
parent
0f2add9e8d
commit
04c7fb53e0
@ -101,5 +101,6 @@ int ossl_quic_tls_get_error(QUIC_TLS *qtls,
|
||||
ERR_STATE **error_state);
|
||||
|
||||
int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls);
|
||||
int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls);
|
||||
|
||||
#endif
|
||||
|
@ -994,7 +994,7 @@ static int ch_on_handshake_alert(void *arg, unsigned char alert_code)
|
||||
* TLS CertificateRequest messages, and clients MUST treat receipt of such
|
||||
* messages as a connection error of type PROTOCOL_VIOLATION.
|
||||
*/
|
||||
if (alert_code == SSL3_AD_UNEXPECTED_MESSAGE
|
||||
if (alert_code == SSL_AD_UNEXPECTED_MESSAGE
|
||||
&& ch->handshake_complete
|
||||
&& ossl_quic_tls_is_cert_request(ch->qtls))
|
||||
ossl_quic_channel_raise_protocol_error(ch,
|
||||
@ -1002,6 +1002,20 @@ static int ch_on_handshake_alert(void *arg, unsigned char alert_code)
|
||||
0,
|
||||
"Post-handshake TLS "
|
||||
"CertificateRequest received");
|
||||
/*
|
||||
* RFC 9001 s. 4.6.1: Servers MUST NOT send the early_data extension with a
|
||||
* max_early_data_size field set to any value other than 0xffffffff. A
|
||||
* client MUST treat receipt of a NewSessionTicket that contains an
|
||||
* early_data extension with any other value as a connection error of type
|
||||
* PROTOCOL_VIOLATION.
|
||||
*/
|
||||
else if (alert_code == SSL_AD_ILLEGAL_PARAMETER
|
||||
&& ch->handshake_complete
|
||||
&& ossl_quic_tls_has_bad_max_early_data(ch->qtls))
|
||||
ossl_quic_channel_raise_protocol_error(ch,
|
||||
QUIC_ERR_PROTOCOL_VIOLATION,
|
||||
0,
|
||||
"Bad max_early_data received");
|
||||
else
|
||||
ossl_quic_channel_raise_protocol_error(ch,
|
||||
QUIC_ERR_CRYPTO_ERR_BEGIN
|
||||
|
@ -853,3 +853,19 @@ int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls)
|
||||
|
||||
return sc->s3.tmp.message_type == SSL3_MT_CERTIFICATE_REQUEST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the last session associated with the connection has an
|
||||
* invalid max_early_data value for QUIC.
|
||||
*/
|
||||
int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls)
|
||||
{
|
||||
uint32_t max_early_data = SSL_get0_session(qtls->args.s)->ext.max_early_data;
|
||||
|
||||
/*
|
||||
* If max_early_data was present we always ensure a non-zero value is
|
||||
* stored in the session for QUIC. Therefore if max_early_data == 0 here
|
||||
* we can be confident that it was not present in the NewSessionTicket
|
||||
*/
|
||||
return max_early_data != 0xffffffff && max_early_data != 0;
|
||||
}
|
||||
|
@ -1934,6 +1934,22 @@ int tls_parse_stoc_early_data(SSL_CONNECTION *s, PACKET *pkt,
|
||||
|
||||
s->session->ext.max_early_data = max_early_data;
|
||||
|
||||
if (SSL_IS_QUIC_HANDSHAKE(s) && max_early_data != 0xffffffff) {
|
||||
/*
|
||||
* QUIC allows missing max_early_data, or a max_early_data value
|
||||
* of 0xffffffff. Missing max_early_data is stored in the session
|
||||
* as 0. This is indistinguishable in OpenSSL from a present
|
||||
* max_early_data value that was 0. In order that later checks for
|
||||
* invalid max_early_data correctly treat as an error the case where
|
||||
* max_early_data is present and it is 0, we store any invalid
|
||||
* value in the same (non-zero) way. Otherwise we would have to
|
||||
* introduce a new flag just for this.
|
||||
*/
|
||||
s->session->ext.max_early_data = 1;
|
||||
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_MAX_EARLY_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user