From 346e8afee2fcb778599b6c56bba39639d3a91453 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Tue, 19 Aug 2025 14:37:19 +0200 Subject: [PATCH] Add client hello callback related functions This exposes the OpenSSL functions SSL_CTX_set_client_hello_cb, SSL_client_hello_get0_ext and SSL_client_hello_get1_extensions_present. These are required to implement to the client hello callback functionality in pyOpenSSL. Signed-off-by: Arne Schwabe --- src/_cffi_src/openssl/ssl.py | 30 +++++++++++++++++++ .../hazmat/bindings/openssl/_conditional.py | 9 ++++++ 2 files changed, 39 insertions(+) diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 2a4aa5e794ce..515bfda3fc1d 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -31,6 +31,7 @@ static const long Cryptography_HAS_SRTP; static const long Cryptography_HAS_DTLS_GET_DATA_MTU; static const long Cryptography_HAS_SSL_GET0_GROUP_NAME; +static const long Cryptography_HAS_CLIENT_HELLO_CB; static const long SSL_FILETYPE_PEM; static const long SSL_FILETYPE_ASN1; @@ -391,6 +392,18 @@ int DTLSv1_listen(SSL *, BIO_ADDR *); size_t DTLS_get_data_mtu(SSL *); +/* Client hello callback support */ +void SSL_CTX_set_client_hello_cb( + SSL_CTX *, + int (*)(SSL *, int *, void *), + void *); +int SSL_client_hello_get1_extensions_present( + SSL *, int **, + size_t *); +int SSL_client_hello_get0_ext( + SSL *, unsigned int, + const unsigned char **, + size_t *); /* Custom extensions. */ typedef int (*custom_ext_add_cb)(SSL *, unsigned int, @@ -685,4 +698,21 @@ static const long Cryptography_HAS_SSL_GET0_GROUP_NAME = 0; const char *(*SSL_get0_group_name)(SSL *) = NULL; #endif + +#if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_IS_BORINGSSL +static const long Cryptography_HAS_CLIENT_HELLO_CB = 0; +void (*SSL_CTX_set_client_hello_cb)( + SSL_CTX *, + int (*)(SSL *, int *, void *), + void *) = NULL; +int (*SSL_client_hello_get1_extensions_present)( + SSL *, int **, + size_t *) = NULL; +int (*SSL_client_hello_get0_ext)( + SSL *s, unsigned int, + const unsigned char **, + size_t *) = NULL; +#else +static const long Cryptography_HAS_CLIENT_HELLO_CB = 1; +#endif """ diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py index 063bcf5bfcc9..558631e390d6 100644 --- a/src/cryptography/hazmat/bindings/openssl/_conditional.py +++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py @@ -165,6 +165,14 @@ def cryptography_has_ssl_get0_group_name() -> list[str]: return ["SSL_get0_group_name"] +def cryptography_has_client_hello_cb() -> list[str]: + return [ + "SSL_CTX_set_client_hello_cb", + "SSL_client_hello_get1_extensions_present", + "SSL_client_hello_get0_ext", + ] + + # 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 @@ -204,4 +212,5 @@ def cryptography_has_ssl_get0_group_name() -> list[str]: "Cryptography_HAS_SSL_GET0_GROUP_NAME": ( cryptography_has_ssl_get0_group_name ), + "Cryptography_HAS_CLIENT_HELLO_CB": cryptography_has_client_hello_cb, }