Factor out the default signature algorithm logic.

This is done in three different places.

Change-Id: I1e55a14c464b1953b3d4de22b50688082ea65129
Reviewed-on: https://boringssl-review.googlesource.com/15306
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@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 0629078..f204286 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -1255,11 +1255,8 @@
         goto f_err;
       }
       hs->new_session->peer_signature_algorithm = signature_algorithm;
-    } else if (hs->peer_pubkey->type == EVP_PKEY_RSA) {
-      signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
-    } else if (hs->peer_pubkey->type == EVP_PKEY_EC) {
-      signature_algorithm = SSL_SIGN_ECDSA_SHA1;
-    } else {
+    } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm,
+                                                    hs->peer_pubkey)) {
       al = SSL_AD_UNSUPPORTED_CERTIFICATE;
       OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
       goto f_err;
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index 63027d6..4eaf3cb 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -1722,11 +1722,8 @@
       goto f_err;
     }
     hs->new_session->peer_signature_algorithm = signature_algorithm;
-  } else if (hs->peer_pubkey->type == EVP_PKEY_RSA) {
-    signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
-  } else if (hs->peer_pubkey->type == EVP_PKEY_EC) {
-    signature_algorithm = SSL_SIGN_ECDSA_SHA1;
-  } else {
+  } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm,
+                                                  hs->peer_pubkey)) {
     al = SSL_AD_UNSUPPORTED_CERTIFICATE;
     OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
     goto f_err;
diff --git a/ssl/internal.h b/ssl/internal.h
index 1ed7e15..e7a3f7a 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1272,6 +1272,11 @@
  * error. */
 int tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *sigalgs);
 
+/* tls1_get_legacy_signature_algorithm sets |*out| to the signature algorithm
+ * that should be used with |pkey| in TLS 1.1 and earlier. It returns one on
+ * success and zero if |pkey| may not be used at those versions. */
+int tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey);
+
 /* tls1_choose_signature_algorithm sets |*out| to a signature algorithm for use
  * with |hs|'s private key based on the peer's preferences and the algorithms
  * supported. It returns one on success and zero on error. */
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index c2a5dde..000a8cd 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -3328,24 +3328,31 @@
   return 1;
 }
 
+int tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) {
+  switch (EVP_PKEY_id(pkey)) {
+    case EVP_PKEY_RSA:
+      *out = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
+      return 1;
+    case EVP_PKEY_EC:
+      *out = SSL_SIGN_ECDSA_SHA1;
+      return 1;
+    default:
+      return 0;
+  }
+}
+
 int tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) {
   SSL *const ssl = hs->ssl;
   CERT *cert = ssl->cert;
 
   /* Before TLS 1.2, the signature algorithm isn't negotiated as part of the
-   * handshake. It is fixed at MD5-SHA1 for RSA and SHA1 for ECDSA. */
+   * handshake. */
   if (ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
-    switch (EVP_PKEY_id(hs->local_pubkey)) {
-      case EVP_PKEY_RSA:
-        *out = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
-        return 1;
-      case EVP_PKEY_EC:
-        *out = SSL_SIGN_ECDSA_SHA1;
-        return 1;
-      default:
-        OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
-        return 0;
+    if (!tls1_get_legacy_signature_algorithm(out, hs->local_pubkey)) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
+      return 0;
     }
+    return 1;
   }
 
   const uint16_t *sigalgs = cert->sigalgs;