bpo-24334: Cleanup SSLSocket (#5252)

* The SSLSocket is no longer implemented on top of SSLObject to
  avoid an extra level of indirection.
* Owner and session are now handled in the internal constructor.
* _ssl._SSLSocket now uses the same method names as SSLSocket and
  SSLObject.
* Channel binding type check is now handled in C code. Channel binding
  is always available.

The patch also changes the signature of SSLObject.__init__(). In my
opinion it's fine. A SSLObject is not a user-constructable object.
SSLContext.wrap_bio() is the only valid factory.
This commit is contained in:
Christian Heimes 2018-02-24 21:10:57 +01:00 committed by GitHub
parent b18f8bc1a7
commit 141c5e8c24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 183 additions and 117 deletions

View File

@ -166,10 +166,7 @@ import warnings
socket_error = OSError # keep that public name in module namespace
if _ssl.HAS_TLS_UNIQUE:
CHANNEL_BINDING_TYPES = ['tls-unique']
else:
CHANNEL_BINDING_TYPES = []
CHANNEL_BINDING_TYPES = ['tls-unique']
HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')
@ -407,11 +404,11 @@ class SSLContext(_SSLContext):
server_hostname=None, session=None):
# Need to encode server_hostname here because _wrap_bio() can only
# handle ASCII str.
sslobj = self._wrap_bio(
return self.sslobject_class(
incoming, outgoing, server_side=server_side,
server_hostname=self._encode_hostname(server_hostname)
server_hostname=self._encode_hostname(server_hostname),
session=session, _context=self,
)
return self.sslobject_class(sslobj, session=session)
def set_npn_protocols(self, npn_protocols):
protos = bytearray()
@ -616,12 +613,13 @@ class SSLObject:
* The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery.
"""
def __init__(self, sslobj, owner=None, session=None):
self._sslobj = sslobj
# Note: _sslobj takes a weak reference to owner
self._sslobj.owner = owner or self
if session is not None:
self._sslobj.session = session
def __init__(self, incoming, outgoing, server_side=False,
server_hostname=None, session=None, _context=None):
self._sslobj = _context._wrap_bio(
incoming, outgoing, server_side=server_side,
server_hostname=server_hostname,
owner=self, session=session
)
@property
def context(self):
@ -684,7 +682,7 @@ class SSLObject:
Return None if no certificate was provided, {} if a certificate was
provided, but not validated.
"""
return self._sslobj.peer_certificate(binary_form)
return self._sslobj.getpeercert(binary_form)
def selected_npn_protocol(self):
"""Return the currently selected NPN protocol as a string, or ``None``
@ -732,13 +730,7 @@ class SSLObject:
"""Get channel binding data for current connection. Raise ValueError
if the requested `cb_type` is not supported. Return bytes of the data
or None if the data is not available (e.g. before the handshake)."""
if cb_type not in CHANNEL_BINDING_TYPES:
raise ValueError("Unsupported channel binding type")
if cb_type != "tls-unique":
raise NotImplementedError(
"{0} channel binding type not implemented"
.format(cb_type))
return self._sslobj.tls_unique_cb()
return self._sslobj.get_channel_binding(cb_type)
def version(self):
"""Return a string identifying the protocol version used by the
@ -832,10 +824,10 @@ class SSLSocket(socket):
if connected:
# create the SSL object
try:
sslobj = self._context._wrap_socket(self, server_side,
self.server_hostname)
self._sslobj = SSLObject(sslobj, owner=self,
session=self._session)
self._sslobj = self._context._wrap_socket(
self, server_side, self.server_hostname,
owner=self, session=self._session,
)
if do_handshake_on_connect:
timeout = self.gettimeout()
if timeout == 0.0:
@ -895,10 +887,13 @@ class SSLSocket(socket):
Return zero-length string on EOF."""
self._checkClosed()
if not self._sslobj:
if self._sslobj is None:
raise ValueError("Read on closed or unwrapped SSL socket.")
try:
return self._sslobj.read(len, buffer)
if buffer is not None:
return self._sslobj.read(len, buffer)
else:
return self._sslobj.read(len)
except SSLError as x:
if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
if buffer is not None:
@ -913,7 +908,7 @@ class SSLSocket(socket):
number of bytes of DATA actually transmitted."""
self._checkClosed()
if not self._sslobj:
if self._sslobj is None:
raise ValueError("Write on closed or unwrapped SSL socket.")
return self._sslobj.write(data)
@ -929,41 +924,42 @@ class SSLSocket(socket):
def selected_npn_protocol(self):
self._checkClosed()
if not self._sslobj or not _ssl.HAS_NPN:
if self._sslobj is None or not _ssl.HAS_NPN:
return None
else:
return self._sslobj.selected_npn_protocol()
def selected_alpn_protocol(self):
self._checkClosed()
if not self._sslobj or not _ssl.HAS_ALPN:
if self._sslobj is None or not _ssl.HAS_ALPN:
return None
else:
return self._sslobj.selected_alpn_protocol()
def cipher(self):
self._checkClosed()
if not self._sslobj:
if self._sslobj is None:
return None
else:
return self._sslobj.cipher()
def shared_ciphers(self):
self._checkClosed()
if not self._sslobj:
if self._sslobj is None:
return None
return self._sslobj.shared_ciphers()
else:
return self._sslobj.shared_ciphers()
def compression(self):
self._checkClosed()
if not self._sslobj:
if self._sslobj is None:
return None
else:
return self._sslobj.compression()
def send(self, data, flags=0):
self._checkClosed()
if self._sslobj:
if self._sslobj is not None:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to send() on %s" %
@ -974,7 +970,7 @@ class SSLSocket(socket):
def sendto(self, data, flags_or_addr, addr=None):
self._checkClosed()
if self._sslobj:
if self._sslobj is not None:
raise ValueError("sendto not allowed on instances of %s" %
self.__class__)
elif addr is None:
@ -990,7 +986,7 @@ class SSLSocket(socket):
def sendall(self, data, flags=0):
self._checkClosed()
if self._sslobj:
if self._sslobj is not None:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to sendall() on %s" %
@ -1008,15 +1004,15 @@ class SSLSocket(socket):
"""Send a file, possibly by using os.sendfile() if this is a
clear-text socket. Return the total number of bytes sent.
"""
if self._sslobj is None:
if self._sslobj is not None:
return self._sendfile_use_send(file, offset, count)
else:
# os.sendfile() works with plain sockets only
return super().sendfile(file, offset, count)
else:
return self._sendfile_use_send(file, offset, count)
def recv(self, buflen=1024, flags=0):
self._checkClosed()
if self._sslobj:
if self._sslobj is not None:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to recv() on %s" %
@ -1031,7 +1027,7 @@ class SSLSocket(socket):
nbytes = len(buffer)
elif nbytes is None:
nbytes = 1024
if self._sslobj:
if self._sslobj is not None:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to recv_into() on %s" %
@ -1042,7 +1038,7 @@ class SSLSocket(socket):
def recvfrom(self, buflen=1024, flags=0):
self._checkClosed()
if self._sslobj:
if self._sslobj is not None:
raise ValueError("recvfrom not allowed on instances of %s" %
self.__class__)
else:
@ -1050,7 +1046,7 @@ class SSLSocket(socket):
def recvfrom_into(self, buffer, nbytes=None, flags=0):
self._checkClosed()
if self._sslobj:
if self._sslobj is not None:
raise ValueError("recvfrom_into not allowed on instances of %s" %
self.__class__)
else:
@ -1066,7 +1062,7 @@ class SSLSocket(socket):
def pending(self):
self._checkClosed()
if self._sslobj:
if self._sslobj is not None:
return self._sslobj.pending()
else:
return 0
@ -1078,7 +1074,7 @@ class SSLSocket(socket):
def unwrap(self):
if self._sslobj:
s = self._sslobj.unwrap()
s = self._sslobj.shutdown()
self._sslobj = None
return s
else:
@ -1096,6 +1092,11 @@ class SSLSocket(socket):
if timeout == 0.0 and block:
self.settimeout(None)
self._sslobj.do_handshake()
if self.context.check_hostname:
if not self.server_hostname:
raise ValueError("check_hostname needs server_hostname "
"argument")
match_hostname(self.getpeercert(), self.server_hostname)
finally:
self.settimeout(timeout)
@ -1104,11 +1105,12 @@ class SSLSocket(socket):
raise ValueError("can't connect in server-side mode")
# Here we assume that the socket is client-side, and not
# connected at the time of the call. We connect it, then wrap it.
if self._connected:
if self._connected or self._sslobj is not None:
raise ValueError("attempt to connect already-connected SSLSocket!")
sslobj = self.context._wrap_socket(self, False, self.server_hostname)
self._sslobj = SSLObject(sslobj, owner=self,
session=self._session)
self._sslobj = self.context._wrap_socket(
self, False, self.server_hostname,
owner=self, session=self._session
)
try:
if connect_ex:
rc = super().connect_ex(addr)
@ -1151,18 +1153,24 @@ class SSLSocket(socket):
if the requested `cb_type` is not supported. Return bytes of the data
or None if the data is not available (e.g. before the handshake).
"""
if self._sslobj is None:
if self._sslobj is not None:
return self._sslobj.get_channel_binding(cb_type)
else:
if cb_type not in CHANNEL_BINDING_TYPES:
raise ValueError(
"{0} channel binding type not implemented".format(cb_type)
)
return None
return self._sslobj.get_channel_binding(cb_type)
def version(self):
"""
Return a string identifying the protocol version used by the
current SSL channel, or None if there is no established channel.
"""
if self._sslobj is None:
if self._sslobj is not None:
return self._sslobj.version()
else:
return None
return self._sslobj.version()
# Python does not support forward declaration of types.

View File

@ -455,6 +455,8 @@ class BasicSocketTests(unittest.TestCase):
self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
self.assertRaises(OSError, ss.send, b'x')
self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
self.assertRaises(NotImplementedError, ss.sendmsg,
[b'x'], (), 0, ('0.0.0.0', 0))
def test_timeout(self):
# Issue #8524: when creating an SSL socket, the timeout of the
@ -3381,11 +3383,13 @@ class ThreadedTests(unittest.TestCase):
chatty=False) as server:
with context.wrap_socket(socket.socket()) as s:
self.assertIs(s.version(), None)
self.assertIs(s._sslobj, None)
s.connect((HOST, server.port))
if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
self.assertEqual(s.version(), 'TLSv1.2')
else: # 0.9.8 to 1.0.1
self.assertIn(s.version(), ('TLSv1', 'TLSv1.2'))
self.assertIs(s._sslobj, None)
self.assertIs(s.version(), None)
@unittest.skipUnless(ssl.HAS_TLSv1_3,

View File

@ -0,0 +1,4 @@
Internal implementation details of ssl module were cleaned up. The SSLSocket
has one less layer of indirection. Owner and session information are now
handled by the SSLSocket and SSLObject constructor. Channel binding
implementation has been simplified.

View File

@ -408,6 +408,8 @@ class _ssl.SSLSession "PySSLSession *" "&PySSLSession_Type"
static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout);
static int PySSL_set_owner(PySSLSocket *, PyObject *, void *);
static int PySSL_set_session(PySSLSocket *, PyObject *, void *);
#define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type)
#define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type)
#define PySSLSession_Check(v) (Py_TYPE(v) == &PySSLSession_Type)
@ -799,6 +801,7 @@ static PySSLSocket *
newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
enum py_ssl_server_or_client socket_type,
char *server_hostname,
PyObject *owner, PyObject *session,
PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio)
{
PySSLSocket *self;
@ -875,6 +878,18 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
return NULL;
}
}
if (owner && owner != Py_None) {
if (PySSL_set_owner(self, owner, NULL) == -1) {
Py_DECREF(self);
return NULL;
}
}
if (session && session != Py_None) {
if (PySSL_set_session(self, session, NULL) == -1) {
Py_DECREF(self);
return NULL;
}
}
return self;
}
@ -1677,7 +1692,7 @@ _ssl__test_decode_cert_impl(PyObject *module, PyObject *path)
/*[clinic input]
_ssl._SSLSocket.peer_certificate
_ssl._SSLSocket.getpeercert
der as binary_mode: bool = False
/
@ -1693,8 +1708,8 @@ return the certificate even if it wasn't validated.
[clinic start generated code]*/
static PyObject *
_ssl__SSLSocket_peer_certificate_impl(PySSLSocket *self, int binary_mode)
/*[clinic end generated code: output=f0dc3e4d1d818a1d input=8281bd1d193db843]*/
_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode)
/*[clinic end generated code: output=1f0ab66dfb693c88 input=c0fbe802e57629b7]*/
{
int verification;
X509 *peer_cert;
@ -2395,13 +2410,11 @@ error:
_ssl._SSLSocket.shutdown
Does the SSL shutdown handshake with the remote end.
Returns the underlying socket object.
[clinic start generated code]*/
static PyObject *
_ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=ede2cc1a2ddf0ee4]*/
/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=11d39e69b0a2bf4a]*/
{
int err, sockstate, nonblocking;
int zeros = 0;
@ -2506,37 +2519,48 @@ error:
}
/*[clinic input]
_ssl._SSLSocket.tls_unique_cb
_ssl._SSLSocket.get_channel_binding
cb_type: str = "tls-unique"
Returns the 'tls-unique' channel binding data, as defined by RFC 5929.
Get channel binding data for current connection.
If the TLS handshake is not yet complete, None is returned.
Raise ValueError if the requested `cb_type` is not supported. Return bytes
of the data or None if the data is not available (e.g. before the handshake).
Only 'tls-unique' channel binding data from RFC 5929 is supported.
[clinic start generated code]*/
static PyObject *
_ssl__SSLSocket_tls_unique_cb_impl(PySSLSocket *self)
/*[clinic end generated code: output=f3a832d603f586af input=439525c7b3d8d34d]*/
_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self,
const char *cb_type)
/*[clinic end generated code: output=34bac9acb6a61d31 input=08b7e43b99c17d41]*/
{
PyObject *retval = NULL;
char buf[PySSL_CB_MAXLEN];
size_t len;
if (SSL_session_reused(self->ssl) ^ !self->socket_type) {
/* if session is resumed XOR we are the client */
len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN);
if (strcmp(cb_type, "tls-unique") == 0) {
if (SSL_session_reused(self->ssl) ^ !self->socket_type) {
/* if session is resumed XOR we are the client */
len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN);
}
else {
/* if a new session XOR we are the server */
len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN);
}
}
else {
/* if a new session XOR we are the server */
len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN);
PyErr_Format(
PyExc_ValueError,
"'%s' channel binding type not implemented",
cb_type
);
return NULL;
}
/* It cannot be negative in current OpenSSL version as of July 2011 */
if (len == 0)
Py_RETURN_NONE;
retval = PyBytes_FromStringAndSize(buf, len);
return retval;
return PyBytes_FromStringAndSize(buf, len);
}
#ifdef OPENSSL_VERSION_1_1
@ -2706,7 +2730,8 @@ static PyMethodDef PySSLMethods[] = {
_SSL__SSLSOCKET_WRITE_METHODDEF
_SSL__SSLSOCKET_READ_METHODDEF
_SSL__SSLSOCKET_PENDING_METHODDEF
_SSL__SSLSOCKET_PEER_CERTIFICATE_METHODDEF
_SSL__SSLSOCKET_GETPEERCERT_METHODDEF
_SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF
_SSL__SSLSOCKET_CIPHER_METHODDEF
_SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF
_SSL__SSLSOCKET_VERSION_METHODDEF
@ -2714,7 +2739,6 @@ static PyMethodDef PySSLMethods[] = {
_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF
_SSL__SSLSOCKET_COMPRESSION_METHODDEF
_SSL__SSLSOCKET_SHUTDOWN_METHODDEF
_SSL__SSLSOCKET_TLS_UNIQUE_CB_METHODDEF
{NULL, NULL}
};
@ -3810,13 +3834,17 @@ _ssl._SSLContext._wrap_socket
sock: object(subclass_of="PySocketModule.Sock_Type")
server_side: int
server_hostname as hostname_obj: object = None
*
owner: object = None
session: object = None
[clinic start generated code]*/
static PyObject *
_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
int server_side, PyObject *hostname_obj)
/*[clinic end generated code: output=6973e4b60995e933 input=83859b9156ddfc63]*/
int server_side, PyObject *hostname_obj,
PyObject *owner, PyObject *session)
/*[clinic end generated code: output=f103f238633940b4 input=957d5006183d1894]*/
{
char *hostname = NULL;
PyObject *res;
@ -3830,6 +3858,7 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
res = (PyObject *) newPySSLSocket(self, (PySocketSockObject *)sock,
server_side, hostname,
owner, session,
NULL, NULL);
if (hostname != NULL)
PyMem_Free(hostname);
@ -3842,14 +3871,18 @@ _ssl._SSLContext._wrap_bio
outgoing: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *")
server_side: int
server_hostname as hostname_obj: object = None
*
owner: object = None
session: object = None
[clinic start generated code]*/
static PyObject *
_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
PySSLMemoryBIO *outgoing, int server_side,
PyObject *hostname_obj)
/*[clinic end generated code: output=4fe4ba75ad95940d input=17725ecdac0bf220]*/
PyObject *hostname_obj, PyObject *owner,
PyObject *session)
/*[clinic end generated code: output=5c5d6d9b41f99332 input=8cf22f4d586ac56a]*/
{
char *hostname = NULL;
PyObject *res;
@ -3862,6 +3895,7 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
}
res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname,
owner, session,
incoming, outgoing);
PyMem_Free(hostname);
@ -5663,10 +5697,6 @@ PyInit__ssl(void)
Py_INCREF(r);
PyModule_AddObject(m, "HAS_SNI", r);
r = Py_True;
Py_INCREF(r);
PyModule_AddObject(m, "HAS_TLS_UNIQUE", r);
#ifdef OPENSSL_NO_ECDH
r = Py_False;
#else

View File

@ -45,8 +45,8 @@ exit:
return return_value;
}
PyDoc_STRVAR(_ssl__SSLSocket_peer_certificate__doc__,
"peer_certificate($self, der=False, /)\n"
PyDoc_STRVAR(_ssl__SSLSocket_getpeercert__doc__,
"getpeercert($self, der=False, /)\n"
"--\n"
"\n"
"Returns the certificate for the peer.\n"
@ -59,23 +59,23 @@ PyDoc_STRVAR(_ssl__SSLSocket_peer_certificate__doc__,
"peer certificate, or None if no certificate was provided. This will\n"
"return the certificate even if it wasn\'t validated.");
#define _SSL__SSLSOCKET_PEER_CERTIFICATE_METHODDEF \
{"peer_certificate", (PyCFunction)_ssl__SSLSocket_peer_certificate, METH_FASTCALL, _ssl__SSLSocket_peer_certificate__doc__},
#define _SSL__SSLSOCKET_GETPEERCERT_METHODDEF \
{"getpeercert", (PyCFunction)_ssl__SSLSocket_getpeercert, METH_FASTCALL, _ssl__SSLSocket_getpeercert__doc__},
static PyObject *
_ssl__SSLSocket_peer_certificate_impl(PySSLSocket *self, int binary_mode);
_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode);
static PyObject *
_ssl__SSLSocket_peer_certificate(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs)
_ssl__SSLSocket_getpeercert(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
int binary_mode = 0;
if (!_PyArg_ParseStack(args, nargs, "|p:peer_certificate",
if (!_PyArg_ParseStack(args, nargs, "|p:getpeercert",
&binary_mode)) {
goto exit;
}
return_value = _ssl__SSLSocket_peer_certificate_impl(self, binary_mode);
return_value = _ssl__SSLSocket_getpeercert_impl(self, binary_mode);
exit:
return return_value;
@ -293,9 +293,7 @@ PyDoc_STRVAR(_ssl__SSLSocket_shutdown__doc__,
"shutdown($self, /)\n"
"--\n"
"\n"
"Does the SSL shutdown handshake with the remote end.\n"
"\n"
"Returns the underlying socket object.");
"Does the SSL shutdown handshake with the remote end.");
#define _SSL__SSLSOCKET_SHUTDOWN_METHODDEF \
{"shutdown", (PyCFunction)_ssl__SSLSocket_shutdown, METH_NOARGS, _ssl__SSLSocket_shutdown__doc__},
@ -309,24 +307,39 @@ _ssl__SSLSocket_shutdown(PySSLSocket *self, PyObject *Py_UNUSED(ignored))
return _ssl__SSLSocket_shutdown_impl(self);
}
PyDoc_STRVAR(_ssl__SSLSocket_tls_unique_cb__doc__,
"tls_unique_cb($self, /)\n"
PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__,
"get_channel_binding($self, /, cb_type=\'tls-unique\')\n"
"--\n"
"\n"
"Returns the \'tls-unique\' channel binding data, as defined by RFC 5929.\n"
"Get channel binding data for current connection.\n"
"\n"
"If the TLS handshake is not yet complete, None is returned.");
"Raise ValueError if the requested `cb_type` is not supported. Return bytes\n"
"of the data or None if the data is not available (e.g. before the handshake).\n"
"Only \'tls-unique\' channel binding data from RFC 5929 is supported.");
#define _SSL__SSLSOCKET_TLS_UNIQUE_CB_METHODDEF \
{"tls_unique_cb", (PyCFunction)_ssl__SSLSocket_tls_unique_cb, METH_NOARGS, _ssl__SSLSocket_tls_unique_cb__doc__},
#define _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF \
{"get_channel_binding", (PyCFunction)_ssl__SSLSocket_get_channel_binding, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLSocket_get_channel_binding__doc__},
static PyObject *
_ssl__SSLSocket_tls_unique_cb_impl(PySSLSocket *self);
_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self,
const char *cb_type);
static PyObject *
_ssl__SSLSocket_tls_unique_cb(PySSLSocket *self, PyObject *Py_UNUSED(ignored))
_ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
return _ssl__SSLSocket_tls_unique_cb_impl(self);
PyObject *return_value = NULL;
static const char * const _keywords[] = {"cb_type", NULL};
static _PyArg_Parser _parser = {"|s:get_channel_binding", _keywords, 0};
const char *cb_type = "tls-unique";
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
&cb_type)) {
goto exit;
}
return_value = _ssl__SSLSocket_get_channel_binding_impl(self, cb_type);
exit:
return return_value;
}
static PyObject *
@ -538,7 +551,8 @@ PyDoc_STRVAR(_ssl__SSLContext_load_dh_params__doc__,
{"load_dh_params", (PyCFunction)_ssl__SSLContext_load_dh_params, METH_O, _ssl__SSLContext_load_dh_params__doc__},
PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__,
"_wrap_socket($self, /, sock, server_side, server_hostname=None)\n"
"_wrap_socket($self, /, sock, server_side, server_hostname=None, *,\n"
" owner=None, session=None)\n"
"--\n"
"\n");
@ -547,23 +561,26 @@ PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__,
static PyObject *
_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
int server_side, PyObject *hostname_obj);
int server_side, PyObject *hostname_obj,
PyObject *owner, PyObject *session);
static PyObject *
_ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"sock", "server_side", "server_hostname", NULL};
static _PyArg_Parser _parser = {"O!i|O:_wrap_socket", _keywords, 0};
static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL};
static _PyArg_Parser _parser = {"O!i|O$OO:_wrap_socket", _keywords, 0};
PyObject *sock;
int server_side;
PyObject *hostname_obj = Py_None;
PyObject *owner = Py_None;
PyObject *session = Py_None;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
PySocketModule.Sock_Type, &sock, &server_side, &hostname_obj)) {
PySocketModule.Sock_Type, &sock, &server_side, &hostname_obj, &owner, &session)) {
goto exit;
}
return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj);
return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj, owner, session);
exit:
return return_value;
@ -571,7 +588,7 @@ exit:
PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__,
"_wrap_bio($self, /, incoming, outgoing, server_side,\n"
" server_hostname=None)\n"
" server_hostname=None, *, owner=None, session=None)\n"
"--\n"
"\n");
@ -581,24 +598,27 @@ PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__,
static PyObject *
_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
PySSLMemoryBIO *outgoing, int server_side,
PyObject *hostname_obj);
PyObject *hostname_obj, PyObject *owner,
PyObject *session);
static PyObject *
_ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", NULL};
static _PyArg_Parser _parser = {"O!O!i|O:_wrap_bio", _keywords, 0};
static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL};
static _PyArg_Parser _parser = {"O!O!i|O$OO:_wrap_bio", _keywords, 0};
PySSLMemoryBIO *incoming;
PySSLMemoryBIO *outgoing;
int server_side;
PyObject *hostname_obj = Py_None;
PyObject *owner = Py_None;
PyObject *session = Py_None;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
&PySSLMemoryBIO_Type, &incoming, &PySSLMemoryBIO_Type, &outgoing, &server_side, &hostname_obj)) {
&PySSLMemoryBIO_Type, &incoming, &PySSLMemoryBIO_Type, &outgoing, &server_side, &hostname_obj, &owner, &session)) {
goto exit;
}
return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj);
return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj, owner, session);
exit:
return return_value;
@ -1155,4 +1175,4 @@ exit:
#ifndef _SSL_ENUM_CRLS_METHODDEF
#define _SSL_ENUM_CRLS_METHODDEF
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
/*[clinic end generated code: output=84e1fd89aff9b0f7 input=a9049054013a1b77]*/
/*[clinic end generated code: output=d987411caeb106e7 input=a9049054013a1b77]*/