diff options
author | Christian Heimes <christian@python.org> | 2021-05-01 18:53:10 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-01 18:53:10 (GMT) |
commit | e983252b516edb15d4338b0a47631b59ef1e2536 (patch) | |
tree | e57aad415654f5ce8646cf10fd293a5e8e1c0ad4 /Modules/_ssl.c | |
parent | 50c21ad35372983680b44130be560d856c5f27ca (diff) | |
download | cpython-e983252b516edb15d4338b0a47631b59ef1e2536.zip cpython-e983252b516edb15d4338b0a47631b59ef1e2536.tar.gz cpython-e983252b516edb15d4338b0a47631b59ef1e2536.tar.bz2 |
bpo-43998: Default to TLS 1.2 and increase cipher suite security (GH-25778)
The ssl module now has more secure default settings. Ciphers without forward
secrecy or SHA-1 MAC are disabled by default. Security level 2 prohibits
weak RSA, DH, and ECC keys with less than 112 bits of security.
:class:`~ssl.SSLContext` defaults to minimum protocol version TLS 1.2.
Settings are based on Hynek Schlawack's research.
```
$ openssl version
OpenSSL 1.1.1k FIPS 25 Mar 2021
$ openssl ciphers -v '@SECLEVEL=2:ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES:DHE+AES:!aNULL:!eNULL:!aDSS:!SHA1:!AESCCM'
TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD
TLS_AES_128_CCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESCCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256
DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256
```
Signed-off-by: Christian Heimes <christian@python.org>
Diffstat (limited to 'Modules/_ssl.c')
-rw-r--r-- | Modules/_ssl.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 65370c5..9163927 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -152,15 +152,27 @@ extern const SSL_METHOD *TLSv1_2_method(void); #ifndef PY_SSL_DEFAULT_CIPHER_STRING #error "Py_SSL_DEFAULT_CIPHERS 0 needs Py_SSL_DEFAULT_CIPHER_STRING" #endif + #ifndef PY_SSL_MIN_PROTOCOL + #define PY_SSL_MIN_PROTOCOL TLS1_2_VERSION + #endif #elif PY_SSL_DEFAULT_CIPHERS == 1 /* Python custom selection of sensible cipher suites - * DEFAULT: OpenSSL's default cipher list. Since 1.0.2 the list is in sensible order. + * @SECLEVEL=2: security level 2 with 112 bits minimum security (e.g. 2048 bits RSA key) + * ECDH+*: enable ephemeral elliptic curve Diffie-Hellman + * DHE+*: fallback to ephemeral finite field Diffie-Hellman + * encryption order: AES AEAD (GCM), ChaCha AEAD, AES CBC * !aNULL:!eNULL: really no NULL ciphers - * !MD5:!3DES:!DES:!RC4:!IDEA:!SEED: no weak or broken algorithms on old OpenSSL versions. * !aDSS: no authentication with discrete logarithm DSA algorithm - * !SRP:!PSK: no secure remote password or pre-shared key authentication + * !SHA1: no weak SHA1 MAC + * !AESCCM: no CCM mode, it's uncommon and slow + * + * Based on Hynek's excellent blog post (update 2021-02-11) + * https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ */ - #define PY_SSL_DEFAULT_CIPHER_STRING "DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK" + #define PY_SSL_DEFAULT_CIPHER_STRING "@SECLEVEL=2:ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES:DHE+AES:!aNULL:!eNULL:!aDSS:!SHA1:!AESCCM" + #ifndef PY_SSL_MIN_PROTOCOL + #define PY_SSL_MIN_PROTOCOL TLS1_2_VERSION + #endif #elif PY_SSL_DEFAULT_CIPHERS == 2 /* Ignored in SSLContext constructor, only used to as _ssl.DEFAULT_CIPHER_STRING */ #define PY_SSL_DEFAULT_CIPHER_STRING SSL_DEFAULT_CIPHER_LIST @@ -3095,8 +3107,25 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) ERR_clear_error(); PyErr_SetString(get_state_ctx(self)->PySSLErrorObject, "No cipher can be selected."); - return NULL; + goto error; } +#ifdef PY_SSL_MIN_PROTOCOL + switch(proto_version) { + case PY_SSL_VERSION_TLS: + case PY_SSL_VERSION_TLS_CLIENT: + case PY_SSL_VERSION_TLS_SERVER: + result = SSL_CTX_set_min_proto_version(ctx, PY_SSL_MIN_PROTOCOL); + if (result == 0) { + PyErr_Format(PyExc_ValueError, + "Failed to set minimum protocol 0x%x", + PY_SSL_MIN_PROTOCOL); + goto error; + } + break; + default: + break; + } +#endif /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory usage for no cost at all. */ @@ -3119,6 +3148,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) #endif return (PyObject *)self; + error: + Py_XDECREF(self); + ERR_clear_error(); + return NULL; } static int |