+/*
+ * For TLS 1.2 servers check if we have a certificate which can be used
+ * with the signature algorithm "lu" and return index of certificate.
+ */
+
+static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu)
+{
+ int sig_idx = lu->sig_idx;
+ const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(sig_idx);
+
+ /* If not recognised or not supported by cipher mask it is not suitable */
+ if (clu == NULL || !(clu->amask & s->s3->tmp.new_cipher->algorithm_auth))
+ return -1;
+
+ return s->s3->tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1;
+}
+
+/*
+ * Returns true if |s| has a usable certificate configured for use
+ * with signature scheme |sig|.
+ * "Usable" includes a check for presence as well as applying
+ * the signature_algorithm_cert restrictions sent by the peer (if any).
+ * Returns false if no usable certificate is found.
+ */
+static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
+{
+ const SIGALG_LOOKUP *lu;
+ int mdnid, pknid;
+ size_t i;
+
+ /* TLS 1.2 callers can override lu->sig_idx, but not TLS 1.3 callers. */
+ if (idx == -1)
+ idx = sig->sig_idx;
+ if (!ssl_has_cert(s, idx))
+ return 0;
+ if (s->s3->tmp.peer_cert_sigalgs != NULL) {
+ for (i = 0; i < s->s3->tmp.peer_cert_sigalgslen; i++) {
+ lu = tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]);
+ if (lu == NULL
+ || !X509_get_signature_info(s->cert->pkeys[idx].x509, &mdnid,
+ &pknid, NULL, NULL))
+ continue;
+ /*
+ * TODO 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;
+ }
+ return 1;
+}
+