/* Provenance: openssl/openssl check_cert_usable (fixed). * repo: openssl/openssl * commit: 1e8c398db67404babd3e5af999bb6bd86f720c76 * parent: f636f9ca0fa1bae5b42f9e787f025c96fb09c43a * commit_url: https://github.com/openssl/openssl/commit/1e8c398db67404babd3e5af999bb6bd86f720c76 * cve: CVE-2026-14457 * license: Apache-2.0 * function: check_cert_usable * relpath: ssl/t1_lib.c */ static int check_cert_usable(SSL_CONNECTION *s, const SIGALG_LOOKUP *sig, X509 *x, EVP_PKEY *pkey) { const SIGALG_LOOKUP *lu; int mdnid, pknid, supported; size_t i; const char *mdname = NULL; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* * If the given EVP_PKEY cannot support signing with this digest, * the answer is simply 'no'. */ if (sig->hash != NID_undef) mdname = OBJ_nid2sn(sig->hash); supported = EVP_PKEY_digestsign_supports_digest(pkey, sctx->libctx, mdname, sctx->propq); if (supported <= 0) return 0; /* * When RPK is negotiated there are no certificate signatures to * constrain, and there may not even be a certificate configured. */ if (TLSEXT_cert_type_rpk == (s->server ? s->ext.server_cert_type : s->ext.client_cert_type)) return 1; /* * RPK was enabled, adding candidate private-key-only slots, but was not * negotiated, so the key-only slot is not usable. */ if (x == NULL) return 0; /* * The TLS 1.3 signature_algorithms_cert extension places restrictions * on the sigalg with which the certificate was signed (by its issuer). */ if (s->s3.tmp.peer_cert_sigalgs != NULL) { if (!X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL)) return 0; for (i = 0; i < s->s3.tmp.peer_cert_sigalgslen; i++) { lu = tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]); if (lu == NULL) continue; /* * This does not differentiate between the * rsa_pss_pss_* and rsa_pss_rsae_* schemes since we do not * have a chain here that lets us look at the key OID in the * signing certificate. */ if (mdnid == lu->hash && pknid == lu->sig) return 1; } return 0; } /* * Without signat_algorithms_cert, any certificate for which we have * a viable public key is permitted. */ return 1; }