mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
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:
parent
919c7e806e
commit
6401823db3
7 changed files with 497 additions and 7 deletions
|
|
@ -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::
|
||||
|
|
|
|||
|
|
@ -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
|
||||
-------
|
||||
|
|
|
|||
28
Lib/ssl.py
28
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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
136
Modules/_ssl.c
136
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
|
||||
|
|
@ -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
143
Modules/clinic/_ssl.c.h
generated
|
|
@ -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]*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue