/* Provenance: openssl/openssl tls_post_process_server_rpk (fixed). * repo: openssl/openssl * commit: 798779d43494549b611233f92652f0da5328fbe7 * parent: 0db27ec7f8abd258d2e8849ac555ca26ba0cd8d6 * commit_url: https://github.com/openssl/openssl/commit/798779d43494549b611233f92652f0da5328fbe7 * cve: CVE-2024-12797 * license: Apache-2.0 * function: tls_post_process_server_rpk * relpath: ssl/statem/statem_clnt.c */ static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc, WORK_STATE wst) { size_t certidx; const SSL_CERT_LOOKUP *clu; int v_ok; if (sc->session->peer_rpk == NULL) { SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_RAW_PUBLIC_KEY); return WORK_ERROR; } if (sc->rwstate == SSL_RETRY_VERIFY) sc->rwstate = SSL_NOTHING; ERR_set_mark(); v_ok = ssl_verify_rpk(sc, sc->session->peer_rpk); if (v_ok <= 0 && sc->verify_mode != SSL_VERIFY_NONE) { ERR_clear_last_mark(); SSLfatal(sc, ssl_x509err2alert(sc->verify_result), SSL_R_CERTIFICATE_VERIFY_FAILED); return WORK_ERROR; } ERR_pop_to_mark(); /* but we keep s->verify_result */ if (v_ok > 0 && sc->rwstate == SSL_RETRY_VERIFY) { return WORK_MORE_A; } if ((clu = ssl_cert_lookup_by_pkey(sc->session->peer_rpk, &certidx, SSL_CONNECTION_GET_CTX(sc))) == NULL) { SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return WORK_ERROR; } /* * Check certificate type is consistent with ciphersuite. For TLS 1.3 * skip check since TLS 1.3 ciphersuites can be used with any certificate * type. */ if (!SSL_CONNECTION_IS_TLS13(sc)) { if ((clu->amask & sc->s3.tmp.new_cipher->algorithm_auth) == 0) { SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_RPK_TYPE); return WORK_ERROR; } } /* Ensure there is no peer/peer_chain */ X509_free(sc->session->peer); sc->session->peer = NULL; sk_X509_pop_free(sc->session->peer_chain, X509_free); sc->session->peer_chain = NULL; sc->session->verify_result = sc->verify_result; /* Save the current hash state for when we receive the CertificateVerify */ if (SSL_CONNECTION_IS_TLS13(sc) && !ssl_handshake_hash(sc, sc->cert_verify_hash, sizeof(sc->cert_verify_hash), &sc->cert_verify_hash_len)) { /* SSLfatal() already called */ return WORK_ERROR; } return WORK_FINISHED_CONTINUE; }