Files
Marius Ciepluch 0116f9bea6 feat(real-world-vfc-slice): add labeled OpenSSL/Firefox/Chromium/curl pair corpus
Harvest 176 isolated vuln-vs-fix functions (109 CVEs, 352 training rows)
into benchmarks/pairs/vfc with provenance and a JSONL training manifest.
Score the slice as an honesty dashboard (ousast pairs --slice vfc);
keep the pair gate on the local fixtures only.
2026-09-04 16:45:38 +02:00

133 lines
4.6 KiB
C

/* Provenance: openssl/openssl tls_process_finished (fixed).
* repo: openssl/openssl
* commit: 2b9e2afc382490592078cdb69d06f54f0fefd4c6
* parent: 7b2625274f5d5ec90aee522ec4e4f3aa08fa5b70
* commit_url: https://github.com/openssl/openssl/commit/2b9e2afc382490592078cdb69d06f54f0fefd4c6
* cve: CVE-2021-3449
* license: OpenSSL License
* function: tls_process_finished
* relpath: ssl/statem/statem_lib.c
*/
MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
{
size_t md_len;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
int was_first = SSL_IS_FIRST_HANDSHAKE(s);
int ok;
/* This is a real handshake so make sure we clean it up at the end */
if (s->server) {
/*
* To get this far we must have read encrypted data from the client. We
* no longer tolerate unencrypted alerts. This is ignored if less than
* TLSv1.3
*/
if (s->rlayer.rrlmethod->set_plain_alerts != NULL)
s->rlayer.rrlmethod->set_plain_alerts(s->rlayer.rrl, 0);
if (s->post_handshake_auth != SSL_PHA_REQUESTED)
s->statem.cleanuphand = 1;
if (SSL_CONNECTION_IS_TLS13(s)
&& !tls13_save_handshake_digest_for_pha(s)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
}
}
/*
* In TLSv1.3 a Finished message signals a key change so the end of the
* message must be on a record boundary.
*/
if (SSL_CONNECTION_IS_TLS13(s)
&& RECORD_LAYER_processed_read_pending(&s->rlayer)) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY);
return MSG_PROCESS_ERROR;
}
/* If this occurs, we have missed a message */
if (!SSL_CONNECTION_IS_TLS13(s) && !s->s3.change_cipher_spec) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
return MSG_PROCESS_ERROR;
}
s->s3.change_cipher_spec = 0;
md_len = s->s3.tmp.peer_finish_md_len;
if (md_len != PACKET_remaining(pkt)) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_DIGEST_LENGTH);
return MSG_PROCESS_ERROR;
}
ok = CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md,
md_len);
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (ok != 0) {
if (PACKET_data(pkt)[0] ^ s->s3.tmp.peer_finish_md[0] != 0xFF) {
ok = 0;
}
}
#endif
if (ok != 0) {
SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DIGEST_CHECK_FAILED);
return MSG_PROCESS_ERROR;
}
/*
* Copy the finished so we can use it for renegotiation checks
*/
if (!ossl_assert(md_len <= EVP_MAX_MD_SIZE)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return MSG_PROCESS_ERROR;
}
if (s->server) {
memcpy(s->s3.previous_client_finished, s->s3.tmp.peer_finish_md,
md_len);
s->s3.previous_client_finished_len = md_len;
} else {
memcpy(s->s3.previous_server_finished, s->s3.tmp.peer_finish_md,
md_len);
s->s3.previous_server_finished_len = md_len;
}
/*
* In TLS1.3 we also have to change cipher state and do any final processing
* of the initial server flight (if we are a client)
*/
if (SSL_CONNECTION_IS_TLS13(s)) {
if (s->server) {
if (s->post_handshake_auth != SSL_PHA_REQUESTED &&
!ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
}
} else {
/* TLS 1.3 gets the secret size from the handshake md */
size_t dummy;
if (!ssl->method->ssl3_enc->generate_master_secret(s,
s->master_secret, s->handshake_secret, 0,
&dummy)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
}
if (!ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_READ)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
}
if (!tls_process_initial_server_flight(s)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
}
}
}
if (was_first
&& !SSL_IS_FIRST_HANDSHAKE(s)
&& s->rlayer.rrlmethod->set_first_handshake != NULL)
s->rlayer.rrlmethod->set_first_handshake(s->rlayer.rrl, 0);
return MSG_PROCESS_FINISHED_READING;
}