190 lines
6.1 KiB
Diff
190 lines
6.1 KiB
Diff
--- 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))
|