mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Issue #27866: Add SSLContext.get_ciphers() method to get a list of all enabled ciphers.
This commit is contained in:
parent
dffa3949c7
commit
25bfcd5d9e
5 changed files with 211 additions and 1 deletions
117
Modules/_ssl.c
117
Modules/_ssl.c
|
@ -1519,6 +1519,76 @@ cipher_to_tuple(const SSL_CIPHER *cipher)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000UL
|
||||
static PyObject *
|
||||
cipher_to_dict(const SSL_CIPHER *cipher)
|
||||
{
|
||||
const char *cipher_name, *cipher_protocol;
|
||||
|
||||
unsigned long cipher_id;
|
||||
int alg_bits, strength_bits, len;
|
||||
char buf[512] = {0};
|
||||
#if OPENSSL_VERSION_1_1
|
||||
int aead, nid;
|
||||
const char *skcipher = NULL, *digest = NULL, *kx = NULL, *auth = NULL;
|
||||
#endif
|
||||
PyObject *retval;
|
||||
|
||||
retval = PyDict_New();
|
||||
if (retval == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* can be NULL */
|
||||
cipher_name = SSL_CIPHER_get_name(cipher);
|
||||
cipher_protocol = SSL_CIPHER_get_version(cipher);
|
||||
cipher_id = SSL_CIPHER_get_id(cipher);
|
||||
SSL_CIPHER_description(cipher, buf, sizeof(buf) - 1);
|
||||
len = strlen(buf);
|
||||
if (len > 1 && buf[len-1] == '\n')
|
||||
buf[len-1] = '\0';
|
||||
strength_bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
|
||||
|
||||
#if OPENSSL_VERSION_1_1
|
||||
aead = SSL_CIPHER_is_aead(cipher);
|
||||
nid = SSL_CIPHER_get_cipher_nid(cipher);
|
||||
skcipher = nid != NID_undef ? OBJ_nid2ln(nid) : NULL;
|
||||
nid = SSL_CIPHER_get_digest_nid(cipher);
|
||||
digest = nid != NID_undef ? OBJ_nid2ln(nid) : NULL;
|
||||
nid = SSL_CIPHER_get_kx_nid(cipher);
|
||||
kx = nid != NID_undef ? OBJ_nid2ln(nid) : NULL;
|
||||
nid = SSL_CIPHER_get_auth_nid(cipher);
|
||||
auth = nid != NID_undef ? OBJ_nid2ln(nid) : NULL;
|
||||
#endif
|
||||
|
||||
retval = Py_BuildValue(
|
||||
"{sksssssssisi"
|
||||
#if OPENSSL_VERSION_1_1
|
||||
"sOssssssss"
|
||||
#endif
|
||||
"}",
|
||||
"id", cipher_id,
|
||||
"name", cipher_name,
|
||||
"protocol", cipher_protocol,
|
||||
"description", buf,
|
||||
"strength_bits", strength_bits,
|
||||
"alg_bits", alg_bits
|
||||
#if OPENSSL_VERSION_1_1
|
||||
,"aead", aead ? Py_True : Py_False,
|
||||
"symmetric", skcipher,
|
||||
"digest", digest,
|
||||
"kea", kx,
|
||||
"auth", auth
|
||||
#endif
|
||||
);
|
||||
return retval;
|
||||
|
||||
error:
|
||||
Py_XDECREF(retval);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*[clinic input]
|
||||
_ssl._SSLSocket.shared_ciphers
|
||||
[clinic start generated code]*/
|
||||
|
@ -2478,6 +2548,52 @@ _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000UL
|
||||
/*[clinic input]
|
||||
_ssl._SSLContext.get_ciphers
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_ssl__SSLContext_get_ciphers_impl(PySSLContext *self)
|
||||
/*[clinic end generated code: output=a56e4d68a406dfc4 input=a2aadc9af89b79c5]*/
|
||||
{
|
||||
SSL *ssl = NULL;
|
||||
STACK_OF(SSL_CIPHER) *sk = NULL;
|
||||
SSL_CIPHER *cipher;
|
||||
int i=0;
|
||||
PyObject *result = NULL, *dct;
|
||||
|
||||
ssl = SSL_new(self->ctx);
|
||||
if (ssl == NULL) {
|
||||
_setSSLError(NULL, 0, __FILE__, __LINE__);
|
||||
goto exit;
|
||||
}
|
||||
sk = SSL_get_ciphers(ssl);
|
||||
|
||||
result = PyList_New(sk_SSL_CIPHER_num(sk));
|
||||
if (result == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
|
||||
cipher = sk_SSL_CIPHER_value(sk, i);
|
||||
dct = cipher_to_dict(cipher);
|
||||
if (dct == NULL) {
|
||||
Py_CLEAR(result);
|
||||
goto exit;
|
||||
}
|
||||
PyList_SET_ITEM(result, i, dct);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (ssl != NULL)
|
||||
SSL_free(ssl);
|
||||
return result;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OPENSSL_NPN_NEGOTIATED
|
||||
static int
|
||||
do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen,
|
||||
|
@ -3645,6 +3761,7 @@ static struct PyMethodDef context_methods[] = {
|
|||
_SSL__SSLCONTEXT_SET_SERVERNAME_CALLBACK_METHODDEF
|
||||
_SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF
|
||||
_SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF
|
||||
_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -378,6 +378,27 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL)
|
||||
|
||||
PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__,
|
||||
"get_ciphers($self, /)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF \
|
||||
{"get_ciphers", (PyCFunction)_ssl__SSLContext_get_ciphers, METH_NOARGS, _ssl__SSLContext_get_ciphers__doc__},
|
||||
|
||||
static PyObject *
|
||||
_ssl__SSLContext_get_ciphers_impl(PySSLContext *self);
|
||||
|
||||
static PyObject *
|
||||
_ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return _ssl__SSLContext_get_ciphers_impl(self);
|
||||
}
|
||||
|
||||
#endif /* (OPENSSL_VERSION_NUMBER >= 0x10002000UL) */
|
||||
|
||||
PyDoc_STRVAR(_ssl__SSLContext__set_npn_protocols__doc__,
|
||||
"_set_npn_protocols($self, protos, /)\n"
|
||||
"--\n"
|
||||
|
@ -1128,6 +1149,10 @@ exit:
|
|||
#define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF
|
||||
#endif /* !defined(_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF) */
|
||||
|
||||
#ifndef _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF
|
||||
#define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF
|
||||
#endif /* !defined(_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF) */
|
||||
|
||||
#ifndef _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF
|
||||
#define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF
|
||||
#endif /* !defined(_SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF) */
|
||||
|
@ -1143,4 +1168,4 @@ exit:
|
|||
#ifndef _SSL_ENUM_CRLS_METHODDEF
|
||||
#define _SSL_ENUM_CRLS_METHODDEF
|
||||
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
|
||||
/*[clinic end generated code: output=6057f95343369849 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=2e7907a7d8f97ccf input=a9049054013a1b77]*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue