diff --git a/README.md b/README.md index d023c509..37ebcc63 100644 --- a/README.md +++ b/README.md @@ -5,34 +5,11 @@ BoringSSL bindings for the Rust programming language and TLS adapters for [tokio](https://github.com/tokio-rs/tokio) and [hyper](https://github.com/hyperium/hyper) built on top of it. -[Documentation](https://docs.rs/boring). - -## Release Support - -By default, the crate statically links with the latest BoringSSL master branch. - -## Support for pre-built binaries - -While this crate can build BoringSSL on its own, you may want to provide pre-built binaries instead. -To do so, specify the environment variable `BORING_BSSL_PATH` with the path to the binaries. - -You can also provide specific headers by setting `BORING_BSSL_INCLUDE_PATH`. - -_Notes_: The crate will look for headers in the `$BORING_BSSL_INCLUDE_PATH/openssl/` folder, make sure to place your headers there. - -_Warning_: When providing a different version of BoringSSL make sure to use a compatible one, the crate relies on the presence of certain functions. - -## Building with a FIPS-validated module - -Only BoringCrypto module version 853ca1ea1168dff08011e5d42d94609cc0ca2e27, as certified with -[FIPS 140-2 certificate 4407](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4407) -is supported by this crate. Support is enabled by this crate's `fips` feature. - -`boring-sys` comes with a test that FIPS is enabled/disabled depending on the feature flag. You can run it as follows: - -```bash -$ cargo test --features fips fips::is_enabled -``` +## Documentation + - Boring API: + - tokio TLS adapters: + - hyper HTTPS connector: + - FFI bindings: ## Contribution diff --git a/boring-sys/build.rs b/boring-sys/build.rs index 4e09198e..8f88ecf4 100644 --- a/boring-sys/build.rs +++ b/boring-sys/build.rs @@ -354,7 +354,7 @@ fn ensure_patches_applied() -> io::Result<()> { if cfg!(feature = "rpk") { println!("cargo:warning=applying RPK patch to boringssl"); - run_apply_patch_script("scripts/apply_rpk_patch.sh", "src")?; + run_apply_patch_script("scripts/apply_rpk_patch.sh", "")?; } Ok(()) diff --git a/boring-sys/patches/rpk-patch/include/openssl/ssl.h.patch b/boring-sys/patches/rpk-patch/include/openssl/ssl.h.patch deleted file mode 100644 index cf2f220a..00000000 --- a/boring-sys/patches/rpk-patch/include/openssl/ssl.h.patch +++ /dev/null @@ -1,84 +0,0 @@ ---- google_boringssl/include/openssl/ssl.h 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/include/openssl/ssl.h 2021-02-03 20:24:49.000000000 -0800 -@@ -138,6 +138,25 @@ - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ -+/* ==================================================================== -+ * 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. -+ */ - - #ifndef OPENSSL_HEADER_SSL_H - #define OPENSSL_HEADER_SSL_H -@@ -1102,6 +1121,16 @@ - SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, size_t num_certs, - EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); - -+// SSL_CTX_set_nullchain_and_key sets the private key for a -+// TLS client or server. Reference to the given |EVP_PKEY| -+// object is added as needed. Exactly one of |privkey| or |privkey_method| -+// may be non-NULL. Returns one on success and zero on error. -+// Note the lack of a corresponding public-key certificate. -+// See SSL_CTX_set_server_raw_public_key_certificate. -+OPENSSL_EXPORT int SSL_CTX_set_nullchain_and_key( -+ SSL_CTX *ctx, -+ EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); -+ - // SSL_set_chain_and_key sets the certificate chain and private key for a TLS - // client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| - // objects are added as needed. Exactly one of |privkey| or |privkey_method| -@@ -1110,6 +1139,16 @@ - SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, - const SSL_PRIVATE_KEY_METHOD *privkey_method); - -+// SSL_set_nullchain_and_key sets the private key for a TLS -+// client or server. Reference to the given |EVP_PKEY| -+// object is added as needed. Exactly one of |privkey| or |privkey_method| -+// may be non-NULL. Returns one on success and zero on error. -+// Note the lack of a corresponding public-key certificate. -+// See SSL_set_server_raw_public_key_certificate. -+OPENSSL_EXPORT int SSL_set_nullchain_and_key( -+ SSL *ssl, EVP_PKEY *privkey, -+ const SSL_PRIVATE_KEY_METHOD *privkey_method); -+ - // SSL_CTX_get0_chain returns the list of |CRYPTO_BUFFER|s that were set by - // |SSL_CTX_set_chain_and_key|. Reference counts are not incremented by this - // call. The return value may be |NULL| if no chain has been set. -@@ -2821,6 +2860,21 @@ - OPENSSL_EXPORT int SSL_has_application_settings(const SSL *ssl); - - -+// Server Certificate Type. -+ -+#define TLSEXT_CERTIFICATETYPE_X509 0 -+#define TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY 2 -+ -+OPENSSL_EXPORT int SSL_CTX_set_server_raw_public_key_certificate( -+ SSL_CTX *ctx, const uint8_t *raw_public_key, unsigned raw_public_key_len); -+ -+OPENSSL_EXPORT int SSL_CTX_has_server_raw_public_key_certificate(SSL_CTX *ctx); -+ -+OPENSSL_EXPORT int SSL_set_server_raw_public_key_certificate( -+ SSL *ssl, const uint8_t *raw_public_key, unsigned raw_public_key_len); -+ -+OPENSSL_EXPORT int SSL_has_server_raw_public_key_certificate(SSL *ssl); -+ - // Certificate compression. - // - // Certificates in TLS 1.3 can be compressed (RFC 8879). BoringSSL supports this diff --git a/boring-sys/patches/rpk-patch/include/openssl/tls1.h.patch b/boring-sys/patches/rpk-patch/include/openssl/tls1.h.patch deleted file mode 100644 index de1fb345..00000000 --- a/boring-sys/patches/rpk-patch/include/openssl/tls1.h.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- google_boringssl/include/openssl/tls1.h 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/include/openssl/tls1.h 2021-02-03 20:24:49.000000000 -0800 -@@ -146,6 +146,25 @@ - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ -+/* ==================================================================== -+ * 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. -+ */ - - #ifndef OPENSSL_HEADER_TLS1_H - #define OPENSSL_HEADER_TLS1_H -@@ -197,6 +216,9 @@ - // ExtensionType value from RFC 7301 - #define TLSEXT_TYPE_application_layer_protocol_negotiation 16 - -+// ExtensionType value from RFC 7250 -+#define TLSEXT_TYPE_server_certificate_type 20 -+ - // ExtensionType value from RFC 7685 - #define TLSEXT_TYPE_padding 21 - diff --git a/boring-sys/patches/rpk-patch/ssl/extensions.cc.patch b/boring-sys/patches/rpk-patch/ssl/extensions.cc.patch deleted file mode 100644 index 99de7e2a..00000000 --- a/boring-sys/patches/rpk-patch/ssl/extensions.cc.patch +++ /dev/null @@ -1,189 +0,0 @@ ---- 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 - -@@ -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)) diff --git a/boring-sys/patches/rpk-patch/ssl/handshake.cc.patch b/boring-sys/patches/rpk-patch/ssl/handshake.cc.patch deleted file mode 100644 index 96b99502..00000000 --- a/boring-sys/patches/rpk-patch/ssl/handshake.cc.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- google_boringssl/ssl/handshake.cc 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/ssl/handshake.cc 2021-02-03 20:24:49.000000000 -0800 -@@ -109,6 +109,25 @@ - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ -+/* ==================================================================== -+ * 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 - -@@ -149,6 +168,7 @@ - cert_compression_negotiated(false), - apply_jdk11_workaround(false), - can_release_private_key(false), -+ server_certificate_type_negotiated(false), - channel_id_negotiated(false) { - assert(ssl); - -@@ -333,7 +353,21 @@ - - uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN; - enum ssl_verify_result_t ret; -- if (hs->config->custom_verify_callback != nullptr) { -+ if (hs->server_certificate_type_negotiated && -+ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY) { -+ ret = ssl_verify_invalid; -+ EVP_PKEY *peer_pubkey = hs->peer_pubkey.get(); -+ CBS spki = MakeConstSpan(ssl->config->server_raw_public_key_certificate); -+ EVP_PKEY *pubkey = EVP_parse_public_key(&spki); -+ if (!pubkey) { -+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); -+ alert = SSL_AD_INTERNAL_ERROR; -+ } else if (EVP_PKEY_cmp(peer_pubkey, pubkey) == 1 /* Equal */) { -+ ret = ssl_verify_ok; -+ } else { -+ alert = SSL_AD_BAD_CERTIFICATE; -+ } -+ } else if (hs->config->custom_verify_callback != nullptr) { - ret = hs->config->custom_verify_callback(ssl, &alert); - switch (ret) { - case ssl_verify_ok: diff --git a/boring-sys/patches/rpk-patch/ssl/internal.h.patch b/boring-sys/patches/rpk-patch/ssl/internal.h.patch deleted file mode 100644 index f730ea15..00000000 --- a/boring-sys/patches/rpk-patch/ssl/internal.h.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- google_boringssl/ssl/internal.h 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/ssl/internal.h 2021-02-03 20:24:49.000000000 -0800 -@@ -138,6 +138,25 @@ - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ -+/* ==================================================================== -+ * 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. -+ */ - - #ifndef OPENSSL_HEADER_SSL_INTERNAL_H - #define OPENSSL_HEADER_SSL_INTERNAL_H -@@ -1279,6 +1298,8 @@ - // configured. - bool ssl_has_certificate(const SSL_HANDSHAKE *hs); - -+bool ssl_has_raw_public_key_certificate(const SSL_HANDSHAKE *hs); -+ - // ssl_parse_cert_chain parses a certificate list from |cbs| in the format used - // by a TLS Certificate message. On success, it advances |cbs| and returns - // true. Otherwise, it returns false and sets |*out_alert| to an alert to send -@@ -1687,6 +1708,8 @@ - // |cert_compression_negotiated| is true. - uint16_t cert_compression_alg_id; - -+ uint8_t server_certificate_type; -+ - // ech_hpke_ctx is the HPKE context used in ECH. On the server, it is - // initialized if |ech_status| is |ssl_ech_accepted|. On the client, it is - // initialized if |selected_ech_config| is not nullptr. -@@ -1817,6 +1840,8 @@ - // cert_compression_negotiated is true iff |cert_compression_alg_id| is valid. - bool cert_compression_negotiated : 1; - -+ bool server_certificate_type_negotiated : 1; -+ - // apply_jdk11_workaround is true if the peer is probably a JDK 11 client - // which implemented TLS 1.3 incorrectly. - bool apply_jdk11_workaround : 1; -@@ -2731,6 +2756,9 @@ - // along with their corresponding ALPS values. - GrowableArray alps_configs; - -+ Array server_certificate_type_list; -+ Array server_raw_public_key_certificate; -+ - // Contains the QUIC transport params that this endpoint will send. - Array quic_transport_params; - -@@ -3306,6 +3334,9 @@ - // format. - bssl::Array alpn_client_proto_list; - -+ bssl::Array server_certificate_type_list; -+ bssl::Array server_raw_public_key_certificate; -+ - // SRTP profiles we are willing to do from RFC 5764 - bssl::UniquePtr srtp_profiles; - diff --git a/boring-sys/patches/rpk-patch/ssl/ssl_cert.cc.patch b/boring-sys/patches/rpk-patch/ssl/ssl_cert.cc.patch deleted file mode 100644 index 29d8d392..00000000 --- a/boring-sys/patches/rpk-patch/ssl/ssl_cert.cc.patch +++ /dev/null @@ -1,118 +0,0 @@ ---- google_boringssl/ssl/ssl_cert.cc 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/ssl/ssl_cert.cc 2021-02-03 20:24:49.000000000 -0800 -@@ -111,6 +111,25 @@ - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ -+/* ==================================================================== -+ * 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 - -@@ -302,6 +321,25 @@ - return 1; - } - -+static int cert_set_key( -+ CERT *cert, -+ EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) { -+ if (privkey == NULL && privkey_method == NULL) { -+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ -+ if (privkey != NULL && privkey_method != NULL) { -+ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD); -+ return 0; -+ } -+ -+ cert->privatekey = UpRef(privkey); -+ cert->key_method = privkey_method; -+ -+ return 1; -+} -+ - bool ssl_set_cert(CERT *cert, UniquePtr buffer) { - switch (check_leaf_cert_and_privkey(buffer.get(), cert->privatekey.get())) { - case leaf_cert_and_privkey_error: -@@ -343,6 +381,12 @@ - ssl_has_private_key(hs); - } - -+bool ssl_has_raw_public_key_certificate(const SSL_HANDSHAKE *hs) { -+ return hs->server_certificate_type_negotiated && -+ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY && -+ ssl_has_private_key(hs); -+} -+ - bool ssl_parse_cert_chain(uint8_t *out_alert, - UniquePtr *out_chain, - UniquePtr *out_pubkey, -@@ -727,11 +771,20 @@ - - bool ssl_on_certificate_selected(SSL_HANDSHAKE *hs) { - SSL *const ssl = hs->ssl; -- if (!ssl_has_certificate(hs)) { -+ if (!ssl_has_certificate(hs) && -+ !ssl_has_raw_public_key_certificate(hs)) { - // Nothing to do. - return true; - } - -+ if (ssl_has_raw_public_key_certificate(hs)) { -+ CBS spki = MakeConstSpan( -+ ssl->config->server_raw_public_key_certificate.data(), -+ ssl->config->server_raw_public_key_certificate.size()); -+ hs->local_pubkey = UniquePtr(EVP_parse_public_key(&spki)); -+ return hs->local_pubkey != NULL; -+ } -+ - if (!ssl->ctx->x509_method->ssl_auto_chain_if_needed(hs)) { - return false; - } -@@ -886,6 +939,15 @@ - privkey, privkey_method); - } - -+int SSL_set_nullchain_and_key(SSL *ssl, -+ EVP_PKEY *privkey, -+ const SSL_PRIVATE_KEY_METHOD *privkey_method) { -+ if (!ssl->config) { -+ return 0; -+ } -+ return cert_set_key(ssl->config->cert.get(), privkey, privkey_method); -+} -+ - int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, - size_t num_certs, EVP_PKEY *privkey, - const SSL_PRIVATE_KEY_METHOD *privkey_method) { -@@ -893,6 +955,12 @@ - privkey_method); - } - -+int SSL_CTX_set_nullchain_and_key(SSL_CTX *ctx, -+ EVP_PKEY *privkey, -+ const SSL_PRIVATE_KEY_METHOD *privkey_method) { -+ return cert_set_key(ctx->cert.get(), privkey, privkey_method); -+} -+ - const STACK_OF(CRYPTO_BUFFER)* SSL_CTX_get0_chain(const SSL_CTX *ctx) { - return ctx->cert->chain.get(); - } diff --git a/boring-sys/patches/rpk-patch/ssl/ssl_lib.cc.patch b/boring-sys/patches/rpk-patch/ssl/ssl_lib.cc.patch deleted file mode 100644 index 94a824fc..00000000 --- a/boring-sys/patches/rpk-patch/ssl/ssl_lib.cc.patch +++ /dev/null @@ -1,94 +0,0 @@ ---- google_boringssl/ssl/ssl_lib.cc 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/ssl/ssl_lib.cc 2021-02-03 20:24:49.000000000 -0800 -@@ -137,6 +137,25 @@ - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. */ -+/* ==================================================================== -+ * 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 - -@@ -712,6 +731,11 @@ - ssl->config->handoff = ctx->handoff; - ssl->quic_method = ctx->quic_method; - -+ ssl->config->server_certificate_type_list.CopyFrom( -+ ctx->server_certificate_type_list); -+ ssl->config->server_raw_public_key_certificate.CopyFrom( -+ ctx->server_raw_public_key_certificate); -+ - if (!ssl->method->ssl_new(ssl.get()) || - !ssl->ctx->x509_method->ssl_new(ssl->s3->hs.get())) { - return nullptr; -@@ -3124,5 +3148,52 @@ - ctx->legacy_ocsp_callback_arg = arg; - return 1; - } -+ -+int SSL_CTX_set_server_raw_public_key_certificate(SSL_CTX *ctx, -+ const uint8_t *raw_public_key, unsigned raw_public_key_len) { -+ if (!ctx->server_raw_public_key_certificate.CopyFrom( -+ MakeConstSpan(raw_public_key, raw_public_key_len))) { -+ return 0; /* Failure */ -+ } -+ -+ if (!ctx->server_certificate_type_list.Init(1)) { -+ return 0; -+ } -+ ctx->server_certificate_type_list[0] = TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY; -+ -+ return 1; /* Success */ -+} -+ -+int SSL_CTX_has_server_raw_public_key_certificate(SSL_CTX *ctx) { -+ return !ctx->server_raw_public_key_certificate.empty(); -+} -+ -+int SSL_set_server_raw_public_key_certificate(SSL *ssl, -+ const uint8_t *raw_public_key, unsigned raw_public_key_len) { -+ if (!ssl->config) { -+ return 0; /* Failure */ -+ } -+ -+ if (!ssl->config->server_raw_public_key_certificate.CopyFrom( -+ MakeConstSpan(raw_public_key, raw_public_key_len))) { -+ return 0; -+ } -+ -+ if (!ssl->config->server_certificate_type_list.Init(1)) { -+ return 0; -+ } -+ ssl->config->server_certificate_type_list[0] = -+ TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY; -+ -+ return 1; /* Success */ -+} -+ -+int SSL_has_server_raw_public_key_certificate(SSL *ssl) { -+ if (!ssl->config) { -+ return 0; /* Failure */ -+ } -+ -+ return !ssl->config->server_raw_public_key_certificate.empty(); -+} - - namespace fips202205 { - \ No newline at end of file diff --git a/boring-sys/patches/rpk-patch/ssl/tls13_both.cc.patch b/boring-sys/patches/rpk-patch/ssl/tls13_both.cc.patch deleted file mode 100644 index fd4b1813..00000000 --- a/boring-sys/patches/rpk-patch/ssl/tls13_both.cc.patch +++ /dev/null @@ -1,79 +0,0 @@ ---- google_boringssl/ssl/tls13_both.cc 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/ssl/tls13_both.cc 2021-02-03 20:24:49.000000000 -0800 -@@ -11,6 +11,25 @@ - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -+/* ==================================================================== -+ * 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 - -@@ -203,7 +222,16 @@ - return false; - } - -- if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { -+ if (hs->server_certificate_type_negotiated && -+ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY) { -+ pkey = UniquePtr(EVP_parse_public_key(&certificate)); -+ if (!pkey) { -+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); -+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); -+ return false; -+ } -+ } -+ else if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { - pkey = ssl_cert_parse_pubkey(&certificate); - if (!pkey) { - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); -@@ -319,7 +347,10 @@ - } - - if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) { -- if (!allow_anonymous) { -+ if (!allow_anonymous && -+ !(hs->server_certificate_type_negotiated && -+ hs->server_certificate_type == -+ TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); - return false; -@@ -436,6 +467,20 @@ - return false; - } - -+ if (hs->server_certificate_type_negotiated && -+ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY) { -+ CBB leaf, extensions; -+ if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) || -+ !CBB_add_bytes(&leaf, -+ ssl->config->server_raw_public_key_certificate.data(), -+ ssl->config->server_raw_public_key_certificate.size()) || -+ !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) { -+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); -+ return false; -+ } -+ return ssl_add_message_cbb(ssl, cbb.get()); -+ } -+ - if (!ssl_has_certificate(hs)) { - return ssl_add_message_cbb(ssl, cbb.get()); - } diff --git a/boring-sys/patches/rpk-patch/ssl/tls13_server.cc.patch b/boring-sys/patches/rpk-patch/ssl/tls13_server.cc.patch deleted file mode 100644 index 7fab6ad4..00000000 --- a/boring-sys/patches/rpk-patch/ssl/tls13_server.cc.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- google_boringssl/ssl/tls13_server.cc 2021-02-03 18:29:04.000000000 -0800 -+++ boringssl/ssl/tls13_server.cc 2021-02-03 20:24:49.000000000 -0800 -@@ -11,6 +11,25 @@ - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -+/* ==================================================================== -+ * 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 - -@@ -759,7 +778,8 @@ - - // Send the server Certificate message, if necessary. - if (!ssl->s3->session_reused) { -- if (!ssl_has_certificate(hs)) { -+ if (!ssl_has_certificate(hs) && -+ !ssl_has_raw_public_key_certificate(hs)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); - return ssl_hs_error; - } diff --git a/boring-sys/patches/rpk.patch b/boring-sys/patches/rpk.patch new file mode 100644 index 00000000..d7ea46a3 --- /dev/null +++ b/boring-sys/patches/rpk.patch @@ -0,0 +1,792 @@ +diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h +index 53aa9b453..87309c3e1 100644 +--- a/src/include/openssl/ssl.h ++++ b/src/include/openssl/ssl.h +@@ -138,6 +138,25 @@ + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ ++/* ==================================================================== ++ * 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. ++ */ + + #ifndef OPENSSL_HEADER_SSL_H + #define OPENSSL_HEADER_SSL_H +@@ -1136,6 +1155,16 @@ OPENSSL_EXPORT int SSL_CTX_set_chain_and_key( + SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); + ++// SSL_CTX_set_nullchain_and_key sets the private key for a ++// TLS client or server. Reference to the given |EVP_PKEY| ++// object is added as needed. Exactly one of |privkey| or |privkey_method| ++// may be non-NULL. Returns one on success and zero on error. ++// Note the lack of a corresponding public-key certificate. ++// See SSL_CTX_set_server_raw_public_key_certificate. ++OPENSSL_EXPORT int SSL_CTX_set_nullchain_and_key( ++ SSL_CTX *ctx, ++ EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); ++ + // SSL_set_chain_and_key sets the certificate chain and private key for a TLS + // client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| + // objects are added as needed. Exactly one of |privkey| or |privkey_method| +@@ -1144,6 +1173,16 @@ OPENSSL_EXPORT int SSL_set_chain_and_key( + SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method); + ++// SSL_set_nullchain_and_key sets the private key for a TLS ++// client or server. Reference to the given |EVP_PKEY| ++// object is added as needed. Exactly one of |privkey| or |privkey_method| ++// may be non-NULL. Returns one on success and zero on error. ++// Note the lack of a corresponding public-key certificate. ++// See SSL_set_server_raw_public_key_certificate. ++OPENSSL_EXPORT int SSL_set_nullchain_and_key( ++ SSL *ssl, EVP_PKEY *privkey, ++ const SSL_PRIVATE_KEY_METHOD *privkey_method); ++ + // SSL_CTX_get0_chain returns the list of |CRYPTO_BUFFER|s that were set by + // |SSL_CTX_set_chain_and_key|. Reference counts are not incremented by this + // call. The return value may be |NULL| if no chain has been set. +@@ -3023,6 +3062,21 @@ OPENSSL_EXPORT void SSL_get0_peer_application_settings(const SSL *ssl, + OPENSSL_EXPORT int SSL_has_application_settings(const SSL *ssl); + + ++// Server Certificate Type. ++ ++#define TLSEXT_CERTIFICATETYPE_X509 0 ++#define TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY 2 ++ ++OPENSSL_EXPORT int SSL_CTX_set_server_raw_public_key_certificate( ++ SSL_CTX *ctx, const uint8_t *raw_public_key, unsigned raw_public_key_len); ++ ++OPENSSL_EXPORT int SSL_CTX_has_server_raw_public_key_certificate(SSL_CTX *ctx); ++ ++OPENSSL_EXPORT int SSL_set_server_raw_public_key_certificate( ++ SSL *ssl, const uint8_t *raw_public_key, unsigned raw_public_key_len); ++ ++OPENSSL_EXPORT int SSL_has_server_raw_public_key_certificate(SSL *ssl); ++ + // Certificate compression. + // + // Certificates in TLS 1.3 can be compressed (RFC 8879). BoringSSL supports this +diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h +index 772fb87a3..be605c1aa 100644 +--- a/src/include/openssl/tls1.h ++++ b/src/include/openssl/tls1.h +@@ -146,6 +146,25 @@ + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ ++/* ==================================================================== ++ * 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. ++ */ + + #ifndef OPENSSL_HEADER_TLS1_H + #define OPENSSL_HEADER_TLS1_H +@@ -197,6 +216,9 @@ extern "C" { + // ExtensionType value from RFC 7301 + #define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + ++// ExtensionType value from RFC 7250 ++#define TLSEXT_TYPE_server_certificate_type 20 ++ + // ExtensionType value from RFC 7685 + #define TLSEXT_TYPE_padding 21 + +diff --git a/src/ssl/extensions.cc b/src/ssl/extensions.cc +index 5ee280221..2692e5478 100644 +--- a/src/ssl/extensions.cc ++++ b/src/ssl/extensions.cc +@@ -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 + +@@ -3094,6 +3113,146 @@ bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert, + 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[] = { + { +@@ -3267,6 +3426,13 @@ static const struct tls_extension kExtensions[] = { + 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)) +diff --git a/src/ssl/handshake.cc b/src/ssl/handshake.cc +index 8d5a23872..b9ac70dfe 100644 +--- a/src/ssl/handshake.cc ++++ b/src/ssl/handshake.cc +@@ -109,6 +109,25 @@ + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ ++/* ==================================================================== ++ * 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 + +@@ -150,6 +169,7 @@ SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg) + cert_compression_negotiated(false), + apply_jdk11_workaround(false), + can_release_private_key(false), ++ server_certificate_type_negotiated(false), + channel_id_negotiated(false) { + assert(ssl); + +@@ -365,7 +385,21 @@ enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) { + + uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN; + enum ssl_verify_result_t ret; +- if (hs->config->custom_verify_callback != nullptr) { ++ if (hs->server_certificate_type_negotiated && ++ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY) { ++ ret = ssl_verify_invalid; ++ EVP_PKEY *peer_pubkey = hs->peer_pubkey.get(); ++ CBS spki = MakeConstSpan(ssl->config->server_raw_public_key_certificate); ++ EVP_PKEY *pubkey = EVP_parse_public_key(&spki); ++ if (!pubkey) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ++ alert = SSL_AD_INTERNAL_ERROR; ++ } else if (EVP_PKEY_cmp(peer_pubkey, pubkey) == 1 /* Equal */) { ++ ret = ssl_verify_ok; ++ } else { ++ alert = SSL_AD_BAD_CERTIFICATE; ++ } ++ } else if (hs->config->custom_verify_callback != nullptr) { + ret = hs->config->custom_verify_callback(ssl, &alert); + switch (ret) { + case ssl_verify_ok: +diff --git a/src/ssl/internal.h b/src/ssl/internal.h +index 1e6da2153..f04888384 100644 +--- a/src/ssl/internal.h ++++ b/src/ssl/internal.h +@@ -138,6 +138,25 @@ + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ ++/* ==================================================================== ++ * 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. ++ */ + + #ifndef OPENSSL_HEADER_SSL_INTERNAL_H + #define OPENSSL_HEADER_SSL_INTERNAL_H +@@ -1286,6 +1305,8 @@ int ssl_write_buffer_flush(SSL *ssl); + // configured. + bool ssl_has_certificate(const SSL_HANDSHAKE *hs); + ++bool ssl_has_raw_public_key_certificate(const SSL_HANDSHAKE *hs); ++ + // ssl_parse_cert_chain parses a certificate list from |cbs| in the format used + // by a TLS Certificate message. On success, it advances |cbs| and returns + // true. Otherwise, it returns false and sets |*out_alert| to an alert to send +@@ -1887,6 +1908,8 @@ struct SSL_HANDSHAKE { + // |cert_compression_negotiated| is true. + uint16_t cert_compression_alg_id; + ++ uint8_t server_certificate_type; ++ + // ech_hpke_ctx is the HPKE context used in ECH. On the server, it is + // initialized if |ech_status| is |ssl_ech_accepted|. On the client, it is + // initialized if |selected_ech_config| is not nullptr. +@@ -2037,6 +2060,8 @@ struct SSL_HANDSHAKE { + // cert_compression_negotiated is true iff |cert_compression_alg_id| is valid. + bool cert_compression_negotiated : 1; + ++ bool server_certificate_type_negotiated : 1; ++ + // apply_jdk11_workaround is true if the peer is probably a JDK 11 client + // which implemented TLS 1.3 incorrectly. + bool apply_jdk11_workaround : 1; +@@ -3049,6 +3074,9 @@ struct SSL_CONFIG { + // along with their corresponding ALPS values. + GrowableArray alps_configs; + ++ Array server_certificate_type_list; ++ Array server_raw_public_key_certificate; ++ + // Contains the QUIC transport params that this endpoint will send. + Array quic_transport_params; + +@@ -3648,6 +3676,9 @@ struct ssl_ctx_st { + // format. + bssl::Array alpn_client_proto_list; + ++ bssl::Array server_certificate_type_list; ++ bssl::Array server_raw_public_key_certificate; ++ + // SRTP profiles we are willing to do from RFC 5764 + bssl::UniquePtr srtp_profiles; + +diff --git a/src/ssl/ssl_cert.cc b/src/ssl/ssl_cert.cc +index aa46a8bb6..d90840fce 100644 +--- a/src/ssl/ssl_cert.cc ++++ b/src/ssl/ssl_cert.cc +@@ -111,6 +111,25 @@ + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ ++/* ==================================================================== ++ * 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 + +@@ -302,6 +321,25 @@ static int cert_set_chain_and_key( + return 1; + } + ++static int cert_set_key( ++ CERT *cert, ++ EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) { ++ if (privkey == NULL && privkey_method == NULL) { ++ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); ++ return 0; ++ } ++ ++ if (privkey != NULL && privkey_method != NULL) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD); ++ return 0; ++ } ++ ++ cert->privatekey = UpRef(privkey); ++ cert->key_method = privkey_method; ++ ++ return 1; ++} ++ + bool ssl_set_cert(CERT *cert, UniquePtr buffer) { + switch (check_leaf_cert_and_privkey(buffer.get(), cert->privatekey.get())) { + case leaf_cert_and_privkey_error: +@@ -343,6 +381,12 @@ bool ssl_has_certificate(const SSL_HANDSHAKE *hs) { + ssl_has_private_key(hs); + } + ++bool ssl_has_raw_public_key_certificate(const SSL_HANDSHAKE *hs) { ++ return hs->server_certificate_type_negotiated && ++ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY && ++ ssl_has_private_key(hs); ++} ++ + bool ssl_parse_cert_chain(uint8_t *out_alert, + UniquePtr *out_chain, + UniquePtr *out_pubkey, +@@ -721,11 +765,20 @@ bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, + + bool ssl_on_certificate_selected(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; +- if (!ssl_has_certificate(hs)) { ++ if (!ssl_has_certificate(hs) && ++ !ssl_has_raw_public_key_certificate(hs)) { + // Nothing to do. + return true; + } + ++ if (ssl_has_raw_public_key_certificate(hs)) { ++ CBS spki = MakeConstSpan( ++ ssl->config->server_raw_public_key_certificate.data(), ++ ssl->config->server_raw_public_key_certificate.size()); ++ hs->local_pubkey = UniquePtr(EVP_parse_public_key(&spki)); ++ return hs->local_pubkey != NULL; ++ } ++ + if (!ssl->ctx->x509_method->ssl_auto_chain_if_needed(hs)) { + return false; + } +@@ -880,6 +933,15 @@ int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs, + privkey, privkey_method); + } + ++int SSL_set_nullchain_and_key(SSL *ssl, ++ EVP_PKEY *privkey, ++ const SSL_PRIVATE_KEY_METHOD *privkey_method) { ++ if (!ssl->config) { ++ return 0; ++ } ++ return cert_set_key(ssl->config->cert.get(), privkey, privkey_method); ++} ++ + int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { +@@ -887,6 +949,12 @@ int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, + privkey_method); + } + ++int SSL_CTX_set_nullchain_and_key(SSL_CTX *ctx, ++ EVP_PKEY *privkey, ++ const SSL_PRIVATE_KEY_METHOD *privkey_method) { ++ return cert_set_key(ctx->cert.get(), privkey, privkey_method); ++} ++ + const STACK_OF(CRYPTO_BUFFER)* SSL_CTX_get0_chain(const SSL_CTX *ctx) { + return ctx->cert->chain.get(); + } +diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc +index 838761af5..e4f1a12b7 100644 +--- a/src/ssl/ssl_lib.cc ++++ b/src/ssl/ssl_lib.cc +@@ -137,6 +137,25 @@ + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. */ ++/* ==================================================================== ++ * 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 + +@@ -687,6 +706,11 @@ SSL *SSL_new(SSL_CTX *ctx) { + ssl->config->handoff = ctx->handoff; + ssl->quic_method = ctx->quic_method; + ++ ssl->config->server_certificate_type_list.CopyFrom( ++ ctx->server_certificate_type_list); ++ ssl->config->server_raw_public_key_certificate.CopyFrom( ++ ctx->server_raw_public_key_certificate); ++ + if (!ssl->method->ssl_new(ssl.get()) || + !ssl->ctx->x509_method->ssl_new(ssl->s3->hs.get())) { + return nullptr; +@@ -3140,6 +3164,53 @@ int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg) { + return 1; + } + ++int SSL_CTX_set_server_raw_public_key_certificate(SSL_CTX *ctx, ++ const uint8_t *raw_public_key, unsigned raw_public_key_len) { ++ if (!ctx->server_raw_public_key_certificate.CopyFrom( ++ MakeConstSpan(raw_public_key, raw_public_key_len))) { ++ return 0; /* Failure */ ++ } ++ ++ if (!ctx->server_certificate_type_list.Init(1)) { ++ return 0; ++ } ++ ctx->server_certificate_type_list[0] = TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY; ++ ++ return 1; /* Success */ ++} ++ ++int SSL_CTX_has_server_raw_public_key_certificate(SSL_CTX *ctx) { ++ return !ctx->server_raw_public_key_certificate.empty(); ++} ++ ++int SSL_set_server_raw_public_key_certificate(SSL *ssl, ++ const uint8_t *raw_public_key, unsigned raw_public_key_len) { ++ if (!ssl->config) { ++ return 0; /* Failure */ ++ } ++ ++ if (!ssl->config->server_raw_public_key_certificate.CopyFrom( ++ MakeConstSpan(raw_public_key, raw_public_key_len))) { ++ return 0; ++ } ++ ++ if (!ssl->config->server_certificate_type_list.Init(1)) { ++ return 0; ++ } ++ ssl->config->server_certificate_type_list[0] = ++ TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY; ++ ++ return 1; /* Success */ ++} ++ ++int SSL_has_server_raw_public_key_certificate(SSL *ssl) { ++ if (!ssl->config) { ++ return 0; /* Failure */ ++ } ++ ++ return !ssl->config->server_raw_public_key_certificate.empty(); ++} ++ + namespace fips202205 { + + // (References are to SP 800-52r2): +diff --git a/src/ssl/tls13_both.cc b/src/ssl/tls13_both.cc +index 5ab5a1c93..79135613e 100644 +--- a/src/ssl/tls13_both.cc ++++ b/src/ssl/tls13_both.cc +@@ -11,6 +11,25 @@ + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ ++/* ==================================================================== ++ * 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 + +@@ -197,7 +216,16 @@ bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + return false; + } + +- if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { ++ if (hs->server_certificate_type_negotiated && ++ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY) { ++ pkey = UniquePtr(EVP_parse_public_key(&certificate)); ++ if (!pkey) { ++ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); ++ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ++ return false; ++ } ++ } ++ else if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { + pkey = ssl_cert_parse_pubkey(&certificate); + if (!pkey) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); +@@ -299,7 +327,10 @@ bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) { +- if (!allow_anonymous) { ++ if (!allow_anonymous && ++ !(hs->server_certificate_type_negotiated && ++ hs->server_certificate_type == ++ TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); + return false; +@@ -416,6 +447,20 @@ bool tls13_add_certificate(SSL_HANDSHAKE *hs) { + return false; + } + ++ if (hs->server_certificate_type_negotiated && ++ hs->server_certificate_type == TLSEXT_CERTIFICATETYPE_RAW_PUBLIC_KEY) { ++ CBB leaf, extensions; ++ if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) || ++ !CBB_add_bytes(&leaf, ++ ssl->config->server_raw_public_key_certificate.data(), ++ ssl->config->server_raw_public_key_certificate.size()) || ++ !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) { ++ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); ++ return false; ++ } ++ return ssl_add_message_cbb(ssl, cbb.get()); ++ } ++ + if (!ssl_has_certificate(hs)) { + return ssl_add_message_cbb(ssl, cbb.get()); + } +diff --git a/src/ssl/tls13_server.cc b/src/ssl/tls13_server.cc +index 9d26f4e00..a92689761 100644 +--- a/src/ssl/tls13_server.cc ++++ b/src/ssl/tls13_server.cc +@@ -11,6 +11,25 @@ + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ ++/* ==================================================================== ++ * 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 + +@@ -860,7 +879,8 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { + + // Send the server Certificate message, if necessary. + if (!ssl->s3->session_reused) { +- if (!ssl_has_certificate(hs)) { ++ if (!ssl_has_certificate(hs) && ++ !ssl_has_raw_public_key_certificate(hs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + return ssl_hs_error; + } diff --git a/boring-sys/scripts/apply_rpk_patch.sh b/boring-sys/scripts/apply_rpk_patch.sh index 6cca5d17..c9f6d611 100755 --- a/boring-sys/scripts/apply_rpk_patch.sh +++ b/boring-sys/scripts/apply_rpk_patch.sh @@ -2,4 +2,4 @@ set -euo pipefail -git apply -v --whitespace=fix ../../../patches/rpk-patch/include/*/*.patch ../../../patches/rpk-patch/ssl/*.patch +git apply -v --whitespace=fix ../../patches/rpk.patch diff --git a/boring-sys/src/lib.rs b/boring-sys/src/lib.rs index 8e8f5c7b..db168d09 100644 --- a/boring-sys/src/lib.rs +++ b/boring-sys/src/lib.rs @@ -10,7 +10,6 @@ non_upper_case_globals, unused_imports )] - #![cfg_attr(docsrs, feature(doc_auto_cfg))] use std::convert::TryInto; diff --git a/boring/src/lib.rs b/boring/src/lib.rs index 261f57c5..c96888dd 100644 --- a/boring/src/lib.rs +++ b/boring/src/lib.rs @@ -1,6 +1,57 @@ //! Bindings to BoringSSL //! //! This crate provides a safe interface to the BoringSSL cryptography library. +//! +//! # Versioning +//! +//! ## Crate versioning +//! +//! The crate and all the related crates (FFI bindings, etc.) are released simultaneously and all +//! bumped to the same version disregard whether particular crate has any API changes or not. +//! However, semantic versioning guarantees still hold, as all the crate versions will be updated +//! based on the crate with most significant changes. +//! +//! ## BoringSSL version +//! +//! By default, the crate aims to statically link with the latest BoringSSL master branch. +//! *Note*: any BoringSSL revision bumps will be released as a major version update of all crates. +//! +//! # Compilation and linking options +//! +//! ## Support for pre-built binaries +//! +//! While this crate can build BoringSSL on its own, you may want to provide pre-built binaries instead. +//! To do so, specify the environment variable `BORING_BSSL_PATH` with the path to the binaries. +//! +//! You can also provide specific headers by setting `BORING_BSSL_INCLUDE_PATH`. +//! +//! _Notes_: The crate will look for headers in the `$BORING_BSSL_INCLUDE_PATH/openssl/` folder, make sure to place your headers there. +//! +//! _Warning_: When providing a different version of BoringSSL make sure to use a compatible one, the crate relies on the presence of certain functions. +//! +//! ## Building with a FIPS-validated module +//! +//! Only BoringCrypto module version `853ca1ea1168dff08011e5d42d94609cc0ca2e27`, as certified with +//! [FIPS 140-2 certificate 4407](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4407) +//! is supported by this crate. Support is enabled by this crate's `fips` feature. +//! +//! `boring-sys` comes with a test that FIPS is enabled/disabled depending on the feature flag. You can run it as follows: +//! +//! ```bash +//! $ cargo test --features fips fips::is_enabled +//! ``` +//! +//! # Optional patches +//! +//! ## Raw Public Key +//! +//! The crate can be compiled with [RawPublicKey](https://datatracker.ietf.org/doc/html/rfc7250) +//! support by turning on `rpk` compilation feature. +//! +//! ## Post-quantum cryptography +//! +//! The crate can be compiled with [post-quantum cryptography](https://blog.cloudflare.com/post-quantum-for-all/) +//! support by turning on `post-quantum` compilation feature. #![cfg_attr(docsrs, feature(doc_auto_cfg))]