def _connect_tls_proxy(self, hostname, conn): """ Establish a TLS connection to the proxy using the provided SSL context. """ proxy_config = self.proxy_config ssl_context = proxy_config.ssl_context if ssl_context: # If the user provided a proxy context, we assume CA and client # certificates have already been set return ssl_wrap_socket( sock=conn, server_hostname=hostname, ssl_context=ssl_context, ) ssl_context = create_proxy_ssl_context( self.ssl_version, self.cert_reqs, self.ca_certs, self.ca_cert_dir, self.ca_cert_data, ) # If no cert was provided, use only the default options for server # certificate validation socket = ssl_wrap_socket( sock=conn, ca_certs=self.ca_certs, ca_cert_dir=self.ca_cert_dir, ca_cert_data=self.ca_cert_data, server_hostname=hostname, ssl_context=ssl_context, ) if ssl_context.verify_mode != ssl.CERT_NONE and not getattr( ssl_context, "check_hostname", False): # While urllib3 attempts to always turn off hostname matching from # the TLS library, this cannot always be done. So we check whether # the TLS Library still thinks it's matching hostnames. cert = socket.getpeercert() if not cert.get("subjectAltName", ()): warnings.warn( ("Certificate for {0} has no `subjectAltName`, falling back to check for a " "`commonName` for now. This feature is being removed by major browsers and " "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 " "for details.)".format(hostname)), SubjectAltNameWarning, ) _match_hostname(cert, hostname) self.proxy_is_verified = ssl_context.verify_mode == ssl.CERT_REQUIRED return socket
def verifyThumbprint(socket): rawThumbprint = hashlib.sha1(socket.getpeercert(True)).hexdigest() thumbprint = ':'.join(rawThumbprint[i:i + 2] for i in range(0, len(rawThumbprint), 2)).upper() if (os.path.isfile("/var/artillery/configServerThumbprint")): knownThumbprint = open("/var/artillery/configServerThumbprint", 'r').read() if (knownThumbprint == thumbprint): return True else: write_log( "[!] %s: Artillery Config Manager: invalid server thumbprint %s" % (grab_time(), thumbprint)) return False else: open("/var/artillery/configServerThumbprint", "w").write(thumbprint) return True
def _get_channel_bindings_application_data(response): """ https://tools.ietf.org/html/rfc5929 4. The 'tls-server-end-point' Channel Binding Type Gets the application_data value for the 'tls-server-end-point' CBT Type. This is ultimately the SHA256 hash of the certificate of the HTTPS endpoint appended onto tls-server-end-point. This value is then passed along to the kerberos library to bind to the auth response. If the socket is not an SSL socket or the raw HTTP object is not a urllib3 HTTPResponse then None will be returned and the Kerberos auth will use GSS_C_NO_CHANNEL_BINDINGS :param response: The original 401 response from the server :return: byte string used on the application_data.value field on the CBT struct """ application_data = None raw_response = response.raw if isinstance(raw_response, HTTPResponse): try: if sys.version_info > (3, 0): socket = raw_response._fp.fp.raw._sock else: socket = raw_response._fp.fp._sock except AttributeError: warnings.warn( "Failed to get raw socket for CBT; has urllib3 impl changed", NoCertificateRetrievedWarning) else: try: server_certificate = socket.getpeercert(True) except AttributeError: pass else: certificate_hash = _get_certificate_hash(server_certificate) application_data = b'tls-server-end-point:' + certificate_hash else: warnings.warn( "Requests is running with a non urllib3 backend, cannot retrieve server certificate for CBT", NoCertificateRetrievedWarning) return application_data
def verify_tls(self, socket, hostname, context, as_callback=True): """ Verify a TLS connection. Return behaviour is dependent on the as_callback parameter: - If True, a return value of None means verification succeeded, else it failed. - If False, a return value of True means verification succeeded, an exception or False means it failed. """ cert = socket.getpeercert() try: # Make sure the hostnames for which this certificate is valid include the one we're connecting to. ssl.match_hostname(cert, hostname) except ssl.CertificateError: if not as_callback: raise # Try to give back a more elaborate error message if possible. if hasattr(ssl, 'ALERT_DESCRIPTION_BAD_CERTIFICATE'): return ssl.ALERT_DESCRIPTION_BAD_CERTIFICATE return True # Verification done. if as_callback: return None return True