mirror of
https://github.com/openssl/openssl.git
synced 2025-02-23 14:42:15 +08:00
Fallback on old style PSK callbacks if the new style ones aren't present
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/5554)
This commit is contained in:
parent
e73c6eaeff
commit
f3d40db1b9
@ -744,6 +744,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
|
||||
unsigned int context, X509 *x,
|
||||
size_t chainidx)
|
||||
{
|
||||
char identity[PSK_MAX_IDENTITY_LEN + 1];
|
||||
const unsigned char *id = NULL;
|
||||
size_t idlen = 0;
|
||||
SSL_SESSION *psksess = NULL;
|
||||
@ -763,6 +764,58 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
|
||||
if (psksess == NULL && s->psk_client_callback != NULL) {
|
||||
unsigned char psk[PSK_MAX_PSK_LEN];
|
||||
size_t psklen = 0;
|
||||
|
||||
memset(identity, 0, sizeof(identity));
|
||||
psklen = s->psk_client_callback(s, NULL, identity, sizeof(identity) - 1,
|
||||
psk, sizeof(psk));
|
||||
|
||||
if (psklen > PSK_MAX_PSK_LEN) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR);
|
||||
return EXT_RETURN_FAIL;
|
||||
} else if (psklen > 0) {
|
||||
const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 };
|
||||
const SSL_CIPHER *cipher;
|
||||
|
||||
idlen = strlen(identity);
|
||||
if (idlen > PSK_MAX_IDENTITY_LEN) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
id = (unsigned char *)identity;
|
||||
|
||||
/*
|
||||
* We found a PSK using an old style callback. We don't know
|
||||
* the digest so we default to SHA256 as per the TLSv1.3 spec
|
||||
*/
|
||||
cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id);
|
||||
if (cipher == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
|
||||
psksess = SSL_SESSION_new();
|
||||
if (psksess == NULL
|
||||
|| !SSL_SESSION_set1_master_key(psksess, psk, psklen)
|
||||
|| !SSL_SESSION_set_cipher(psksess, cipher)
|
||||
|| !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_cleanse(psk, psklen);
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
OPENSSL_cleanse(psk, psklen);
|
||||
}
|
||||
}
|
||||
|
||||
SSL_SESSION_free(s->psksession);
|
||||
s->psksession = psksess;
|
||||
if (psksess != NULL) {
|
||||
|
@ -1028,6 +1028,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
for (id = 0; PACKET_remaining(&identities) != 0; id++) {
|
||||
PACKET identity;
|
||||
unsigned long ticket_agel;
|
||||
size_t idlen;
|
||||
|
||||
if (!PACKET_get_length_prefixed_2(&identities, &identity)
|
||||
|| !PACKET_get_net_4(&identities, &ticket_agel)) {
|
||||
@ -1036,15 +1037,66 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
return 0;
|
||||
}
|
||||
|
||||
idlen = PACKET_remaining(&identity);
|
||||
if (s->psk_find_session_cb != NULL
|
||||
&& !s->psk_find_session_cb(s, PACKET_data(&identity),
|
||||
PACKET_remaining(&identity),
|
||||
&& !s->psk_find_session_cb(s, PACKET_data(&identity), idlen,
|
||||
&sess)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_PARSE_CTOS_PSK, SSL_R_BAD_EXTENSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sess == NULL
|
||||
&& s->psk_server_callback != NULL
|
||||
&& idlen <= PSK_MAX_IDENTITY_LEN) {
|
||||
char *pskid = NULL;
|
||||
unsigned char pskdata[PSK_MAX_PSK_LEN];
|
||||
unsigned int pskdatalen;
|
||||
|
||||
if (!PACKET_strndup(&identity, &pskid)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
pskdatalen = s->psk_server_callback(s, pskid, pskdata,
|
||||
sizeof(pskdata));
|
||||
OPENSSL_free(pskid);
|
||||
if (pskdatalen > PSK_MAX_PSK_LEN) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
} else if (pskdatalen > 0) {
|
||||
const SSL_CIPHER *cipher;
|
||||
const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 };
|
||||
|
||||
/*
|
||||
* We found a PSK using an old style callback. We don't know
|
||||
* the digest so we default to SHA256 as per the TLSv1.3 spec
|
||||
*/
|
||||
cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id);
|
||||
if (cipher == NULL) {
|
||||
OPENSSL_cleanse(pskdata, pskdatalen);
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sess = SSL_SESSION_new();
|
||||
if (sess == NULL
|
||||
|| !SSL_SESSION_set1_master_key(sess, pskdata,
|
||||
pskdatalen)
|
||||
|| !SSL_SESSION_set_cipher(sess, cipher)
|
||||
|| !SSL_SESSION_set_protocol_version(sess,
|
||||
TLS1_3_VERSION)) {
|
||||
OPENSSL_cleanse(pskdata, pskdatalen);
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_cleanse(pskdata, pskdatalen);
|
||||
}
|
||||
}
|
||||
|
||||
if (sess != NULL) {
|
||||
/* We found a PSK */
|
||||
SSL_SESSION *sesstmp = ssl_session_dup(sess, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user