gh-138252: Add support in SSL module for getting and setting TLS signature algorithms (#138269)

The signature algorithms allowed for certificate-based client authentication or
for the server to complete the TLS handshake can be defined on a SSL context via
`ctx.set_client_sigalgs()` and `ctx.set_server_sigalgs()`.

With OpenSSL 3.4 or later, the list of available TLS algorithms can be retrieved
by `ssl.get_sigalgs()`.

With OpenSSL 3.5 or later, the selected signature algorithms can be retrieved from
SSL sockets via `socket.client_sigalg()` and `socket.server_sigalg()`.

This commit also partially amends 377b787618
by using `PyUnicode_DecodeFSDefault` instead of `PyUnicode_DecodeASCII` in
`_ssl._SSLContext.get_groups`, so that functions consistently decode strings
obtained from OpenSSL.

---------

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Ron Frederick 2025-09-08 01:36:12 -07:00 committed by GitHub
parent 919c7e806e
commit 6401823db3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 497 additions and 7 deletions

View file

@ -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
<https://docs.openssl.org/master/man3/SSL_CTX_set1_client_sigalgs_list/>`_.
.. 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
<https://docs.openssl.org/master/man3/SSL_CTX_set1_sigalgs_list/>`_.
.. 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::

View file

@ -442,6 +442,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
-------

View file

@ -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()

View file

@ -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()

View file

@ -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.

View file

@ -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
@ -6234,6 +6328,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)
{
@ -6637,6 +6764,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

143
Modules/clinic/_ssl.c.h generated
View file

@ -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 @@ exit:
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 @@ exit:
#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]*/