diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 42fcd38cc7d3df..74b354845b2643 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -215,6 +215,25 @@ purposes. :data:`VERIFY_X509_STRICT` in its default verify flags. +Signature algorithms +^^^^^^^^^^^^^^^^^^^^ + +.. function:: get_sigalgs() + + Return a list of available TLS signature algorithm names used + by servers to complete the TLS handshake or clients requesting + certificate-based authentication. For example:: + + >>> ssl.get_sigalgs() # doctest: +SKIP + ['ecdsa_secp256r1_sha256', 'ecdsa_secp384r1_sha384', ...] + + These names can be used when building string values to pass to the + :meth:`SSLContext.set_client_sigalgs` and + :meth:`SSLContext.set_server_sigalgs` methods. + + .. versionadded:: next + + Exceptions ^^^^^^^^^^ @@ -1297,6 +1316,22 @@ SSL sockets also have the following additional methods and attributes: .. versionadded:: next +.. method:: SSLSocket.client_sigalg() + + Return the signature algorithm used for performing certificate-based client + authentication on this connection, or ``None`` if no connection has been + established or client authentication didn't occur. + + .. versionadded:: next + +.. method:: SSLSocket.server_sigalg() + + Return the signature algorithm used by the server to complete the TLS + handshake on this connection, or ``None`` if no connection has been + established or the cipher suite has no signature. + + .. versionadded:: next + .. method:: SSLSocket.compression() Return the compression algorithm being used as a string, or ``None`` @@ -1725,6 +1760,35 @@ to speed up repeated connections from the same clients. .. versionadded:: next +.. method:: SSLContext.set_client_sigalgs(sigalgs) + + Set the signature algorithms allowed for certificate-based client + authentication. It should be a string in the `OpenSSL client sigalgs + list format + `_. + + .. note:: + + When connected, the :meth:`SSLSocket.client_sigalg` method of SSL + sockets will return the signature algorithm used for performing + certificate-based client authentication on that connection. + + .. versionadded:: next + +.. method:: SSLContext.set_server_sigalgs(sigalgs) + + Set the signature algorithms allowed for the server to complete the TLS + handshake. It should be a string in the `OpenSSL sigalgs list format + `_. + + .. note:: + + When connected, the :meth:`SSLSocket.server_sigalg` method of SSL + sockets will return the signature algorithm used by the server to + complete the TLS handshake on that connection. + + .. versionadded:: next + .. method:: SSLContext.set_alpn_protocols(protocols) Specify which protocols the socket should advertise during the SSL/TLS @@ -2876,7 +2940,7 @@ of TLS/SSL. Some new TLS 1.3 features are not yet available. process certificate requests while they send or receive application data from the server. - TLS 1.3 features like early data, deferred TLS client cert request, - signature algorithm configuration, and rekeying are not supported yet. + and rekeying are not supported yet. .. seealso:: diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 24c19200e035fc..ea129d602b38cb 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -433,6 +433,23 @@ ssl connection is made. (Contributed by Ron Frederick in :gh:`137197`.) +* Added new methods for managing signature algorithms: + + * :func:`ssl.get_sigalgs` returns a list of all available TLS signature + algorithms. This call requires OpenSSL 3.4 or later. + * :meth:`ssl.SSLContext.set_client_sigalgs` sets the signature algorithms + allowed for certificate-based client authentication. + * :meth:`ssl.SSLContext.set_server_sigalgs` sets the signature algorithms + allowed for the server to complete the TLS handshake. + * :meth:`ssl.SSLSocket.client_sigalg` returns the signature algorithm + selected for client authentication on the current connection. This call + requires OpenSSL 3.5 or later. + * :meth:`ssl.SSLSocket.server_sigalg` returns the signature algorithm + selected for the server to complete the TLS handshake on the current + connection. This call requires OpenSSL 3.5 or later. + + (Contributed by Ron Frederick in :gh:`138252`.) + tarfile ------- diff --git a/Lib/ssl.py b/Lib/ssl.py index 5b8762bcdc25d1..493ea901d93324 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -13,6 +13,9 @@ Functions: + get_sigalgs -- return a list of all available TLS signature + algorithms (requires OpenSSL 3.4 or later) + cert_time_to_seconds -- convert time string used for certificate notBefore and notAfter functions to integer seconds past the Epoch (the time values @@ -112,6 +115,7 @@ except ImportError: # RAND_egd is not supported on some platforms pass +from _ssl import get_sigalgs from _ssl import ( @@ -935,6 +939,14 @@ def group(self): """Return the currently selected key agreement group name.""" return self._sslobj.group() + def client_sigalg(self): + """Return the selected client authentication signature algorithm.""" + return self._sslobj.client_sigalg() + + def server_sigalg(self): + """Return the selected server handshake signature algorithm.""" + return self._sslobj.server_sigalg() + def shared_ciphers(self): """Return a list of ciphers shared by the client during the handshake or None if this is not a valid server connection. @@ -1222,6 +1234,22 @@ def group(self): else: return self._sslobj.group() + @_sslcopydoc + def client_sigalg(self): + self._checkClosed() + if self._sslobj is None: + return None + else: + return self._sslobj.client_sigalg() + + @_sslcopydoc + def server_sigalg(self): + self._checkClosed() + if self._sslobj is None: + return None + else: + return self._sslobj.server_sigalg() + @_sslcopydoc def shared_ciphers(self): self._checkClosed() diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index b05c7bb059e76d..d6e06445d53179 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -51,6 +51,10 @@ CAN_GET_SELECTED_OPENSSL_GROUP = ssl.OPENSSL_VERSION_INFO >= (3, 2) CAN_IGNORE_UNKNOWN_OPENSSL_GROUPS = ssl.OPENSSL_VERSION_INFO >= (3, 3) CAN_GET_AVAILABLE_OPENSSL_GROUPS = ssl.OPENSSL_VERSION_INFO >= (3, 5) +CAN_GET_AVAILABLE_OPENSSL_SIGALGS = ssl.OPENSSL_VERSION_INFO >= (3, 4) +CAN_SET_CLIENT_SIGALGS = "AWS-LC" not in ssl.OPENSSL_VERSION +CAN_IGNORE_UNKNOWN_OPENSSL_SIGALGS = ssl.OPENSSL_VERSION_INFO >= (3, 3) +CAN_GET_SELECTED_OPENSSL_SIGALG = ssl.OPENSSL_VERSION_INFO >= (3, 5) PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') PROTOCOL_TO_TLS_VERSION = {} @@ -294,7 +298,8 @@ def test_wrap_socket(sock, *, USE_SAME_TEST_CONTEXT = False _TEST_CONTEXT = None -def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): +def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True, + client_cert=None): """Create context client_context, server_context, hostname = testing_context() @@ -321,6 +326,10 @@ def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): if server_chain: server_context.load_verify_locations(SIGNING_CA) + if client_cert: + client_context.load_cert_chain(client_cert) + server_context.verify_mode = ssl.CERT_REQUIRED + if USE_SAME_TEST_CONTEXT: if _TEST_CONTEXT is not None: _TEST_CONTEXT = client_context, server_context, hostname @@ -990,6 +999,37 @@ def test_get_groups(self): self.assertNotIn('P-256', ctx.get_groups()) self.assertIn('P-256', ctx.get_groups(include_aliases=True)) + @unittest.skipUnless(CAN_GET_AVAILABLE_OPENSSL_SIGALGS, + "SSL library doesn't support getting sigalgs") + def test_get_sigalgs(self): + self.assertIn('rsa_pss_rsae_sha256', ssl.get_sigalgs()) + + @unittest.skipUnless(CAN_SET_CLIENT_SIGALGS, + "SSL library doesn't support setting client sigalgs") + def test_set_client_sigalgs(self): + ctx = ssl.create_default_context() + + self.assertIsNone(ctx.set_client_sigalgs('rsa_pss_rsae_sha256')) + + self.assertRaises(ssl.SSLError, ctx.set_client_sigalgs, + 'rsa_pss_rsae_sha256:foo') + + # Ignoring unknown sigalgs is only supported since OpenSSL 3.3. + if CAN_IGNORE_UNKNOWN_OPENSSL_SIGALGS: + self.assertIsNone(ctx.set_client_sigalgs('rsa_pss_rsae_sha256:?foo')) + + def test_set_server_sigalgs(self): + ctx = ssl.create_default_context() + + self.assertIsNone(ctx.set_server_sigalgs('rsa_pss_rsae_sha256')) + + self.assertRaises(ssl.SSLError, ctx.set_server_sigalgs, + 'rsa_pss_rsae_sha256:foo') + + # Ignoring unknown sigalgs is only supported since OpenSSL 3.3. + if CAN_IGNORE_UNKNOWN_OPENSSL_SIGALGS: + self.assertIsNone(ctx.set_server_sigalgs('rsa_pss_rsae_sha256:?foo')) + def test_options(self): # Test default SSLContext options ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -2814,6 +2854,9 @@ def server_params_test(client_context, server_context, indata=b"FOO\n", }) if CAN_GET_SELECTED_OPENSSL_GROUP: stats.update({'group': s.group()}) + if CAN_GET_SELECTED_OPENSSL_SIGALG: + stats.update({'client_sigalg': s.client_sigalg()}) + stats.update({'server_sigalg': s.server_sigalg()}) s.close() stats['server_alpn_protocols'] = server.selected_alpn_protocols stats['server_shared_ciphers'] = server.shared_ciphers @@ -4273,6 +4316,71 @@ def test_groups(self): chatty=True, connectionchatty=True, sni_name=hostname) + @unittest.skipUnless(CAN_SET_CLIENT_SIGALGS, + "SSL library doesn't support setting client sigalgs") + def test_client_sigalgs(self): + # no mutual auth, so cient_sigalg should be None + client_context, server_context, hostname = testing_context() + stats = server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + if CAN_GET_SELECTED_OPENSSL_SIGALG: + self.assertIsNone(stats['client_sigalg']) + + # server auto, client rsa_pss_rsae_sha384 + sigalg = "rsa_pss_rsae_sha384" + client_context, server_context, hostname = \ + testing_context(client_cert=SIGNED_CERTFILE) + client_context.set_client_sigalgs(sigalg) + stats = server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + if CAN_GET_SELECTED_OPENSSL_SIGALG: + self.assertEqual(stats['client_sigalg'], sigalg) + + @unittest.skipUnless(CAN_SET_CLIENT_SIGALGS, + "SSL library doesn't support setting client sigalgs") + def test_client_sigalgs_mismatch(self): + client_context, server_context, hostname = \ + testing_context(client_cert=SIGNED_CERTFILE) + client_context.set_client_sigalgs("rsa_pss_rsae_sha256") + server_context.set_client_sigalgs("rsa_pss_rsae_sha384") + + # Some systems return ConnectionResetError on handshake failures + with self.assertRaises((ssl.SSLError, ConnectionResetError)): + server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + + def test_server_sigalgs(self): + # server rsa_pss_rsae_sha384, client auto + sigalg = "rsa_pss_rsae_sha384" + client_context, server_context, hostname = testing_context() + server_context.set_server_sigalgs(sigalg) + stats = server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + if CAN_GET_SELECTED_OPENSSL_SIGALG: + self.assertEqual(stats['server_sigalg'], sigalg) + + # server auto, client rsa_pss_rsae_sha384 + client_context, server_context, hostname = testing_context() + client_context.set_server_sigalgs(sigalg) + stats = server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + if CAN_GET_SELECTED_OPENSSL_SIGALG: + self.assertEqual(stats['server_sigalg'], sigalg) + + def test_server_sigalgs_mismatch(self): + client_context, server_context, hostname = testing_context() + client_context.set_server_sigalgs("rsa_pss_rsae_sha256") + server_context.set_server_sigalgs("rsa_pss_rsae_sha384") + with self.assertRaises(ssl.SSLError): + server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + def test_selected_alpn_protocol(self): # selected_alpn_protocol() is None unless ALPN is used. client_context, server_context, hostname = testing_context() diff --git a/Misc/NEWS.d/next/Library/2025-08-30-17-58-04.gh-issue-138252.CDiEby.rst b/Misc/NEWS.d/next/Library/2025-08-30-17-58-04.gh-issue-138252.CDiEby.rst new file mode 100644 index 00000000000000..95420cea2993d9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-08-30-17-58-04.gh-issue-138252.CDiEby.rst @@ -0,0 +1,4 @@ +:mod:`ssl`: :class:`~ssl.SSLContext` objects can now set client and server +TLS signature algorithms. If Python has been built with OpenSSL 3.5 or later, +:class:`~ssl.SSLSocket` objects can return the signature algorithms selected +on a connection. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 2388bbb3bae631..d95d227491d873 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2200,6 +2200,56 @@ _ssl__SSLSocket_group_impl(PySSLSocket *self) #endif } +static PyObject * +ssl_socket_signame_impl(PySSLSocket *socket, + enum py_ssl_server_or_client self_socket_type) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30500000L + int ret; + const char *sigalg; + + if (socket->ssl == NULL) { + Py_RETURN_NONE; + } + ret = (socket->socket_type == self_socket_type) + ? SSL_get0_signature_name(socket->ssl, &sigalg) + : SSL_get0_peer_signature_name(socket->ssl, &sigalg); + if (ret == 0) { + Py_RETURN_NONE; + } + assert(sigalg != NULL); + return PyUnicode_DecodeFSDefault(sigalg); +#else + PyErr_SetString(PyExc_NotImplementedError, + "Getting sig algorithms requires OpenSSL 3.5 or later."); + return NULL; +#endif +} + +/*[clinic input] +@critical_section +_ssl._SSLSocket.client_sigalg +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_client_sigalg_impl(PySSLSocket *self) +/*[clinic end generated code: output=499dd7fbf021a47b input=a0d9696b5414c627]*/ +{ + return ssl_socket_signame_impl(self, PY_SSL_CLIENT); +} + +/*[clinic input] +@critical_section +_ssl._SSLSocket.server_sigalg +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_server_sigalg_impl(PySSLSocket *self) +/*[clinic end generated code: output=c508a766a8e275dc input=9063e562a1e6b946]*/ +{ + return ssl_socket_signame_impl(self, PY_SSL_SERVER); +} + /*[clinic input] @critical_section _ssl._SSLSocket.version @@ -3276,6 +3326,8 @@ static PyMethodDef PySSLMethods[] = { _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF _SSL__SSLSOCKET_CIPHER_METHODDEF _SSL__SSLSOCKET_GROUP_METHODDEF + _SSL__SSLSOCKET_CLIENT_SIGALG_METHODDEF + _SSL__SSLSOCKET_SERVER_SIGALG_METHODDEF _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF _SSL__SSLSOCKET_VERSION_METHODDEF _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF @@ -3727,7 +3779,6 @@ _ssl__SSLContext_get_groups_impl(PySSLContext *self, int include_aliases) num = sk_OPENSSL_CSTRING_num(groups); result = PyList_New(num); if (result == NULL) { - _setSSLError(get_state_ctx(self), "Can't allocate list", 0, __FILE__, __LINE__); goto error; } @@ -3739,9 +3790,7 @@ _ssl__SSLContext_get_groups_impl(PySSLContext *self, int include_aliases) // Group names are plain ASCII, so there's no chance of a decoding // error here. However, an allocation failure could occur when // constructing the Unicode version of the names. - item = PyUnicode_DecodeASCII(group, strlen(group), "strict"); - if (item == NULL) { - _setSSLError(get_state_ctx(self), "Can't allocate group name", 0, __FILE__, __LINE__); + if ((item = PyUnicode_DecodeFSDefault(group)) == NULL) { goto error; } @@ -3761,6 +3810,49 @@ _ssl__SSLContext_get_groups_impl(PySSLContext *self, int include_aliases) #endif } +/*[clinic input] +@critical_section +_ssl._SSLContext.set_client_sigalgs + sigalgslist: str + / +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_set_client_sigalgs_impl(PySSLContext *self, + const char *sigalgslist) +/*[clinic end generated code: output=f4f5be160a29c7d6 input=500d853ce9fd94ff]*/ +{ +#ifdef OPENSSL_IS_AWSLC + _setSSLError(get_state_ctx(self), "can't set client sigalgs on AWS-LC", 0, __FILE__, __LINE__); + return NULL; +#else + if (!SSL_CTX_set1_client_sigalgs_list(self->ctx, sigalgslist)) { + _setSSLError(get_state_ctx(self), "unrecognized signature algorithm", 0, __FILE__, __LINE__); + return NULL; + } + Py_RETURN_NONE; +#endif +} + +/*[clinic input] +@critical_section +_ssl._SSLContext.set_server_sigalgs + sigalgslist: str + / +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_set_server_sigalgs_impl(PySSLContext *self, + const char *sigalgslist) +/*[clinic end generated code: output=31ecb1d310285644 input=653b752e4f8d801b]*/ +{ + if (!SSL_CTX_set1_sigalgs_list(self->ctx, sigalgslist)) { + _setSSLError(get_state_ctx(self), "unrecognized signature algorithm", 0, __FILE__, __LINE__); + return NULL; + } + Py_RETURN_NONE; +} + static int do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, const unsigned char *server_protocols, unsigned int server_protocols_len, @@ -5616,6 +5708,8 @@ static struct PyMethodDef context_methods[] = { _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF _SSL__SSLCONTEXT_SET_CIPHERSUITES_METHODDEF _SSL__SSLCONTEXT_SET_GROUPS_METHODDEF + _SSL__SSLCONTEXT_SET_CLIENT_SIGALGS_METHODDEF + _SSL__SSLCONTEXT_SET_SERVER_SIGALGS_METHODDEF _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF @@ -6241,6 +6335,39 @@ _ssl_get_default_verify_paths_impl(PyObject *module) return NULL; } +/*[clinic input] +_ssl.get_sigalgs +[clinic start generated code]*/ + +static PyObject * +_ssl_get_sigalgs_impl(PyObject *module) +/*[clinic end generated code: output=ab0791b63856854b input=d96dd6cefec3f86b]*/ +{ +#if OPENSSL_VERSION_NUMBER >= 0x30400000L + const char *sigalgs; + PyObject *sigalgs_str, *sigalgs_list; + + if ((sigalgs = SSL_get1_builtin_sigalgs(NULL)) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + if ((sigalgs_str = PyUnicode_DecodeFSDefault(sigalgs)) == NULL) { + OPENSSL_free((void *)sigalgs); + return NULL; + } + + OPENSSL_free((void *)sigalgs); + sigalgs_list = PyUnicode_Split(sigalgs_str, _Py_LATIN1_CHR(':'), -1); + Py_DECREF(sigalgs_str); + return sigalgs_list; +#else + PyErr_SetString(PyExc_NotImplementedError, + "Getting signature algorithms requires OpenSSL 3.4 or later."); + return NULL; +#endif +} + static PyObject* asn1obj2py(_sslmodulestate *state, ASN1_OBJECT *obj) { @@ -6644,6 +6771,7 @@ static PyMethodDef PySSL_methods[] = { _SSL_RAND_BYTES_METHODDEF _SSL_RAND_STATUS_METHODDEF _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF + _SSL_GET_SIGALGS_METHODDEF _SSL_ENUM_CERTIFICATES_METHODDEF _SSL_ENUM_CRLS_METHODDEF _SSL_TXT2OBJ_METHODDEF diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index e8b51c1f1e326d..0e8e4a7c8a73c7 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -219,6 +219,52 @@ _ssl__SSLSocket_group(PyObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } +PyDoc_STRVAR(_ssl__SSLSocket_client_sigalg__doc__, +"client_sigalg($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_CLIENT_SIGALG_METHODDEF \ + {"client_sigalg", (PyCFunction)_ssl__SSLSocket_client_sigalg, METH_NOARGS, _ssl__SSLSocket_client_sigalg__doc__}, + +static PyObject * +_ssl__SSLSocket_client_sigalg_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_client_sigalg(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_client_sigalg_impl((PySSLSocket *)self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_server_sigalg__doc__, +"server_sigalg($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_SERVER_SIGALG_METHODDEF \ + {"server_sigalg", (PyCFunction)_ssl__SSLSocket_server_sigalg, METH_NOARGS, _ssl__SSLSocket_server_sigalg__doc__}, + +static PyObject * +_ssl__SSLSocket_server_sigalg_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_server_sigalg(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_server_sigalg_impl((PySSLSocket *)self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLSocket_version__doc__, "version($self, /)\n" "--\n" @@ -1136,6 +1182,84 @@ _ssl__SSLContext_get_groups(PyObject *self, PyObject *const *args, Py_ssize_t na return return_value; } +PyDoc_STRVAR(_ssl__SSLContext_set_client_sigalgs__doc__, +"set_client_sigalgs($self, sigalgslist, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_CLIENT_SIGALGS_METHODDEF \ + {"set_client_sigalgs", (PyCFunction)_ssl__SSLContext_set_client_sigalgs, METH_O, _ssl__SSLContext_set_client_sigalgs__doc__}, + +static PyObject * +_ssl__SSLContext_set_client_sigalgs_impl(PySSLContext *self, + const char *sigalgslist); + +static PyObject * +_ssl__SSLContext_set_client_sigalgs(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *sigalgslist; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("set_client_sigalgs", "argument", "str", arg); + goto exit; + } + Py_ssize_t sigalgslist_length; + sigalgslist = PyUnicode_AsUTF8AndSize(arg, &sigalgslist_length); + if (sigalgslist == NULL) { + goto exit; + } + if (strlen(sigalgslist) != (size_t)sigalgslist_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_set_client_sigalgs_impl((PySSLContext *)self, sigalgslist); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_set_server_sigalgs__doc__, +"set_server_sigalgs($self, sigalgslist, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_SERVER_SIGALGS_METHODDEF \ + {"set_server_sigalgs", (PyCFunction)_ssl__SSLContext_set_server_sigalgs, METH_O, _ssl__SSLContext_set_server_sigalgs__doc__}, + +static PyObject * +_ssl__SSLContext_set_server_sigalgs_impl(PySSLContext *self, + const char *sigalgslist); + +static PyObject * +_ssl__SSLContext_set_server_sigalgs(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *sigalgslist; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("set_server_sigalgs", "argument", "str", arg); + goto exit; + } + Py_ssize_t sigalgslist_length; + sigalgslist = PyUnicode_AsUTF8AndSize(arg, &sigalgslist_length); + if (sigalgslist == NULL) { + goto exit; + } + if (strlen(sigalgslist) != (size_t)sigalgslist_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_set_server_sigalgs_impl((PySSLContext *)self, sigalgslist); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, "_set_alpn_protocols($self, protos, /)\n" "--\n" @@ -2892,6 +3016,23 @@ _ssl_get_default_verify_paths(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } +PyDoc_STRVAR(_ssl_get_sigalgs__doc__, +"get_sigalgs($module, /)\n" +"--\n" +"\n"); + +#define _SSL_GET_SIGALGS_METHODDEF \ + {"get_sigalgs", (PyCFunction)_ssl_get_sigalgs, METH_NOARGS, _ssl_get_sigalgs__doc__}, + +static PyObject * +_ssl_get_sigalgs_impl(PyObject *module); + +static PyObject * +_ssl_get_sigalgs(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _ssl_get_sigalgs_impl(module); +} + PyDoc_STRVAR(_ssl_txt2obj__doc__, "txt2obj($module, /, txt, name=False)\n" "--\n" @@ -3181,4 +3322,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=4e35d2ea2fc46023 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a630a1e83927d47 input=a9049054013a1b77]*/