def connect(self, url, **options): """ Connect to url. url is websocket url scheme. ie. ws://host:port/resource You can customize using 'options'. If you set "header" dict object, you can set your own custom header. >>> ws = WebSocket() >>> ws.connect("ws://echo.websocket.org/", ... header={"User-Agent: MyProgram", ... "x-custom: header"}) timeout: socket timeout time. This value is integer. if you set None for this value, it means "use default_timeout value" options: current support option is only "header". if you set header as dict value, the custom HTTP headers are added. """ hostname, port, resource, is_secure = _parse_url(url) # TODO: we need to support proxy self.sock.connect((hostname, port)) if is_secure: if HAVE_SSL: sslopt = dict(cert_reqs=ssl.CERT_REQUIRED, ca_certs=os.path.join(os.path.dirname(__file__), "cacert.pem")) sslopt.update(self.sslopt) self.sock = ssl.wrap_socket(self.sock, **sslopt) match_hostname(self.sock.getpeercert(), hostname) else: raise WebSocketException("SSL not available.") self._handshake(hostname, port, resource, **options)
def connect(self): # Create the raw socket and wrap it in ssl. httplib.HTTPConnection.connect(self) self.sock = ssl.wrap_socket(self.sock, **self.__kwargs) # Verify the remote hostname. match_hostname(self.sock.getpeercert(), self.host.split(':', 1)[0])
def _on_connect(self, parsed): if self._timeout is not None: self.io_loop.remove_timeout(self._timeout) self._timeout = None if self.request.request_timeout: self._timeout = self.io_loop.add_timeout( self.start_time + self.request.request_timeout, self._on_timeout) if (self.request.validate_cert and isinstance(self.stream, SSLIOStream)): match_hostname(self.stream.socket.getpeercert(), parsed.hostname) if (self.request.method not in self._SUPPORTED_METHODS and not self.request.allow_nonstandard_methods): raise KeyError("unknown method %s" % self.request.method) for key in ('network_interface', 'proxy_host', 'proxy_port', 'proxy_username', 'proxy_password'): if getattr(self.request, key, None): raise NotImplementedError('%s not supported' % key) if "Host" not in self.request.headers: self.request.headers["Host"] = parsed.netloc username, password = None, None if parsed.username is not None: username, password = parsed.username, parsed.password elif self.request.auth_username is not None: username = self.request.auth_username password = self.request.auth_password or '' if username is not None: auth = utf8(username) + b(":") + utf8(password) self.request.headers["Authorization"] = (b("Basic ") + base64.b64encode(auth)) if self.request.user_agent: self.request.headers["User-Agent"] = self.request.user_agent if not self.request.allow_nonstandard_methods: if self.request.method in ("POST", "PUT"): assert self.request.body is not None else: assert self.request.body is None if self.request.body is not None: self.request.headers["Content-Length"] = str(len( self.request.body)) if (self.request.method == "POST" and "Content-Type" not in self.request.headers): self.request.headers["Content-Type"] = "application/x-www-form-urlencoded" if self.request.use_gzip: self.request.headers["Accept-Encoding"] = "gzip" req_path = ((parsed.path or '/') + (('?' + parsed.query) if parsed.query else '')) request_lines = [utf8("%s %s HTTP/1.1" % (self.request.method, req_path))] for k, v in self.request.headers.get_all(): line = utf8(k) + b(": ") + utf8(v) if b('\n') in line: raise ValueError('Newline in header: ' + repr(line)) request_lines.append(line) self.stream.write(b("\r\n").join(request_lines) + b("\r\n\r\n")) if self.request.body is not None: self.stream.write(self.request.body) self.stream.read_until_regex(b("\r?\n\r?\n"), self._on_headers)
def connect(self): """ Wrap socket properly. """ sock = None source_addr = getattr(self, 'source_address', None) timeout = getattr(self, 'timeout', DEFAULT_TIMEOUT) makesock = getattr(socket, 'create_connection', _create_connection) if source_addr: # TODO: socket.create_connection doesn't support source_address # in Python 2.6 warn(RuntimeWarning, "No support for binding a source address, will ignore") sock = makesock((self.host, self.port), timeout) if (getattr(self, '_tunnel_host', None) and hasattr(self, '_tunnel')): self.sock = sock self._tunnel() # this will throw NameError if we call the function without ssl # support self.sock = ssl.wrap_socket(sock, keyfile=self.key_file, certfile=self.cert_file, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_file) if self.ca_file and self.do_match_hostname: match_hostname(self.sock.getpeercert(), self.host)
def connect(self): """ Connect Checks if verification is toggled; if not, just call httplib.HTTPSConnection's connect """ if not self.verify: return httplib.HTTPSConnection.connect(self) # otherwise, create a connection and verify the hostname # use socket.create_connection (in 2.6+) if possible if getattr(socket, 'create_connection', None): sock = socket.create_connection((self.host, self.port), self.timeout) else: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((self.host, self.port)) # Activate the HTTP proxy if self.http_proxy_used: self._activate_http_proxy(sock=sock) self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_cert, ssl_version=libcloud.security.SSL_VERSION) cert = self.sock.getpeercert() try: match_hostname(cert, self.host) except CertificateError: e = sys.exc_info()[1] raise ssl.SSLError('Failed to verify hostname: %s' % (str(e)))
def cert_verify_hostname(s): # hostname verification (disabled) from backports.ssl_match_hostname import match_hostname, CertificateError try: match_hostname(s.getpeercert(True), host) print_error("hostname matches", host) except CertificateError, ce: print_error("hostname did not match", host)
def connect(self): httplib.HTTPConnection.connect(self) self.sock = ssl.wrap_socket(self.sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs=os.path.normpath( os.path.join(os.path.dirname(__file__), 'cacerts.txt'))) match_hostname(self.sock.getpeercert(), self.host)
def convert_to_ssl(self, sni=None, alpn_protos=None, **sslctx_kwargs): """ cert: Path to a file containing both client cert and private key. options: A bit field consisting of OpenSSL.SSL.OP_* values verify_options: A bit field consisting of OpenSSL.SSL.VERIFY_* values ca_path: Path to a directory of trusted CA certificates prepared using the c_rehash tool ca_pemfile: Path to a PEM formatted trusted CA certificate """ verification_mode = sslctx_kwargs.get("verify_options", None) if verification_mode == SSL.VERIFY_PEER and not sni: raise exceptions.TlsException("Cannot validate certificate hostname without SNI") context = self.create_ssl_context(alpn_protos=alpn_protos, sni=sni, **sslctx_kwargs) self.connection = SSL.Connection(context, self.connection) if sni: self.sni = sni self.connection.set_tlsext_host_name(sni.encode("idna")) self.connection.set_connect_state() try: self.connection.do_handshake() except SSL.Error as v: if self.ssl_verification_error: raise self.ssl_verification_error else: raise exceptions.TlsException("SSL handshake error: %s" % repr(v)) else: # Fix for pre v1.0 OpenSSL, which doesn't throw an exception on # certificate validation failure if verification_mode == SSL.VERIFY_PEER and self.ssl_verification_error: raise self.ssl_verification_error self.cert = certs.SSLCert(self.connection.get_peer_certificate()) # Keep all server certificates in a list for i in self.connection.get_peer_cert_chain(): self.server_certs.append(certs.SSLCert(i)) # Validate TLS Hostname try: crt = dict(subjectAltName=[("DNS", x.decode("ascii", "strict")) for x in self.cert.altnames]) if self.cert.cn: crt["subject"] = [[["commonName", self.cert.cn.decode("ascii", "strict")]]] if sni: hostname = sni else: hostname = "no-hostname" ssl_match_hostname.match_hostname(crt, hostname) except (ValueError, ssl_match_hostname.CertificateError) as e: self.ssl_verification_error = exceptions.InvalidCertificateException( "Certificate Verification Error for {}: {}".format(sni or repr(self.address), str(e)) ) if verification_mode == SSL.VERIFY_PEER: raise self.ssl_verification_error self.ssl_established = True self.rfile.set_descriptor(self.connection) self.wfile.set_descriptor(self.connection)
def convert_to_ssl(self, sni=None, alpn_protos=None, **sslctx_kwargs): """ cert: Path to a file containing both client cert and private key. options: A bit field consisting of OpenSSL.SSL.OP_* values verify_options: A bit field consisting of OpenSSL.SSL.VERIFY_* values ca_path: Path to a directory of trusted CA certificates prepared using the c_rehash tool ca_pemfile: Path to a PEM formatted trusted CA certificate """ verification_mode = sslctx_kwargs.get('verify_options', None) if verification_mode == SSL.VERIFY_PEER and not sni: raise TlsException("Cannot validate certificate hostname without SNI") context = self.create_ssl_context( alpn_protos=alpn_protos, **sslctx_kwargs ) self.connection = SSL.Connection(context, self.connection) if sni: self.sni = sni self.connection.set_tlsext_host_name(sni) self.connection.set_connect_state() try: self.connection.do_handshake() except SSL.Error as v: if self.ssl_verification_error: raise InvalidCertificateException("SSL handshake error: %s" % repr(v)) else: raise TlsException("SSL handshake error: %s" % repr(v)) else: # Fix for pre v1.0 OpenSSL, which doesn't throw an exception on # certificate validation failure if verification_mode == SSL.VERIFY_PEER and self.ssl_verification_error is not None: raise InvalidCertificateException("SSL handshake error: certificate verify failed") self.cert = certutils.SSLCert(self.connection.get_peer_certificate()) # Validate TLS Hostname try: crt = dict( subjectAltName=[("DNS", x.decode("ascii", "strict")) for x in self.cert.altnames] ) if self.cert.cn: crt["subject"] = [[["commonName", self.cert.cn.decode("ascii", "strict")]]] if sni: hostname = sni.decode("ascii", "strict") else: hostname = "no-hostname" ssl_match_hostname.match_hostname(crt, hostname) except (ValueError, ssl_match_hostname.CertificateError) as e: self.ssl_verification_error = dict(depth=0, errno="Invalid Hostname") if verification_mode == SSL.VERIFY_PEER: raise InvalidCertificateException("Presented certificate for {} is not valid: {}".format(sni, str(e))) self.ssl_established = True self.rfile.set_descriptor(self.connection) self.wfile.set_descriptor(self.connection)
def connect(self): httplib.HTTPConnection.connect(self) self.sock = ssl.wrap_socket(self.sock, keyfile=self.key_file, certfile=self.cert_file, cert_reqs=self.cert_reqs, ca_certs=self.ca_certs) if self.cert_reqs & ssl.CERT_REQUIRED: cert = self.sock.getpeercert() hostname = self.host.split(':', 0)[0] match_hostname(cert, hostname)
def hostname_mismatch(self, ssl_sock): """ Check if wrong hostname is identified get the server's certificate using getpeercert() match_hostname should mismatch for wrong hostname """ try: match_hostname(ssl_sock.getpeercert(), "www.example-wrong.com") self.nfail += 1 logging.info('\n match_hostname failed to identify wrong hostname') except CertificateError: logging.info('\nIdentified mismatch in hostname')
def connect(self): httplib.HTTPConnection.connect(self) self.sock = ssl.wrap_socket(self.sock, keyfile=self.key_file, certfile=self.cert_file, cert_reqs=self.cert_reqs, ca_certs=self.ca_certs) if self.cert_reqs & ssl.CERT_REQUIRED: cert = self.sock.getpeercert() hostname = self.host.split(':', 0)[0] # Fix for invalid subjectAltName in cis.porezna-uprava.hr certificate if 'subjectAltName' in cert: del cert['subjectAltName'] match_hostname(cert, hostname)
def hostname_match(self, ssl_sock): """ Check if hostname is matching get the server's certificate using getpeercert() Verify the cert matches the hostname """ try: match_hostname(ssl_sock.getpeercert(), "www.example.com") except CertificateError: logging.error('hostname doesnt match. \n') self.nfail += 1 raise error.TestError('\nTest failed to match hostname')
def connect(self, host, port=None): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(self.socket_connect_timeout) # connect timeout self.sock.connect((host, port or self.port)) self.sock.settimeout(self.socket_timeout) # regular timeout if self.ssl_enable: self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, ssl_version=self.ssl_version, ciphers=self.ssl_ciphers, server_side=False, cert_reqs=self.cert_required, ca_certs=self.cacerts) if self.validate_hostname: try: match_hostname(self.sock.getpeercert(), host) except CertificateError, e: self.log.exception("SSL hostname mismatch") raise EppConnectionError(str(e))
def _certificate_hostname_mismatch(self, certificate): """ Determines whether or not a given certificate matches the previously configured domain. The ``altSubjectName`` property is checked first, taking into account the explicit and wildcard fields there. If the ``altSubjectName`` property is not present, the ``commonName`` property of the ``subject`` field is checked. Arguments: * ``certificate``: A certificate object as returned by :py:meth:`~peace_of_mind.certificates.CertificateChecker.get_certificate` Returns False or :py:const:`~peace_of_mind.certificates.ERROR_SSL_CERT_HOST_MISMATCH` if the certificate has expired. """ try: match_hostname(certificate, self._domain) except CertificateError: return ERROR_SSL_CERT_HOST_MISMATCH return False
def verify_hostname(self, sock, hostname): u""" Attempt to match the peer hostname and certificate. If a certificate was not provided, and we don't require a certificate, this function will report a warning if the hostname doesn't match. This is also true if we disable hostname verification with set_verify_hostname(False). If we require peer certificates and hostname verification, this function will raise a ssl_match_hostname.CertificateError if the hostname doesn't match. :param ssl.SSLSocket sock: The connected socket we want to verify :param string hostname: The hostname that should match the certificate """ cert = sock.getpeercert() if cert is None: warn(RuntimeWarning(u'Peer did not supply a certificate.')) if not cert and self._wrap_param['cert_reqs'] == SSLConfig.NONE: # Empty dict or None, don't care. We don't even look at the # certificate. return if cert is None and self._wrap_param['cert_reqs'] == SSLConfig.OPTIONAL: # It's ok that the peer did not provide a certificate, # and without a certificate there's nothing to verify. # # We should NOT get an empty dict here! return try: ssl_match_hostname.match_hostname(cert, hostname) except ssl_match_hostname.CertificateError: if not self._do_verify_hostname: # We checked it anyway warn(RuntimeWarning(u'Invalid hostname in certificate')) return raise
def connect(self): # Add certificate verification conn = self._new_conn() resolved_cert_reqs = resolve_cert_reqs(self.cert_reqs) resolved_ssl_version = resolve_ssl_version(self.ssl_version) hostname = self.host if getattr(self, '_tunnel_host', None): # _tunnel_host was added in Python 2.6.3 # (See: http://hg.python.org/cpython/rev/0f57b30a152f) self.sock = conn # Calls self._set_hostport(), so self.host is # self._tunnel_host below. self._tunnel() # Mark this connection as not reusable self.auto_open = 0 # Override the host with the one we're requesting data from. hostname = self._tunnel_host # Wrap socket using verification with the root certs in # trusted_root_certs self.sock = ssl_wrap_socket(conn, self.key_file, self.cert_file, cert_reqs=resolved_cert_reqs, ca_certs=self.ca_certs, server_hostname=hostname, ssl_version=resolved_ssl_version) if resolved_cert_reqs != ssl.CERT_NONE: if self.assert_fingerprint: assert_fingerprint(self.sock.getpeercert(binary_form=True), self.assert_fingerprint) elif self.assert_hostname is not False: match_hostname(self.sock.getpeercert(), self.assert_hostname or hostname) self.is_verified = resolved_cert_reqs == ssl.CERT_REQUIRED
def connect(self, url, **options): """ Connect to url. url is websocket url scheme. ie. ws://host:port/resource You can customize using 'options'. If you set "header" dict object, you can set your own custom header. >>> ws = WebSocket() >>> ws.connect("ws://echo.websocket.org/", ... header={"User-Agent: MyProgram", ... "x-custom: header"}) timeout: socket timeout time. This value is integer. if you set None for this value, it means "use default_timeout value" options: current support option is only "header". if you set header as dict value, the custom HTTP headers are added. """ hostname, port, resource, is_secure = _parse_url(url) # TODO: we need to support proxy self.sock.connect((hostname, port)) if is_secure: if HAVE_SSL: sslopt = dict(ssl_version=ssl.PROTOCOL_TLSv1, server_hostname=hostname, cert_reqs=ssl.CERT_REQUIRED, ca_certs=os.path.join(os.path.dirname(__file__), "cacert.pem")) sslopt.update(self.sslopt) self.sock = ssl.wrap_socket(self.sock, **sslopt) match_hostname(self.sock.getpeercert(), hostname) else: raise WebSocketException("SSL not available.") self._handshake(hostname, port, resource, **options)
def connect(self): "Connect to a host on a given (SSL) port." if not getattr(self, 'timeout', None): self.timeout = socket.getdefaulttimeout() args = [(self.host, self.port), self.timeout] if hasattr(self, 'source_address'): args.append(self.source_address) sock = socket.create_connection(*args) if getattr(self, '_tunnel_host', None): self.sock = sock self._tunnel() self.sock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1, ca_certs=CERT_FILE, cert_reqs=ssl.CERT_REQUIRED) try: match_hostname(self.sock.getpeercert(), self.host) except CertificateError: self.sock.shutdown(socket.SHUT_RDWR) self.sock.close() raise
def test_match_dns_success(self): assert match_hostname(self.cert, 'touhou.gensokyo.jp') is None
def test_match_localhost_success(self): assert match_hostname(self.cert, 'localhost') is None
def test_match_ip_address_success(self): assert match_hostname(self.cert, '127.0.0.1') is None
def _check_ssl_certificate_hostname(self): LOGGER.info('SSL peer certificate %s', self.socket.getpeercert()) match_hostname(self.socket.getpeercert(), self.params.host)
def after_connect(self, sock): super(SSLConnectionPool, self).after_connect(sock) if not self.insecure: match_hostname(sock.getpeercert(), self._host)
def ok(cert, hostname): ssl.match_hostname(cert, hostname)
def test_match_hostname(self): def ok(cert, hostname): ssl.match_hostname(cert, hostname) def fail(cert, hostname): self.assertRaises(ssl.CertificateError, ssl.match_hostname, cert, hostname) # -- Hostname matching -- cert = {'subject': ((('commonName', 'example.com'),),)} ok(cert, 'example.com') ok(cert, 'ExAmple.cOm') fail(cert, 'www.example.com') fail(cert, '.example.com') fail(cert, 'example.org') fail(cert, 'exampleXcom') cert = {'subject': ((('commonName', '*.a.com'),),)} ok(cert, 'foo.a.com') fail(cert, 'bar.foo.a.com') fail(cert, 'a.com') fail(cert, 'Xa.com') fail(cert, '.a.com') # only match wildcards when they are the only thing # in left-most segment cert = {'subject': ((('commonName', 'f*.com'),),)} fail(cert, 'foo.com') fail(cert, 'f.com') fail(cert, 'bar.com') fail(cert, 'foo.a.com') fail(cert, 'bar.foo.com') # NULL bytes are bad, CVE-2013-4073 cert = {'subject': ((('commonName', 'null.python.org\x00example.org'),),)} ok(cert, 'null.python.org\x00example.org') # or raise an error? fail(cert, 'example.org') fail(cert, 'null.python.org') # error cases with wildcards cert = {'subject': ((('commonName', '*.*.a.com'),),)} fail(cert, 'bar.foo.a.com') fail(cert, 'a.com') fail(cert, 'Xa.com') fail(cert, '.a.com') cert = {'subject': ((('commonName', 'a.*.com'),),)} fail(cert, 'a.foo.com') fail(cert, 'a..com') fail(cert, 'a.com') # wildcard doesn't match IDNA prefix 'xn--' # Divergence: explicitly mark text string with u idna = u'püthon.python.org'.encode("idna").decode("ascii") cert = {'subject': ((('commonName', idna),),)} ok(cert, idna) cert = {'subject': ((('commonName', 'x*.python.org'),),)} fail(cert, idna) cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)} fail(cert, idna) # wildcard in first fragment and IDNA A-labels in sequent fragments # are supported. # Divergence: explicitly mark text strings with u idna = u'www*.pythön.org'.encode("idna").decode("ascii") cert = {'subject': ((('commonName', idna),),)} fail(cert, u'www.pythön.org'.encode("idna").decode("ascii")) fail(cert, u'www1.pythön.org'.encode("idna").decode("ascii")) fail(cert, u'ftp.pythön.org'.encode("idna").decode("ascii")) fail(cert, u'pythön.org'.encode("idna").decode("ascii")) # Slightly fake real-world example cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT', 'subject': ((('commonName', 'linuxfrz.org'),),), 'subjectAltName': (('DNS', 'linuxfr.org'), ('DNS', 'linuxfr.com'), ('othername', '<unsupported>'))} ok(cert, 'linuxfr.org') ok(cert, 'linuxfr.com') # Not a "DNS" entry fail(cert, '<unsupported>') # When there is a subjectAltName, commonName isn't used fail(cert, 'linuxfrz.org') # A pristine real-world example cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'Mountain View'),), (('organizationName', 'Google Inc'),), (('commonName', 'mail.google.com'),))} ok(cert, 'mail.google.com') fail(cert, 'gmail.com') # Only commonName is considered fail(cert, 'California') # -- IPv4 matching -- cert = {'subject': ((('commonName', 'example.com'),),), 'subjectAltName': (('DNS', 'example.com'), ('IP Address', '10.11.12.13'), ('IP Address', '14.15.16.17'))} ok(cert, '10.11.12.13') ok(cert, '14.15.16.17') fail(cert, '14.15.16.18') fail(cert, 'example.net') # -- IPv6 matching -- if hasattr(socket, 'AF_INET6'): cert = {'subject': ((('commonName', 'example.com'),),), 'subjectAltName': ( ('DNS', 'example.com'), ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'), ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))} ok(cert, '2001::cafe') ok(cert, '2003::baba') fail(cert, '2003::bebe') fail(cert, 'example.net') # -- Miscellaneous -- # Neither commonName nor subjectAltName cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'Mountain View'),), (('organizationName', 'Google Inc'),))} fail(cert, 'mail.google.com') # No DNS entry in subjectAltName but a commonName cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'Mountain View'),), (('commonName', 'mail.google.com'),)), 'subjectAltName': (('othername', 'blabla'), )} ok(cert, 'mail.google.com') # No DNS entry subjectAltName and no commonName cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', 'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'Mountain View'),), (('organizationName', 'Google Inc'),)), 'subjectAltName': (('othername', 'blabla'),)} fail(cert, 'google.com') # Empty cert / no cert self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com') self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com') # Issue #17980: avoid denials of service by refusing more than one # wildcard per fragment. cert = {'subject': ((('commonName', 'a*b.example.com'),),)} with self.assertRaisesRegex( ssl.CertificateError, "partial wildcards in leftmost label are not supported"): ssl.match_hostname(cert, 'axxb.example.com') cert = {'subject': ((('commonName', 'www.*.example.com'),),)} with self.assertRaisesRegex( ssl.CertificateError, "wildcard can only be present in the leftmost label"): ssl.match_hostname(cert, 'www.sub.example.com') cert = {'subject': ((('commonName', 'a*b*.example.com'),),)} with self.assertRaisesRegex( ssl.CertificateError, "too many wildcards"): ssl.match_hostname(cert, 'axxbxxc.example.com') cert = {'subject': ((('commonName', '*'),),)} with self.assertRaisesRegex( ssl.CertificateError, "sole wildcard without additional labels are not support"): ssl.match_hostname(cert, 'host') cert = {'subject': ((('commonName', '*.com'),),)} with self.assertRaisesRegex( ssl.CertificateError, r"hostname 'com' doesn't match '\*.com'"): ssl.match_hostname(cert, 'com') # extra checks for _inet_paton() for invalid in ['1', '', '1.2.3', '256.0.0.1', '127.0.0.1/24']: with self.assertRaises(ValueError): ssl._inet_paton(invalid) for ipaddr in ['127.0.0.1', '192.168.0.1']: self.assertTrue(ssl._inet_paton(ipaddr)) if hasattr(socket, 'AF_INET6'): for ipaddr in ['::1', '2001:db8:85a3::8a2e:370:7334']: self.assertTrue(ssl._inet_paton(ipaddr))
def test_match_ip_address_failure(self): with pytest.raises(CertificateError): match_hostname(self.cert, '192.168.0.25')
def test_match_dns_failure(self): with pytest.raises(CertificateError): match_hostname(self.cert, 'foobar.co.uk')
sock.settimeout(5) ssl_sock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_REQUIRED, ca_certs='/etc/pki/tls/cert.pem' ) try: ssl_sock.connect((args.hostname, 443)) except ssl.SSLError, error: print args.hostname + ": Port 443 not open" sys.exit(1) try: match_hostname(ssl_sock.getpeercert(), args.hostname) except ValueError: print args.hostname + ": Certificate not valid" sys.exit(1) ciphertype = ssl_sock.cipher()[1] expires = ssl_sock.getpeercert()['notAfter'] from M2Crypto import SSL SSL.Connection.clientPostConnectionCheck = None ctx = SSL.Context() conn = SSL.Connection(ctx) conn.connect((args.hostname, 443)) cert = conn.get_peer_cert() certinfo = cert.get_subject().as_text()
print >>sys.stderr, 'usage: sslclient.py <hostname>' sys.exit(2) # First we connect, as usual, with a socket. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((hostname, 443)) # Next, we turn the socket over to the SSL library! ca_certs_path = os.path.join(os.path.dirname(script_name), 'certfiles.crt') sslsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs_path) # Does the certificate that the server proffered *really* match the # hostname to which we are trying to connect? We need to check. try: match_hostname(sslsock.getpeercert(), hostname) except CertificateError, ce: print 'Certificate error:', str(ce) sys.exit(1) # From here on, our `sslsock` works like a normal socket. We can, for # example, make an impromptu HTTP call. sslsock.sendall('GET / HTTP/1.0\r\n\r\n') result = sslsock.makefile().read() # quick way to read until EOF sslsock.close() print 'The document https://%s/ is %d bytes long' % (hostname, len(result))
# First we connect, as usual, with a socket. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((hostname, 443)) # Next, we turn the socket over to the SSL library! ca_certs_path = os.path.join(os.path.dirname(script_name), 'certfiles.crt') sslsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs_path) # Does the certificate that the server proffered *really* match the # hostname to which we are trying to connect? We need to check. try: match_hostname(sslsock.getpeercert(), hostname) except CertificateError, ce: print 'Certificate error:', str(ce) sys.exit(1) # From here on, our `sslsock` works like a normal socket. We can, for # example, make an impromptu HTTP call. sslsock.sendall('GET / HTTP/1.0\r\n\r\n') result = sslsock.makefile().read() # quick way to read until EOF sslsock.close() print 'The document https://%s/ is %d bytes long' % (hostname, len(result))