Skip to content

Commit 426feda

Browse files
committed
Readd firefox tls13 support
1 parent 988ea61 commit 426feda

3 files changed

Lines changed: 132 additions & 67 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
> 5. Upgrade to more recent version of curl, 8.13.0 as of April, 2025.
1515
> 6. Ability to change extension orders and enable/disable TLS grease.
1616
> 7. Single binary to support Chrome, Safari and Firefox.
17-
> 8. (In progress) Built with http/3 enabled.
17+
> 8. Built with http/3 enabled.
1818
> 9. A user-friendly Python binding: [curl_cffi](https://github.com/lexiforest/curl_cffi).
1919
> 10. More prebuilt binaries, including Windows, Arm, and even RISC-V!
2020
> 11. Commercial support at [impersonate.pro](https://impersonate.pro).

patches/boringssl.patch

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,13 @@ index 884d7891e..92cd3a025 100644
151151

152152
diff --git a/export.sh b/export.sh
153153
new file mode 100755
154-
index 000000000..d044063cc
154+
index 000000000..892803529
155155
--- /dev/null
156156
+++ b/export.sh
157157
@@ -0,0 +1,8 @@
158158
+#!/bin/bash
159159
+
160-
+# From here: https://chromium.googlesource.com/chromium/src.git/+/refs/tags/134.0.6970.1/DEPS
160+
+# From here: https://chromium.googlesource.com/chromium/src.git/+/refs/tags/135.0.7049.41/DEPS
161161
+
162162
+BASE_COMMIT=673e61fc215b178a90c0e67858bbf162c8158993
163163
+
@@ -193,7 +193,7 @@ index bf5536dc4..990a20a80 100644
193193
#if defined(__cplusplus)
194194
} /* extern C */
195195
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
196-
index 7c6804d65..a1fd43fcc 100644
196+
index 7c6804d65..1790167e1 100644
197197
--- a/include/openssl/ssl.h
198198
+++ b/include/openssl/ssl.h
199199
@@ -1653,6 +1653,12 @@ OPENSSL_EXPORT size_t SSL_get_all_standard_cipher_names(const char **out,
@@ -218,7 +218,7 @@ index 7c6804d65..a1fd43fcc 100644
218218

219219
// SSL_CTX_set1_group_ids sets the preferred groups for |ctx| to |group_ids|.
220220
// Each element of |group_ids| should be one of the |SSL_GROUP_*| constants. It
221-
@@ -4898,6 +4906,12 @@ OPENSSL_EXPORT void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled);
221+
@@ -4898,6 +4906,15 @@ OPENSSL_EXPORT void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled);
222222
// permute extensions. For now, this is only implemented for the ClientHello.
223223
OPENSSL_EXPORT void SSL_set_permute_extensions(SSL *ssl, int enabled);
224224

@@ -227,11 +227,14 @@ index 7c6804d65..a1fd43fcc 100644
227227
+
228228
+// curl-impersonate
229229
+OPENSSL_EXPORT int SSL_CTX_set_key_usage_check_enabled(SSL_CTX *ctx, int enabled);
230+
+
231+
+// curl-impersonate
232+
+OPENSSL_EXPORT int SSL_CTX_set_use_firefox_tls13_ciphers(SSL_CTX *ctx, int enabled);
230233
+
231234
// SSL_max_seal_overhead returns the maximum overhead, in bytes, of sealing a
232235
// record with |ssl|.
233236
OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl);
234-
@@ -5215,6 +5229,33 @@ OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str);
237+
@@ -5215,6 +5232,33 @@ OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str);
235238
// more convenient to codesearch for specific algorithm values.
236239
OPENSSL_EXPORT int SSL_set1_sigalgs_list(SSL *ssl, const char *str);
237240

@@ -265,7 +268,7 @@ index 7c6804d65..a1fd43fcc 100644
265268
#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)(arg)))
266269
#define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
267270
#define SSL_SESSION_set_app_data(s, a) \
268-
@@ -5593,6 +5634,8 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg);
271+
@@ -5593,6 +5637,8 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg);
269272
#define SSL_CURVE_SECP384R1 SSL_GROUP_SECP384R1
270273
#define SSL_CURVE_SECP521R1 SSL_GROUP_SECP521R1
271274
#define SSL_CURVE_X25519 SSL_GROUP_X25519
@@ -551,7 +554,7 @@ index 4bd5c5d69..1adae1322 100644
551554
if (!kExtensions[i].add_clienthello(hs, &extensions, &extensions, type)) {
552555
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
553556
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc
554-
index 4ce8d1802..e0d6afbde 100644
557+
index 4ce8d1802..53a863d20 100644
555558
--- a/ssl/handshake_client.cc
556559
+++ b/ssl/handshake_client.cc
557560
@@ -26,6 +26,8 @@
@@ -563,7 +566,27 @@ index 4ce8d1802..e0d6afbde 100644
563566
#include <openssl/ec_key.h>
564567
#include <openssl/ecdsa.h>
565568
#include <openssl/err.h>
566-
@@ -431,8 +433,10 @@ static enum ssl_hs_wait_t do_start_connect(SSL_HANDSHAKE *hs) {
569+
@@ -125,11 +127,19 @@ static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out,
570+
TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff,
571+
TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff,
572+
};
573+
+ // curl-impersonate: Firefox uses a different order
574+
+ static const uint16_t kCiphersFirefox[] = {
575+
+ TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff,
576+
+ TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff,
577+
+ TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff,
578+
+ };
579+
580+
const bool has_aes_hw = ssl->config->aes_hw_override
581+
? ssl->config->aes_hw_override_value
582+
: EVP_has_aes_hardware();
583+
+
584+
const bssl::Span<const uint16_t> ciphers =
585+
+ ssl->config->use_firefox_tls13_ciphers ? kCiphersFirefox :
586+
ssl->config->compliance_policy == ssl_compliance_policy_cnsa_202407
587+
? bssl::Span<const uint16_t>(kCiphersCNSA)
588+
: (has_aes_hw ? bssl::Span<const uint16_t>(kCiphersAESHardware)
589+
@@ -431,8 +441,10 @@ static enum ssl_hs_wait_t do_start_connect(SSL_HANDSHAKE *hs) {
567590
hs->early_data_offered = true;
568591
}
569592

@@ -574,7 +597,7 @@ index 4ce8d1802..e0d6afbde 100644
574597
!ssl_encrypt_client_hello(hs, Span(ech_enc, ech_enc_len)) ||
575598
!ssl_add_client_hello(hs)) {
576599
return ssl_hs_error;
577-
@@ -1026,7 +1030,28 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) {
600+
@@ -1026,7 +1038,28 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) {
578601
hs->peer_psk_identity_hint.reset(raw);
579602
}
580603

@@ -604,7 +627,7 @@ index 4ce8d1802..e0d6afbde 100644
604627
// Parse the server parameters.
605628
uint8_t group_type;
606629
uint16_t group_id;
607-
@@ -1366,7 +1391,9 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
630+
@@ -1366,7 +1399,9 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
608631
ssl_key_usage_t intended_use = (alg_k & SSL_kRSA)
609632
? key_usage_encipherment
610633
: key_usage_digital_signature;
@@ -615,7 +638,7 @@ index 4ce8d1802..e0d6afbde 100644
615638
if (hs->config->enforce_rsa_key_usage ||
616639
EVP_PKEY_id(hs->peer_pubkey.get()) != EVP_PKEY_RSA) {
617640
return ssl_hs_error;
618-
@@ -1440,6 +1467,64 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
641+
@@ -1440,6 +1475,64 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
619642
!CBB_flush(&body)) {
620643
return ssl_hs_error;
621644
}
@@ -681,7 +704,7 @@ index 4ce8d1802..e0d6afbde 100644
681704
CBB child;
682705
if (!CBB_add_u8_length_prefixed(&body, &child)) {
683706
diff --git a/ssl/internal.h b/ssl/internal.h
684-
index 05af44f7b..f5bdd2441 100644
707+
index 05af44f7b..9f26466e9 100644
685708
--- a/ssl/internal.h
686709
+++ b/ssl/internal.h
687710
@@ -697,10 +697,11 @@ BSSL_NAMESPACE_BEGIN
@@ -729,7 +752,7 @@ index 05af44f7b..f5bdd2441 100644
729752
// peer_key is the peer's ECDH key for a TLS 1.2 client.
730753
Array<uint8_t> peer_key;
731754

732-
@@ -2515,6 +2520,12 @@ bssl::UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSL *ssl,
755+
@@ -2515,6 +2520,15 @@ bssl::UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSL *ssl,
733756
// for |hs|, if applicable. It returns true on success and false on error.
734757
bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs);
735758

@@ -738,11 +761,14 @@ index 05af44f7b..f5bdd2441 100644
738761
+
739762
+// curl-impersonate
740763
+bool ssl_set_key_usage_check_enabled(SSL_HANDSHAKE *hs);
764+
+
765+
+// curl-impersonate
766+
+bool ssl_set_use_firefox_tls13_ciphers(SSL_HANDSHAKE *hs);
741767
+
742768
// ssl_setup_key_shares computes client key shares and saves them in |hs|. It
743769
// returns true on success and false on failure. If |override_group_id| is zero,
744770
// it offers the default groups, including GREASE. If it is non-zero, it offers
745-
@@ -3581,6 +3592,12 @@ struct SSL_CONFIG {
771+
@@ -3581,6 +3595,15 @@ struct SSL_CONFIG {
746772
// crypto
747773
UniquePtr<SSLCipherPreferenceList> cipher_list;
748774

@@ -751,11 +777,14 @@ index 05af44f7b..f5bdd2441 100644
751777
+
752778
+ // curl-impersonate
753779
+ int key_usage_check_enabled = 1;
780+
+
781+
+ // curl-impersonate
782+
+ int use_firefox_tls13_ciphers = 0;
754783
+
755784
// This is used to hold the local certificate used (i.e. the server
756785
// certificate for a server or the client certificate for a client).
757786
UniquePtr<CERT> cert;
758-
@@ -3639,6 +3656,10 @@ struct SSL_CONFIG {
787+
@@ -3639,6 +3662,10 @@ struct SSL_CONFIG {
759788
// accepted from the peer in decreasing order of preference.
760789
Array<uint16_t> verify_sigalgs;
761790

@@ -766,7 +795,7 @@ index 05af44f7b..f5bdd2441 100644
766795
// srtp_profiles is the list of configured SRTP protection profiles for
767796
// DTLS-SRTP.
768797
UniquePtr<STACK_OF(SRTP_PROTECTION_PROFILE)> srtp_profiles;
769-
@@ -3704,6 +3725,14 @@ struct SSL_CONFIG {
798+
@@ -3704,6 +3731,14 @@ struct SSL_CONFIG {
770799
// hardware support, and use the value in aes_hw_override_value instead.
771800
bool aes_hw_override : 1;
772801

@@ -781,7 +810,7 @@ index 05af44f7b..f5bdd2441 100644
781810
// aes_hw_override_value is used for testing to indicate the support or lack
782811
// of support for AES hw. The value is only considered if |aes_hw_override| is
783812
// true.
784-
@@ -4076,6 +4105,12 @@ struct ssl_ctx_st : public bssl::RefCounted<ssl_ctx_st> {
813+
@@ -4076,6 +4111,15 @@ struct ssl_ctx_st : public bssl::RefCounted<ssl_ctx_st> {
785814

786815
bssl::UniquePtr<bssl::SSLCipherPreferenceList> cipher_list;
787816

@@ -790,11 +819,14 @@ index 05af44f7b..f5bdd2441 100644
790819
+
791820
+ // curl-impersonate
792821
+ int key_usage_check_enabled = 1;
822+
+
823+
+ // curl-impersonate
824+
+ int use_firefox_tls13_ciphers = 0;
793825
+
794826
X509_STORE *cert_store = nullptr;
795827
LHASH_OF(SSL_SESSION) *sessions = nullptr;
796828
// Most session-ids that will be cached, default is
797-
@@ -4300,6 +4335,10 @@ struct ssl_ctx_st : public bssl::RefCounted<ssl_ctx_st> {
829+
@@ -4300,6 +4344,10 @@ struct ssl_ctx_st : public bssl::RefCounted<ssl_ctx_st> {
798830
// accepted from the peer in decreasing order of preference.
799831
bssl::Array<uint16_t> verify_sigalgs;
800832

@@ -805,7 +837,7 @@ index 05af44f7b..f5bdd2441 100644
805837
// retain_only_sha256_of_client_certs is true if we should compute the SHA256
806838
// hash of the peer's certificate and then discard it to save memory and
807839
// session space. Only effective on the server side.
808-
@@ -4352,6 +4391,14 @@ struct ssl_ctx_st : public bssl::RefCounted<ssl_ctx_st> {
840+
@@ -4352,6 +4400,14 @@ struct ssl_ctx_st : public bssl::RefCounted<ssl_ctx_st> {
809841
// |aes_hw_override| is true.
810842
bool aes_hw_override_value : 1;
811843

@@ -1138,7 +1170,7 @@ index e60016c82..476dc3915 100644
11381170

11391171
} // namespace
11401172
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
1141-
index c859ea612..a2034bf0c 100644
1173+
index c859ea612..4bc42faf4 100644
11421174
--- a/ssl/ssl_lib.cc
11431175
+++ b/ssl/ssl_lib.cc
11441176
@@ -401,7 +401,8 @@ ssl_ctx_st::ssl_ctx_st(const SSL_METHOD *ssl_method)
@@ -1151,12 +1183,13 @@ index c859ea612..a2034bf0c 100644
11511183
CRYPTO_MUTEX_init(&lock);
11521184
CRYPTO_new_ex_data(&ex_data);
11531185
}
1154-
@@ -520,14 +521,18 @@ SSL *SSL_new(SSL_CTX *ctx) {
1186+
@@ -520,14 +521,19 @@ SSL *SSL_new(SSL_CTX *ctx) {
11551187
ssl->config->retain_only_sha256_of_client_certs =
11561188
ctx->retain_only_sha256_of_client_certs;
11571189
ssl->config->permute_extensions = ctx->permute_extensions;
11581190
+ ssl->config->extension_order = ctx->extension_order; // curl-impersonate
11591191
+ ssl->config->key_usage_check_enabled = ctx->key_usage_check_enabled; // curl-impersonate
1192+
+ ssl->config->use_firefox_tls13_ciphers = ctx->use_firefox_tls13_ciphers; // curl-impersonate
11601193
ssl->config->aes_hw_override = ctx->aes_hw_override;
11611194
ssl->config->aes_hw_override_value = ctx->aes_hw_override_value;
11621195
ssl->config->compliance_policy = ctx->compliance_policy;
@@ -1171,23 +1204,23 @@ index c859ea612..a2034bf0c 100644
11711204
return nullptr;
11721205
}
11731206

1174-
@@ -547,6 +552,7 @@ SSL *SSL_new(SSL_CTX *ctx) {
1207+
@@ -547,6 +553,7 @@ SSL *SSL_new(SSL_CTX *ctx) {
11751208
ssl->config->signed_cert_timestamps_enabled =
11761209
ctx->signed_cert_timestamps_enabled;
11771210
ssl->config->ocsp_stapling_enabled = ctx->ocsp_stapling_enabled;
11781211
+ ssl->config->record_size_limit = ctx->record_size_limit;
11791212
ssl->config->handoff = ctx->handoff;
11801213
ssl->quic_method = ctx->quic_method;
11811214

1182-
@@ -571,6 +577,7 @@ SSL_CONFIG::SSL_CONFIG(SSL *ssl_arg)
1215+
@@ -571,6 +578,7 @@ SSL_CONFIG::SSL_CONFIG(SSL *ssl_arg)
11831216
jdk11_workaround(false),
11841217
quic_use_legacy_codepoint(false),
11851218
permute_extensions(false),
11861219
+ key_shares_limit(0),
11871220
alps_use_new_codepoint(false) {
11881221
assert(ssl);
11891222
}
1190-
@@ -2068,6 +2075,28 @@ void SSL_enable_ocsp_stapling(SSL *ssl) {
1223+
@@ -2068,6 +2076,28 @@ void SSL_enable_ocsp_stapling(SSL *ssl) {
11911224
ssl->config->ocsp_stapling_enabled = true;
11921225
}
11931226

@@ -1216,7 +1249,7 @@ index c859ea612..a2034bf0c 100644
12161249
void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
12171250
size_t *out_len) {
12181251
SSL_SESSION *session = SSL_get_session(ssl);
1219-
@@ -2889,6 +2918,17 @@ void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled) {
1252+
@@ -2889,6 +2919,22 @@ void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled) {
12201253
ctx->permute_extensions = !!enabled;
12211254
}
12221255

@@ -1230,6 +1263,11 @@ index c859ea612..a2034bf0c 100644
12301263
+ ctx->key_usage_check_enabled = enabled;
12311264
+ return 0;
12321265
+}
1266+
+
1267+
+int SSL_CTX_set_use_firefox_tls13_ciphers(SSL_CTX *ctx, int enabled) {
1268+
+ ctx->use_firefox_tls13_ciphers = enabled;
1269+
+ return 0;
1270+
+}
12331271
+
12341272
void SSL_set_permute_extensions(SSL *ssl, int enabled) {
12351273
if (!ssl->config) {

0 commit comments

Comments
 (0)