From 6640b727ebd2b65a94239ba4ed1d2bda38d7d2ce Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Wed, 27 Mar 2024 16:32:52 -0700 Subject: [PATCH] Use the new BoringSSL ERR_ symbol APIs. Python needs to map OpenSSL error codes like ERR_R_INTERNAL_ERROR into strings like "INTERNAL_ERROR". OpenSSL lacks an API for this, so CPython instead maintains its own table. This table is necessarily sensitive to the OpenSSL version and causes issues for BoringSSL. Rather than maintain our own copy of this table, BoringSSL has APIs to do the thing CPython actually wants. This patch switches CPython to use them. To keep the patch small, it doesn't ifdef the err_codes_to_names, etc., fields, but they are no longer necessary. See https://github.com/openssl/openssl/issues/19848 and https://discuss.python.org/t/error-tables-in-the-ssl-module/25431 for context. BoringSSL API addition: https://boringssl.googlesource.com/boringssl/+/dbad745811195c00b729efd0ee0a09b7d9fce1d2 --- Modules/_ssl.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 39c4f8bbc5c8a1..e953471ce712d1 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -479,10 +479,30 @@ fill_and_set_sslerror(_sslmodulestate *state, { PyObject *err_value = NULL, *reason_obj = NULL, *lib_obj = NULL; PyObject *verify_obj = NULL, *verify_code_obj = NULL; - PyObject *init_value, *msg, *key; + PyObject *init_value, *msg; if (errcode != 0) { +#if defined(OPENSSL_IS_BORINGSSL) + const char *lib_str, *reason_str; + + lib_str = ERR_lib_symbol_name(errcode); + if (lib_str != NULL) { + lib_obj = PyUnicode_FromString(lib_str); + if (lib_obj == NULL) { + goto fail; + } + } + + reason_str = ERR_reason_symbol_name(errcode); + if (reason_str != NULL) { + reason_obj = PyUnicode_FromString(reason_str); + if (reason_obj == NULL) { + goto fail; + } + } +#else int lib, reason; + PyObject *key; lib = ERR_GET_LIB(errcode); reason = ERR_GET_REASON(errcode); @@ -502,6 +522,7 @@ fill_and_set_sslerror(_sslmodulestate *state, if (lib_obj == NULL && PyErr_Occurred()) { goto fail; } +#endif /* OPENSSL_IS_BORINGSSL */ if (errstr == NULL) errstr = ERR_reason_error_string(errcode); } @@ -6291,6 +6312,11 @@ sslmodule_init_constants(PyObject *m) static int sslmodule_init_errorcodes(PyObject *module) { +#if defined(OPENSSL_IS_BORINGSSL) + /* BoringSSL does not use error tables and instead provides the necessary + API directly. */ + return 0; +#else _sslmodulestate *state = get_ssl_state(module); struct py_ssl_error_code *errcode; @@ -6339,6 +6365,7 @@ sslmodule_init_errorcodes(PyObject *module) } return 0; +#endif /* OPENSSL_IS_BORINGSSL */ } static void