feat: Add setup extension permutation (#28)
This commit is contained in:
parent
292b2a1513
commit
66cc25a270
|
|
@ -482,7 +482,10 @@ fn ensure_patches_applied(config: &Config) -> io::Result<()> {
|
|||
}
|
||||
|
||||
println!("cargo:warning=applying 44b3df6f03d85c901767250329c571db405122d5 patch to boringssl");
|
||||
apply_patch(config, "boringssl-44b3df6f03d85c901767250329c571db405122d5.patch")?;
|
||||
apply_patch(
|
||||
config,
|
||||
"boringssl-44b3df6f03d85c901767250329c571db405122d5.patch",
|
||||
)?;
|
||||
|
||||
// if config.features.pq_experimental {
|
||||
// println!("cargo:warning=applying experimental post quantum crypto patch to boringssl");
|
||||
|
|
|
|||
|
|
@ -4176,7 +4176,7 @@ index 4dd8841b1..23ffcd446 100644
|
|||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
|
||||
index 53aa9b453..5470b863e 100644
|
||||
index 53aa9b453..f86ae1b47 100644
|
||||
--- a/src/include/openssl/ssl.h
|
||||
+++ b/src/include/openssl/ssl.h
|
||||
@@ -2378,6 +2378,13 @@ OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves);
|
||||
|
|
@ -4193,10 +4193,15 @@ index 53aa9b453..5470b863e 100644
|
|||
|
||||
// SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently
|
||||
// completed handshake or 0 if not applicable.
|
||||
@@ -4570,6 +4577,22 @@ OPENSSL_EXPORT void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled);
|
||||
@@ -4570,6 +4577,27 @@ OPENSSL_EXPORT void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled);
|
||||
// permute extensions. For now, this is only implemented for the ClientHello.
|
||||
OPENSSL_EXPORT void SSL_set_permute_extensions(SSL *ssl, int enabled);
|
||||
|
||||
+// SSL_CTX_set_extension_permutation configures whether sockets on |ctx| should
|
||||
+// permute extensions. For now, this is only implemented for the ClientHello.
|
||||
+OPENSSL_EXPORT int SSL_CTX_set_extension_permutation(SSL_CTX* ctx, const uint8_t *permutation,
|
||||
+ size_t permutation_len);
|
||||
+
|
||||
+// SSL_set_record_size_limit configures whether sockets on |ssl| should
|
||||
+// send record size limit extension.
|
||||
+OPENSSL_EXPORT void SSL_set_record_size_limit(SSL *ssl, uint16_t limit);
|
||||
|
|
@ -4216,7 +4221,7 @@ index 53aa9b453..5470b863e 100644
|
|||
// SSL_max_seal_overhead returns the maximum overhead, in bytes, of sealing a
|
||||
// record with |ssl|.
|
||||
OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl);
|
||||
@@ -4874,6 +4897,10 @@ OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str);
|
||||
@@ -4874,6 +4902,10 @@ OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str);
|
||||
// more convenient to codesearch for specific algorithm values.
|
||||
OPENSSL_EXPORT int SSL_set1_sigalgs_list(SSL *ssl, const char *str);
|
||||
|
||||
|
|
@ -4262,7 +4267,7 @@ index 5c7e881bf..3c0770cf3 100644
|
|||
crypto/pkcs8/test/no_encryption.p12
|
||||
crypto/pkcs8/test/nss.p12
|
||||
diff --git a/src/ssl/extensions.cc b/src/ssl/extensions.cc
|
||||
index 5ee280221..b4a33cc11 100644
|
||||
index 5ee280221..dd1284d18 100644
|
||||
--- a/src/ssl/extensions.cc
|
||||
+++ b/src/ssl/extensions.cc
|
||||
@@ -207,6 +207,10 @@ static bool tls1_check_duplicate_extensions(const CBS *cbs) {
|
||||
|
|
@ -4427,6 +4432,55 @@ index 5ee280221..b4a33cc11 100644
|
|||
};
|
||||
|
||||
#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
|
||||
@@ -3280,6 +3367,12 @@ static_assert(kNumExtensions <=
|
||||
|
||||
bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs) {
|
||||
if (!hs->config->permute_extensions) {
|
||||
+ if (!hs->ssl->ctx->extension_permutation.empty()) {
|
||||
+ Array<uint8_t> permutation;
|
||||
+ permutation.Init(hs->ssl->ctx->extension_permutation.size());
|
||||
+ permutation.CopyFrom(hs->ssl->ctx->extension_permutation);
|
||||
+ hs->extension_permutation = std::move(permutation);
|
||||
+ }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3357,10 +3450,16 @@ static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out,
|
||||
}
|
||||
}
|
||||
|
||||
- for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) {
|
||||
+ const size_t numExtensions = hs->extension_permutation.empty()
|
||||
+ ? kNumExtensions
|
||||
+ : hs->extension_permutation.size();
|
||||
+ for (size_t unpermuted = 0; unpermuted < numExtensions; unpermuted++) {
|
||||
size_t i = hs->extension_permutation.empty()
|
||||
? unpermuted
|
||||
: hs->extension_permutation[unpermuted];
|
||||
+ if (i >= kNumExtensions) {
|
||||
+ continue;
|
||||
+ }
|
||||
const size_t len_before = CBB_len(&extensions);
|
||||
const size_t len_compressed_before = CBB_len(compressed.get());
|
||||
if (!kExtensions[i].add_clienthello(hs, &extensions, compressed.get(),
|
||||
@@ -3466,10 +3565,16 @@ bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded,
|
||||
}
|
||||
|
||||
bool last_was_empty = false;
|
||||
- for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) {
|
||||
+ const size_t numExtensions = hs->extension_permutation.empty()
|
||||
+ ? kNumExtensions
|
||||
+ : hs->extension_permutation.size();
|
||||
+ for (size_t unpermuted = 0; unpermuted < numExtensions; unpermuted++) {
|
||||
size_t i = hs->extension_permutation.empty()
|
||||
? unpermuted
|
||||
: hs->extension_permutation[unpermuted];
|
||||
+ if (i >= kNumExtensions) {
|
||||
+ continue;
|
||||
+ }
|
||||
const size_t len_before = CBB_len(&extensions);
|
||||
if (!kExtensions[i].add_clienthello(hs, &extensions, &extensions, type)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
|
||||
diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc
|
||||
index 971ebd0b1..e70e6c868 100644
|
||||
--- a/src/ssl/handshake_client.cc
|
||||
|
|
@ -4504,7 +4558,7 @@ index 971ebd0b1..e70e6c868 100644
|
|||
if (hs->min_version < TLS1_3_VERSION && type != ssl_client_hello_inner) {
|
||||
bool any_enabled = false;
|
||||
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
|
||||
index 1e6da2153..a46e94b91 100644
|
||||
index 1e6da2153..f931d3f7a 100644
|
||||
--- a/src/ssl/internal.h
|
||||
+++ b/src/ssl/internal.h
|
||||
@@ -554,8 +554,13 @@ BSSL_NAMESPACE_BEGIN
|
||||
|
|
@ -4566,7 +4620,7 @@ index 1e6da2153..a46e94b91 100644
|
|||
// retain_only_sha256_of_client_certs is true if we should compute the SHA256
|
||||
// hash of the peer's certificate and then discard it to save memory and
|
||||
// session space. Only effective on the server side.
|
||||
@@ -3748,6 +3767,12 @@ struct ssl_ctx_st {
|
||||
@@ -3748,6 +3767,15 @@ struct ssl_ctx_st {
|
||||
// |aes_hw_override| is true.
|
||||
bool aes_hw_override_value : 1;
|
||||
|
||||
|
|
@ -4575,6 +4629,9 @@ index 1e6da2153..a46e94b91 100644
|
|||
+
|
||||
+ // key_shares limit is the maximum number of key shares to send.
|
||||
+ uint8_t key_shares_limit = 0;
|
||||
+
|
||||
+ // extension_permutation is the permutation of extensions to send.
|
||||
+ bssl::Array<uint8_t> extension_permutation;
|
||||
+
|
||||
private:
|
||||
~ssl_ctx_st();
|
||||
|
|
@ -5433,7 +5490,7 @@ index 09a9ad380..a972e8dd1 100644
|
|||
return nullptr;
|
||||
}
|
||||
diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc
|
||||
index 838761af5..a467a6d01 100644
|
||||
index 838761af5..93447106f 100644
|
||||
--- a/src/ssl/ssl_lib.cc
|
||||
+++ b/src/ssl/ssl_lib.cc
|
||||
@@ -537,7 +537,8 @@ ssl_ctx_st::ssl_ctx_st(const SSL_METHOD *ssl_method)
|
||||
|
|
@ -5508,7 +5565,32 @@ index 838761af5..a467a6d01 100644
|
|||
void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
|
||||
size_t *out_len) {
|
||||
SSL_SESSION *session = SSL_get_session(ssl);
|
||||
@@ -3151,7 +3178,7 @@ namespace fips202205 {
|
||||
@@ -2939,6 +2966,24 @@ void SSL_set_permute_extensions(SSL *ssl, int enabled) {
|
||||
ssl->config->permute_extensions = !!enabled;
|
||||
}
|
||||
|
||||
+int SSL_CTX_set_extension_permutation(SSL_CTX *ctx, const uint8_t *permutation, size_t permutation_len) {
|
||||
+ if (!permutation || permutation_len == 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ bssl::Array<uint8_t> arr;
|
||||
+ if (!arr.Init(permutation_len)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ for (size_t i = 0; i < permutation_len; ++i) {
|
||||
+ arr[i] = permutation[i];
|
||||
+ }
|
||||
+
|
||||
+ ctx->extension_permutation = std::move(arr);
|
||||
+ return !ctx->extension_permutation.empty();
|
||||
+}
|
||||
+
|
||||
int32_t SSL_get_ticket_age_skew(const SSL *ssl) {
|
||||
return ssl->s3->ticket_age_skew;
|
||||
}
|
||||
@@ -3151,7 +3196,7 @@ namespace fips202205 {
|
||||
// Section 3.3.1
|
||||
// "The server shall be configured to only use cipher suites that are
|
||||
// composed entirely of NIST approved algorithms"
|
||||
|
|
|
|||
|
|
@ -1888,6 +1888,60 @@ impl SslContextBuilder {
|
|||
unsafe { ffi::SSL_CTX_set_key_shares_limit(self.as_ptr(), limit as _) }
|
||||
}
|
||||
|
||||
#[corresponds(SSL_CTX_set_extension_permutation)]
|
||||
#[cfg(not(feature = "fips-compat"))]
|
||||
pub fn set_extension_permutation(
|
||||
&mut self,
|
||||
shuffled: &[ExtensionType],
|
||||
) -> Result<(), ErrorStack> {
|
||||
const BORING_SSLEXTENSION_PERMUTATION: [ExtensionType; 25] = [
|
||||
ExtensionType::SERVER_NAME,
|
||||
ExtensionType::ENCRYPTED_CLIENT_HELLO,
|
||||
ExtensionType::EXTENDED_MASTER_SECRET,
|
||||
ExtensionType::RENEGOTIATE,
|
||||
ExtensionType::SUPPORTED_GROUPS,
|
||||
ExtensionType::EC_POINT_FORMATS,
|
||||
ExtensionType::SESSION_TICKET,
|
||||
ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION,
|
||||
ExtensionType::STATUS_REQUEST,
|
||||
ExtensionType::SIGNATURE_ALGORITHMS,
|
||||
ExtensionType::NEXT_PROTO_NEG,
|
||||
ExtensionType::CERTIFICATE_TIMESTAMP,
|
||||
ExtensionType::CHANNEL_ID,
|
||||
ExtensionType::SRTP,
|
||||
ExtensionType::KEY_SHARE,
|
||||
ExtensionType::PSK_KEY_EXCHANGE_MODES,
|
||||
ExtensionType::EARLY_DATA,
|
||||
ExtensionType::SUPPORTED_VERSIONS,
|
||||
ExtensionType::COOKIE,
|
||||
ExtensionType::QUIC_TRANSPORT_PARAMETERS_STANDARD,
|
||||
ExtensionType::QUIC_TRANSPORT_PARAMETERS_LEGACY,
|
||||
ExtensionType::CERT_COMPRESSION,
|
||||
ExtensionType::DELEGATED_CREDENTIAL,
|
||||
ExtensionType::APPLICATION_SETTINGS,
|
||||
ExtensionType::RECORD_SIZE_LIMIT,
|
||||
];
|
||||
|
||||
let mut indices = Vec::with_capacity(shuffled.len());
|
||||
for &ext in shuffled {
|
||||
if let Some(index) = BORING_SSLEXTENSION_PERMUTATION
|
||||
.iter()
|
||||
.position(|&e| e == ext)
|
||||
{
|
||||
indices.push(index as u8);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cvt(ffi::SSL_CTX_set_extension_permutation(
|
||||
self.as_ptr(),
|
||||
indices.as_ptr() as *const _,
|
||||
indices.len() as _,
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Configures whether ClientHello extensions should be permuted.
|
||||
///
|
||||
/// Note: This is gated to non-fips because the fips feature builds with a separate
|
||||
|
|
|
|||
Loading…
Reference in New Issue