Remove mask_a and mask_k from CERT.

This resolves a TODO, trims per-connection memory, and makes more sense.
These masks have nothing to do with certificate configuration.

Change-Id: I783e6158e51f58cce88e3e68dfa0ed965bdc894c
Reviewed-on: https://boringssl-review.googlesource.com/13368
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index c3d3572..d53cb01 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -554,11 +554,59 @@
   return ret;
 }
 
+/* ssl_get_client_disabled sets |*out_mask_a| and |*out_mask_k| to masks of
+ * disabled algorithms. */
+static void ssl_get_client_disabled(SSL *ssl, uint32_t *out_mask_a,
+                                    uint32_t *out_mask_k) {
+  int have_rsa = 0, have_ecdsa = 0;
+  *out_mask_a = 0;
+  *out_mask_k = 0;
+
+  /* Now go through all signature algorithms seeing if we support any for RSA or
+   * ECDSA. Do this for all versions not just TLS 1.2. */
+  const uint16_t *sigalgs;
+  size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
+  for (size_t i = 0; i < num_sigalgs; i++) {
+    switch (sigalgs[i]) {
+      case SSL_SIGN_RSA_PSS_SHA512:
+      case SSL_SIGN_RSA_PSS_SHA384:
+      case SSL_SIGN_RSA_PSS_SHA256:
+      case SSL_SIGN_RSA_PKCS1_SHA512:
+      case SSL_SIGN_RSA_PKCS1_SHA384:
+      case SSL_SIGN_RSA_PKCS1_SHA256:
+      case SSL_SIGN_RSA_PKCS1_SHA1:
+        have_rsa = 1;
+        break;
+
+      case SSL_SIGN_ECDSA_SECP521R1_SHA512:
+      case SSL_SIGN_ECDSA_SECP384R1_SHA384:
+      case SSL_SIGN_ECDSA_SECP256R1_SHA256:
+      case SSL_SIGN_ECDSA_SHA1:
+        have_ecdsa = 1;
+        break;
+    }
+  }
+
+  /* Disable auth if we don't include any appropriate signature algorithms. */
+  if (!have_rsa) {
+    *out_mask_a |= SSL_aRSA;
+  }
+  if (!have_ecdsa) {
+    *out_mask_a |= SSL_aECDSA;
+  }
+
+  /* PSK requires a client callback. */
+  if (ssl->psk_client_callback == NULL) {
+    *out_mask_a |= SSL_aPSK;
+    *out_mask_k |= SSL_kPSK;
+  }
+}
+
 static int ssl_write_client_cipher_list(SSL *ssl, CBB *out,
                                         uint16_t min_version,
                                         uint16_t max_version) {
-  /* Prepare disabled cipher masks. */
-  ssl_set_client_disabled(ssl);
+  uint32_t mask_a, mask_k;
+  ssl_get_client_disabled(ssl, &mask_a, &mask_k);
 
   CBB child;
   if (!CBB_add_u16_length_prefixed(out, &child)) {
@@ -594,8 +642,8 @@
     for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
       const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
       /* Skip disabled ciphers */
-      if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
-          (cipher->algorithm_auth & ssl->cert->mask_a)) {
+      if ((cipher->algorithm_mkey & mask_k) ||
+          (cipher->algorithm_auth & mask_a)) {
         continue;
       }
       if (SSL_CIPHER_get_min_version(cipher) > max_version ||
@@ -799,7 +847,6 @@
 
 static int ssl3_get_server_hello(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  CERT *ct = ssl->cert;
   int al = SSL_AD_INTERNAL_ERROR;
   CBS server_hello, server_random, session_id;
   uint16_t server_wire_version, cipher_suite;
@@ -916,7 +963,9 @@
   }
 
   /* The cipher must be allowed in the selected version and enabled. */
-  if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) ||
+  uint32_t mask_a, mask_k;
+  ssl_get_client_disabled(ssl, &mask_a, &mask_k);
+  if ((c->algorithm_mkey & mask_k) || (c->algorithm_auth & mask_a) ||
       SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl) ||
       SSL_CIPHER_get_max_version(c) < ssl3_protocol_version(ssl) ||
       !sk_SSL_CIPHER_find(SSL_get_ciphers(ssl), NULL, c)) {