예제 #1
0
    def test_get_dh_info_ecdh_p256(self):
        with ModernOpenSslServer(cipher="ECDHE-RSA-AES256-SHA",
                                 groups="P-256") as server:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            ssl_client = SslClient(ssl_version=OpenSslVersionEnum.TLSV1_2,
                                   underlying_socket=sock,
                                   ssl_verify=OpenSslVerifyEnum.NONE)

            try:
                ssl_client.do_handshake()
            finally:
                ssl_client.shutdown()

            dh_info = ssl_client.get_dh_info()

            assert isinstance(dh_info, NistEcDhKeyExchangeInfo)
            assert dh_info.key_type == OpenSslEvpPkeyEnum.EC
            assert dh_info.key_size == 256
            assert dh_info.curve == OpenSslEcNidEnum.PRIME256V1
            assert len(dh_info.public_key) == 65
            assert len(dh_info.x) == 32
            assert len(dh_info.y) == 32
예제 #2
0
    def test_set_groups_curve_x448(self):
        # Given a server that supports a bunch of curves
        with ModernOpenSslServer(
                cipher="ECDHE-RSA-AES256-SHA",
                groups="X25519:prime256v1:X448:secp384r1:secp192k1") as server:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            # And a client that only supports a specific curve: X448
            ssl_client = SslClient(
                ssl_version=OpenSslVersionEnum.TLSV1_2,
                underlying_socket=sock,
                ssl_verify=OpenSslVerifyEnum.NONE,
            )
            configured_curve = OpenSslEcNidEnum.X448
            ssl_client.set_groups([configured_curve])

            # When the client connects to the server
            try:
                ssl_client.do_handshake()
            finally:
                ssl_client.shutdown()

            # The curve enabled in the client is the one that was used
            dh_info = ssl_client.get_ephemeral_key()
            assert isinstance(dh_info, EcDhEphemeralKeyInfo)
            assert dh_info.curve == configured_curve
            assert dh_info.type == OpenSslEvpPkeyEnum.X448
            assert dh_info.size == 448
            assert len(dh_info.public_bytes) == 56
예제 #3
0
    def test_get_dh_info_ecdh_x25519(self):
        with ModernOpenSslServer(cipher="ECDHE-RSA-AES256-SHA",
                                 groups="X25519") as server:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            ssl_client = SslClient(
                ssl_version=OpenSslVersionEnum.TLSV1_2,
                underlying_socket=sock,
                ssl_verify=OpenSslVerifyEnum.NONE,
            )

            try:
                ssl_client.do_handshake()
            finally:
                ssl_client.shutdown()

            dh_info = ssl_client.get_ephemeral_key()

            assert isinstance(dh_info, EcDhEphemeralKeyInfo)
            assert dh_info.type == OpenSslEvpPkeyEnum.X25519
            assert dh_info.size == 253
            assert dh_info.curve == OpenSslEcNidEnum.X25519
            assert len(dh_info.public_bytes) == 32
예제 #4
0
파일: X509_Tests.py 프로젝트: danadam/nassl
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        ssl_client = SslClient(sock=sock, ssl_verify=SSL_VERIFY_NONE)
        ssl_client.do_handshake()
        self.cert = ssl_client.get_peer_certificate()._x509
예제 #5
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        ssl_client = SslClient(sock=sock, ssl_verify=SSL_VERIFY_NONE)
        ssl_client.do_handshake()
        self.cert = ssl_client.get_peer_certificate()._x509
예제 #6
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("login.live.com", 443))

        ssl_client = SslClient(sock=sock, ssl_verify=SSL_VERIFY_NONE)
        ssl_client.set_tlsext_status_ocsp()
        ssl_client.do_handshake()
        self.ocsp_response = ssl_client.get_tlsext_status_ocsp_resp()._ocsp_response
예제 #7
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("login.live.com", 443))

        ssl_client = SslClient(sock=sock, ssl_verify=SSL_VERIFY_NONE)
        ssl_client.set_tlsext_status_ocsp()
        ssl_client.do_handshake()
        self.ocsp_response = ssl_client.get_tlsext_status_ocsp_resp(
        )._ocsp_response
예제 #8
0
    def test(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        ssl_client = SslClient(sock=sock, ssl_verify=SSL_VERIFY_NONE)
        ssl_client.do_handshake()
        self.name_entry = ssl_client.get_peer_certificate()._x509.get_subject_name_entries()[0];

        self.assertIsNotNone(self.name_entry.get_data())
        self.assertIsNotNone(self.name_entry.get_object())
예제 #9
0
    def setUp(self):
        # Requires being online :(
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.fr", 443))

        ssl_client = SslClient(ssl_version=SSLV23,
                               sock=sock,
                               ssl_verify=SSL_VERIFY_NONE)
        ssl_client.do_handshake()
        self.ssl_client = ssl_client
        self.cert = ssl_client.get_peer_certificate()
예제 #10
0
    def test(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(('www.google.com', 443))

        sslClient = SslClient(sock=sock, ssl_verify=OpenSslVerifyEnum.NONE)
        sslClient.do_handshake()
        self.x509ext = sslClient.get_peer_certificate()._x509.get_extensions()[0]

        self.assertIsNotNone(self.x509ext.get_data())
        self.assertIsNotNone(self.x509ext.get_object())
        self.assertIsNotNone(self.x509ext.get_critical())
예제 #11
0
    def test(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        ssl_client = SslClient(sock=sock, ssl_verify=SSL_VERIFY_NONE)
        ssl_client.do_handshake()
        self.name_entry = ssl_client.get_peer_certificate(
        )._x509.get_subject_name_entries()[0]

        self.assertIsNotNone(self.name_entry.get_data())
        self.assertIsNotNone(self.name_entry.get_object())
예제 #12
0
    def test(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        sslClient = SslClient(sock=sock, ssl_verify=SSL_VERIFY_NONE)
        sslClient.do_handshake()
        self.x509ext = sslClient.get_peer_certificate()._x509.get_extensions()[0]

        self.assertIsNotNone(self.x509ext.get_data())
        self.assertIsNotNone(self.x509ext.get_object())
        self.assertIsNotNone(self.x509ext.get_critical())
예제 #13
0
    def test_hostname_validation(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.fr", 443))

        ssl_client = SslClient(ssl_version=SSLV23, sock=sock, ssl_verify=SSL_VERIFY_NONE)
        ssl_client.do_handshake()
        self.ssl_client = ssl_client
        self.cert = ssl_client.get_peer_certificate()

        self.assertEqual(X509_NAME_MATCHES_SAN, self.cert.matches_hostname('www.google.fr'))
        self.assertEqual(X509_NAME_MISMATCH, self.cert.matches_hostname('www.tests.com'))
예제 #14
0
def get_certificate_chain(host: str, port: int) -> List[str]:

    """ Connect to the host on the port and obtain certificate chain.
     TODO: Tests against WantReadError and WantX509LookupError needed. """

    cert_chain = []

    soc = socket(AF_INET, SOCK_STREAM, proto=0)
    soc.settimeout(3)

    try:
        soc.connect((host, port))

    except gaierror:
        raise Exception(f"{host}:{port} is invalid or not known.") from None

    except timeout:
        raise Exception(f"Connection to {host}:{port} timed out.") from None

    except OverflowError:
        raise Exception(f"Illegal port: {port}. Port must be between 0-65535.") from None

    except TypeError:
        raise Exception(f"Illegal port: {port}. Port must be between 0-65535.") from None

    ssl_client = SslClient(
        ssl_version=OpenSslVersionEnum.SSLV23,
        underlying_socket=soc,
        ssl_verify=OpenSslVerifyEnum.NONE
    )

    # Add Server Name Indication (SNI) extension to the CLIENT HELLO
    ssl_client.set_tlsext_host_name(host)

    try:
        ssl_client.do_handshake()
        cert_chain = ssl_client.get_received_chain()

    except WantReadError as err:
        raise ValueError(err.strerror) from None

    except WantX509LookupError as err:
        raise ValueError(err.strerror) from None

    except OpenSSLError as err:
        raise ValueError(err) from None

    finally:
        ssl_client.shutdown()
        soc = None

    return cert_chain
예제 #15
0
    def test_sct_parsing(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(('sslanalyzer.comodoca.com', 443))

        ssl_client = SslClient(underlying_socket=sock, ssl_verify=OpenSslVerifyEnum.NONE)
        ssl_client.set_tlsext_status_ocsp()
        ssl_client.do_handshake()
        ocsp_response = ssl_client.get_tlsext_status_ocsp_resp()
        ssl_client.shutdown()
        sock.close()

        self.assertIsNotNone(ocsp_response.as_dict()['responses'][0]['singleExtensions']['ctCertificateScts'])
예제 #16
0
    def test_tls_1_3(self):
        # Given a server that supports TLS 1.3
        with ModernOpenSslServer() as server:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            ssl_client = SslClient(ssl_version=OpenSslVersionEnum.TLSV1_3,
                                   underlying_socket=sock,
                                   ssl_verify=OpenSslVerifyEnum.NONE)
            # When doing the TLS 1.3 handshake, it succeeds
            try:
                ssl_client.do_handshake()
            finally:
                ssl_client.shutdown()
예제 #17
0
    def test_hostname_validation(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(('www.google.fr', 443))

        ssl_client = SslClient(ssl_version=OpenSslVersionEnum.SSLV23,
                               sock=sock,
                               ssl_verify=OpenSslVerifyEnum.NONE)
        ssl_client.do_handshake()
        self.ssl_client = ssl_client
        self.cert = ssl_client.get_peer_certificate()

        self.assertEqual(HostnameValidationResultEnum.NAME_MATCHES_SAN,
                         self.cert.matches_hostname('www.google.fr'))
        self.assertEqual(HostnameValidationResultEnum.NAME_DOES_NOT_MATCH,
                         self.cert.matches_hostname('www.tests.com'))
예제 #18
0
    def test_client_authentication_tls_1_3(self):
        # Given a server that requires client authentication
        with ModernOpenSslServer(
                client_auth_config=ClientAuthConfigEnum.REQUIRED) as server:
            # And the client provides an invalid client certificate (actually the server cert)
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            ssl_client = SslClient(ssl_version=OpenSslVersionEnum.TLSV1_3,
                                   underlying_socket=sock,
                                   ssl_verify=OpenSslVerifyEnum.NONE)

            # When doing the handshake the right error is returned
            with pytest.raises(ClientCertificateRequested):
                ssl_client.do_handshake()
예제 #19
0
    def test_client_authentication_tls_1_3(self):
        # Given a server that requires client authentication
        with ModernOpenSslServer(client_auth_config=ClientAuthConfigEnum.REQUIRED) as server:
            # And the client provides an invalid client certificate (actually the server cert)
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            ssl_client = SslClient(
                ssl_version=OpenSslVersionEnum.TLSV1_3,
                underlying_socket=sock,
                ssl_verify=OpenSslVerifyEnum.NONE,
            )

            # When doing the handshake the right error is returned
            with pytest.raises(ClientCertificateRequested):
                ssl_client.do_handshake()
예제 #20
0
    def test_tls_1_3(self):
        # Given a server that supports TLS 1.3
        with ModernOpenSslServer() as server:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            ssl_client = SslClient(
                ssl_version=OpenSslVersionEnum.TLSV1_3,
                underlying_socket=sock,
                ssl_verify=OpenSslVerifyEnum.NONE
            )
            # When doing the TLS 1.3 handshake, it succeeds
            try:
                ssl_client.do_handshake()
            finally:
                ssl_client.shutdown()
예제 #21
0
    def test(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(('www.cloudflare.com', 443))

        ssl_client = SslClient(underlying_socket=sock,
                               ssl_verify=OpenSslVerifyEnum.NONE)
        ssl_client.set_tlsext_status_ocsp()
        ssl_client.do_handshake()
        ocsp_response = ssl_client.get_tlsext_status_ocsp_resp()
        ssl_client.shutdown()

        self.assertEqual(ocsp_response.status,
                         OcspResponseStatusEnum.SUCCESSFUL)

        # Test as_text()
        self.assertIsNotNone(ocsp_response.as_text())

        # Test verify with a wrong certificate
        test_file = tempfile.NamedTemporaryFile(delete=False, mode='wt')
        test_file.write("""-----BEGIN CERTIFICATE-----
MIIDCjCCAnOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBgDELMAkGA1UEBhMCRlIx
DjAMBgNVBAgMBVBhcmlzMQ4wDAYDVQQHDAVQYXJpczEWMBQGA1UECgwNRGFzdGFy
ZGx5IEluYzEMMAoGA1UECwwDMTIzMQ8wDQYDVQQDDAZBbCBCYW4xGjAYBgkqhkiG
9w0BCQEWC2xvbEBsb2wuY29tMB4XDTEzMDEyNzAwMDM1OFoXDTE0MDEyNzAwMDM1
OFowgZcxCzAJBgNVBAYTAkZSMQwwCgYDVQQIDAMxMjMxDTALBgNVBAcMBFRlc3Qx
IjAgBgNVBAoMGUludHJvc3B5IFRlc3QgQ2xpZW50IENlcnQxCzAJBgNVBAsMAjEy
MRUwEwYDVQQDDAxBbGJhbiBEaXF1ZXQxIzAhBgkqhkiG9w0BCQEWFG5hYmxhLWMw
ZDNAZ21haWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlnvP1ltVO
8JDNT3AA99QqtiqCi/7BeEcFDm2al46mv7looz6CmB84osrusNVFsS5ICLbrCmeo
w5sxW7VVveGueBQyWynngl2PmmufA5Mhwq0ZY8CvwV+O7m0hEXxzwbyGa23ai16O
zIiaNlBAb0mC2vwJbsc3MTMovE6dHUgmzQIDAQABo3sweTAJBgNVHRMEAjAAMCwG
CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV
HQ4EFgQUYR45okpFsqTYB1wlQQblLH9cRdgwHwYDVR0jBBgwFoAUP0X2HQlaca7D
NBzVbsjsdhzOqUQwDQYJKoZIhvcNAQEFBQADgYEAWEOxpRjvKvTurDXK/sEUw2KY
gmbbGP3tF+fQ/6JS1VdCdtLxxJAHHTW62ugVTlmJZtpsEGlg49BXAEMblLY/K7nm
dWN8oZL+754GaBlJ+wK6/Nz4YcuByJAnN8OeTY4Acxjhks8PrAbZgcf0FdpJaAlk
Pd2eQ9+DkopOz3UGU7c=
-----END CERTIFICATE-----""")
        test_file.close()
        self.assertRaises(OcspResponseNotTrustedError, ocsp_response.verify,
                          test_file.name)

        # No SCT extension
        self.assertFalse('singleExtensions' in ocsp_response.as_dict()
                         ['responses'][0].keys())
예제 #22
0
    def _create_tls_1_3_session(server_host: str,
                                server_port: int) -> _nassl.SSL_SESSION:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect((server_host, server_port))

        ssl_client = SslClient(ssl_version=OpenSslVersionEnum.TLSV1_3,
                               underlying_socket=sock,
                               ssl_verify=OpenSslVerifyEnum.NONE)

        try:
            ssl_client.do_handshake()
            ssl_client.write(ModernOpenSslServer.HELLO_MSG)
            ssl_client.read(2048)
            session = ssl_client.get_session()

        finally:
            ssl_client.shutdown()
        return session
예제 #23
0
    def test_tls_1_3_write_early_data_does_not_finish_handshake(self):
        # Given a server that supports TLS 1.3 and early data
        with ModernOpenSslServer(max_early_data=512) as server:
            # That has a previous TLS 1.3 session with the server
            session = self._create_tls_1_3_session(server.hostname,
                                                   server.port)
            assert session

            # And the server accepts early data
            max_early = session.get_max_early_data()
            assert max_early > 0

            # When creating a new connection
            sock_early_data = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock_early_data.settimeout(5)
            sock_early_data.connect((server.hostname, server.port))

            ssl_client_early_data = SslClient(
                ssl_version=OpenSslVersionEnum.TLSV1_3,
                underlying_socket=sock_early_data,
                ssl_verify=OpenSslVerifyEnum.NONE,
            )

            # That re-uses the previous TLS 1.3 session
            ssl_client_early_data.set_session(session)
            assert OpenSslEarlyDataStatusEnum.NOT_SENT == ssl_client_early_data.get_early_data_status(
            )

            # When sending early data
            ssl_client_early_data.write_early_data(b"EARLY DATA")

            # It succeeds
            assert not ssl_client_early_data.is_handshake_completed()
            assert OpenSslEarlyDataStatusEnum.REJECTED == ssl_client_early_data.get_early_data_status(
            )

            # And after completing the handshake, the early data was accepted
            ssl_client_early_data.do_handshake()
            assert OpenSslEarlyDataStatusEnum.ACCEPTED == ssl_client_early_data.get_early_data_status(
            )

            ssl_client_early_data.shutdown()
예제 #24
0
    def _create_tls_1_3_session(server_host: str, server_port: int) -> _nassl.SSL_SESSION:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect((server_host, server_port))

        ssl_client = SslClient(
            ssl_version=OpenSslVersionEnum.TLSV1_3,
            underlying_socket=sock,
            ssl_verify=OpenSslVerifyEnum.NONE
        )

        try:
            ssl_client.do_handshake()
            ssl_client.write(ModernOpenSslServer.HELLO_MSG)
            ssl_client.read(2048)
            session = ssl_client.get_session()

        finally:
            ssl_client.shutdown()
        return session
예제 #25
0
    def test_tls_1_3_write_early_data_does_not_finish_handshake(self):
        # Given a server that supports TLS 1.3 and early data
        with ModernOpenSslServer(max_early_data=512) as server:
            # That has a previous TLS 1.3 session with the server
            session = self._create_tls_1_3_session(server.hostname, server.port)
            assert session

            # And the server accepts early data
            max_early = session.get_max_early_data()
            assert max_early > 0

            # When creating a new connection
            sock_early_data = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock_early_data.settimeout(5)
            sock_early_data.connect((server.hostname, server.port))

            ssl_client_early_data = SslClient(
                ssl_version=OpenSslVersionEnum.TLSV1_3,
                underlying_socket=sock_early_data,
                ssl_verify=OpenSslVerifyEnum.NONE
            )

            # That re-uses the previous TLS 1.3 session
            ssl_client_early_data.set_session(session)
            assert OpenSslEarlyDataStatusEnum.NOT_SENT == ssl_client_early_data.get_early_data_status()

            # When sending early data
            ssl_client_early_data.write_early_data(b'EARLY DATA')

            # It succeeds
            assert not ssl_client_early_data.is_handshake_completed()
            assert OpenSslEarlyDataStatusEnum.REJECTED == ssl_client_early_data.get_early_data_status()

            # And after completing the handshake, the early data was accepted
            ssl_client_early_data.do_handshake()
            assert OpenSslEarlyDataStatusEnum.ACCEPTED == ssl_client_early_data.get_early_data_status()

            ssl_client_early_data.shutdown()
예제 #26
0
    def test_get_verified_chain_but_validation_failed(self):
        # Given an SslClient connecting to Google
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        ssl_client = SslClient(
            ssl_version=OpenSslVersionEnum.TLSV1_2,
            underlying_socket=sock,
            # That is configured to silently fail validation
            ssl_verify=OpenSslVerifyEnum.NONE,
        )

        # When doing a TLS handshake, it succeeds
        try:
            ssl_client.do_handshake()

            # And when requesting the verified certificate chain
            with pytest.raises(CertificateChainVerificationFailed):
                # It fails because certificate validation failed
                ssl_client.get_verified_chain()
        finally:
            ssl_client.shutdown()
예제 #27
0
    def test_get_verified_chain(self):
        # Given an SslClient connecting to Google
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.yahoo.com", 443))
        print(str(Path(__file__).absolute().parent / "google_roots.pem"))
        ssl_client = SslClient(
            ssl_version=OpenSslVersionEnum.TLSV1_2,
            underlying_socket=sock,
            # That is configured to properly validate certificates
            ssl_verify=OpenSslVerifyEnum.PEER,
            ssl_verify_locations=Path(__file__).absolute().parent /
            "mozilla.pem",
        )

        # When doing a TLS handshake, it succeeds
        try:
            ssl_client.do_handshake()

            # And when requesting the verified certificate chain, it returns it
            assert ssl_client.get_verified_chain()
        finally:
            ssl_client.shutdown()
예제 #28
0
    def test_get_verified_chain(self):
        # Given an SslClient connecting to Google
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(('www.yahoo.com', 443))
        print(str(Path(__file__).absolute().parent / 'google_roots.pem'))
        ssl_client = SslClient(
            ssl_version=OpenSslVersionEnum.TLSV1_2,
            underlying_socket=sock,

            # That is configured to properly validate certificates
            ssl_verify=OpenSslVerifyEnum.PEER,
            ssl_verify_locations=str(Path(__file__).absolute().parent / 'mozilla.pem')
        )

        # When doing a TLS handshake, it succeeds
        try:
            ssl_client.do_handshake()

            # And when requesting the verified certificate chain, it returns it
            assert ssl_client.get_verified_chain()
        finally:
            ssl_client.shutdown()
예제 #29
0
    def test_get_verified_chain_but_validation_failed(self):
        # Given an SslClient connecting to Google
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(('www.google.com', 443))

        ssl_client = SslClient(
            ssl_version=OpenSslVersionEnum.TLSV1_2,
            underlying_socket=sock,

            # That is configured to silently fail validation
            ssl_verify=OpenSslVerifyEnum.NONE
        )

        # When doing a TLS handshake, it succeeds
        try:
            ssl_client.do_handshake()

            # And when requesting the verified certificate chain
            with pytest.raises(CouldNotBuildVerifiedChain):
                # It fails because certificate validation failed
                ssl_client.get_verified_chain()
        finally:
            ssl_client.shutdown()
예제 #30
0
    def test_set_ciphersuites(self):
        # Given a server that supports TLS 1.3
        with ModernOpenSslServer() as server:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((server.hostname, server.port))

            # And a client that only supports a specific TLS 1.3 cipher suite
            ssl_client = SslClient(
                ssl_version=OpenSslVersionEnum.TLSV1_3,
                underlying_socket=sock,
                ssl_verify=OpenSslVerifyEnum.NONE,
            )
            ssl_client.set_ciphersuites("TLS_CHACHA20_POLY1305_SHA256")

            # When doing the TLS 1.3 handshake, it succeeds
            try:
                ssl_client.do_handshake()
            finally:
                ssl_client.shutdown()

        # And client's cipher suite was used
        assert "TLS_CHACHA20_POLY1305_SHA256" == ssl_client.get_current_cipher_name(
        )
예제 #31
0
def get_certificate_chain(host: str, port: int) -> List[str]:
    """Connect to the host on the port and obtain certificate chain"""

    func_name: str = "get_certificate_chain"

    cert_chain: list = []

    soc = socket(AF_INET, SOCK_STREAM, proto=0)
    soc.settimeout(3)

    try:
        soc.connect((host, port))

    except gaierror:
        raise Exception(
            f"{func_name}: {host}:{port} is invalid or not known.") from None

    except timeout:
        raise Exception(
            f"{func_name}: Connection to {host}:{port} timed out.") from None

    except (OverflowError, TypeError):
        raise Exception(
            f"{func_name}: Illegal port: {port}. Port must be between 0-65535."
        ) from None

    except ConnectionRefusedError:
        raise Exception(
            f"{func_name}: Connection to {host}:{port} refused.") from None

    ssl_client = SslClient(
        ssl_version=OpenSslVersionEnum.SSLV23,
        underlying_socket=soc,
        ssl_verify=OpenSslVerifyEnum.NONE,
    )

    # Add Server Name Indication (SNI) extension to the Client Hello
    ssl_client.set_tlsext_host_name(host)

    try:
        ssl_client.do_handshake()
        cert_chain = ssl_client.get_received_chain()

    except IOError as err:
        raise ValueError(
            f"{func_name}: {host} did not respond to the Client Hello."
        ) from None

    except (WantReadError, WantX509LookupError) as err:
        raise ValueError(f"{func_name}: {err.strerror}") from None

    except OpenSSLError as err:
        if "1408F10B" in err.args[0]:
            # https://github.com/openssl/openssl/issues/6805
            raise ValueError(
                f"{func_name}: Remote host is not using SSL/TLS on port: {port}"
            ) from None

        raise ValueError(f"{func_name}: {err}") from None

    finally:
        # shutdown() will also close the underlying socket
        ssl_client.shutdown()

    return cert_chain
예제 #32
0
from nassl.ssl_client import OpenSslVersionEnum, SslClient, OpenSslVerifyEnum
import socket

mozilla_store = 'tests/mozilla.pem'
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect(('www.yahoo.com', 443))

ssl_client = SslClient(
    ssl_version=OpenSslVersionEnum.TLSV1_2,
    underlying_socket=sock,
    ssl_verify=OpenSslVerifyEnum.PEER,
    ssl_verify_locations=mozilla_store,
)
ssl_client.set_tlsext_status_ocsp()
ssl_client.do_handshake()

print('Received certificate chain')
for pem_cert in ssl_client.get_received_chain():
    print(pem_cert)

print('Verified certificate chain')
for pem_cert in ssl_client.get_verified_chain():
    print(pem_cert)

print('OCSP Stapling')
ocsp_resp = ssl_client.get_tlsext_status_ocsp_resp()
if ocsp_resp:
    ocsp_resp.verify(mozilla_store)
    print(ocsp_resp.as_dict())
예제 #33
0
class EarlyDataClient():
    def __init__(self, **kw):
        self.socket = None
        self.session = None
        self.client = None

        self.dest = kw.get('dest', 'localhost')
        self.port = kw.get('port', 443)
        self.socket_timeout = kw.get('socket_timeout', 5)
        self.regular_data = kw.get('regular_data', b'XXX-REGULAR-DATA-XXX')
        self.early_data = kw.get('early_data', b'XXX-EARLY-DATA-XXX')
        self.read_size = kw.get('read_size', 2048)

    def _init(self, dest='localhost', port=443, timeout=5):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.settimeout(timeout)
        self.socket.connect((dest, port))
        self.client = SslClient(ssl_version=OpenSslVersionEnum.TLSV1_3, underlying_socket=self.socket,
                           ssl_verify_locations=u'mozilla.pem')

    def _finish_handshake(self):
        if not self.client.is_handshake_completed():
            self.client.do_handshake()
            print('\tCipher suite:', self.client.get_current_cipher_name())

    def _close(self):
        self.client.shutdown()
        self.socket.close()
        print('\n')

    def _write_read_close(self, data_to_send=b'XXX-REGULAR-DATA-XXX', read_size=2048):
        try:
            self.client.write(data_to_send)
            self.client.read(2048)
            self.session = self.client.get_session()
        except socket.timeout as e:
            print('\n\tSocket was timed out. Closing...')
        finally:
            self._close()

    def _send_early_data(self, early_data_to_send=b'XXX-EARLY-DATA-XXX'):
        self.client.set_session(self.session)
        self.client.write_early_data(early_data_to_send)
        self._finish_handshake()
        print('\t', self.client.get_early_data_status())
        self._close()

    def test_early(self, early_data_to_send=b'XXX-EARLY-DATA-XXX'):
        print('First Session:')
        self._init(dest=self.dest, port=self.port)
        self._finish_handshake()
        self._write_read_close(data_to_send=self.regular_data)
        
        if self.session:
            print('Reused Session:')
            self._init(dest=self.dest, port=self.port)
            if self.session.get_max_early_data() > 0:
                self._send_early_data()
            else:
                print('\n\tServer does not support Early-Data. Closing...')
                self._close
        else:
            print('\nPrevious session failed, can`t send early data. Closing...')

        print('='*80, '\n')
예제 #34
0
from nassl.ssl_client import OpenSslVersionEnum, SslClient, OpenSslVerifyEnum
import socket

mozilla_store = Path("tests") / "mozilla.pem"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect(("www.yahoo.com", 443))

ssl_client = SslClient(
    ssl_version=OpenSslVersionEnum.TLSV1_2,
    underlying_socket=sock,
    ssl_verify=OpenSslVerifyEnum.PEER,
    ssl_verify_locations=mozilla_store,
)
ssl_client.set_tlsext_status_ocsp()
ssl_client.do_handshake()

print("Received certificate chain")
for pem_cert in ssl_client.get_received_chain():
    print(pem_cert)

print("Verified certificate chain")
for pem_cert in ssl_client.get_verified_chain():
    print(pem_cert)

print("OCSP Stapling")
ocsp_resp = ssl_client.get_tlsext_status_ocsp_resp()
if ocsp_resp:
    ocsp_resp.verify(Path(mozilla_store))
    print(ocsp_resp.status)