summaryrefslogtreecommitdiffstats
path: root/Modules/_ssl.c
diff options
context:
space:
mode:
authorBenjamin Fogle <benfogle@gmail.com>2023-03-22 14:08:41 (GMT)
committerGitHub <noreply@github.com>2023-03-22 14:08:41 (GMT)
commitaf9c34f6ef8dceb21871206eb3e4d350f6e3d3dc (patch)
tree8759d3d65c3e259381da95426e85899842064829 /Modules/_ssl.c
parentea93bde4ece139d4152a59f2c38aa6568559447c (diff)
downloadcpython-af9c34f6ef8dceb21871206eb3e4d350f6e3d3dc.zip
cpython-af9c34f6ef8dceb21871206eb3e4d350f6e3d3dc.tar.gz
cpython-af9c34f6ef8dceb21871206eb3e4d350f6e3d3dc.tar.bz2
gh-96931: Fix incorrect results in ssl.SSLSocket.shared_ciphers (#96932)
Diffstat (limited to 'Modules/_ssl.c')
-rw-r--r--Modules/_ssl.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 321b6ec..36b66cd 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -1998,24 +1998,44 @@ static PyObject *
_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self)
/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/
{
- STACK_OF(SSL_CIPHER) *ciphers;
- int i;
+ STACK_OF(SSL_CIPHER) *server_ciphers;
+ STACK_OF(SSL_CIPHER) *client_ciphers;
+ int i, len;
PyObject *res;
+ const SSL_CIPHER* cipher;
+
+ /* Rather than use SSL_get_shared_ciphers, we use an equivalent algorithm because:
+
+ 1) It returns a colon seperated list of strings, in an undefined
+ order, that we would have to post process back into tuples.
+ 2) It will return a truncated string with no indication that it has
+ done so, if the buffer is too small.
+ */
- ciphers = SSL_get_ciphers(self->ssl);
- if (!ciphers)
+ server_ciphers = SSL_get_ciphers(self->ssl);
+ if (!server_ciphers)
Py_RETURN_NONE;
- res = PyList_New(sk_SSL_CIPHER_num(ciphers));
+ client_ciphers = SSL_get_client_ciphers(self->ssl);
+ if (!client_ciphers)
+ Py_RETURN_NONE;
+
+ res = PyList_New(sk_SSL_CIPHER_num(server_ciphers));
if (!res)
return NULL;
- for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
- PyObject *tup = cipher_to_tuple(sk_SSL_CIPHER_value(ciphers, i));
+ len = 0;
+ for (i = 0; i < sk_SSL_CIPHER_num(server_ciphers); i++) {
+ cipher = sk_SSL_CIPHER_value(server_ciphers, i);
+ if (sk_SSL_CIPHER_find(client_ciphers, cipher) < 0)
+ continue;
+
+ PyObject *tup = cipher_to_tuple(cipher);
if (!tup) {
Py_DECREF(res);
return NULL;
}
- PyList_SET_ITEM(res, i, tup);
+ PyList_SET_ITEM(res, len++, tup);
}
+ Py_SET_SIZE(res, len);
return res;
}