gh-96931: Fix incorrect results in ssl.SSLSocket.shared_ciphers (#96932)

This commit is contained in:
Benjamin Fogle 2023-03-22 10:08:41 -04:00 • committed by GitHub
parent ea93bde4ec
commit af9c34f6ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 12 deletions

View file

@ -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;
ciphers = SSL_get_ciphers(self->ssl);
if (!ciphers)
/* 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.
*/
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;
}