Beispiel #1
0
    def __init__(self,
                 abstract_socket: AbstractAioSocket,
                 context: ssl.SSLContext = ssl.create_default_context(),
                 server_side: bool = False,
                 server_hostname: str = None,
                 loop: asyncio.AbstractEventLoop = None):

        self.incoming = ssl.MemoryBIO()
        self.outgoing = ssl.MemoryBIO()

        self.client_random = None
        self.master_secret = None

        self.abstract_socket = abstract_socket
        self.server_side = server_side

        self.tls: ssl.SSLObject = context.wrap_bio(self.incoming,
                                                   self.outgoing, server_side,
                                                   server_hostname)

        self.wrapped = False

        if loop is None:
            self.loop: asyncio.AbstractEventLoop = asyncio.get_event_loop()
        else:
            self.loop: asyncio.AbstractEventLoop = loop
Beispiel #2
0
    def __init__(self,
                 socket,
                 ssl_context,
                 server_hostname=None,
                 suppress_ragged_eofs=True):
        """

        Create an SSLTransport around socket using the provided ssl_context.

        """

        self.incoming = ssl.MemoryBIO()

        self.outgoing = ssl.MemoryBIO()

        self.suppress_ragged_eofs = suppress_ragged_eofs

        self.socket = socket

        self.sslobj = ssl_context.wrap_bio(self.incoming,
                                           self.outgoing,
                                           server_hostname=server_hostname)

        # Perform initial handshake.

        self._ssl_io_loop(self.sslobj.do_handshake)
Beispiel #3
0
 def init_tls(self):
     self.log.debug("initializing TLS context...")
     self.tls_ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
     self.tls_in = ssl.MemoryBIO()
     self.tls_out = ssl.MemoryBIO()
     self.tls = self.tls_ctx.wrap_bio(self.tls_in, self.tls_out, False,
                                      None)
Beispiel #4
0
    def __init__(self,
                 transport_stream,
                 ssl_context,
                 *,
                 server_hostname=None,
                 server_side=False,
                 https_compatible=False,
                 max_refill_bytes=_default_max_refill_bytes):
        self.transport_stream = transport_stream
        self._state = _State.OK
        self._max_refill_bytes = max_refill_bytes
        self._https_compatible = https_compatible
        self._outgoing = _stdlib_ssl.MemoryBIO()
        self._incoming = _stdlib_ssl.MemoryBIO()
        self._ssl_object = ssl_context.wrap_bio(
            self._incoming,
            self._outgoing,
            server_side=server_side,
            server_hostname=server_hostname)
        # Tracks whether we've already done the initial handshake
        self._handshook = _Once(self._do_handshake)

        # These are used to synchronize access to self.transport_stream
        self._inner_send_lock = _sync.StrictFIFOLock()
        self._inner_recv_count = 0
        self._inner_recv_lock = _sync.Lock()

        # These are used to make sure that our caller doesn't attempt to make
        # multiple concurrent calls to send_all/wait_send_all_might_not_block
        # or to receive_some.
        self._outer_send_conflict_detector = ConflictDetector(
            "another task is currently sending data on this SSLStream")
        self._outer_recv_conflict_detector = ConflictDetector(
            "another task is currently receiving data on this SSLStream")
Beispiel #5
0
def check_handshake(server_context, client_context, err=None):
    hostname = 'localhost'
    c_in = ssl.MemoryBIO()
    c_out = ssl.MemoryBIO()
    s_in = ssl.MemoryBIO()
    s_out = ssl.MemoryBIO()
    client = client_context.wrap_bio(c_in, c_out, server_hostname=hostname)
    server = server_context.wrap_bio(s_in, s_out, server_side=True)

    try:
        for _ in range(5):
            try:
                client.do_handshake()
            except ssl.SSLWantReadError:
                pass
            if c_out.pending:
                s_in.write(c_out.read())
            try:
                server.do_handshake()
            except ssl.SSLWantReadError:
                pass
            if s_out.pending:
                c_in.write(s_out.read())
    except Exception as e:
        if err is None:
            assert False
        else:
            assert isinstance(e, err)
    else:
        if err is not None:
            assert False
Beispiel #6
0
    def __init__(self,
                 server_side: bool = False,
                 alpn: typing.Optional[typing.List[str]] = None,
                 sni: typing.Optional[bytes] = b"example.mitmproxy.org"):
        self.inc = ssl.MemoryBIO()
        self.out = ssl.MemoryBIO()
        self.ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER
                                  if server_side else ssl.PROTOCOL_TLS_CLIENT)

        self.ctx.verify_mode = ssl.CERT_OPTIONAL
        self.ctx.load_verify_locations(cafile=tlsdata.path(
            "../../net/data/verificationcerts/trusted-root.crt"), )

        if alpn:
            self.ctx.set_alpn_protocols(alpn)
        if server_side:
            self.ctx.load_cert_chain(
                certfile=tlsdata.path(
                    "../../net/data/verificationcerts/trusted-leaf.crt"),
                keyfile=tlsdata.path(
                    "../../net/data/verificationcerts/trusted-leaf.key"),
            )

        self.obj = self.ctx.wrap_bio(
            self.inc,
            self.out,
            server_hostname=None if server_side else sni,
            server_side=server_side,
        )
Beispiel #7
0
    def __init__(self,
                 socket,
                 ssl_context,
                 suppress_ragged_eofs=True,
                 **wrap_bio_kwargs):
        """
        Create an SSLTransport around socket using the provided ssl_context.

        :param socket:
            The socket object to wrap.
        :param ssl_context:
            :class:`ssl.SSLContext` to use call :func:`ssl.SSLContext.wrap_bio` on.
        :param suppress_ragged_eofs:
            Suppress ``ssl.SSL_ERROR_EOF`` read errors.
        :param wrap_bio_kwargs:
            These args will be passed to :func:`ssl.SSLContext.wrap_bio`
        """
        self.incoming = ssl.MemoryBIO()
        self.outgoing = ssl.MemoryBIO()

        self.suppress_ragged_eofs = suppress_ragged_eofs
        self.socket = socket

        self.sslobj = ssl_context.wrap_bio(self.incoming, self.outgoing,
                                           **wrap_bio_kwargs)

        # Perform initial handshake.
        self._ssl_io_loop(self.sslobj.do_handshake)
Beispiel #8
0
    def handle_notification_connection(self):
        self.incoming = ssl.MemoryBIO()
        self.outgoing = ssl.MemoryBIO()

        try:
            notif_tls_ctx.load_verify_locations(cadata=parse_authorized_certs())
            self.tls_bio = notif_tls_ctx.wrap_bio(incoming=self.incoming, outgoing=self.outgoing, server_side=True)
            self.do_handshake()
        except Exception as e:
            print_with_timestamp('(Bluetooth) Failed TLS handshake notif_conn: {}'.format(e))
            return

        # one recv should not take longer than 10 sec
        self.socket.settimeout(10)

        notification_flags_size = struct.unpack('>I', recvall(self.socket, 4))[0]
        notification_flags_encrypted = recvall(self.socket, notification_flags_size)
        notification_flags = struct.unpack('>B', self.tls_decrypt(notification_flags_encrypted))[0]

        if notification_flags & FLAG_INCLUDE_TITLE == FLAG_INCLUDE_TITLE:
            include_title = True
        else:
            include_title = False

        if notification_flags & FLAG_INCLUDE_MESSAGE == FLAG_INCLUDE_MESSAGE:
            include_message = True
        else:
            include_message = False

        if notification_flags & FLAG_INCLUDE_ICON == FLAG_INCLUDE_ICON:
            include_icon = True
        else:
            include_icon = False

        title = ''
        message = ''

        if include_title or include_message:
            title_and_or_message_size = struct.unpack('>I', recvall(self.socket, 4))[0]
            title_and_or_message_encrypted = recvall(self.socket, title_and_or_message_size)
            title_and_or_message = self.tls_decrypt(title_and_or_message_encrypted).decode()
            if include_title:
                title = title_and_or_message.split('|||')[0]
            if include_message:
                message = title_and_or_message.split('|||')[1]

        if include_icon:
            icon_tmp_file = tempfile.NamedTemporaryFile(buffering=0, dir=TMP_DIR_PATH)
            icon_size = struct.unpack('>I', recvall(self.socket, 4))[0]
            icon_encrypted = recvall(self.socket, icon_size)
            icon = self.tls_decrypt(icon_encrypted)
            try:
                icon_tmp_file.write(icon)
                Notification(title, message, hashlib.sha1(title.encode() + message.encode() + icon).digest(),
                             icon_tmp_file).show()
            except Exception:
                Notification(title, message, hashlib.sha1(title.encode() + message.encode()).digest()).show()
        else:
            Notification(title, message, hashlib.sha1(title.encode() + message.encode()).digest()).show()
Beispiel #9
0
def make_tls_objects():
    tls_in_buff = ssl.MemoryBIO()
    tls_out_buff = ssl.MemoryBIO()
    ctx = ssl.SSLContext(ssl.PROTOCOL_TLS)
    ctx.load_cert_chain(cert_file, key_file)
    ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
    ctx.set_alpn_protocols(["h2"])
    tls_obj = ctx.wrap_bio(tls_in_buff, tls_out_buff, server_side=True)
    return tls_obj, tls_in_buff, tls_out_buff
Beispiel #10
0
    def __init__(self, src: ScanHost[IPAddressType],
                 dst: ScanHost[IPAddressType]) -> None:
        super(TLSProtocol, self).__init__(src, dst)

        self._in_bio = ssl.MemoryBIO()
        self._out_bio = ssl.MemoryBIO()
        self._ssl = self._SSL_CTX.wrap_bio(self._in_bio,
                                           self._out_bio,
                                           server_side=False,
                                           server_hostname=self._dst.host)
 def __init__(self, handle, readable=True, writable=True, server_side=False):
     super().__init__(handle, readable=readable, writable=writable, server_side=server_side)
     self.finish_handshake = False
     from .http_proxy_server import CertUtil
     self._context = CertUtil.get_context()
     self._incoming = ssl.MemoryBIO()
     self._outgoing = ssl.MemoryBIO()
     self._handshake_lock = asyncio.Lock()
     self._ssl_obj = self._context.wrap_bio(self._incoming, self._outgoing, self._server_side)
     self.__must_write = lambda: self._MustDo(self.__write_to_pipe())
Beispiel #12
0
    async def wrap(
        cls,
        transport_stream: AnyByteStream,
        *,
        server_side: Optional[bool] = None,
        hostname: Optional[str] = None,
        ssl_context: Optional[ssl.SSLContext] = None,
        standard_compatible: bool = True,
    ) -> "TLSStream":
        """
        Wrap an existing stream with Transport Layer Security.

        This performs a TLS handshake with the peer.

        :param transport_stream: a bytes-transporting stream to wrap
        :param server_side: ``True`` if this is the server side of the connection, ``False`` if
            this is the client side (if omitted, will be set to ``False`` if ``hostname`` has been
            provided, ``False`` otherwise). Used only to create a default context when an explicit
            context has not been provided.
        :param hostname: host name of the peer (if host name checking is desired)
        :param ssl_context: the SSLContext object to use (if not provided, a secure default will be
            created)
        :param standard_compatible: if ``False``, skip the closing handshake when closing the
            connection, and don't raise an exception if the peer does the same
        :raises ~ssl.SSLError: if the TLS handshake fails

        """
        if server_side is None:
            server_side = not hostname

        if not ssl_context:
            purpose = (
                ssl.Purpose.CLIENT_AUTH if server_side else ssl.Purpose.SERVER_AUTH
            )
            ssl_context = ssl.create_default_context(purpose)

            # Re-enable detection of unexpected EOFs if it was disabled by Python
            if hasattr(ssl, "OP_IGNORE_UNEXPECTED_EOF"):
                ssl_context.options ^= ssl.OP_IGNORE_UNEXPECTED_EOF  # type: ignore[attr-defined]

        bio_in = ssl.MemoryBIO()
        bio_out = ssl.MemoryBIO()
        ssl_object = ssl_context.wrap_bio(
            bio_in, bio_out, server_side=server_side, server_hostname=hostname
        )
        wrapper = cls(
            transport_stream=transport_stream,
            standard_compatible=standard_compatible,
            _ssl_object=ssl_object,
            _read_bio=bio_in,
            _write_bio=bio_out,
        )
        await wrapper._call_sslobject_method(ssl_object.do_handshake)
        return wrapper
Beispiel #13
0
    async def StartTLS(self):
        self._normal_send = self._ssl_send
        self._normal_recv = self._ssl_recv
        if (self._Debug):
            self.Send = self._debug_send
            self.Recv = self._debug_recv
            self.Close = self._debug_close
        else:
            self.Send = self._normal_send
            self.Recv = self._normal_recv
            self.Close = self._normal_close

        self._tls_in_buff = ssl.MemoryBIO()
        self._tls_out_buff = ssl.MemoryBIO()
        self._tls_obj = self._SSL_Context.wrap_bio(
            self._tls_in_buff,
            self._tls_out_buff,
            server_side=self._server_side)
        if (self._server_side):
            # Recv Client Hello
            self._tls_in_buff.write(await asyncio.wait_for(
                self._Reader.read(self._Recvsize), timeout=self._Timeout))
        # || TLS Handshake
        try:
            self._tls_obj.do_handshake()
        except ssl.SSLWantReadError:
            if (self._server_side):
                self._Writer.write(self._tls_out_buff.read())
                await asyncio.wait_for(self._Writer.drain(),
                                       timeout=self._Timeout)
                self._tls_in_buff.write(await asyncio.wait_for(
                    self._Reader.read(self._Recvsize), timeout=self._Timeout))
                self._tls_obj.do_handshake()
                self._Writer.write(self._tls_out_buff.read())
                await asyncio.wait_for(self._Writer.drain(),
                                       timeout=self._Timeout)
            else:
                # Client Hello
                self._Writer.write(self._tls_out_buff.read())
                await asyncio.wait_for(self._Writer.drain(),
                                       timeout=self._Timeout)
                # Server Hello
                self._tls_in_buff.write(await asyncio.wait_for(
                    self._Reader.read(self._Recvsize), timeout=self._Timeout))
                try:
                    self._tls_obj.do_handshake()
                except ssl.SSLWantReadError:
                    self._Writer.write(self._tls_out_buff.read())
                    await asyncio.wait_for(self._Writer.drain(),
                                           timeout=self._Timeout)
                    self._tls_in_buff.write(await asyncio.wait_for(
                        self._Reader.read(self._Recvsize),
                        timeout=self._Timeout))
Beispiel #14
0
 def __init__(self, writer, reader, pem_file):
     """@param: writer and reader are asyncio stream writer and reader objects"""
     self._tlsInBuff = ssl.MemoryBIO()
     self._tlsOutBuff = ssl.MemoryBIO()
     ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1)
     ctx.set_ciphers('RSA:!aNULL')
     ctx.check_hostname = False
     ctx.load_cert_chain(pem_file)
     self._tlsObj = ctx.wrap_bio(self._tlsInBuff,
                                 self._tlsOutBuff,
                                 server_side=True)
     self.writer = writer
     self.reader = reader
Beispiel #15
0
    def __init__(self, reader, writer):
        super().__init__(reader, writer)
        self.ServerSide = True
        self.ServerName = None
        self.ALPN = None
        self.SslContext = None

        self.isTryingHandshake = False

        self._tls_in_buff = ssl.MemoryBIO()
        self._tls_out_buff = ssl.MemoryBIO()
        self._tls_Readsize = 8
        self._client_hello_buf = None
Beispiel #16
0
    def handle_notification_connection(self):
        self.incoming = ssl.MemoryBIO()
        self.outgoing = ssl.MemoryBIO()
        try:
            if bluetooth_support_kitkat:
                notif_tls_ctx_kitkat_bt.load_verify_locations(cadata=parse_authorized_certs())
                self.tls_bio = notif_tls_ctx_kitkat_bt.wrap_bio(incoming=self.incoming, outgoing=self.outgoing,
                                                                server_side=True)
            else:
                notif_tls_ctx.load_verify_locations(cadata=parse_authorized_certs())
                self.tls_bio = notif_tls_ctx.wrap_bio(incoming=self.incoming, outgoing=self.outgoing, server_side=True)
            self.do_handshake()
        except Exception as e:
            logging.error('(Bluetooth) Failed TLS handshake notif_conn: {}'.format(e))
            return

        # one recv should not take longer than 10 sec
        self.socket.settimeout(10)

        notification_flags_size = struct.unpack('>I', recvall(self.socket, 4))[0]
        notification_flags_encrypted = recvall(self.socket, notification_flags_size)
        notification_flags = struct.unpack('>B', self.tls_decrypt(notification_flags_encrypted))[0]

        include_title   = chkflags(notification_flags, FLAG_INCLUDE_TITLE)
        include_message = chkflags(notification_flags, FLAG_INCLUDE_MESSAGE)
        include_icon    = chkflags(notification_flags, FLAG_INCLUDE_ICON)

        title = ''
        message = ''

        if include_title or include_message:
            title_and_or_message_size = struct.unpack('>I', recvall(self.socket, 4))[0]
            title_and_or_message_encrypted = recvall(self.socket, title_and_or_message_size)
            title_and_or_message = self.tls_decrypt(title_and_or_message_encrypted).decode()
            if include_title:
                title = title_and_or_message.split('|||')[0]
            if include_message:
                message = title_and_or_message.split('|||')[1]

        if include_icon:
            icon_size = struct.unpack('>I', recvall(self.socket, 4))[0]
            icon_encrypted = recvall(self.socket, icon_size)
            icon_bytes = self.tls_decrypt(icon_encrypted)
            try:
                Notification(title, message, icon_bytes).show()
            except Exception:
                Notification(title, message).show()
        else:
            Notification(title, message).show()
Beispiel #17
0
    def __init__(self, netstream, hostname, log=None):
        if log is None:
            self.log = logging.getLogger('SSLStream.%s' % (hostname, ))
        else:
            self.log = log
        self.reof = False

        self.netstream = netstream
        self.incoming = ssl.MemoryBIO()
        self.outgoing = ssl.MemoryBIO()
        self.ctx = ssl.create_default_context()
        self.obj = self.ctx.wrap_bio(self.incoming,
                                     self.outgoing,
                                     server_side=False,
                                     server_hostname=hostname)
        self.handshake_done = False
        self.log.debug('%s', f'wrapped {self.netstream!r}')
Beispiel #18
0
    def __init__(
        self,
        transport_stream,
        ssl_context,
        *,
        server_hostname=None,
        server_side=False,
        https_compatible=False,
        max_refill_bytes="unused and deprecated"
    ):
        self.transport_stream = transport_stream
        self._state = _State.OK
        if max_refill_bytes != "unused and deprecated":
            warn_deprecated(
                "max_refill_bytes=...", "0.12.0", issue=959, instead=None
            )
        self._https_compatible = https_compatible
        self._outgoing = _stdlib_ssl.MemoryBIO()
        self._delayed_outgoing = None
        self._incoming = _stdlib_ssl.MemoryBIO()
        self._ssl_object = ssl_context.wrap_bio(
            self._incoming,
            self._outgoing,
            server_side=server_side,
            server_hostname=server_hostname
        )
        # Tracks whether we've already done the initial handshake
        self._handshook = _Once(self._do_handshake)

        # These are used to synchronize access to self.transport_stream
        self._inner_send_lock = _sync.StrictFIFOLock()
        self._inner_recv_count = 0
        self._inner_recv_lock = _sync.Lock()

        # These are used to make sure that our caller doesn't attempt to make
        # multiple concurrent calls to send_all/wait_send_all_might_not_block
        # or to receive_some.
        self._outer_send_conflict_detector = ConflictDetector(
            "another task is currently sending data on this SSLStream"
        )
        self._outer_recv_conflict_detector = ConflictDetector(
            "another task is currently receiving data on this SSLStream"
        )

        self._estimated_receive_size = STARTING_RECEIVE_SIZE
Beispiel #19
0
    def __init__(self, maxlen=-1):
        """ Creates StreamReader instance.

        Params:

        maxlen - maximal allowed netstring length.
        """
        self._maxlen = maxlen
        self._incoming = ssl.MemoryBIO()
        self._fetcher = None
Beispiel #20
0
 def __init__(self, context, server_side, server_hostname=None):
     """
     The *context* argument specifies the ssl.SSLContext to use.
     The *server_side* argument indicates whether this is a server side or
     client side transport.
     The optional *server_hostname* argument can be used to specify the
     hostname you are connecting to. You may only specify this parameter if
     the _ssl module supports Server Name Indication (SNI).
     """
     self._context = context
     self._server_side = server_side
     self._server_hostname = server_hostname
     self._state = _UNWRAPPED
     self._incoming = ssl.MemoryBIO()
     self._outgoing = ssl.MemoryBIO()
     self._sslobj = None
     self._need_ssldata = False
     self._handshake_cb = None
     self._shutdown_cb = None
Beispiel #21
0
    def __init__(self,
                 loop,
                 app_protocol,
                 sslcontext,
                 waiter,
                 server_side=False,
                 server_hostname=None,
                 call_connection_made=True,
                 ssl_handshake_timeout=None):
        if ssl is None:
            raise RuntimeError('stdlib ssl module not available')

        if ssl_handshake_timeout is None:
            ssl_handshake_timeout = constants.SSL_HANDSHAKE_TIMEOUT
        elif ssl_handshake_timeout <= 0:
            raise ValueError(
                f"ssl_handshake_timeout should be a positive number, "
                f"got {ssl_handshake_timeout}")

        if not sslcontext:
            sslcontext = _create_transport_context(server_side,
                                                   server_hostname)

        self._waiter = waiter
        self._app_transport = _SSLTransport(loop, self)
        self._app_protocol = app_protocol
        self._server_side = server_side
        if server_hostname and not server_side:
            self._server_hostname = server_hostname
        else:
            self._server_hostname = None
        self._sslcontext = sslcontext
        # SSL-specific extra info. More info are set when the handshake
        # completes.
        self._extra = dict(sslcontext=sslcontext)

        self._sslobj = None
        self._transport = None
        self._state = _UNWRAPPED
        self._incoming = ssl.MemoryBIO()
        self._outgoing = ssl.MemoryBIO()
        self._ssl_buffer = bytearray(262144)
Beispiel #22
0
    def _do_ssl_handshake(self):
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
        incoming = ssl.MemoryBIO()
        outgoing = ssl.MemoryBIO()

        sslobj = context.wrap_bio(incoming, outgoing, False)

        # do_handshake()
        while True:
            try:
                sslobj.do_handshake()
            except ssl.SSLWantReadError:
                self._send_message(TDS_PRELOGIN, outgoing.read())
                tag, _, _, buf = self._read_response_packet()
                assert tag == TDS_PRELOGIN
                incoming.write(buf)
            else:
                break

        return sslobj, incoming, outgoing
Beispiel #23
0
 def test_spoof_https_site_through_https_proxy(self):
     # This is a proof-of-concept for proxying HTTPS requests through an
     # HTTPS server. Typically, HTTPS requests are proxied via CONNECT verb
     # on a plain-text HTTP server. This means proxy credentials are sent
     # in the clear, as well as the intended destination. Proxying via HTTPS
     # allows these to be nominally protected. At this time, no major
     # HTTP libraries support proxying HTTPS requests through HTTPS servers,
     # so the actual request portion of the test is quite crude, reading and
     # writing directly to sockets. The use of the `ssl.SSLContext.wrap_bio`
     # method allows arbitrary SSL I/O, provided data is written to and read
     # out of BIO instances. This is required as it's not possible to for an
     # `ssl.SSLContext` socket to wrap another `ssl.SSLContext` socket.
     expected = upstream_content = b"octet-comeback-squirmy"
     chunk_size = 4096
     httpd = spoof.HTTPServer(
         sslContext=spoof.SSLContext.fromCertChain(self.cert, self.key))
     httpd.defaultResponse = [200, [], ""]
     httpd.start()
     httpd.upstream = spoof.HTTPUpstreamServer(
         sslContext=spoof.SSLContext.fromCertChain(self.cert, self.key))
     httpd.upstream.defaultResponse = [200, [], upstream_content]
     httpd.upstream.start()
     client = ssl.create_default_context(cafile=self.cert).wrap_socket(
         socket.create_connection(httpd.serverAddress),
         server_hostname=httpd.address)
     client.sendall(b"CONNECT google.com HTTP/1.0\r\n\r\n")
     client.recv(chunk_size)  # response headers
     tunnel_in = ssl.MemoryBIO()
     tunnel_out = ssl.MemoryBIO()
     tunnel = ssl.create_default_context(cafile=self.cert).wrap_bio(
         tunnel_in, tunnel_out, server_hostname="google.com")
     tunnel_cmd = functools.partial(utils.ssl_io_loop, client, tunnel_in,
                                    tunnel_out)
     tunnel_cmd(tunnel.do_handshake)
     tunnel_cmd(tunnel.write, b"GET / HTTP/1.0\r\n\r\n")
     tunnel_cmd(tunnel.read, chunk_size)  # response headers
     result = tunnel_cmd(tunnel.read, chunk_size)
     client.close()
     httpd.upstream.stop()
     httpd.stop()
     self.assertEqual(expected, result)
Beispiel #24
0
def test_set_keylog_bio(tmpdir, context, ssl_server):
    keylog = tmpdir / "sslkeylog.txt"
    sslkeylog.set_keylog(str(keylog))

    with closing(socket.create_connection(ADDRESS)) as sock:
        incoming = ssl.MemoryBIO()
        outgoing = ssl.MemoryBIO()
        sslobj = context.wrap_bio(incoming,
                                  outgoing,
                                  server_side=False,
                                  server_hostname=ADDRESS[0])

        ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)

    time.sleep(2)

    data = keylog.read_text("utf-8").splitlines()
    if sslkeylog.OPENSSL111:
        assert len(data) == 10
    else:
        assert len(data) == 2
        for line in data:
            assert LOG_LINE_REGEX.search(line)
Beispiel #25
0
    def __init__(self, parent_context, ssl_context, server_hostname):
        self._parent_context = parent_context
        self._ssl_context = ssl_context

        # We need this extra buffer to implement the peek/consume API, which
        # the MemoryBIO object does not allow.
        self._ciphertext_buffer = bytearray()

        # Set up the SSLObject we're going to back this with.
        server_side = isinstance(parent_context, ServerContext)
        self._in_bio = ssl.MemoryBIO()
        self._out_bio = ssl.MemoryBIO()
        self._object = ssl_context.wrap_bio(self._in_bio,
                                            self._out_bio,
                                            server_side=server_side,
                                            server_hostname=server_hostname)

        # Keep track of the fact that we are the owner of this object.
        _object_to_buffer_map[self._object] = self

        # We need to track whether the connection is established to properly
        # report the TLS version. This is to work around a Python bug:
        # https://bugs.python.org/issue29781
        self._connection_established = False
Beispiel #26
0
    async def handle(self):
        """ does the thing """

        self.body = b''
        try:
            method_line, self.headers, self.body = await self.read_request(self
                                                                           )
        except asyncio.streams.IncompleteReadError:
            self.writer.close()
            return False

        # GET http://www.example.com/ HTTP/1.1
        self.method, self.url, self.version = method_line.decode().split()
        if self.ssl:
            # if https, the host is omitted because the client thinks its talking directly to the server
            self.url = f"https://{self.ssl_hostname}{self.url}"

        self.log(f"{self.method} {self.url} {self.version}")
        """
        if self.url == 'http://oopsiewhoopsie.proxy/breakhttps.crt':
            async with aiofiles.open(CA_PATH + "/ca.crt", "rb") as f:
                self.body = await f.read()
            await self.send_response("200 :ok_hand:", body=self.body, addn_headers={
                'Content-Type': 'application/x-x509-ca-cert',
                'Connection': 'close'
            })

            self.writer.close()
            return False
        """

        # SSL proxy
        # CONNECT example.com:443 HTTP/1.1
        if self.method == "CONNECT" and self.url.endswith(":443"):
            self.ssl_hostname = self.url.split(':')[0]
            cert_path = os.path.join(CERTS_PATH, self.ssl_hostname + ".crt")
            if not os.path.isfile(cert_path):
                subprocess.check_call(["./mkcrt", self.ssl_hostname])
                self.log(f"./mkcrt {self.ssl_hostname} -> {cert_path}")
            self.writer.write(b"HTTP/1.1 200 Yeet Dab\r\n\r\n")

            # REALLY hacky lul
            self.ssl = True
            self._ssl_ctx = ssl.SSLContext()
            self._ssl_ctx.load_cert_chain(cert_path,
                                          keyfile=f"{CA_PATH}/cert.key")
            self._ssl_in = ssl.MemoryBIO()
            self._ssl_out = ssl.MemoryBIO()
            self._ssl_obj = self._ssl_ctx.wrap_bio(
                self._ssl_in,
                self._ssl_out,
                server_side=True,
                server_hostname=self.ssl_hostname)
            self._ssl_buf = b''
            await self.ssl_handshake()
            return True

        # drop unsupported headers oopsy whoopsy
        # reee keepalives

        keepalive = self.headers.get("Connection", "f").lower() == "keep-alive" or \
            self.headers.get("Proxy-Connection", "f").lower() == "keep-alive"

        # to hell with trailers, also the client doesn't support keepalive
        for k in ["Connection", "Proxy-Connection", "TE"]:
            try:
                del self.headers[k]
            except KeyError:
                pass

        # make the request to the host
        await self.respond()

        #self.log(f"keepalive == {keepalive}")
        if not keepalive:
            self.writer.close()

        return keepalive
Beispiel #27
0
from contextlib import contextmanager
import ssl

client_ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
client_ctx.check_hostname = False
client_ctx.verify_mode = ssl.CERT_NONE

cinb = ssl.MemoryBIO()
coutb = ssl.MemoryBIO()
cso = client_ctx.wrap_bio(cinb, coutb)

server_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
server_ctx.load_cert_chain("server.crt", "server.key", "xxxx")
sinb = ssl.MemoryBIO()
soutb = ssl.MemoryBIO()
sso = server_ctx.wrap_bio(sinb, soutb, server_side=True)


@contextmanager
def expect(etype):
    try:
        yield
    except etype:
        pass
    else:
        raise AssertionError("expected {}".format(etype))


with expect(ssl.SSLWantReadError):
    cso.do_handshake()
assert not cinb.pending
Beispiel #28
0
    def handle_pair_request(self):
        if bluetooth_support_kitkat:
            pair_tls_ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_TLSv1)
            pair_tls_ctx.set_ciphers('DHE-RSA-AES256-SHA')
            pair_tls_ctx.load_dh_params(DHPARAM_PATH)
        else:
            pair_tls_ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_TLSv1_2)
            pair_tls_ctx.set_ciphers('ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA')
            pair_tls_ctx.set_ecdh_curve('prime256v1')

        pair_tls_ctx.load_cert_chain(CERTIFICATE_PATH, RSA_PRIVATE_KEY_PATH)

        self.incoming = ssl.MemoryBIO()
        self.outgoing = ssl.MemoryBIO()
        self.tls_bio = pair_tls_ctx.wrap_bio(incoming=self.incoming, outgoing=self.outgoing, server_side=True)

        try:
            self.do_handshake()
        except ssl.SSLError as ssle:
            logging.error('(Bluetooth) Failed TLS handshake pair_request: {}'.format(ssle))
            return

        logging.info('(Bluetooth) Pair request from: {}\n'.format(self.address))

        '''I don't know how else to do this when using SSLEngine/SSL_BIO, I don't see any security
        issue with sending the length of the encrypted data in cleartext, using something like wireshark
        it's possible to see the length anyway'''
        client_cert_size = struct.unpack('>I', recvall(self.socket, 4))[0]
        client_cert_encrypted = recvall(self.socket, client_cert_size)
        client_cert = self.tls_decrypt(client_cert_encrypted)

        sha256 = hashlib.sha256(client_cert + SERVER_CERT_DER).hexdigest().upper()
        sha256_format = [sha256[x:x + 2] for x in range(0, len(sha256), 2)]

        print('It is very important that you verify that the following hash matches what is viewed on your phone\n'
              'It is a sha256 hash like so: sha256(client_cert + server_cert)\n\n'
              'If the hash don\'t match there could be a man-in-the-middle attack\n'
              'Or something else is not right, you should abort if they don\'t match!\n')
        print(' '.join(sha256_format[:8]))
        print(' '.join(sha256_format[8:16]))
        print(' '.join(sha256_format[16:24]))
        print(' '.join(sha256_format[24:]))

        self.server_allow_pair = False
        self.client_allow_pair = False

        try:
            termios.tcflush(sys.stdin, termios.TCIFLUSH)
        except Exception:
            pass
        self.user_input_prompt = 'Enter "yes" to accept pairing or "no" to deny: '
        print('\n{}'.format(self.user_input_prompt), end='')

        threading.Thread(target=self.pair_response_thread).start()
        while not BluetoothHandler.cancel_pairing:
            ready = select.select([sys.stdin], [], [], 1)[0]
            if ready:
                user_input = sys.stdin.readline().strip()
                if user_input.casefold() == 'yes'.casefold():
                    encrypted = self.tls_encrypt(ACCEPT_PAIRING)
                    encrypted_size = struct.pack('>I', len(encrypted))
                    self.socket.sendall(encrypted_size)
                    self.socket.sendall(encrypted)
                    self.server_allow_pair = True
                    if not self.client_allow_pair:
                        print('Waiting for client response')
                    while not BluetoothHandler.cancel_pairing:
                        if self.client_allow_pair:
                            add_to_authorized_certs(client_cert)
                            break
                        else:
                            time.sleep(1)
                    break
                elif user_input.casefold() == 'no'.casefold():
                    encrypted = self.tls_encrypt(DENY_PAIRING)
                    encrypted_size = struct.pack('>I', len(encrypted))
                    self.socket.sendall(encrypted_size)
                    self.socket.sendall(encrypted)
                    print('Pairing canceled')
                    BluetoothHandler.cancel_pairing = True
                else:
                    print(self.user_input_prompt, end='', flush=True)
Beispiel #29
0
 def __init__(self, ctx, sock, **kwargs):
     self.incoming = ssl.MemoryBIO()
     self.outgoing = ssl.MemoryBIO()
     self.obj = ctx.wrap_bio(self.incoming, self.outgoing, **kwargs)
     self.sock = sock
Beispiel #30
0
    def __init__(self, loop, app_protocol, sslcontext, waiter,
                 server_side=False, server_hostname=None,
                 call_connection_made=True,
                 ssl_handshake_timeout=None,
                 ssl_shutdown_timeout=None):
        if ssl is None:
            raise RuntimeError("stdlib ssl module not available")

        self._ssl_buffer = bytearray(self.max_size)
        self._ssl_buffer_view = memoryview(self._ssl_buffer)

        if ssl_handshake_timeout is None:
            ssl_handshake_timeout = constants.SSL_HANDSHAKE_TIMEOUT
        elif ssl_handshake_timeout <= 0:
            raise ValueError(
                f"ssl_handshake_timeout should be a positive number, "
                f"got {ssl_handshake_timeout}")
        if ssl_shutdown_timeout is None:
            ssl_shutdown_timeout = constants.SSL_SHUTDOWN_TIMEOUT
        elif ssl_shutdown_timeout <= 0:
            raise ValueError(
                f"ssl_shutdown_timeout should be a positive number, "
                f"got {ssl_shutdown_timeout}")

        if not sslcontext:
            sslcontext = _create_transport_context(
                server_side, server_hostname)

        self._server_side = server_side
        if server_hostname and not server_side:
            self._server_hostname = server_hostname
        else:
            self._server_hostname = None
        self._sslcontext = sslcontext
        # SSL-specific extra info. More info are set when the handshake
        # completes.
        self._extra = dict(sslcontext=sslcontext)

        # App data write buffering
        self._write_backlog = collections.deque()
        self._write_buffer_size = 0

        self._waiter = waiter
        self._loop = loop
        self._set_app_protocol(app_protocol)
        self._app_transport = None
        self._app_transport_created = False
        # transport, ex: SelectorSocketTransport
        self._transport = None
        self._ssl_handshake_timeout = ssl_handshake_timeout
        self._ssl_shutdown_timeout = ssl_shutdown_timeout
        # SSL and state machine
        self._incoming = ssl.MemoryBIO()
        self._outgoing = ssl.MemoryBIO()
        self._state = SSLProtocolState.UNWRAPPED
        self._conn_lost = 0  # Set when connection_lost called
        if call_connection_made:
            self._app_state = AppProtocolState.STATE_INIT
        else:
            self._app_state = AppProtocolState.STATE_CON_MADE
        self._sslobj = self._sslcontext.wrap_bio(
            self._incoming, self._outgoing,
            server_side=self._server_side,
            server_hostname=self._server_hostname)

        # Flow Control

        self._ssl_writing_paused = False

        self._app_reading_paused = False

        self._ssl_reading_paused = False
        self._incoming_high_water = 0
        self._incoming_low_water = 0
        self._set_read_buffer_limits()
        self._eof_received = False

        self._app_writing_paused = False
        self._outgoing_high_water = 0
        self._outgoing_low_water = 0
        self._set_write_buffer_limits()
        self._get_app_transport()