--- google_boringssl/ssl/extensions.cc	2021-02-03 18:29:04.000000000 -0800
+++ boringssl/ssl/extensions.cc	2021-02-03 20:24:49.000000000 -0800
@@ -105,6 +105,25 @@
  * This product includes cryptographic software written by Eric Young
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com). */
+/* ====================================================================
+ * Copyright 2020 Apple Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the “Software”),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
 
 #include <openssl/ssl.h>
 
@@ -3234,6 +3253,146 @@
   return true;
 }
 
+// Server Certificate Type
+
+static bool ext_server_certificate_type_add_clienthello(const SSL_HANDSHAKE *hs,
+                                                        CBB *out,
+                                                        CBB *out_compressible,
+                                                        ssl_client_hello_type_t type) {
+
+  if (hs->max_version <= TLS1_2_VERSION) {
+    return true;
+  }
+
+  if (hs->config->server_certificate_type_list.empty()) {
+    return true;
+  }
+
+  CBB contents, server_certificate_types;
+  if (!CBB_add_u16(out, TLSEXT_TYPE_server_certificate_type) ||
+      !CBB_add_u16_length_prefixed(out, &contents) ||
+      !CBB_add_u8_length_prefixed(&contents, &server_certificate_types) ||
+      !CBB_add_bytes(&server_certificate_types,
+                     hs->config->server_certificate_type_list.data(),
+                     hs->config->server_certificate_type_list.size()) ||
+      !CBB_flush(out)) {
+    return false;
+  }
+
+  return true;
+}
+
+static bool ssl_is_certificate_type_allowed(CBS *certificate_type_list,
+                                            uint8_t certificate_type)
+{
+  uint8_t supported_certificate_type;
+  while (CBS_len(certificate_type_list) > 0) {
+    if (!CBS_get_u8(certificate_type_list,
+                    &supported_certificate_type)) {
+      break;
+    }
+
+    if (supported_certificate_type != certificate_type) {
+      continue;
+    }
+
+    return true;
+  }
+
+  return false;
+}
+
+static bool ext_server_certificate_type_parse_serverhello(SSL_HANDSHAKE *hs,
+                                                          uint8_t *out_alert,
+                                                          CBS *content)
+{
+  if (hs->max_version <= TLS1_2_VERSION ||
+      hs->config->server_certificate_type_list.empty()) {
+    return true;
+  }
+
+  // Strict
+  if (!content) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+    return false;
+  }
+
+  CBS certificate_type_list =
+    MakeConstSpan(hs->config->server_certificate_type_list);
+
+  uint8_t certificate_type;
+  if (CBS_get_u8(content, &certificate_type) &&
+      ssl_is_certificate_type_allowed(&certificate_type_list,
+                                      certificate_type)) {
+    hs->server_certificate_type = certificate_type;
+    hs->server_certificate_type_negotiated = 1;
+    return true;
+  }
+
+  OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+  return false;
+}
+
+static bool ext_server_certificate_type_parse_clienthello(SSL_HANDSHAKE *hs,
+                                                          uint8_t *out_alert,
+                                                          CBS *content)
+{
+  if (!content) {
+    return true;
+  }
+
+  if (hs->max_version <= TLS1_2_VERSION ||
+      hs->config->server_certificate_type_list.empty()) {
+    return true;
+  }
+
+  CBS certificate_type_list =
+    MakeConstSpan(hs->config->server_certificate_type_list);
+
+  CBS type_list;
+  if (!CBS_get_u8_length_prefixed(content, &type_list)) {
+    type_list.len = 0;
+  }
+
+  uint8_t type;
+  while(CBS_len(&type_list) > 0) {
+    if (!CBS_get_u8(&type_list, &type)) {
+      break;
+    }
+
+    if (!ssl_is_certificate_type_allowed(&certificate_type_list, type)) {
+      continue;
+    }
+
+    hs->server_certificate_type = type;
+    hs->server_certificate_type_negotiated = 1;
+    return true;
+  }
+
+  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+  return false;
+}
+
+static bool ext_server_certificate_type_add_serverhello(SSL_HANDSHAKE *hs,
+                                                        CBB *out)
+{
+  if (!hs->server_certificate_type_negotiated) {
+    return true;
+  }
+
+  CBB contents;
+  if (!CBB_add_u16(out, TLSEXT_TYPE_server_certificate_type) ||
+      !CBB_add_u16_length_prefixed(out, &contents) ||
+      !CBB_add_u8(&contents, hs->server_certificate_type) ||
+      !CBB_flush(out)) {
+     return false;
+  }
+
+  return true;
+}
+
 // kExtensions contains all the supported extensions.
 static const struct tls_extension kExtensions[] = {
   {
@@ -3447,6 +3604,13 @@
     ignore_parse_clienthello,
     ext_alps_add_serverhello,
   },
+  {
+    TLSEXT_TYPE_server_certificate_type,
+    ext_server_certificate_type_add_clienthello,
+    ext_server_certificate_type_parse_serverhello,
+    ext_server_certificate_type_parse_clienthello,
+    ext_server_certificate_type_add_serverhello,
+  },
 };
 
 #define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
