diff options
author | Benjamin Fogle <benfogle@gmail.com> | 2023-03-22 14:08:41 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-22 14:08:41 (GMT) |
commit | af9c34f6ef8dceb21871206eb3e4d350f6e3d3dc (patch) | |
tree | 8759d3d65c3e259381da95426e85899842064829 /Modules/_ssl.c | |
parent | ea93bde4ece139d4152a59f2c38aa6568559447c (diff) | |
download | cpython-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.c | 36 |
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; } |