Example #1
0
class TestHTTPS_TLSv1(HTTPSDummyServerTestCase):
    certs = DEFAULT_CERTS.copy()
    certs["ssl_version"] = ssl.PROTOCOL_TLSv1

    def setUp(self):
        self._pool = HTTPSConnectionPool(self.host, self.port)

    def test_set_ssl_version_to_sslv3(self):
        self._pool.ssl_version = ssl.PROTOCOL_SSLv3
        self.assertRaises(SSLError, self._pool.request, "GET", "/")

    def test_ssl_version_as_string(self):
        self._pool.ssl_version = "PROTOCOL_SSLv3"
        self.assertRaises(SSLError, self._pool.request, "GET", "/")

    def test_ssl_version_as_short_string(self):
        self._pool.ssl_version = "SSLv3"
        self.assertRaises(SSLError, self._pool.request, "GET", "/")

    def test_discards_connection_on_sslerror(self):
        self._pool.cert_reqs = "CERT_REQUIRED"
        self.assertRaises(SSLError, self._pool.request, "GET", "/")
        self._pool.ca_certs = DEFAULT_CA
        self._pool.request("GET", "/")

    def test_set_cert_default_cert_required(self):
        conn = VerifiedHTTPSConnection(self.host, self.port)
        conn.set_cert(ca_certs="/etc/ssl/certs/custom.pem")
        self.assertEqual(conn.cert_reqs, "CERT_REQUIRED")
Example #2
0
 def test_invalid_common_name(self):
     https_pool = HTTPSConnectionPool("127.0.0.1", self.port, cert_reqs="CERT_REQUIRED", ca_certs=DEFAULT_CA)
     try:
         https_pool.request("GET", "/")
         self.fail("Didn't raise SSL invalid common name")
     except SSLError as e:
         self.assertTrue("doesn't match" in str(e))
Example #3
0
    def test_ssl_verified_with_platform_ca_certs(self):
        """
        We should rely on the platform CA file to validate authenticity of SSL
        certificates. Since this file is used by many components of the OS,
        such as curl, apt-get, etc., we decided to not touch it, in order to
        not compromise the security of the OS running the test suite (typically
        urllib3 developer's OS).

        This test assumes that httpbin.org uses a certificate signed by a well
        known Certificate Authority.
        """
        try:
            import urllib3.contrib.pyopenssl
        except ImportError:
            raise SkipTest('Test requires PyOpenSSL')
        if (urllib3.connection.ssl_wrap_socket is
                urllib3.contrib.pyopenssl.orig_connection_ssl_wrap_socket):
            # Not patched
            raise SkipTest('Test should only be run after PyOpenSSL '
                           'monkey patching')

        https_pool = HTTPSConnectionPool('httpbin.org', 443,
                                         cert_reqs=ssl.CERT_REQUIRED)

        https_pool.request('HEAD', '/')
Example #4
0
    def test_assert_fingerprint_sha256(self):
        https_pool = HTTPSConnectionPool("localhost", self.port, cert_reqs="CERT_REQUIRED", ca_certs=DEFAULT_CA)

        https_pool.assert_fingerprint = (
            "9A:29:9D:4F:47:85:1C:51:23:F5:9A:A3:" "0F:5A:EF:96:F9:2E:3C:22:2E:FC:E8:BC:" "0E:73:90:37:ED:3B:AA:AB"
        )
        https_pool.request("GET", "/")
Example #5
0
    def test_assert_specific_hostname(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED')

        https_pool.ca_certs = DEFAULT_CA
        https_pool.assert_hostname = 'localhost'
        https_pool.request('GET', '/')
Example #6
0
    def test_https_timeout(self):
        timeout = Timeout(connect=0.001)
        https_pool = HTTPSConnectionPool(TARPIT_HOST, self.port,
                                         timeout=timeout, retries=False,
                                         cert_reqs='CERT_REQUIRED')
        self.addCleanup(https_pool.close)

        timeout = Timeout(total=None, connect=0.001)
        https_pool = HTTPSConnectionPool(TARPIT_HOST, self.port,
                                         timeout=timeout, retries=False,
                                         cert_reqs='CERT_REQUIRED')
        self.addCleanup(https_pool.close)
        self.assertRaises(ConnectTimeoutError, https_pool.request, 'GET', '/')

        timeout = Timeout(read=0.001)
        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         timeout=timeout, retries=False,
                                         cert_reqs='CERT_REQUIRED')
        self.addCleanup(https_pool.close)
        https_pool.ca_certs = DEFAULT_CA
        https_pool.assert_fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:' \
                                        'BF:93:CF:F9:71:CC:07:7D:0A'

        timeout = Timeout(total=None)
        https_pool = HTTPSConnectionPool(self.host, self.port, timeout=timeout,
                                         cert_reqs='CERT_NONE')
        self.addCleanup(https_pool.close)
        https_pool.request('GET', '/')
Example #7
0
    def test_https_timeout(self):
        timeout = Timeout(connect=0.001)
        https_pool = HTTPSConnectionPool(TARPIT_HOST, self.port,
                                         timeout=timeout,
                                         cert_reqs='CERT_REQUIRED')

        timeout = Timeout(total=None, connect=0.001)
        https_pool = HTTPSConnectionPool(TARPIT_HOST, self.port,
                                         timeout=timeout,
                                         cert_reqs='CERT_REQUIRED')
        self.assertRaises(ConnectTimeoutError, https_pool.request, 'GET', '/')

        timeout = Timeout(read=0.001)
        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         timeout=timeout,
                                         cert_reqs='CERT_REQUIRED')
        https_pool.ca_certs = DEFAULT_CA
        https_pool.assert_fingerprint = 'CC:45:6A:90:82:F7FF:C0:8218:8e:' \
                                        '7A:F2:8A:D7:1E:07:33:67:DE'
        url = '/sleep?seconds=0.005'
        self.assertRaises(ReadTimeoutError, https_pool.request, 'GET', url)

        timeout = Timeout(total=None)
        https_pool = HTTPSConnectionPool(self.host, self.port, timeout=timeout,
                                         cert_reqs='CERT_NONE')
        https_pool.request('GET', '/')
Example #8
0
    def test_assert_hostname_false(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        https_pool.assert_hostname = False
        https_pool.request('GET', '/')
Example #9
0
class TestHTTPS_TLSv1(HTTPSDummyServerTestCase):
    certs = DEFAULT_CERTS.copy()
    certs['ssl_version'] = ssl.PROTOCOL_TLSv1

    def setUp(self):
        self._pool = HTTPSConnectionPool(self.host, self.port)

    def test_set_ssl_version_to_sslv3(self):
        self._pool.ssl_version = ssl.PROTOCOL_SSLv3
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')

    def test_ssl_version_as_string(self):
        self._pool.ssl_version = 'PROTOCOL_SSLv3'
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')

    def test_ssl_version_as_short_string(self):
        self._pool.ssl_version = 'SSLv3'
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')

    def test_discards_connection_on_sslerror(self):
        self._pool.cert_reqs = 'CERT_REQUIRED'
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')
        self._pool.ca_certs = DEFAULT_CA
        self._pool.request('GET', '/')

    def test_set_cert_default_cert_required(self):
        conn = VerifiedHTTPSConnection(self.host, self.port)
        conn.set_cert(ca_certs=DEFAULT_CA)
        self.assertEqual(conn.cert_reqs, 'CERT_REQUIRED')
Example #10
0
    def test_verify_none_and_good_fingerprint(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_NONE',
                                         ca_certs=DEFAULT_CA_BAD)

        https_pool.assert_fingerprint = 'CC:45:6A:90:82:F7FF:C0:8218:8e:' \
                                        '7A:F2:8A:D7:1E:07:33:67:DE'
        https_pool.request('GET', '/')
Example #11
0
    def test_assert_fingerprint_md5(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED')

        https_pool.ca_certs = DEFAULT_CA
        https_pool.assert_fingerprint = 'CA:84:E1:AD0E5a:ef:2f:C3:09' \
                                        ':E7:30:F8:CD:C8:5B'
        https_pool.request('GET', '/')
Example #12
0
    def test_assert_fingerprint_sha1(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED')

        https_pool.ca_certs = DEFAULT_CA
        https_pool.assert_fingerprint = 'CC:45:6A:90:82:F7FF:C0:8218:8e:' \
                                        '7A:F2:8A:D7:1E:07:33:67:DE'
        https_pool.request('GET', '/')
Example #13
0
    def test_assert_specific_hostname(self):
        https_pool = HTTPSConnectionPool('localhost', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)
        self.addCleanup(https_pool.close)

        https_pool.assert_hostname = 'localhost'
        https_pool.request('GET', '/')
Example #14
0
    def test_assert_fingerprint_sha1(self):
        https_pool = HTTPSConnectionPool('localhost', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        https_pool.assert_fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:' \
                                        'BF:93:CF:F9:71:CC:07:7D:0A'
        https_pool.request('GET', '/')
Example #15
0
    def test_verify_none_and_good_fingerprint(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_NONE',
                                         ca_certs=DEFAULT_CA_BAD)

        https_pool.assert_fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:' \
                                        'BF:93:CF:F9:71:CC:07:7D:0A'
        https_pool.request('GET', '/')
Example #16
0
    def test_good_fingerprint_and_hostname_mismatch(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        https_pool.assert_fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:' \
                                        'BF:93:CF:F9:71:CC:07:7D:0A'
        https_pool.request('GET', '/')
Example #17
0
 def test_no_ssl(self):
     pool = HTTPSConnectionPool(self.host, self.port)
     pool.ConnectionCls = None
     self.addCleanup(pool.close)
     self.assertRaises(SSLError, pool._new_conn)
     with self.assertRaises(MaxRetryError) as cm:
         pool.request('GET', '/', retries=0)
     self.assertIsInstance(cm.exception.reason, SSLError)
Example #18
0
class TestHTTPS(HTTPSDummyServerTestCase):
    def setUp(self):
        self._pool = HTTPSConnectionPool(self.host, self.port)

    def test_simple(self):
        r = self._pool.request('GET', '/specific_method',
                               fields={'method': 'GET'})
        self.assertEqual(r.status, 200, r.data)

    def test_verified(self):
        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         cert_reqs='CERT_REQUIRED')

        conn = https_pool._new_conn()
        self.assertEqual(conn.__class__, VerifiedHTTPSConnection)

        self.assertRaises(SSLError, https_pool.request, 'GET', '/')

        https_pool.ca_certs = DEFAULT_CA_BAD

        try:
            https_pool.request('GET', '/')
            self.fail("Didn't raise SSL error with wrong CA")
        except SSLError as e:
            self.assertTrue('certificate verify failed' in str(e),
                            "Expected 'certificate verify failed', instead got: %r" % e)

        https_pool.ca_certs = DEFAULT_CA
        https_pool.request('GET', '/') # Should succeed without exceptions.

        https_fail_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                              cert_reqs='CERT_REQUIRED')
        https_fail_pool.ca_certs = DEFAULT_CA

        try:
            https_fail_pool.request('GET', '/')
            self.fail("Didn't raise SSL invalid common name")
        except SSLError as e:
            self.assertTrue("doesn't match" in str(e))

    def test_no_ssl(self):
        import urllib3.connectionpool
        OriginalHTTPSConnection = urllib3.connectionpool.HTTPSConnection
        OriginalSSL = urllib3.connectionpool.ssl

        urllib3.connectionpool.HTTPSConnection = None
        urllib3.connectionpool.ssl = None

        self.assertRaises(SSLError, self._pool._new_conn)

        self.assertRaises(SSLError,
            lambda: self._pool.request('GET', '/specific_method',
                                       fields={'method': 'GET'}))

        # Undo
        urllib3.HTTPSConnection = OriginalHTTPSConnection
        urllib3.connectionpool.ssl = OriginalSSL
Example #19
0
    def test_verified(self):
        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        conn = https_pool._new_conn()
        self.assertEqual(conn.__class__, VerifiedHTTPSConnection)

        https_pool.request('GET', '/')  # Should succeed without exceptions.
Example #20
0
    def test_assert_fingerprint_sha256(self):
        https_pool = HTTPSConnectionPool('localhost', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        https_pool.assert_fingerprint = ('C5:4D:0B:83:84:89:2E:AE:B4:58:BB:12:'
                                         'F7:A6:C4:76:05:03:88:D8:57:65:51:F3:'
                                         '1E:60:B0:8B:70:18:64:E6')
        https_pool.request('GET', '/')
Example #21
0
    def test_assert_fingerprint_md5(self):
        https_pool = HTTPSConnectionPool('localhost', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        https_pool.assert_fingerprint = 'F2:06:5A:42:10:3F:45:1C:17:FE:E6:' \
                                        '07:1E:8A:86:E5'

        https_pool.request('GET', '/')
Example #22
0
    def test_assert_fingerprint_sha256(self):
        https_pool = HTTPSConnectionPool('localhost', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        https_pool.assert_fingerprint = ('9A:29:9D:4F:47:85:1C:51:23:F5:9A:A3:'
                                         '0F:5A:EF:96:F9:2E:3C:22:2E:FC:E8:BC:'
                                         '0E:73:90:37:ED:3B:AA:AB')
        https_pool.request('GET', '/')
Example #23
0
    def test_verified_with_bad_ca_certs(self):
        https_pool = HTTPSConnectionPool(self.host, self.port, cert_reqs="CERT_REQUIRED", ca_certs=DEFAULT_CA_BAD)

        try:
            https_pool.request("GET", "/")
            self.fail("Didn't raise SSL error with bad CA certs")
        except SSLError as e:
            self.assertTrue(
                "certificate verify failed" in str(e), "Expected 'certificate verify failed'," "instead got: %r" % e
            )
Example #24
0
    def test_verified(self):
        https_pool = HTTPSConnectionPool(self.host, self.port, cert_reqs="CERT_REQUIRED")

        conn = https_pool._new_conn()
        self.assertEqual(conn.__class__, VerifiedHTTPSConnection)

        try:
            https_pool.request("GET", "/")
            self.fail("Didn't raise SSL error with no CA")
        except SSLError, e:
            self.assertIn("No root certificates", str(e))
Example #25
0
    def test_verify_none_and_bad_fingerprint(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_NONE',
                                         ca_certs=DEFAULT_CA_BAD)
        self.addCleanup(https_pool.close)

        https_pool.assert_fingerprint = 'AA:AA:AA:AA:AA:AAAA:AA:AAAA:AA:' \
                                        'AA:AA:AA:AA:AA:AA:AA:AA:AA'
        with self.assertRaises(MaxRetryError) as cm:
            https_pool.request('GET', '/', retries=0)
        self.assertIsInstance(cm.exception.reason, SSLError)
Example #26
0
    def test_invalid_common_name(self):
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)
        self.addCleanup(https_pool.close)

        try:
            https_pool.request('GET', '/')
            self.fail("Didn't raise SSL invalid common name")
        except SSLError as e:
            self.assertTrue("doesn't match" in str(e))
Example #27
0
    def test_verified(self):
        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         cert_reqs='CERT_REQUIRED')

        conn = https_pool._new_conn()
        self.assertEqual(conn.__class__, VerifiedHTTPSConnection)

        try:
            https_pool.request('GET', '/')
            self.fail("Didn't raise SSL error with no CA")
        except SSLError, e:
            self.assertTrue('No root certificates' in str(e))
Example #28
0
    def test_good_fingerprint_and_hostname_mismatch(self):
        # This test doesn't run with SecureTransport because we don't turn off
        # hostname validation without turning off all validation, which this
        # test doesn't do (deliberately). We should revisit this if we make
        # new decisions.
        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)
        self.addCleanup(https_pool.close)

        https_pool.assert_fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:' \
                                        'BF:93:CF:F9:71:CC:07:7D:0A'
        https_pool.request('GET', '/')
Example #29
0
    def test_verified_with_bad_ca_certs(self):
        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA_BAD)
        self.addCleanup(https_pool.close)

        try:
            https_pool.request('GET', '/')
            self.fail("Didn't raise SSL error with bad CA certs")
        except SSLError as e:
            self.assertTrue('certificate verify failed' in str(e),
                            "Expected 'certificate verify failed',"
                            "instead got: %r" % e)
Example #30
0
 def test_client_no_intermediate(self):
     client_cert, client_key = (
         DEFAULT_CLIENT_NO_INTERMEDIATE_CERTS['certfile'],
         DEFAULT_CLIENT_NO_INTERMEDIATE_CERTS['keyfile']
     )
     https_pool = HTTPSConnectionPool(self.host, self.port,
                                      cert_file=client_cert,
                                      key_file=client_key)
     try:
         https_pool.request('GET', '/certificate', retries=False)
     except SSLError as e:
         self.assertTrue('alert unknown ca' in str(e) or
                         'invalid certificate chain' in str(e) or
                         'unknown Cert Authority' in str(e))
Example #31
0
 def test_strip_square_brackets_before_validating(self):
     """Test that the fix for #760 works."""
     https_pool = HTTPSConnectionPool('[::1]',
                                      self.port,
                                      cert_reqs='CERT_REQUIRED',
                                      ca_certs=IPV6_ADDR_CA)
     self.addCleanup(https_pool.close)
     r = https_pool.request('GET', '/')
     self.assertEqual(r.status, 200)
Example #32
0
    def test_client_certs_two_files(self):
        """
        Having a client cert in a separate file to its associated key works
        properly.
        """
        done_receiving = Event()
        client_certs = []

        def socket_handler(listener):
            sock = listener.accept()[0]
            sock = self._wrap_in_ssl(sock)

            client_certs.append(sock.getpeercert())

            data = b''
            while not data.endswith(b'\r\n\r\n'):
                data += sock.recv(8192)

            sock.sendall(
                b'HTTP/1.1 200 OK\r\n'
                b'Server: testsocket\r\n'
                b'Connection: close\r\n'
                b'Content-Length: 6\r\n'
                b'\r\n'
                b'Valid!'
            )

            done_receiving.wait(5)
            sock.close()

        self._start_server(socket_handler)
        pool = HTTPSConnectionPool(
            self.host,
            self.port,
            cert_file=DEFAULT_CERTS['certfile'],
            key_file=DEFAULT_CERTS['keyfile'],
            cert_reqs='REQUIRED',
            ca_certs=DEFAULT_CA,
        )
        self.addCleanup(pool.close)
        pool.request('GET', '/', retries=0)
        done_receiving.set()

        self.assertEqual(len(client_certs), 1)
Example #33
0
 def test_warning_for_certs_without_a_san(self):
     """Ensure that a warning is raised when the cert from the server has
     no Subject Alternative Name."""
     with mock.patch('warnings.warn') as warn:
         https_pool = HTTPSConnectionPool(self.host, self.port,
                                          cert_reqs='CERT_REQUIRED',
                                          ca_certs=NO_SAN_CA)
         r = https_pool.request('GET', '/')
         self.assertEqual(r.status, 200)
         self.assertTrue(warn.called)
Example #34
0
 def test_source_address_ignored(self):
     # source_address is ignored in Python 2.6 and earlier.
     for addr in INVALID_SOURCE_ADDRESSES:
         https_pool = HTTPSConnectionPool(self.host,
                                          self.port,
                                          cert_reqs='CERT_REQUIRED',
                                          source_address=addr)
         https_pool.ca_certs = DEFAULT_CA
         r = https_pool.request('GET', '/source_address')
         assert r.status == 200
Example #35
0
    def test_verified_without_ca_certs(self):
        # default is cert_reqs=None which is ssl.CERT_NONE
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         cert_reqs='CERT_REQUIRED')

        try:
            https_pool.request('GET', '/')
            self.fail("Didn't raise SSL error with no CA certs when"
                      "CERT_REQUIRED is set")
        except SSLError as e:
            # there is a different error message depending on whether or
            # not pyopenssl is injected
            self.assertTrue(
                'No root certificates specified' in str(e)
                or 'certificate verify failed' in str(e),
                "Expected 'No root certificates specified' or "
                "'certificate verify failed', "
                "instead got: %r" % e)
Example #36
0
 def test_strip_square_brackets_before_validating(self):
     """Test that the fix for #760 works."""
     if not HAS_IPV6:
         raise SkipTest("Only runs on IPv6 systems")
     https_pool = HTTPSConnectionPool('[::1]',
                                      self.port,
                                      cert_reqs='CERT_REQUIRED',
                                      ca_certs=IPV6_ADDR_CA)
     r = https_pool.request('GET', '/')
     self.assertEqual(r.status, 200)
Example #37
0
    def test_https_timeout(self):
        timeout = Timeout(connect=0.001)
        https_pool = HTTPSConnectionPool(
            TARPIT_HOST,
            self.port,
            timeout=timeout,
            retries=False,
            cert_reqs="CERT_REQUIRED",
        )
        self.addCleanup(https_pool.close)

        timeout = Timeout(total=None, connect=0.001)
        https_pool = HTTPSConnectionPool(
            TARPIT_HOST,
            self.port,
            timeout=timeout,
            retries=False,
            cert_reqs="CERT_REQUIRED",
        )
        self.addCleanup(https_pool.close)
        with pytest.raises(ConnectTimeoutError):
            https_pool.request("GET", "/")

        timeout = Timeout(read=0.01)
        https_pool = HTTPSConnectionPool(
            self.host,
            self.port,
            timeout=timeout,
            retries=False,
            cert_reqs="CERT_REQUIRED",
        )
        self.addCleanup(https_pool.close)
        https_pool.ca_certs = DEFAULT_CA
        https_pool.assert_fingerprint = ("92:81:FE:85:F7:0C:26:60:EC:D6:B3:"
                                         "BF:93:CF:F9:71:CC:07:7D:0A")

        timeout = Timeout(total=None)
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         timeout=timeout,
                                         cert_reqs="CERT_NONE")
        self.addCleanup(https_pool.close)
        https_pool.request("GET", "/")
Example #38
0
    def test_ca_dir_verified(self):
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_cert_dir=DEFAULT_CA_DIR)
        self.addCleanup(https_pool.close)

        with mock.patch('warnings.warn') as warn:
            r = https_pool.request('GET', '/')
            self.assertEqual(r.status, 200)
            self.assertFalse(warn.called, warn.call_args_list)
Example #39
0
    def test_enhanced_ssl_connection(self):
        fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:BF:93:CF:F9:71:CC:07:7D:0A'

        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA,
                                         assert_fingerprint=fingerprint)
        self.addCleanup(https_pool.close)

        r = https_pool.request('GET', '/')
        assert r.status == 200
Example #40
0
class TestHTTPS_TLSv1(HTTPSDummyServerTestCase):
    certs = DEFAULT_CERTS.copy()
    certs['ssl_version'] = ssl.PROTOCOL_TLSv1

    def setUp(self):
        self._pool = HTTPSConnectionPool(self.host, self.port)
        self.addCleanup(self._pool.close)

    def test_discards_connection_on_sslerror(self):
        self._pool.cert_reqs = 'CERT_REQUIRED'
        with self.assertRaises(MaxRetryError) as cm:
            self._pool.request('GET', '/', retries=0)
        self.assertIsInstance(cm.exception.reason, SSLError)
        self._pool.ca_certs = DEFAULT_CA
        self._pool.request('GET', '/')

    def test_set_cert_default_cert_required(self):
        conn = VerifiedHTTPSConnection(self.host, self.port)
        conn.set_cert(ca_certs=DEFAULT_CA)
        self.assertEqual(conn.cert_reqs, 'CERT_REQUIRED')
Example #41
0
 def test_client_intermediate(self):
     client_cert, client_key, client_subject = (
         DEFAULT_CLIENT_CERTS['certfile'], DEFAULT_CLIENT_CERTS['keyfile'],
         DEFAULT_CLIENT_CERTS['subject'])
     https_pool = HTTPSConnectionPool(self.host,
                                      self.port,
                                      key_file=client_key,
                                      cert_file=client_cert)
     r = https_pool.request('GET', '/certificate')
     self.assertDictEqual(json.loads(r.data.decode('utf-8')),
                          client_subject, r.data)
Example #42
0
 def test_client_intermediate(self):
     client_cert, client_key = (
         DEFAULT_CLIENT_CERTS['certfile'],
         DEFAULT_CLIENT_CERTS['keyfile'],
     )
     https_pool = HTTPSConnectionPool(self.host, self.port,
                                      key_file=client_key,
                                      cert_file=client_cert)
     r = https_pool.request('GET', '/certificate')
     subject = json.loads(r.data.decode('utf-8'))
     assert subject['organizationalUnitName'].startswith(
         'Testing server cert')
Example #43
0
    def test_verified(self):
        https_pool = HTTPSConnectionPool(self.host, self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)

        conn = https_pool._new_conn()
        self.assertEqual(conn.__class__, VerifiedHTTPSConnection)

        with mock.patch('warnings.warn') as warn:
            r = https_pool.request('GET', '/')
            self.assertEqual(r.status, 200)
            self.assertFalse(warn.called, warn.call_args_list)
Example #44
0
 def test_warning_for_certs_without_a_san(self):
     """Ensure that a warning is raised when the cert from the server has
     no Subject Alternative Name."""
     with mock.patch("warnings.warn") as warn:
         https_pool = HTTPSConnectionPool(self.host,
                                          self.port,
                                          cert_reqs="CERT_REQUIRED",
                                          ca_certs=NO_SAN_CA)
         self.addCleanup(https_pool.close)
         r = https_pool.request("GET", "/")
         assert r.status == 200
         assert warn.called
Example #45
0
    def test_verified(self):
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         cert_reqs='CERT_REQUIRED')

        conn = https_pool._new_conn()
        self.assertEqual(conn.__class__, VerifiedHTTPSConnection)

        self.assertRaises(SSLError, https_pool.request, 'GET', '/')

        https_pool.ca_certs = DEFAULT_CA_BAD

        try:
            https_pool.request('GET', '/')
            self.fail("Didn't raise SSL error with wrong CA")
        except SSLError as e:
            self.assertTrue(
                'certificate verify failed' in str(e),
                "Expected 'certificate verify failed',"
                "instead got: %r" % e)

        https_pool.ca_certs = DEFAULT_CA
        https_pool.request('GET', '/')  # Should succeed without exceptions.

        https_fail_pool = HTTPSConnectionPool('127.0.0.1',
                                              self.port,
                                              cert_reqs='CERT_REQUIRED')
        https_fail_pool.ca_certs = DEFAULT_CA

        try:
            https_fail_pool.request('GET', '/')
            self.fail("Didn't raise SSL invalid common name")
        except SSLError as e:
            self.assertTrue("doesn't match" in str(e))
Example #46
0
    def test_https_connect_timeout(self):
        url = '/'
        host, port = self.host, self.port
        timeout = Timeout(connect=SHORT_TIMEOUT)

        # Pool-global timeout
        pool = HTTPSConnectionPool(host, port, timeout=timeout)
        conn = pool._get_conn()
        exc = ReadTimeoutError  # Until we fix it to be ConnectTimeoutError
        pos = 0  # Will be 1 once we fix ConnectTimeoutError
        with self.assertRaises(exc) as cmgr:
            pool._make_request(conn, 'GET', url)
        self.assertEqual(cmgr.exception.args[pos].split()[-1],
                         'timeout=%s)' % timeout.connect_timeout)

        # Retries
        retries = Retry(connect=0)
        self.assertRaises(MaxRetryError,
                          pool.request,
                          'GET',
                          url,
                          retries=retries,
                          timeout=timeout)

        # Request-specific connection timeouts
        timeout2 = Timeout(read=LONG_TIMEOUT, connect=SHORT_TIMEOUT / 100)
        pool = HTTPSConnectionPool(host, port, timeout=timeout2, retries=False)
        conn = pool._get_conn()
        with self.assertRaises(exc) as cmgr:
            pool._make_request(conn, 'GET', url, timeout=timeout2)
        self.assertEqual(cmgr.exception.args[pos].split()[-1],
                         'timeout=%s)' % timeout2.connect_timeout)

        pool._put_conn(conn)
        timeout = Timeout(connect=SHORT_TIMEOUT)
        with self.assertRaises(exc) as cmgr:
            pool.request('GET', url, timeout=timeout)
        self.assertEqual(cmgr.exception.args[pos].split()[-1],
                         'timeout=%s)' % timeout.connect_timeout)
Example #47
0
    def test_ssl_unverified_with_ca_certs(self):
        pool = HTTPSConnectionPool(self.host, self.port,
                                   cert_reqs='CERT_NONE',
                                   ca_certs=DEFAULT_CA_BAD)

        with mock.patch('warnings.warn') as warn:
            r = pool.request('GET', '/')
            self.assertEqual(r.status, 200)
            self.assertTrue(warn.called)

            call, = warn.call_args_list
            category = call[0][1]
            self.assertEqual(category, InsecureRequestWarning)
Example #48
0
class TestHTTPS_TLSv1(HTTPSDummyServerTestCase):
    certs = DEFAULT_CERTS.copy()
    certs['ssl_version'] = ssl.PROTOCOL_TLSv1

    def setUp(self):
        self._pool = HTTPSConnectionPool(self.host, self.port)
        self.addCleanup(self._pool.close)

    @onlyPy27OrNewerOrNonWindows
    def test_discards_connection_on_sslerror(self):
        # This test is skipped on Windows for Python 2.6 because we suspect there
        # is an issue with the OpenSSL for Python 2.6 on Windows.

        self._pool.cert_reqs = 'CERT_REQUIRED'
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')
        self._pool.ca_certs = DEFAULT_CA
        self._pool.request('GET', '/')

    def test_set_cert_default_cert_required(self):
        conn = VerifiedHTTPSConnection(self.host, self.port)
        conn.set_cert(ca_certs=DEFAULT_CA)
        self.assertEqual(conn.cert_reqs, 'CERT_REQUIRED')
Example #49
0
    def test_can_validate_ip_san(self):
        """Ensure that urllib3 can validate SANs with IP addresses in them."""
        try:
            import ipaddress  # noqa: F401
        except ImportError:
            pytest.skip("Only runs on systems with an ipaddress module")

        https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
                                         cert_reqs='CERT_REQUIRED',
                                         ca_certs=DEFAULT_CA)
        self.addCleanup(https_pool.close)
        r = https_pool.request('GET', '/')
        self.assertEqual(r.status, 200)
Example #50
0
 def test_client_no_intermediate(self):
     client_cert, client_key = (
         DEFAULT_CLIENT_NO_INTERMEDIATE_CERTS['certfile'],
         DEFAULT_CLIENT_NO_INTERMEDIATE_CERTS['keyfile'])
     https_pool = HTTPSConnectionPool(self.host,
                                      self.port,
                                      cert_file=client_cert,
                                      key_file=client_key)
     try:
         https_pool.request('GET', '/certificate', retries=False)
     except SSLError as e:
         if not ('alert unknown ca' in str(e) or 'invalid certificate chain'
                 in str(e) or 'unknown Cert Authority' in str(e) or
                 # https://github.com/urllib3/urllib3/issues/1422
                 'connection closed via error' in str(e)
                 or 'WSAECONNRESET' in str(e)):
             raise
     except ProtocolError as e:
         # https://github.com/urllib3/urllib3/issues/1422
         if not ('An existing connection was forcibly closed by the remote host'
                 in str(e)):
             raise
Example #51
0
    def test_verified_without_ca_certs(self):
        # default is cert_reqs=None which is ssl.CERT_NONE
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         cert_reqs="CERT_REQUIRED")
        self.addCleanup(https_pool.close)

        try:
            https_pool.request("GET", "/")
            self.fail("Didn't raise SSL error with no CA certs when"
                      "CERT_REQUIRED is set")
        except MaxRetryError as e:
            assert isinstance(e.reason, SSLError)
            # there is a different error message depending on whether or
            # not pyopenssl is injected
            assert ("No root certificates specified" in str(e.reason)
                    or "certificate verify failed" in str(e.reason)
                    or "invalid certificate chain" in str(e.reason)), (
                        "Expected 'No root certificates specified',  "
                        "'certificate verify failed', or "
                        "'invalid certificate chain', "
                        "instead got: %r" % e.reason)
Example #52
0
    def test_hostname_in_first_request_packet(self):
        if not util.HAS_SNI:
            raise SkipTest('SNI-support not available')

        done_receiving = Event()
        self.buf = b''

        def socket_handler(listener):
            sock = listener.accept()[0]

            self.buf = sock.recv(65536)  # We only accept one packet
            done_receiving.set()  # let the test know it can proceed

        self._start_server(socket_handler)
        pool = HTTPSConnectionPool(self.host, self.port)
        try:
            pool.request('GET', '/', retries=0)
        except SSLError:  # We are violating the protocol
            pass
        done_receiving.wait()
        self.assertTrue(self.host.encode() in self.buf,
                        "missing hostname in SSL handshake")
Example #53
0
    def test_unverified_ssl(self):
        """ Test that bare HTTPSConnection can connect, make requests """
        pool = HTTPSConnectionPool(self.host, self.port)
        pool.ConnectionCls = UnverifiedHTTPSConnection

        with mock.patch('warnings.warn') as warn:
            r = pool.request('GET', '/')
            self.assertEqual(r.status, 200)
            self.assertTrue(warn.called)

            call, = warn.call_args_list
            category = call[0][1]
            self.assertEqual(category, InsecureRequestWarning)
Example #54
0
 def test_client_key_password(self):
     client_cert, client_key = (
         DEFAULT_CLIENT_CERTS['certfile'],
         PASSWORD_CLIENT_KEYFILE,
     )
     https_pool = HTTPSConnectionPool(self.host, self.port,
                                      ca_certs=DEFAULT_CA,
                                      key_file=client_key,
                                      cert_file=client_cert,
                                      key_password="******")
     r = https_pool.request('GET', '/certificate')
     subject = json.loads(r.data.decode('utf-8'))
     assert subject['organizationalUnitName'].startswith(
         'Testing server cert')
Example #55
0
    def test_ca_dir_verified(self):
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         cert_reqs="CERT_REQUIRED",
                                         ca_cert_dir=DEFAULT_CA_DIR)
        self.addCleanup(https_pool.close)

        conn = https_pool._new_conn()
        assert conn.__class__ == VerifiedHTTPSConnection

        with mock.patch("warnings.warn") as warn:
            r = https_pool.request("GET", "/")
            assert r.status == 200
            assert not warn.called, warn.call_args_list
Example #56
0
    def test_can_validate_ipv6_san(self):
        """Ensure that urllib3 can validate SANs with IPv6 addresses in them."""
        try:
            import ipaddress  # noqa: F401
        except ImportError:
            pytest.skip("Only runs on systems with an ipaddress module")

        https_pool = HTTPSConnectionPool("[::1]",
                                         self.port,
                                         cert_reqs="CERT_REQUIRED",
                                         ca_certs=IPV6_SAN_CA)
        self.addCleanup(https_pool.close)
        r = https_pool.request("GET", "/")
        assert r.status == 200
Example #57
0
    def test_https_timeout(self):
        timeout = Timeout(connect=0.001)
        https_pool = HTTPSConnectionPool(TARPIT_HOST,
                                         self.port,
                                         timeout=timeout,
                                         retries=False,
                                         cert_reqs='CERT_REQUIRED')
        self.addCleanup(https_pool.close)

        timeout = Timeout(total=None, connect=0.001)
        https_pool = HTTPSConnectionPool(TARPIT_HOST,
                                         self.port,
                                         timeout=timeout,
                                         retries=False,
                                         cert_reqs='CERT_REQUIRED')
        self.addCleanup(https_pool.close)
        self.assertRaises(ConnectTimeoutError, https_pool.request, 'GET', '/')

        timeout = Timeout(read=0.001)
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         timeout=timeout,
                                         retries=False,
                                         cert_reqs='CERT_REQUIRED')
        self.addCleanup(https_pool.close)
        https_pool.ca_certs = DEFAULT_CA
        https_pool.assert_fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:' \
                                        'BF:93:CF:F9:71:CC:07:7D:0A'

        timeout = Timeout(total=None)
        https_pool = HTTPSConnectionPool(self.host,
                                         self.port,
                                         timeout=timeout,
                                         cert_reqs='CERT_NONE')
        self.addCleanup(https_pool.close)
        https_pool.request('GET', '/')
Example #58
0
    def test_reuse_conn(self):
        # Test pool.request() connection reusal:
        # 1. Create a new connection.
        # 2. Perform a request which will succeed.
        # 3. Reuse the connection - delay the response with original pool settings.
        # 4. Reuse same connection for a successful read request with delay in response.
        # 5. Reuse same connection for a timeout read request.

        # Create the connection pool with default timeouts long enough to connect and read.
        self.set_block_response(None)
        timeout = Timeout(connect=1., read=4)
        headers = make_headers(keep_alive=True)
        pool = HTTPSConnectionPool(self.host,
                                   self.port,
                                   timeout=timeout,
                                   headers=headers,
                                   retries=False)

        # First request - direct with pool._make_request() with delay=conn_timeout+read_timeout-0.5
        delay = timeout.connect_timeout + timeout.read_timeout - 0.5
        self.set_block_response(delay)
        conn = pool._get_conn()
        self.assertIsNone(conn.sock)
        pool._make_request(conn, 'GET', '/')
        self.set_block_response(None)

        # Make a request - it must succeed
        pool.request('GET', '/')

        # Reuse the connection - successful read request with delayed response.
        # * Ensure that new connection is not created by using a short connect timeout with
        #   pool._make_request.
        # * Use a read timeout which will be larger than the pool's connect timeout but shorter
        #   than the pool's read timeout
        timeout = Timeout(connect=SHORT_TIMEOUT, read=2.5)
        delay = 1.1
        # Check that the timeouts are as intended
        self.assertLess(timeout.connect_timeout, pool.timeout.connect_timeout)
        self.assertLess(pool.timeout.connect_timeout, delay)
        self.assertLess(delay, timeout.read_timeout)
        self.assertLess(timeout.read_timeout, pool.timeout.read_timeout)
        # Make the request
        self.set_block_response(delay)
        pool.request('GET', '/', timeout=timeout)

        # Reuse the connection - timeout read request
        delay = timeout.read_timeout + 1
        self.set_block_response(delay)
        now = time.time()
        with self.assertRaises(ReadTimeoutError) as cmgr:
            pool.request('GET', '/', timeout=timeout)
        delta = time.time() - now
        self.assertEqual(cmgr.exception.args[0].split()[-1],
                         'timeout=%s)' % timeout.read_timeout)
        self.assertAlmostEqual(delta, timeout.read_timeout, places=1)
        print('delta={}'.format(delta))
Example #59
0
    def test_unverified_ssl(self):
        """ Test that bare HTTPSConnection can connect, make requests """
        pool = HTTPSConnectionPool(self.host, self.port)
        self.addCleanup(pool.close)

        with mock.patch('warnings.warn') as warn:
            r = pool.request('GET', '/')
            self.assertEqual(r.status, 200)
            self.assertTrue(warn.called)

            # Modern versions of Python, or systems using PyOpenSSL, only emit
            # the unverified warning. Older systems may also emit other
            # warnings, which we want to ignore here.
            calls = warn.call_args_list
            self.assertIn(InsecureRequestWarning, [x[0][1] for x in calls])
Example #60
0
class TestHTTPS_TLSv1(HTTPSDummyServerTestCase):
    certs = DEFAULT_CERTS.copy()
    certs['ssl_version'] = ssl.PROTOCOL_TLSv1

    def setUp(self):
        self._pool = HTTPSConnectionPool(self.host, self.port)

    def test_set_ssl_version_to_sslv3(self):
        self._pool.ssl_version = ssl.PROTOCOL_SSLv3
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')

    def test_ssl_version_as_string(self):
        self._pool.ssl_version = 'PROTOCOL_SSLv3'
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')

    def test_ssl_version_as_short_string(self):
        self._pool.ssl_version = 'SSLv3'
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')

    def test_discards_connection_on_sslerror(self):
        self._pool.cert_reqs = 'CERT_REQUIRED'
        self.assertRaises(SSLError, self._pool.request, 'GET', '/')
        self._pool.ca_certs = DEFAULT_CA
        self._pool.request('GET', '/')