@ -2906,9 +2906,10 @@ bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs,
return false ;
}
static bool ext_alps_add_clienthello ( const SSL_HANDSHAKE * hs , CBB * out ,
CBB * out_compressible ,
ssl_client_hello_type_t type ) {
static bool ext_alps_add_clienthello_impl ( const SSL_HANDSHAKE * hs , CBB * out ,
CBB * out_compressible ,
ssl_client_hello_type_t type ,
bool use_new_codepoint ) {
const SSL * const ssl = hs - > ssl ;
if ( // ALPS requires TLS 1.3.
hs - > max_version < TLS1_3_VERSION | |
@ -2921,8 +2922,18 @@ static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
return true ;
}
if ( use_new_codepoint ! = hs - > config - > alps_use_new_codepoint ) {
// Do nothing, we'll send the other codepoint.
return true ;
}
uint16_t extension_type = TLSEXT_TYPE_application_settings_old ;
if ( hs - > config - > alps_use_new_codepoint ) {
extension_type = TLSEXT_TYPE_application_settings ;
}
CBB contents , proto_list , proto ;
if ( ! CBB_add_u16 ( out_compressible , TLSEXT_TYPE_application_settings ) | |
if ( ! CBB_add_u16 ( out_compressible , extension_type ) | |
! CBB_add_u16_length_prefixed ( out_compressible , & contents ) | |
! CBB_add_u16_length_prefixed ( & contents , & proto_list ) ) {
return false ;
@ -2939,8 +2950,24 @@ static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
return CBB_flush ( out_compressible ) ;
}
static bool ext_alps_parse_serverhello ( SSL_HANDSHAKE * hs , uint8_t * out_alert ,
CBS * contents ) {
static bool ext_alps_add_clienthello ( const SSL_HANDSHAKE * hs , CBB * out ,
CBB * out_compressible ,
ssl_client_hello_type_t type ) {
return ext_alps_add_clienthello_impl ( hs , out , out_compressible , type ,
/*use_new_codepoint=*/ true ) ;
}
static bool ext_alps_add_clienthello_old ( const SSL_HANDSHAKE * hs , CBB * out ,
CBB * out_compressible ,
ssl_client_hello_type_t type ) {
return ext_alps_add_clienthello_impl ( hs , out , out_compressible , type ,
/*use_new_codepoint=*/ false ) ;
}
static bool ext_alps_parse_serverhello_impl ( SSL_HANDSHAKE * hs ,
uint8_t * out_alert ,
CBS * contents ,
bool use_new_codepoint ) {
SSL * const ssl = hs - > ssl ;
if ( contents = = nullptr ) {
return true ;
@ -2949,6 +2976,7 @@ static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
assert ( ! ssl - > s3 - > initial_handshake_complete ) ;
assert ( ! hs - > config - > alpn_client_proto_list . empty ( ) ) ;
assert ( ! hs - > config - > alps_configs . empty ( ) ) ;
assert ( use_new_codepoint = = hs - > config - > alps_use_new_codepoint ) ;
// ALPS requires TLS 1.3.
if ( ssl_protocol_version ( ssl ) < TLS1_3_VERSION ) {
@ -2968,7 +2996,22 @@ static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
return true ;
}
static bool ext_alps_add_serverhello ( SSL_HANDSHAKE * hs , CBB * out ) {
static bool ext_alps_parse_serverhello ( SSL_HANDSHAKE * hs ,
uint8_t * out_alert ,
CBS * contents ) {
return ext_alps_parse_serverhello_impl ( hs , out_alert , contents ,
/*use_new_codepoint=*/ true ) ;
}
static bool ext_alps_parse_serverhello_old ( SSL_HANDSHAKE * hs ,
uint8_t * out_alert ,
CBS * contents ) {
return ext_alps_parse_serverhello_impl ( hs , out_alert , contents ,
/*use_new_codepoint=*/ false ) ;
}
static bool ext_alps_add_serverhello_impl ( SSL_HANDSHAKE * hs , CBB * out ,
bool use_new_codepoint ) {
SSL * const ssl = hs - > ssl ;
// If early data is accepted, we omit the ALPS extension. It is implicitly
// carried over from the previous connection.
@ -2978,8 +3021,18 @@ static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
return true ;
}
if ( use_new_codepoint ! = hs - > config - > alps_use_new_codepoint ) {
// Do nothing, we'll send the other codepoint.
return true ;
}
uint16_t extension_type = TLSEXT_TYPE_application_settings_old ;
if ( hs - > config - > alps_use_new_codepoint ) {
extension_type = TLSEXT_TYPE_application_settings ;
}
CBB contents ;
if ( ! CBB_add_u16 ( out , TLSEXT_TYPE_application_settings ) | |
if ( ! CBB_add_u16 ( out , extension_type ) | |
! CBB_add_u16_length_prefixed ( out , & contents ) | |
! CBB_add_bytes ( & contents ,
hs - > new_session - > local_application_settings . data ( ) ,
@ -2991,6 +3044,14 @@ static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
return true ;
}
static bool ext_alps_add_serverhello ( SSL_HANDSHAKE * hs , CBB * out ) {
return ext_alps_add_serverhello_impl ( hs , out , /*use_new_codepoint=*/ true ) ;
}
static bool ext_alps_add_serverhello_old ( SSL_HANDSHAKE * hs , CBB * out ) {
return ext_alps_add_serverhello_impl ( hs , out , /*use_new_codepoint=*/ false ) ;
}
bool ssl_negotiate_alps ( SSL_HANDSHAKE * hs , uint8_t * out_alert ,
const SSL_CLIENT_HELLO * client_hello ) {
SSL * const ssl = hs - > ssl ;
@ -3001,11 +3062,15 @@ bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert,
// If we negotiate ALPN over TLS 1.3, try to negotiate ALPS.
CBS alps_contents ;
Span < const uint8_t > settings ;
uint16_t extension_type = TLSEXT_TYPE_application_settings_old ;
if ( hs - > config - > alps_use_new_codepoint ) {
extension_type = TLSEXT_TYPE_application_settings ;
}
if ( ssl_protocol_version ( ssl ) > = TLS1_3_VERSION & &
ssl_get_local_application_settings ( hs , & settings ,
ssl - > s3 - > alpn_selected ) & &
ssl_client_hello_get_extension ( client_hello , & alps_contents ,
TLSEXT_TYPE_application_settings ) ) {
extension_type ) ) {
// Check if the client supports ALPS with the selected ALPN.
bool found = false ;
CBS alps_list ;
@ -3216,6 +3281,14 @@ static const struct tls_extension kExtensions[] = {
ignore_parse_clienthello ,
ext_alps_add_serverhello ,
} ,
{
TLSEXT_TYPE_application_settings_old ,
ext_alps_add_clienthello_old ,
ext_alps_parse_serverhello_old ,
// ALPS is negotiated late in |ssl_negotiate_alpn|.
ignore_parse_clienthello ,
ext_alps_add_serverhello_old ,
} ,
} ;
# define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))