Files
Open_Ultra_SAST/benchmarks/pairs/vfc/openssl-cve-2024-5535/fixed.c
T

99 lines
3.3 KiB
C
Raw Normal View History

/* Provenance: openssl/openssl tls_parse_stoc_alpn (fixed).
* repo: openssl/openssl
* commit: 4b375b998798dd516d367036773073e1b88e6433
* parent: 189a7ed3e380e34ea38fe4190a7c9396bace0fb7
* commit_url: https://github.com/openssl/openssl/commit/4b375b998798dd516d367036773073e1b88e6433
* cve: CVE-2024-5535
* license: Apache-2.0
* function: tls_parse_stoc_alpn
* relpath: ssl/statem/extensions_clnt.c
*/
int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
size_t chainidx)
{
size_t len;
PACKET confpkt, protpkt;
int valid = 0;
/* We must have requested it. */
if (!s->s3.alpn_sent) {
SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION);
return 0;
}
/*-
* The extension data consists of:
* uint16 list_length
* uint8 proto_length;
* uint8 proto[proto_length];
*/
if (!PACKET_get_net_2_len(pkt, &len)
|| PACKET_remaining(pkt) != len || !PACKET_get_1_len(pkt, &len)
|| PACKET_remaining(pkt) != len) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
return 0;
}
/* It must be a protocol that we sent */
if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) {
if (PACKET_remaining(&protpkt) != len)
continue;
if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) {
/* Valid protocol found */
valid = 1;
break;
}
}
if (!valid) {
/* The protocol sent from the server does not match one we advertised */
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
return 0;
}
OPENSSL_free(s->s3.alpn_selected);
s->s3.alpn_selected = OPENSSL_malloc(len);
if (s->s3.alpn_selected == NULL) {
s->s3.alpn_selected_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
if (!PACKET_copy_bytes(pkt, s->s3.alpn_selected, len)) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
return 0;
}
s->s3.alpn_selected_len = len;
if (s->session->ext.alpn_selected == NULL
|| s->session->ext.alpn_selected_len != len
|| memcmp(s->session->ext.alpn_selected, s->s3.alpn_selected, len)
!= 0) {
/* ALPN not consistent with the old session so cannot use early_data */
s->ext.early_data_ok = 0;
}
if (!s->hit) {
/*
* This is a new session and so alpn_selected should have been
* initialised to NULL. We should update it with the selected ALPN.
*/
if (!ossl_assert(s->session->ext.alpn_selected == NULL)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
s->session->ext.alpn_selected =
OPENSSL_memdup(s->s3.alpn_selected, s->s3.alpn_selected_len);
if (s->session->ext.alpn_selected == NULL) {
s->session->ext.alpn_selected_len = 0;
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
s->session->ext.alpn_selected_len = s->s3.alpn_selected_len;
}
return 1;
}