diff --git a/Lib/ssl.py b/Lib/ssl.py index 8f6d402209b15f..53cf63c2152cdf 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -149,6 +149,11 @@ lambda name: name.startswith('CERT_'), source=_ssl) +_IntEnum._convert_( + 'KeyUpdateTypes', __name__, + lambda name: name.startswith('KEY_UPDATE_'), + source=_ssl) + PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS _PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()} @@ -780,6 +785,23 @@ def version(self): def verify_client_post_handshake(self): return self._sslobj.verify_client_post_handshake() + def key_update(self, updatetype): + self._sslobj.key_update(updatetype) + + @property + def key_update_type(self): + return KeyUpdateTypes(self._sslobj.get_key_update_type()) + + def renegotiate(self, abbreviated=False): + if abbreviated: + self._sslobj.renegotiate_abbreviated() + else: + self._sslobj.renegotiate() + + @property + def renegotiate_pending(self): + return self._sslobj.renegotiate_pending() + class SSLSocket(socket): """This class implements a subtype of socket.socket that wraps @@ -1090,18 +1112,14 @@ def shutdown(self, how): super().shutdown(how) def unwrap(self): - if self._sslobj: - s = self._sslobj.shutdown() - self._sslobj = None - return s - else: - raise ValueError("No SSL wrapper around " + str(self)) + self._ensure_wrapper() + s = self._sslobj.shutdown() + self._sslobj = None + return s def verify_client_post_handshake(self): - if self._sslobj: - return self._sslobj.verify_client_post_handshake() - else: - raise ValueError("No SSL wrapper around " + str(self)) + self._ensure_wrapper() + return self._sslobj.verify_client_post_handshake() def _real_close(self): self._sslobj = None @@ -1190,6 +1208,76 @@ def version(self): else: return None + def _ensure_wrapper(self): + if not self._sslobj: + raise ValueError("No SSL wrapper around " + str(self)) + + def key_update(self, updatetype): + self._ensure_wrapper() + self._sslobj.key_update(updatetype) + + @property + def key_update_type(self): + self._ensure_wrapper() + return KeyUpdateTypes(self._sslobj.get_key_update_type()) + + def renegotiate(self, abbreviated=False): + self._ensure_wrapper() + if abbreviated: + self._sslobj.renegotiate_abbreviated() + else: + self._sslobj.renegotiate() + + @property + def renegotiate_pending(self): + self._ensure_wrapper() + return self._sslobj.renegotiate_pending() + + +for name, docstr in ( + ('key_update', """\ +Schedule an update of the keys for the current TLS connection. + +If the updatetype parameter is set to KEY_UPDATE_NOT_REQUESTED then the +sending keys for this connection will be updated and the peer will be +informed of the change. If the updatetype parameter is set to +KEY_UPDATE_REQUESTED then the sending keys for this connection will be +updated and the peer will be informed of the change along with a +request for the peer to additionally update its sending keys. It is an +error if updatetype is set to KEY_UPDATE_NONE. + +key_update() must only be called after the initial handshake has been +completed and TLSv1.3 has been negotiated. The key update will not take +place until the next time an IO operation such as read() or write() +takes place on the connection. Alternatively do_handshake() can be +called to force the update to take place immediately. + +Raises NotImplementedError if the TLS implementation doesn't support +TLS 1.3.) + +:param updatetype: KeyUpdateTypes +"""), + ('key_update_type', """\ +Determine whether a key update operation has been scheduled but +not yet performed. + +The type of the pending key update operation will be returned if there +is one, or KEY_UPDATE_NONE otherwise. + +Raises NotImplementedError if the TLS implementation doesn't support +TLS 1.3. +"""), + ('renegotiate', """\ +Start the SSL/TLS renegotiation, requires TLS <= 1.2."""), + ('renegotiate_pending', """\ +Return True if a renegotiation or renegotiation request has been +scheduled but not yet acted on, or False otherwise."""), +): + for cls in (SSLObject, SSLSocket): + getattr(cls, name).__doc__ = docstr + +del name, docstr, cls + # Python does not support forward declaration of types. SSLContext.sslsocket_class = SSLSocket diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 6fd2002e5eec86..66f4e276056844 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -1645,6 +1645,39 @@ def test_bad_server_hostname(self): ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO(), server_hostname="example.org\x00evil.com") + @unittest.skipUnless(ssl.HAS_TLSv1_3, + "test requires TLSv1.3 enabled OpenSSL") + def test_invalid_key_update_type_and_still_in_init(self): + b1 = ssl.MemoryBIO() + b2 = ssl.MemoryBIO() + ctx = ssl.SSLContext() + ctx.load_cert_chain(SIGNED_CERTFILE) + server = ctx.wrap_bio(b1, b2, server_side=True) + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) + ctx.options |= ( + ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2 + ) + sslobj = ctx.wrap_bio(b2, b1, server_side=False) + + handshaking = True + while handshaking: + try: + sslobj.do_handshake() + handshaking = False + except ssl.SSLWantReadError: + handshaking = True + + try: + server.do_handshake() + except ssl.SSLWantReadError: + handshaking = True + + with self.assertRaisesRegex(ssl.SSLError, 'invalid key update type'): + sslobj.key_update(ssl.KEY_UPDATE_NONE) + sslobj.key_update(ssl.KEY_UPDATE_REQUESTED) + with self.assertRaisesRegex(ssl.SSLError, 'still in init'): + sslobj.key_update(ssl.KEY_UPDATE_REQUESTED) + class MemoryBIOTests(unittest.TestCase): @@ -2076,6 +2109,91 @@ def test_bio_read_write_data(self): self.assertEqual(buf, b'foo\n') self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) + def test_bio_renegotiation(self): + sock = socket.socket(socket.AF_INET) + self.addCleanup(sock.close) + sock.connect(self.server_addr) + incoming = ssl.MemoryBIO() + outgoing = ssl.MemoryBIO() + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) + ctx.verify_mode = ssl.CERT_NONE + ctx.options |= ssl.OP_NO_TLSv1_3 + sslobj = ctx.wrap_bio(incoming, outgoing, False) + self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) + + self.assertEqual(outgoing.pending, 0) + sslobj.renegotiate() + self.assertEqual(outgoing.pending, 0) + self.assertTrue(sslobj.renegotiate_pending) + req = b'FOO\n' + self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req) + self.assertFalse(sslobj.renegotiate_pending) + buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024) + self.assertEqual(buf, b'foo\n') + + self.assertEqual(outgoing.pending, 0) + sslobj.renegotiate(abbreviated=True) + self.assertEqual(outgoing.pending, 0) + self.assertTrue(sslobj.renegotiate_pending) + req = b'BAR\n' + self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req) + self.assertFalse(sslobj.renegotiate_pending) + buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024) + self.assertEqual(buf, b'bar\n') + + if IS_OPENSSL_1_1_1 and ssl.HAS_TLSv1_3: + with self.assertRaises(ssl.SSLError, + msg='wrong ssl version'): + sslobj.key_update(ssl.KEY_UPDATE_NOT_REQUESTED) + with self.assertRaises(ssl.SSLError, + msg='wrong ssl version'): + sslobj.key_update(ssl.KEY_UPDATE_REQUESTED) + + self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) + + @unittest.skipUnless(ssl.HAS_TLSv1_3, + "test requires TLSv1.3 enabled OpenSSL") + def test_bio_key_update(self): + sock = socket.socket(socket.AF_INET) + self.addCleanup(sock.close) + sock.connect(self.server_addr) + incoming = ssl.MemoryBIO() + outgoing = ssl.MemoryBIO() + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) + ctx.verify_mode = ssl.CERT_NONE + ctx.options |= ( + ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2 + ) + sslobj = ctx.wrap_bio(incoming, outgoing, False) + self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) + + self.assertEqual(outgoing.pending, 0) + sslobj.key_update(ssl.KEY_UPDATE_REQUESTED) + self.assertEqual(outgoing.pending, 0) + self.assertEqual(sslobj.key_update_type, ssl.KEY_UPDATE_REQUESTED) + req = b'FOO\n' + self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req) + self.assertEqual(sslobj.key_update_type, ssl.KEY_UPDATE_NONE) + buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024) + self.assertEqual(buf, b'foo\n') + + self.assertEqual(outgoing.pending, 0) + sslobj.key_update(ssl.KEY_UPDATE_NOT_REQUESTED) + self.assertEqual(outgoing.pending, 0) + self.assertEqual(sslobj.key_update_type, ssl.KEY_UPDATE_NOT_REQUESTED) + req = b'BAR\n' + self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req) + self.assertEqual(sslobj.key_update_type, ssl.KEY_UPDATE_NONE) + buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024) + self.assertEqual(buf, b'bar\n') + + with self.assertRaises(ssl.SSLError, msg='wrong ssl version'): + sslobj.renegotiate() + with self.assertRaises(ssl.SSLError, msg='wrong ssl version'): + sslobj.renegotiate(abbreviated=True) + + self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) + class NetworkedTests(unittest.TestCase): @@ -4164,6 +4282,78 @@ def test_session_handling(self): self.assertEqual(str(e.exception), 'Session refers to a different SSLContext.') + def test_renegotiation(self): + context = ssl.SSLContext(ssl.PROTOCOL_TLS) + context.load_cert_chain(CERTFILE) + context.options |= ssl.OP_NO_TLSv1_3 + with ThreadedEchoServer(context=context) as server: + with context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + self.assertFalse(s.renegotiate_pending) + s.renegotiate() + self.assertTrue(s.renegotiate_pending) + s.send(b'HELLO') + self.assertEqual(s.recv(1024), b'hello') + self.assertFalse(s.renegotiate_pending) + s.send(b'WORLD') + self.assertEqual(s.recv(1024), b'world') + + self.assertFalse(s.renegotiate_pending) + s.renegotiate(abbreviated=True) + self.assertTrue(s.renegotiate_pending) + s.send(b'HELLO') + self.assertEqual(s.recv(1024), b'hello') + self.assertFalse(s.renegotiate_pending) + s.send(b'WORLD') + self.assertEqual(s.recv(1024), b'world') + + if IS_OPENSSL_1_1_1 and ssl.HAS_TLSv1_3: + with self.assertRaises(ssl.SSLError, + msg='wrong ssl version'): + s.key_update(ssl.KEY_UPDATE_NOT_REQUESTED) + with self.assertRaises(ssl.SSLError, + msg='wrong ssl version'): + s.key_update(ssl.KEY_UPDATE_REQUESTED) + + @unittest.skipUnless(ssl.HAS_TLSv1_3, + "test requires TLSv1.3 enabled OpenSSL") + def test_key_update(self): + context = ssl.SSLContext(ssl.PROTOCOL_TLS) + context.load_cert_chain(CERTFILE) + context.options |= ( + ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2 + ) + with ThreadedEchoServer(context=context) as server: + with context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + self.assertEqual(s.version(), 'TLSv1.3') + + self.assertEqual(s.key_update_type, ssl.KEY_UPDATE_NONE) + s.key_update(ssl.KEY_UPDATE_NOT_REQUESTED) + self.assertEqual(s.key_update_type, + ssl.KEY_UPDATE_NOT_REQUESTED) + s.send(b'HELLO') + self.assertEqual(s.key_update_type, ssl.KEY_UPDATE_NONE) + self.assertEqual(s.recv(1024), b'hello') + self.assertEqual(s.key_update_type, ssl.KEY_UPDATE_NONE) + s.send(b'WORLD') + self.assertEqual(s.recv(1024), b'world') + + self.assertEqual(s.key_update_type, ssl.KEY_UPDATE_NONE) + s.key_update(ssl.KEY_UPDATE_REQUESTED) + self.assertEqual(s.key_update_type, ssl.KEY_UPDATE_REQUESTED) + s.send(b'HELLO') + self.assertEqual(s.key_update_type, ssl.KEY_UPDATE_NONE) + self.assertEqual(s.recv(1024), b'hello') + self.assertEqual(s.key_update_type, ssl.KEY_UPDATE_NONE) + s.send(b'WORLD') + self.assertEqual(s.recv(1024), b'world') + + with self.assertRaises(ssl.SSLError, msg='wrong ssl version'): + s.renegotiate() + with self.assertRaises(ssl.SSLError, msg='wrong ssl version'): + s.renegotiate(abbreviated=True) + @unittest.skipUnless(ssl.HAS_TLSv1_3, "Test needs TLS 1.3") class TestPostHandshakeAuth(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2018-08-09-16-32-47.bpo-33062.2ka0De.rst b/Misc/NEWS.d/next/Library/2018-08-09-16-32-47.bpo-33062.2ka0De.rst new file mode 100644 index 00000000000000..cc62ef7f30022d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-08-09-16-32-47.bpo-33062.2ka0De.rst @@ -0,0 +1 @@ +Added ``renegotiate()`` and ``key_update()`` in :mod:`ssl`. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 93498f475609d0..249c9e6272f23b 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1056,6 +1056,131 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) return NULL; } +/*[clinic input] +_ssl._SSLSocket.key_update + updatetype: int + / + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_key_update_impl(PySSLSocket *self, int updatetype) +/*[clinic end generated code: output=2eb3fb43e045bb4f input=338af2b9ff3d49eb]*/ +{ +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) + int ret; + _PySSLError err; + + PySSL_BEGIN_ALLOW_THREADS + ret = SSL_key_update(self->ssl, updatetype); + err = _PySSL_errno(ret == 0, self->ssl, ret); + PySSL_END_ALLOW_THREADS + self->err = err; + + if (PyErr_CheckSignals()) { + return NULL; + } + + if (ret == 0) { + return PySSL_SetError(self, ret, __FILE__, __LINE__); + } + + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "Updating connection keys is not supported by your " + "OpenSSL version."); + return NULL; +#endif +} + +/*[clinic input] +_ssl._SSLSocket.get_key_update_type +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_get_key_update_type_impl(PySSLSocket *self) +/*[clinic end generated code: output=7b6f5d4028511dd5 input=bebae60fb1855a42]*/ +{ +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) + return PyLong_FromLong(SSL_get_key_update_type(self->ssl)); +#else + PyErr_SetString(PyExc_NotImplementedError, + "Updating connection keys is not supported by your " + "OpenSSL version."); + return NULL; +#endif +} + +/*[clinic input] +_ssl._SSLSocket.renegotiate +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_renegotiate_impl(PySSLSocket *self) +/*[clinic end generated code: output=b050a8b8e7d2bfa0 input=54ed7fee344889c9]*/ +{ + int ret; + _PySSLError err; + + PySSL_BEGIN_ALLOW_THREADS + ret = SSL_renegotiate(self->ssl); + err = _PySSL_errno(ret == 0, self->ssl, ret); + PySSL_END_ALLOW_THREADS + self->err = err; + + if (PyErr_CheckSignals()) { + return NULL; + } + + if (ret == 0) { + return PySSL_SetError(self, ret, __FILE__, __LINE__); + } + + Py_RETURN_NONE; +} + +/*[clinic input] +_ssl._SSLSocket.renegotiate_abbreviated +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_renegotiate_abbreviated_impl(PySSLSocket *self) +/*[clinic end generated code: output=418847227effa5f6 input=41a1acca9477811f]*/ +{ + int ret; + _PySSLError err; + + PySSL_BEGIN_ALLOW_THREADS + ret = SSL_renegotiate_abbreviated(self->ssl); + err = _PySSL_errno(ret == 0, self->ssl, ret); + PySSL_END_ALLOW_THREADS + self->err = err; + + if (PyErr_CheckSignals()) { + return NULL; + } + + if (ret == 0) { + return PySSL_SetError(self, ret, __FILE__, __LINE__); + } + + Py_RETURN_NONE; +} + +/*[clinic input] +_ssl._SSLSocket.renegotiate_pending +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_renegotiate_pending_impl(PySSLSocket *self) +/*[clinic end generated code: output=965855af60c6f3a8 input=29e735de5dcc63f3]*/ +{ + PyObject *v = SSL_renegotiate_pending(self->ssl) ? Py_True : Py_False; + Py_INCREF(v); + return v; +} + static PyObject * _asn1obj2py(const ASN1_OBJECT *name, int no_name) { @@ -2834,6 +2959,11 @@ static PyGetSetDef ssl_getsetlist[] = { static PyMethodDef PySSLMethods[] = { _SSL__SSLSOCKET_DO_HANDSHAKE_METHODDEF + _SSL__SSLSOCKET_KEY_UPDATE_METHODDEF + _SSL__SSLSOCKET_GET_KEY_UPDATE_TYPE_METHODDEF + _SSL__SSLSOCKET_RENEGOTIATE_METHODDEF + _SSL__SSLSOCKET_RENEGOTIATE_ABBREVIATED_METHODDEF + _SSL__SSLSOCKET_RENEGOTIATE_PENDING_METHODDEF _SSL__SSLSOCKET_WRITE_METHODDEF _SSL__SSLSOCKET_READ_METHODDEF _SSL__SSLSOCKET_PENDING_METHODDEF @@ -5971,6 +6101,14 @@ PyInit__ssl(void) PyModule_AddIntConstant(m, "HOSTFLAG_SINGLE_LABEL_SUBDOMAINS", X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); #endif +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) + PyModule_AddIntConstant(m, "KEY_UPDATE_NONE", + SSL_KEY_UPDATE_NONE); + PyModule_AddIntConstant(m, "KEY_UPDATE_NOT_REQUESTED", + SSL_KEY_UPDATE_NOT_REQUESTED); + PyModule_AddIntConstant(m, "KEY_UPDATE_REQUESTED", + SSL_KEY_UPDATE_REQUESTED); +#endif /* protocol versions */ PyModule_AddIntConstant(m, "PROTO_MINIMUM_SUPPORTED", diff --git a/Modules/_ssl_data.h b/Modules/_ssl_data.h index 85165b90bc389c..35194b0d5cebe8 100644 --- a/Modules/_ssl_data.h +++ b/Modules/_ssl_data.h @@ -294,16 +294,24 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_RSA_ENCRYPT", ERR_LIB_SSL, 119}, #endif + #ifdef SSL_R_INVALID_KEY_UPDATE_TYPE + {"INVALID_KEY_UPDATE_TYPE", ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE}, + #else #ifdef SSL_R_BAD_RSA_E_LENGTH {"BAD_RSA_E_LENGTH", ERR_LIB_SSL, SSL_R_BAD_RSA_E_LENGTH}, #else {"BAD_RSA_E_LENGTH", ERR_LIB_SSL, 120}, #endif + #endif + #ifdef SSL_R_STILL_IN_INIT + {"STILL_IN_INIT", ERR_LIB_SSL, SSL_R_STILL_IN_INIT}, + #else #ifdef SSL_R_BAD_RSA_MODULUS_LENGTH {"BAD_RSA_MODULUS_LENGTH", ERR_LIB_SSL, SSL_R_BAD_RSA_MODULUS_LENGTH}, #else {"BAD_RSA_MODULUS_LENGTH", ERR_LIB_SSL, 121}, #endif + #endif #ifdef SSL_R_BAD_RSA_SIGNATURE {"BAD_RSA_SIGNATURE", ERR_LIB_SSL, SSL_R_BAD_RSA_SIGNATURE}, #else diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 186e6432c2e35c..e3d05c69d51ee3 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -19,6 +19,100 @@ _ssl__SSLSocket_do_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) return _ssl__SSLSocket_do_handshake_impl(self); } +PyDoc_STRVAR(_ssl__SSLSocket_key_update__doc__, +"key_update($self, updatetype, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_KEY_UPDATE_METHODDEF \ + {"key_update", (PyCFunction)_ssl__SSLSocket_key_update, METH_O, _ssl__SSLSocket_key_update__doc__}, + +static PyObject * +_ssl__SSLSocket_key_update_impl(PySSLSocket *self, int updatetype); + +static PyObject * +_ssl__SSLSocket_key_update(PySSLSocket *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int updatetype; + + if (!PyArg_Parse(arg, "i:key_update", &updatetype)) { + goto exit; + } + return_value = _ssl__SSLSocket_key_update_impl(self, updatetype); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_get_key_update_type__doc__, +"get_key_update_type($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_GET_KEY_UPDATE_TYPE_METHODDEF \ + {"get_key_update_type", (PyCFunction)_ssl__SSLSocket_get_key_update_type, METH_NOARGS, _ssl__SSLSocket_get_key_update_type__doc__}, + +static PyObject * +_ssl__SSLSocket_get_key_update_type_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_get_key_update_type(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_get_key_update_type_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_renegotiate__doc__, +"renegotiate($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_RENEGOTIATE_METHODDEF \ + {"renegotiate", (PyCFunction)_ssl__SSLSocket_renegotiate, METH_NOARGS, _ssl__SSLSocket_renegotiate__doc__}, + +static PyObject * +_ssl__SSLSocket_renegotiate_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_renegotiate(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_renegotiate_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_renegotiate_abbreviated__doc__, +"renegotiate_abbreviated($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_RENEGOTIATE_ABBREVIATED_METHODDEF \ + {"renegotiate_abbreviated", (PyCFunction)_ssl__SSLSocket_renegotiate_abbreviated, METH_NOARGS, _ssl__SSLSocket_renegotiate_abbreviated__doc__}, + +static PyObject * +_ssl__SSLSocket_renegotiate_abbreviated_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_renegotiate_abbreviated(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_renegotiate_abbreviated_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_renegotiate_pending__doc__, +"renegotiate_pending($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_RENEGOTIATE_PENDING_METHODDEF \ + {"renegotiate_pending", (PyCFunction)_ssl__SSLSocket_renegotiate_pending, METH_NOARGS, _ssl__SSLSocket_renegotiate_pending__doc__}, + +static PyObject * +_ssl__SSLSocket_renegotiate_pending_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_renegotiate_pending(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_renegotiate_pending_impl(self); +} + PyDoc_STRVAR(_ssl__test_decode_cert__doc__, "_test_decode_cert($module, path, /)\n" "--\n" @@ -1193,4 +1287,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=c4e73b70ac3618ba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2bb8c041e0c81578 input=a9049054013a1b77]*/