Promote SSL_get0_certificate_types to a proper function.

BUG=404754

Change-Id: I94785e970d2f08e46826edd2ac41215500f46e99
Reviewed-on: https://boringssl-review.googlesource.com/5671
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index c91d893..7a30d55 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1989,7 +1989,6 @@
 #define SSL_CTRL_SET_CURVES 91
 #define SSL_CTRL_SET_SIGALGS 97
 #define SSL_CTRL_SET_CLIENT_SIGALGS 101
-#define SSL_CTRL_GET_CLIENT_CERT_TYPES 103
 #define SSL_CTRL_SET_CLIENT_CERT_TYPES 104
 #define SSL_CTRL_SET_VERIFY_CERT_STORE 106
 #define SSL_CTRL_SET_CHAIN_CERT_STORE 107
@@ -2081,6 +2080,12 @@
 OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out,
                                              size_t max_out);
 
+/* SSL_get0_certificate_types, for a client, sets |*out_types| to an array
+ * containing the client certificate types requested by a server. It returns the
+ * length of the array. */
+OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl,
+                                                 const uint8_t **out_types);
+
 #define SSL_CTX_set0_verify_cert_store(ctx, st) \
   SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, (char *)st)
 #define SSL_CTX_set1_verify_cert_store(ctx, st) \
@@ -2115,9 +2120,6 @@
 #define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
   SSL_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS, clistlen, (int *)slist)
 
-#define SSL_get0_certificate_types(s, clist) \
-  SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist)
-
 #define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
   SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CLIENT_CERT_TYPES, clistlen, (char *)clist)
 #define SSL_set1_client_certificate_types(s, clist, clistlen) \
@@ -2704,6 +2706,7 @@
 #define SSL_CTRL_EXTRA_CHAIN_CERT doesnt_exist
 #define SSL_CTRL_GET_CHAIN_CERTS doesnt_exist
 #define SSL_CTRL_GET_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist
 #define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist
 #define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist
 #define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist
@@ -2785,6 +2788,7 @@
 #define SSL_clear_mode SSL_clear_mode
 #define SSL_clear_options SSL_clear_options
 #define SSL_enable_tls_channel_id SSL_enable_tls_channel_id
+#define SSL_get0_certificate_types SSL_get0_certificate_types
 #define SSL_get0_chain_certs SSL_get0_chain_certs
 #define SSL_get_max_cert_list SSL_get_max_cert_list
 #define SSL_get_mode SSL_get_mode
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 2330fbd..6baf6f1 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -372,6 +372,15 @@
   return 1;
 }
 
+size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
+  if (ssl->server || !ssl->s3->tmp.cert_req) {
+    *out_types = NULL;
+    return 0;
+  }
+  *out_types = ssl->s3->tmp.certificate_types;
+  return ssl->s3->tmp.num_certificate_types;
+}
+
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) {
   int ret = 0;
 
@@ -405,17 +414,6 @@
     case SSL_CTRL_SET_CLIENT_SIGALGS:
       return tls1_set_sigalgs(s->cert, parg, larg, 1);
 
-    case SSL_CTRL_GET_CLIENT_CERT_TYPES: {
-      const uint8_t **pctype = parg;
-      if (s->server || !s->s3->tmp.cert_req) {
-        return 0;
-      }
-      if (pctype) {
-        *pctype = s->s3->tmp.certificate_types;
-      }
-      return (int)s->s3->tmp.num_certificate_types;
-    }
-
     case SSL_CTRL_SET_CLIENT_CERT_TYPES:
       if (!s->server) {
         return 0;
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 5fd97ca..53f8e29 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -795,14 +795,13 @@
   }
 
   if (!config->expected_certificate_types.empty()) {
-    uint8_t *certificate_types;
-    int num_certificate_types =
+    const uint8_t *certificate_types;
+    size_t certificate_types_len =
         SSL_get0_certificate_types(ssl, &certificate_types);
-    if (num_certificate_types !=
-        (int)config->expected_certificate_types.size() ||
+    if (certificate_types_len != config->expected_certificate_types.size() ||
         memcmp(certificate_types,
                config->expected_certificate_types.data(),
-               num_certificate_types) != 0) {
+               certificate_types_len) != 0) {
       fprintf(stderr, "certificate types mismatch\n");
       return false;
     }