Skip to content

Commit 8e836bb

Browse files
bpo-41195: Add getter for Openssl security level (GH-21282)
Add an accessor under SSLContext.security_level as a wrapper around SSL_CTX_get_security_level, see: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_security_level.html ------ This is my first time contributing, so please pull me up on all the things I missed or did incorrectly. Automerge-Triggered-By: @tiran
1 parent 38d3864 commit 8e836bb

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

Doc/library/ssl.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,16 @@ to speed up repeated connections from the same clients.
20322032

20332033
.. versionadded:: 3.7
20342034

2035+
.. attribute:: SSLContext.security_level
2036+
2037+
An integer representing the `security level
2038+
<https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_security_level.html>`_
2039+
for the context. This attribute is read-only.
2040+
2041+
.. availability:: OpenSSL 1.1.0 or newer
2042+
2043+
.. versionadded:: 3.10
2044+
20352045
.. attribute:: SSLContext.verify_flags
20362046

20372047
The flags for certificate verification operations. You can set flags like

Lib/test/test_ssl.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,25 @@ def test_min_max_version(self):
12701270
ctx.maximum_version = ssl.TLSVersion.TLSv1
12711271

12721272

1273+
@unittest.skipUnless(
1274+
hasattr(ssl.SSLContext, 'security_level'),
1275+
"requires OpenSSL >= 1.1.0"
1276+
)
1277+
def test_security_level(self):
1278+
ctx = ssl.SSLContext()
1279+
# The default security callback allows for levels between 0-5
1280+
# with OpenSSL defaulting to 1, however some vendors override the
1281+
# default value (e.g. Debian defaults to 2)
1282+
security_level_range = {
1283+
0,
1284+
1, # OpenSSL default
1285+
2, # Debian
1286+
3,
1287+
4,
1288+
5,
1289+
}
1290+
self.assertIn(ctx.security_level, security_level_range)
1291+
12731292
@unittest.skipUnless(have_verify_flags(),
12741293
"verify_flags need OpenSSL > 0.9.8")
12751294
def test_verify_flags(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add read-only ssl.SSLContext.security_level attribute to retrieve the
2+
context's security level.

Modules/_ssl.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3746,6 +3746,15 @@ PyDoc_STRVAR(PySSLContext_num_tickets_doc,
37463746
"Control the number of TLSv1.3 session tickets");
37473747
#endif /* OpenSSL 1.1.1 */
37483748

3749+
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
3750+
static PyObject *
3751+
get_security_level(PySSLContext *self, void *c)
3752+
{
3753+
return PyLong_FromLong(SSL_CTX_get_security_level(self->ctx));
3754+
}
3755+
PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level");
3756+
#endif /* OpenSSL 1.1.0 */
3757+
37493758
static PyObject *
37503759
get_options(PySSLContext *self, void *c)
37513760
{
@@ -4793,6 +4802,10 @@ static PyGetSetDef context_getsetlist[] = {
47934802
(setter) set_verify_flags, NULL},
47944803
{"verify_mode", (getter) get_verify_mode,
47954804
(setter) set_verify_mode, NULL},
4805+
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
4806+
{"security_level", (getter) get_security_level,
4807+
NULL, PySSLContext_security_level_doc},
4808+
#endif
47964809
{NULL}, /* sentinel */
47974810
};
47984811

0 commit comments

Comments
 (0)