Fix the cookie/key_share extensions for use with SSL_stateless()
Fixes some bugs identified during testing. Reviewed-by: Ben Kaduk <kaduk@mit.edu> (Merged from https://github.com/openssl/openssl/pull/4435)
This commit is contained in:
parent
d6bb50a5f9
commit
dd77962e09
1 changed files with 30 additions and 21 deletions
|
@ -696,7 +696,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
|||
int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
size_t chainidx)
|
||||
{
|
||||
unsigned int format, version, key_share;
|
||||
unsigned int format, version, key_share, group_id;
|
||||
EVP_MD_CTX *hctx;
|
||||
EVP_PKEY *pkey;
|
||||
PACKET cookie, raw, chhash, appcookie;
|
||||
|
@ -789,21 +789,27 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!PACKET_get_net_2(&cookie, &s->s3->group_id)) {
|
||||
if (!PACKET_get_net_2(&cookie, &group_id)) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
|
||||
SSL_R_LENGTH_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ciphdata = PACKET_data(&cookie);
|
||||
if (!PACKET_forward(&cookie, 2)) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
|
||||
SSL_R_LENGTH_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
s->s3->tmp.new_cipher = ssl_get_cipher_by_char(s, ciphdata, 0);
|
||||
if (s->s3->tmp.new_cipher == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
if (group_id != s->s3->group_id
|
||||
|| s->s3->tmp.new_cipher
|
||||
!= ssl_get_cipher_by_char(s, ciphdata, 0)) {
|
||||
/*
|
||||
* We chose a different cipher or group id this time around to what is
|
||||
* in the cookie. Something must have changed.
|
||||
*/
|
||||
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
|
||||
SSL_R_BAD_CIPHER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1497,23 +1503,26 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt,
|
|||
size_t encoded_pt_len = 0;
|
||||
EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL;
|
||||
|
||||
if (ckey == NULL) {
|
||||
/* No key_share received from client */
|
||||
if (s->hello_retry_request == SSL_HRR_PENDING) {
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
|
||||
|| !WPACKET_start_sub_packet_u16(pkt)
|
||||
|| !WPACKET_put_bytes_u16(pkt, s->s3->group_id)
|
||||
|| !WPACKET_close(pkt)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
|
||||
return EXT_RETURN_SENT;
|
||||
if (s->hello_retry_request == SSL_HRR_PENDING) {
|
||||
if (ckey != NULL) {
|
||||
/* Original key_share was acceptable so don't ask for another one */
|
||||
return EXT_RETURN_NOT_SENT;
|
||||
}
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
|
||||
|| !WPACKET_start_sub_packet_u16(pkt)
|
||||
|| !WPACKET_put_bytes_u16(pkt, s->s3->group_id)
|
||||
|| !WPACKET_close(pkt)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
|
||||
/* Must be resuming. */
|
||||
return EXT_RETURN_SENT;
|
||||
}
|
||||
|
||||
if (ckey == NULL) {
|
||||
/* No key_share received from client - must be resuming */
|
||||
if (!s->hit || !tls13_generate_handshake_secret(s, NULL, 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR);
|
||||
|
|
Loading…
Reference in a new issue