diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1422,6 +1422,13 @@ The protocol version chosen when constructing the context. This attribute is read-only. +.. attribute:: SSLContext.verify_depth + + The maximum depth for the certificate chain verification that shall be + allowed for context + + .. versionadded:: 3.5 + .. attribute:: SSLContext.verify_flags The flags for certificate verification operations. You can set flags like diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -815,6 +815,17 @@ with self.assertRaises(ValueError): ctx.verify_mode = 42 + def test_verify_depth(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + # Default value + self.assertEqual(ctx.verify_depth, -1) + ctx.verify_mode = 0 + self.assertEqual(ctx.verify_depth, 0) + + for depth in range(120): + ctx.verify_depth = depth + self.assertEqual(ctx.verify_depth, depth) + @unittest.skipUnless(have_verify_flags(), "verify_flags need OpenSSL > 0.9.8") def test_verify_flags(self): diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2550,6 +2550,35 @@ return 0; } + +static PyObject * +get_verify_depth(PySSLContext *self) +{ + int n; + n = SSL_CTX_get_verify_depth(self->ctx); + return PyLong_FromLong(n); +} + +static int +set_verify_depth(PySSLContext *self, PyObject *arg) +{ + int depth; + if (!PyArg_Parse(arg, "i", &depth)) + return -1; + + /* + SSL will happily take negative numbers -- throw an exception? + + if (depth < -10) { + PyErr_SetString(PyExc_ValueError, + "invalid value for verify_depth"); + return -1; + } + */ + SSL_CTX_set_verify_depth(self->ctx, depth); + return 0; +} + static PyObject * get_verify_flags(PySSLContext *self, void *c) { @@ -3509,6 +3538,8 @@ (setter) set_check_hostname, NULL}, {"options", (getter) get_options, (setter) set_options, NULL}, + {"verify_depth", (getter) get_verify_depth, + (setter) set_verify_depth, NULL}, {"verify_flags", (getter) get_verify_flags, (setter) set_verify_flags, NULL}, {"verify_mode", (getter) get_verify_mode,