From 585605d6633fad52a9eb730d3c469b3168afc6cb Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Sat, 26 Jun 2021 01:03:14 -0700 Subject: [PATCH 1/9] Expose a few more OpenSSL functions that are useful for DTLS support --- src/_cffi_src/openssl/ssl.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 081ef041fa33..a256ce2b30fe 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -90,6 +90,7 @@ static const long SSL_OP_SINGLE_ECDH_USE; static const long SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; static const long SSL_OP_LEGACY_SERVER_CONNECT; +static const long SSL_OP_NO_RENEGOTIATION; static const long SSL_VERIFY_PEER; static const long SSL_VERIFY_FAIL_IF_NO_PEER_CERT; static const long SSL_VERIFY_CLIENT_ONCE; @@ -225,6 +226,13 @@ unsigned char *, unsigned int * )); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *, + int (*)( + SSL *, + unsigned char *, + unsigned int + )); + long SSL_CTX_get_read_ahead(SSL_CTX *); long SSL_CTX_set_read_ahead(SSL_CTX *, long); @@ -468,6 +476,13 @@ long DTLSv1_handle_timeout(SSL *); long DTLS_set_link_mtu(SSL *, long); long DTLS_get_link_min_mtu(SSL *); +size_t DTLS_get_data_mtu(SSL *); +long SSL_set_mtu(SSL *, long); +typedef ... BIO_ADDR; +BIO_ADDR *BIO_ADDR_new(void); +void BIO_ADDR_free(BIO_ADDR *); +int DTLSv1_listen(SSL *, BIO_ADDR *); + /* Custom extensions. */ typedef int (*custom_ext_add_cb)(SSL *, unsigned int, From c7f3d4d594c4f9281887b87ab9ade565f237e412 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Sat, 26 Jun 2021 08:24:20 -0700 Subject: [PATCH 2/9] Move BIO_ADDR gunk to proper place --- src/_cffi_src/openssl/bio.py | 4 ++++ src/_cffi_src/openssl/ssl.py | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/_cffi_src/openssl/bio.py b/src/_cffi_src/openssl/bio.py index 9310c1beb0f9..2ea05706a6b0 100644 --- a/src/_cffi_src/openssl/bio.py +++ b/src/_cffi_src/openssl/bio.py @@ -10,6 +10,7 @@ TYPES = """ typedef ... BIO; typedef ... BIO_METHOD; +typedef ... BIO_ADDR; """ FUNCTIONS = """ @@ -37,6 +38,9 @@ int BIO_reset(BIO *); void BIO_set_retry_read(BIO *); void BIO_clear_retry_flags(BIO *); + +BIO_ADDR *BIO_ADDR_new(void); +void BIO_ADDR_free(BIO_ADDR *); """ CUSTOMIZATIONS = """ diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index a256ce2b30fe..b92b3d3e52ff 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -478,9 +478,6 @@ long DTLS_get_link_min_mtu(SSL *); size_t DTLS_get_data_mtu(SSL *); long SSL_set_mtu(SSL *, long); -typedef ... BIO_ADDR; -BIO_ADDR *BIO_ADDR_new(void); -void BIO_ADDR_free(BIO_ADDR *); int DTLSv1_listen(SSL *, BIO_ADDR *); From 60fd092378f9b76365f6d41f9a6ec0db4316e7b3 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Sun, 27 Jun 2021 03:35:10 -0700 Subject: [PATCH 3/9] const correct --- src/_cffi_src/openssl/ssl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index b92b3d3e52ff..d9ddcd597302 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -223,13 +223,13 @@ void SSL_CTX_set_cookie_generate_cb(SSL_CTX *, int (*)( SSL *, - unsigned char *, + const unsigned char *, unsigned int * )); void SSL_CTX_set_cookie_verify_cb(SSL_CTX *, int (*)( SSL *, - unsigned char *, + const unsigned char *, unsigned int )); From 8278a690b608baeec2a7da8305e4940fccb2b55a Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Sun, 27 Jun 2021 04:40:14 -0700 Subject: [PATCH 4/9] Throw more #ifdefs at the wall and see if they stick --- src/_cffi_src/openssl/bio.py | 6 ++++-- src/_cffi_src/openssl/ssl.py | 13 ++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/_cffi_src/openssl/bio.py b/src/_cffi_src/openssl/bio.py index 2ea05706a6b0..912b015e1ce2 100644 --- a/src/_cffi_src/openssl/bio.py +++ b/src/_cffi_src/openssl/bio.py @@ -39,9 +39,11 @@ void BIO_set_retry_read(BIO *); void BIO_clear_retry_flags(BIO *); -BIO_ADDR *BIO_ADDR_new(void); -void BIO_ADDR_free(BIO_ADDR *); """ CUSTOMIZATIONS = """ +#if !CRYPTOGRAPHY_IS_LIBRESSL +BIO_ADDR *BIO_ADDR_new(void); +void BIO_ADDR_free(BIO_ADDR *); +#endif """ diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index d9ddcd597302..c535d0cc9ace 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -90,7 +90,6 @@ static const long SSL_OP_SINGLE_ECDH_USE; static const long SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; static const long SSL_OP_LEGACY_SERVER_CONNECT; -static const long SSL_OP_NO_RENEGOTIATION; static const long SSL_VERIFY_PEER; static const long SSL_VERIFY_FAIL_IF_NO_PEER_CERT; static const long SSL_VERIFY_CLIENT_ONCE; @@ -223,7 +222,7 @@ void SSL_CTX_set_cookie_generate_cb(SSL_CTX *, int (*)( SSL *, - const unsigned char *, + unsigned char *, unsigned int * )); void SSL_CTX_set_cookie_verify_cb(SSL_CTX *, @@ -476,7 +475,6 @@ long DTLSv1_handle_timeout(SSL *); long DTLS_set_link_mtu(SSL *, long); long DTLS_get_link_min_mtu(SSL *); -size_t DTLS_get_data_mtu(SSL *); long SSL_set_mtu(SSL *, long); int DTLSv1_listen(SSL *, BIO_ADDR *); @@ -722,4 +720,13 @@ #else static const long Cryptography_HAS_GET_PROTO_VERSION = 1; #endif + +#if !CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 +size_t DTLS_get_data_mtu(SSL *); +static const long SSL_OP_NO_RENEGOTIATION; +#endif + +#if !CRYPTOGRAPHY_IS_LIBRESSL +int DTLSv1_listen(SSL *, BIO_ADDR *); +#endif """ From e9197643d6fc6e2b39dfcfca9ee903dc5fdb184a Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Sun, 27 Jun 2021 18:29:55 -0700 Subject: [PATCH 5/9] njsmith used "think about what he's doing" it's probably not very effective --- src/_cffi_src/openssl/bio.py | 17 ++++++++++++++--- src/_cffi_src/openssl/ssl.py | 22 +++++++++++++--------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/_cffi_src/openssl/bio.py b/src/_cffi_src/openssl/bio.py index 912b015e1ce2..43e76e9236c1 100644 --- a/src/_cffi_src/openssl/bio.py +++ b/src/_cffi_src/openssl/bio.py @@ -39,11 +39,22 @@ void BIO_set_retry_read(BIO *); void BIO_clear_retry_flags(BIO *); +BIO_ADDR *BIO_ADDR_new(void); +void BIO_ADDR_free(BIO_ADDR *); """ CUSTOMIZATIONS = """ -#if !CRYPTOGRAPHY_IS_LIBRESSL -BIO_ADDR *BIO_ADDR_new(void); -void BIO_ADDR_free(BIO_ADDR *); +#if CRYPTOGRAPHY_IS_LIBRESSL +#include +#include +typedef struct sockaddr BIO_ADDR; + +BIO_ADDR *BIO_ADDR_new(void) { + return malloc(sizeof(sockaddr_storage)); +} + +void BIO_ADDR_free(BIO_ADDR *ptr) { + free(ptr); +} #endif """ diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index c535d0cc9ace..e6da41d0d518 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -35,6 +35,7 @@ * supported */ static const long Cryptography_HAS_OP_NO_COMPRESSION; +static const long Cryptography_HAS_OP_NO_RENEGOTIATION; static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING; static const long Cryptography_HAS_SSL_SET_SSL_CTX; static const long Cryptography_HAS_SSL_OP_NO_TICKET; @@ -64,6 +65,7 @@ static const long SSL_OP_NO_TLSv1_3; static const long SSL_OP_NO_DTLSv1; static const long SSL_OP_NO_DTLSv1_2; +static const long SSL_OP_NO_RENEGOTIATION; static const long SSL_OP_NO_COMPRESSION; static const long SSL_OP_SINGLE_DH_USE; static const long SSL_OP_EPHEMERAL_RSA; @@ -477,6 +479,7 @@ long DTLS_get_link_min_mtu(SSL *); long SSL_set_mtu(SSL *, long); int DTLSv1_listen(SSL *, BIO_ADDR *); +size_t DTLS_get_data_mtu(SSL *); /* Custom extensions. */ @@ -566,6 +569,12 @@ static const long Cryptography_HAS_NEXTPROTONEG = 0; static const long Cryptography_HAS_ALPN = 1; +#ifdef SSL_OP_NO_RENEGOTIATION +static const long Cryptography_HAS_OP_NO_RENEGOTIATION = 1; +#else +static const long Cryptography_HAS_OP_NO_RENEGOTIATION = 0; +#endif + #if CRYPTOGRAPHY_IS_LIBRESSL void (*SSL_CTX_set_cert_cb)(SSL_CTX *, int (*)(SSL *, void *), void *) = NULL; void (*SSL_set_cert_cb)(SSL *, int (*)(SSL *, void *), void *) = NULL; @@ -604,6 +613,10 @@ long (*DTLS_get_link_min_mtu)(SSL *) = NULL; #endif +#if CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 +size_t (*DTLS_get_data_mtu)(SSL *) = NULL; +#endif + static const long Cryptography_HAS_DTLS = 1; /* Wrap DTLSv1_get_timeout to avoid cffi to handle a 'struct timeval'. */ long Cryptography_DTLSv1_get_timeout(SSL *ssl, time_t *ptv_sec, @@ -720,13 +733,4 @@ #else static const long Cryptography_HAS_GET_PROTO_VERSION = 1; #endif - -#if !CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 -size_t DTLS_get_data_mtu(SSL *); -static const long SSL_OP_NO_RENEGOTIATION; -#endif - -#if !CRYPTOGRAPHY_IS_LIBRESSL -int DTLSv1_listen(SSL *, BIO_ADDR *); -#endif """ From 1028b7d87e0120233e83d0b92bcef39c59ec1719 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Mon, 28 Jun 2021 01:58:21 -0700 Subject: [PATCH 6/9] LibreSSL is not my favorite library --- src/_cffi_src/openssl/bio.py | 2 +- src/_cffi_src/openssl/ssl.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_cffi_src/openssl/bio.py b/src/_cffi_src/openssl/bio.py index 43e76e9236c1..248a01e50e60 100644 --- a/src/_cffi_src/openssl/bio.py +++ b/src/_cffi_src/openssl/bio.py @@ -50,7 +50,7 @@ typedef struct sockaddr BIO_ADDR; BIO_ADDR *BIO_ADDR_new(void) { - return malloc(sizeof(sockaddr_storage)); + return malloc(sizeof(struct sockaddr_storage)); } void BIO_ADDR_free(BIO_ADDR *ptr) { diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index e6da41d0d518..1e6c7cd88f24 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -573,6 +573,7 @@ static const long Cryptography_HAS_OP_NO_RENEGOTIATION = 1; #else static const long Cryptography_HAS_OP_NO_RENEGOTIATION = 0; +static const long SSL_OP_NO_RENEGOTIATION = 0; #endif #if CRYPTOGRAPHY_IS_LIBRESSL From ad45530c3bd1bba3b768d11ef83e58430daa5d1a Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Mon, 28 Jun 2021 07:04:17 -0700 Subject: [PATCH 7/9] Attempt to hide my new undefined symbols --- .../hazmat/bindings/openssl/_conditional.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index ba01169f1e10..d61eace1a53a 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -244,6 +244,18 @@ def cryptography_has_providers(): ] +def cryptography_has_op_no_renegotiation(): + return [ + "SSL_OP_NO_RENEGOTIATION", + ] + + +def DTLS_get_data_mtu(): + return [ + "DTLS_get_data_mtu", + ] + + # This is a mapping of # {condition: function-returning-names-dependent-on-that-condition} so we can # loop over them and delete unsupported names at runtime. It will be removed @@ -291,4 +303,6 @@ def cryptography_has_providers(): "Cryptography_HAS_SRTP": cryptography_has_srtp, "Cryptography_HAS_GET_PROTO_VERSION": cryptography_has_get_proto_version, "Cryptography_HAS_PROVIDERS": cryptography_has_providers, + "Cryptography_HAS_OP_NO_RENEGOTIATION": cryptography_has_op_no_renegotiation, + "DTLS_get_data_mtu": DTLS_get_data_mtu, } From ae8ed2d5e39b5d9e69da41ac2018c01fe2f62bd1 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Wed, 30 Jun 2021 06:20:29 -0700 Subject: [PATCH 8/9] deflake --- src/cryptography/hazmat/bindings/openssl/_conditional.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index d61eace1a53a..27158a20f96a 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -250,7 +250,7 @@ def cryptography_has_op_no_renegotiation(): ] -def DTLS_get_data_mtu(): +def dtls_get_data_mtu(): return [ "DTLS_get_data_mtu", ] @@ -303,6 +303,8 @@ def DTLS_get_data_mtu(): "Cryptography_HAS_SRTP": cryptography_has_srtp, "Cryptography_HAS_GET_PROTO_VERSION": cryptography_has_get_proto_version, "Cryptography_HAS_PROVIDERS": cryptography_has_providers, - "Cryptography_HAS_OP_NO_RENEGOTIATION": cryptography_has_op_no_renegotiation, - "DTLS_get_data_mtu": DTLS_get_data_mtu, + "Cryptography_HAS_OP_NO_RENEGOTIATION": ( + cryptography_has_op_no_renegotiation + ), + "DTLS_get_data_mtu": dtls_get_data_mtu, } From 1a31c426eaf6e2778e3cee3de1f6deee1d187ea3 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Wed, 30 Jun 2021 10:19:11 -0700 Subject: [PATCH 9/9] Give up on trying to check function pointers for NULLness AFAICT it works fine in CFFI's ABI mode, but I can't figure out how to do it in the API mode. --- src/_cffi_src/openssl/ssl.py | 4 ++++ src/cryptography/hazmat/bindings/openssl/_conditional.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 1e6c7cd88f24..34d0283894f3 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -44,6 +44,7 @@ static const long Cryptography_HAS_SET_CERT_CB; static const long Cryptography_HAS_CUSTOM_EXT; static const long Cryptography_HAS_SRTP; +static const long Cryptography_HAS_DTLS_GET_DATA_MTU; static const long SSL_FILETYPE_PEM; static const long SSL_FILETYPE_ASN1; @@ -615,7 +616,10 @@ #endif #if CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 +static const long Cryptography_HAS_DTLS_GET_DATA_MTU = 0; size_t (*DTLS_get_data_mtu)(SSL *) = NULL; +#else +static const long Cryptography_HAS_DTLS_GET_DATA_MTU = 1; #endif static const long Cryptography_HAS_DTLS = 1; diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 27158a20f96a..191306b6a3f5 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -250,7 +250,7 @@ def cryptography_has_op_no_renegotiation(): ] -def dtls_get_data_mtu(): +def cryptography_has_dtls_get_data_mtu(): return [ "DTLS_get_data_mtu", ] @@ -306,5 +306,5 @@ def dtls_get_data_mtu(): "Cryptography_HAS_OP_NO_RENEGOTIATION": ( cryptography_has_op_no_renegotiation ), - "DTLS_get_data_mtu": dtls_get_data_mtu, + "Cryptography_HAS_DTLS_GET_DATA_MTU": cryptography_has_dtls_get_data_mtu, }