Make redbean SSL more tunable

This change enables SSL compression. It significantly reduces the
network load of the testing infrastructure, for free, since this
revision didn't need to change any runit protocol code. However we
turn it off by default in redbean since no browsers support it.

It turns out that some TLSv1.0 clients (e.g. curl command on RHEL5) will
send an SSLv2-style ClientHello. These types of clients are usually ten+
years old and were designed to interop with servers ten years older than
them. Your redbean is now able to interop with these clients even though
redbean doesn't actually support SSLv2 or SSLv3. Please note that the -B
flag may be passed to disable this along with TLSv1.0, TLSv1.1, 3DES, &c

The following Lua APIs have been added to redbean:

  - ProgramSslCompression(bool)
  - ProgramSslCiphersuite(name:str)
  - ProgramSslPresharedKey(key:str,identity:str)

Lastly the DHE ciphersuites have been enabled. IANA recommends DHE and
with old clients like RHEL5 it's the only perfect forward secrecy they
implement.
This commit is contained in:
Justine Tunney 2021-08-09 07:00:23 -07:00
parent d86027fe90
commit 53b9f83e1c
15 changed files with 567 additions and 227 deletions

View file

@ -538,22 +538,6 @@
#endif
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
#if defined(MBEDTLS_DEPRECATED_REMOVED)
#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS"
#elif defined(MBEDTLS_DEPRECATED_WARNING)
#warning "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS"
#endif
#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
#if defined(MBEDTLS_DEPRECATED_REMOVED)
#error "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
#elif defined(MBEDTLS_DEPRECATED_WARNING)
#warning "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
#endif

View file

@ -16,7 +16,6 @@
/*#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL*/
/*#define MBEDTLS_SSL_PROTO_DTLS*/
/*#define MBEDTLS_SSL_PROTO_SSL3*/
/*#define MBEDTLS_ZLIB_SUPPORT*/
#endif
/* hash functions */
@ -74,8 +73,8 @@
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
/*#define MBEDTLS_DHM_C*/
/*#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED*/
#define MBEDTLS_DHM_C
#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
/*#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED*/
/*#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED*/
/*#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED*/
@ -110,14 +109,44 @@
#define MBEDTLS_ENTROPY_MAX_SOURCES 4
#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8
/* boosts performance from 230k qps to 330k */
#ifndef TINY
#ifndef __FSANITIZE_ADDRESS__
/*
* Boosts performance from 230k qps to 330k
* Hardens against against sbox side channels
*/
#define MBEDTLS_AESNI_C
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_X86_64
#define MBEDTLS_HAVE_SSE2
#define MBEDTLS_AESNI_C
#endif
#ifndef TINY
/*
* TODO(jart): RHEL5 sends SSLv2 hello even though it supports TLS. Is
* DROWN really a problem if we turn this on? Since Google
* supports it on their website. SSLLabs says we're OK.
*/
#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
#endif
#ifndef TINY
/*
* The CIA says "messages should be compressed prior to encryption"
* because "compression reduces the amount of information to be
* encrypted, thereby decreasing the amount of material available for
* cryptanalysis. Additionally, compression is designed to eliminate
* redundancies in the message, further complicating cryptanalysis."
*
* Google says that if you (1) have the ability to record encrypted
* communications made by a machine and (2) have the ability to run code
* on that machine which injects plaintext repeatedly into the encrypted
* messages, then you can extract other small parts of the mesasge which
* the code execution sandbox doesn't allow you to see, and that the
* only solution to stop using compression.
*
* Since we pay $0.12/gb for GCP bandwidth we choose to believe the CIA.
*/
#define MBEDTLS_ZLIB_SUPPORT
#endif
#if IsModeDbg()

View file

@ -34,7 +34,8 @@ THIRD_PARTY_MBEDTLS_A_DIRECTDEPS = \
LIBC_UNICODE \
NET_HTTP \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_GDTOA
THIRD_PARTY_GDTOA \
THIRD_PARTY_ZLIB
THIRD_PARTY_MBEDTLS_A_DEPS := \
$(call uniq,$(foreach x,$(THIRD_PARTY_MBEDTLS_A_DIRECTDEPS),$($(x))))

View file

@ -1075,6 +1075,7 @@ struct mbedtls_ssl_config
unsigned int dtls_srtp_mki_support : 1; /* support having mki_value
in the use_srtp extension */
#endif
bool disable_compression;
};
struct mbedtls_ssl_context
@ -1113,7 +1114,8 @@ struct mbedtls_ssl_context
mbedtls_ssl_session *session; /*!< negotiated session data */
mbedtls_ssl_session *session_negotiate; /*!< session data in negotiation */
mbedtls_ssl_handshake_params *handshake; /*!< params required only during
the handshake process */
the handshake process */
const mbedtls_ecp_curve_info *curve;
/*
* Record layer transformations
*/
@ -1442,7 +1444,7 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *, const unsigned c
int mbedtls_ssl_set_hostname( mbedtls_ssl_context *, const char * );
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *, const unsigned char *, size_t );
int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *, mbedtls_x509_crt *, mbedtls_pk_context * );
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *, const unsigned char *, size_t );
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *, const void *, size_t );
int mbedtls_ssl_set_session( mbedtls_ssl_context *, const mbedtls_ssl_session * );
int mbedtls_ssl_setup( mbedtls_ssl_context *, const mbedtls_ssl_config * );
int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types , const unsigned char *, size_t, const char *, const unsigned char *, size_t, unsigned char *, size_t );

View file

@ -42,17 +42,26 @@ asm(".include \"libc/disclaimer.inc\"");
*/
#if defined(MBEDTLS_SSL_TLS_C)
static const uint16_t ciphersuite_preference[] =
const uint16_t ciphersuite_preference[] =
{
#if defined(MBEDTLS_SSL_CIPHERSUITES)
MBEDTLS_SSL_CIPHERSUITES,
#else
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
/* strong perfect forward secrecy */
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
@ -61,21 +70,14 @@ static const uint16_t ciphersuite_preference[] =
MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256,
MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
@ -83,6 +85,18 @@ static const uint16_t ciphersuite_preference[] =
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
@ -111,8 +125,8 @@ static const uint16_t ciphersuite_preference[] =
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
@ -128,7 +142,7 @@ static const uint16_t ciphersuite_preference[] =
MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, // e.g. IE 8 XP
MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,

View file

@ -1170,7 +1170,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
*q++ = (unsigned char)( n << 1 );
#if defined(MBEDTLS_ZLIB_SUPPORT)
offer_compress = 1;
offer_compress = !ssl->conf->disable_compression;
#else
offer_compress = 0;
#endif
@ -2134,7 +2134,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
accept_comp = 0;
else
#endif
accept_comp = 1;
accept_comp = !ssl->conf->disable_compression;
if( comp != MBEDTLS_SSL_COMPRESS_NULL &&
( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) )

View file

@ -1861,12 +1861,15 @@ read_record_header:
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
#if defined(MBEDTLS_ZLIB_SUPPORT)
for( i = 0; i < comp_len; ++i )
if( !ssl->conf->disable_compression )
{
if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE )
for( i = 0; i < comp_len; ++i )
{
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE;
break;
if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE )
{
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE;
break;
}
}
}
#endif
@ -3364,6 +3367,7 @@ curve_matching_done:
return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
}
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
ssl->curve = *curve;
if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx,
(*curve)->grp_id ) ) != 0 )
{

View file

@ -3166,6 +3166,7 @@ void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
static int ssl_handshake_init( mbedtls_ssl_context *ssl )
{
/* Clear old handshake information if present */
ssl->curve = 0;
if( ssl->transform_negotiate )
mbedtls_ssl_transform_free( ssl->transform_negotiate );
if( ssl->session_negotiate )
@ -4468,7 +4469,7 @@ static void ssl_remove_psk( mbedtls_ssl_context *ssl )
* \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
*/
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
const unsigned char *psk, size_t psk_len )
const void *psk, size_t psk_len )
{
if( psk == NULL || ssl->handshake == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );