同步操作将从 OpenHarmony-SIG/python 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
# Wrapper module for _ssl, providing some additional facilities# implemented in Python. Written by Bill Janssen."""This module provides some more Pythonic support for SSL.Object types:SSLSocket -- subtype of socket.socket which does SSL over the socketExceptions:SSLError -- exception raised for I/O errorsFunctions:cert_time_to_seconds -- convert time string used for certificatenotBefore and notAfter functions to integerseconds past the Epoch (the time valuesreturned from time.time())fetch_server_certificate (HOST, PORT) -- fetch the certificate providedby the server running on HOST at port PORT. Novalidation of the certificate is performed.Integer constants:SSL_ERROR_ZERO_RETURNSSL_ERROR_WANT_READSSL_ERROR_WANT_WRITESSL_ERROR_WANT_X509_LOOKUPSSL_ERROR_SYSCALLSSL_ERROR_SSLSSL_ERROR_WANT_CONNECTSSL_ERROR_EOFSSL_ERROR_INVALID_ERROR_CODEThe following group define certificate requirements that one side isallowing/requiring from the other side:CERT_NONE - no certificates from the other side are required (or willbe looked at if provided)CERT_OPTIONAL - certificates are not required, but if provided will bevalidated, and if validation fails, the connection willalso failCERT_REQUIRED - certificates are required, and will be validated, andif validation fails, the connection will also failThe following constants identify various SSL protocol variants:PROTOCOL_SSLv2PROTOCOL_SSLv3PROTOCOL_SSLv23PROTOCOL_TLSPROTOCOL_TLS_CLIENTPROTOCOL_TLS_SERVERPROTOCOL_TLSv1PROTOCOL_TLSv1_1PROTOCOL_TLSv1_2The following constants identify various SSL alert message descriptions as perhttp://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6ALERT_DESCRIPTION_CLOSE_NOTIFYALERT_DESCRIPTION_UNEXPECTED_MESSAGEALERT_DESCRIPTION_BAD_RECORD_MACALERT_DESCRIPTION_RECORD_OVERFLOWALERT_DESCRIPTION_DECOMPRESSION_FAILUREALERT_DESCRIPTION_HANDSHAKE_FAILUREALERT_DESCRIPTION_BAD_CERTIFICATEALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATEALERT_DESCRIPTION_CERTIFICATE_REVOKEDALERT_DESCRIPTION_CERTIFICATE_EXPIREDALERT_DESCRIPTION_CERTIFICATE_UNKNOWNALERT_DESCRIPTION_ILLEGAL_PARAMETERALERT_DESCRIPTION_UNKNOWN_CAALERT_DESCRIPTION_ACCESS_DENIEDALERT_DESCRIPTION_DECODE_ERRORALERT_DESCRIPTION_DECRYPT_ERRORALERT_DESCRIPTION_PROTOCOL_VERSIONALERT_DESCRIPTION_INSUFFICIENT_SECURITYALERT_DESCRIPTION_INTERNAL_ERRORALERT_DESCRIPTION_USER_CANCELLEDALERT_DESCRIPTION_NO_RENEGOTIATIONALERT_DESCRIPTION_UNSUPPORTED_EXTENSIONALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLEALERT_DESCRIPTION_UNRECOGNIZED_NAMEALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSEALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUEALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY"""import sysimport osfrom collections import namedtuplefrom enum import Enum as _Enum, IntEnum as _IntEnum, IntFlag as _IntFlagimport _ssl # if we can't import it, let the error propagatefrom _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSIONfrom _ssl import _SSLContext, MemoryBIO, SSLSessionfrom _ssl import (SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,SSLSyscallError, SSLEOFError, SSLCertVerificationError)from _ssl import txt2obj as _txt2obj, nid2obj as _nid2objfrom _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytestry:from _ssl import RAND_egdexcept ImportError:# LibreSSL does not provide RAND_egdpassfrom _ssl import (HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1,HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3)from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION_IntEnum._convert_('_SSLMethod', __name__,lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',source=_ssl)_IntFlag._convert_('Options', __name__,lambda name: name.startswith('OP_'),source=_ssl)_IntEnum._convert_('AlertDescription', __name__,lambda name: name.startswith('ALERT_DESCRIPTION_'),source=_ssl)_IntEnum._convert_('SSLErrorNumber', __name__,lambda name: name.startswith('SSL_ERROR_'),source=_ssl)_IntFlag._convert_('VerifyFlags', __name__,lambda name: name.startswith('VERIFY_'),source=_ssl)_IntEnum._convert_('VerifyMode', __name__,lambda name: name.startswith('CERT_'),source=_ssl)PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()}_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None)class TLSVersion(_IntEnum):MINIMUM_SUPPORTED = _ssl.PROTO_MINIMUM_SUPPORTEDSSLv3 = _ssl.PROTO_SSLv3TLSv1 = _ssl.PROTO_TLSv1TLSv1_1 = _ssl.PROTO_TLSv1_1TLSv1_2 = _ssl.PROTO_TLSv1_2TLSv1_3 = _ssl.PROTO_TLSv1_3MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTEDclass _TLSContentType(_IntEnum):"""Content types (record layer)See RFC 8446, section B.1"""CHANGE_CIPHER_SPEC = 20ALERT = 21HANDSHAKE = 22APPLICATION_DATA = 23# pseudo content typesHEADER = 0x100INNER_CONTENT_TYPE = 0x101class _TLSAlertType(_IntEnum):"""Alert types for TLSContentType.ALERT messagesSee RFC 8466, section B.2"""CLOSE_NOTIFY = 0UNEXPECTED_MESSAGE = 10BAD_RECORD_MAC = 20DECRYPTION_FAILED = 21RECORD_OVERFLOW = 22DECOMPRESSION_FAILURE = 30HANDSHAKE_FAILURE = 40NO_CERTIFICATE = 41BAD_CERTIFICATE = 42UNSUPPORTED_CERTIFICATE = 43CERTIFICATE_REVOKED = 44CERTIFICATE_EXPIRED = 45CERTIFICATE_UNKNOWN = 46ILLEGAL_PARAMETER = 47UNKNOWN_CA = 48ACCESS_DENIED = 49DECODE_ERROR = 50DECRYPT_ERROR = 51EXPORT_RESTRICTION = 60PROTOCOL_VERSION = 70INSUFFICIENT_SECURITY = 71INTERNAL_ERROR = 80INAPPROPRIATE_FALLBACK = 86USER_CANCELED = 90NO_RENEGOTIATION = 100MISSING_EXTENSION = 109UNSUPPORTED_EXTENSION = 110CERTIFICATE_UNOBTAINABLE = 111UNRECOGNIZED_NAME = 112BAD_CERTIFICATE_STATUS_RESPONSE = 113BAD_CERTIFICATE_HASH_VALUE = 114UNKNOWN_PSK_IDENTITY = 115CERTIFICATE_REQUIRED = 116NO_APPLICATION_PROTOCOL = 120class _TLSMessageType(_IntEnum):"""Message types (handshake protocol)See RFC 8446, section B.3"""HELLO_REQUEST = 0CLIENT_HELLO = 1SERVER_HELLO = 2HELLO_VERIFY_REQUEST = 3NEWSESSION_TICKET = 4END_OF_EARLY_DATA = 5HELLO_RETRY_REQUEST = 6ENCRYPTED_EXTENSIONS = 8CERTIFICATE = 11SERVER_KEY_EXCHANGE = 12CERTIFICATE_REQUEST = 13SERVER_DONE = 14CERTIFICATE_VERIFY = 15CLIENT_KEY_EXCHANGE = 16FINISHED = 20CERTIFICATE_URL = 21CERTIFICATE_STATUS = 22SUPPLEMENTAL_DATA = 23KEY_UPDATE = 24NEXT_PROTO = 67MESSAGE_HASH = 254CHANGE_CIPHER_SPEC = 0x0101if sys.platform == "win32":from _ssl import enum_certificates, enum_crlsfrom socket import socket, AF_INET, SOCK_STREAM, create_connectionfrom socket import SOL_SOCKET, SO_TYPEimport socket as _socketimport base64 # for DER-to-PEM translationimport errnoimport warningssocket_error = OSError # keep that public name in module namespaceCHANNEL_BINDING_TYPES = ['tls-unique']HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')_RESTRICTED_SERVER_CIPHERS = _DEFAULT_CIPHERSCertificateError = SSLCertVerificationErrordef _dnsname_match(dn, hostname):"""Matching according to RFC 6125, section 6.4.3- Hostnames are compared lower case.- For IDNA, both dn and hostname must be encoded as IDN A-label (ACE).- Partial wildcards like 'www*.example.org', multiple wildcards, solewildcard or wildcards in labels other then the left-most label are notsupported and a CertificateError is raised.- A wildcard must match at least one character."""if not dn:return Falsewildcards = dn.count('*')# speed up common case w/o wildcardsif not wildcards:return dn.lower() == hostname.lower()if wildcards > 1:raise CertificateError("too many wildcards in certificate DNS name: {!r}.".format(dn))dn_leftmost, sep, dn_remainder = dn.partition('.')if '*' in dn_remainder:# Only match wildcard in leftmost segment.raise CertificateError("wildcard can only be present in the leftmost label: ""{!r}.".format(dn))if not sep:# no right sideraise CertificateError("sole wildcard without additional labels are not support: ""{!r}.".format(dn))if dn_leftmost != '*':# no partial wildcard matchingraise CertificateError("partial wildcards in leftmost label are not supported: ""{!r}.".format(dn))hostname_leftmost, sep, hostname_remainder = hostname.partition('.')if not hostname_leftmost or not sep:# wildcard must match at least one charreturn Falsereturn dn_remainder.lower() == hostname_remainder.lower()def _inet_paton(ipname):"""Try to convert an IP address to packed binary formSupports IPv4 addresses on all platforms and IPv6 on platforms with IPv6support."""# inet_aton() also accepts strings like '1', '127.1', some also trailing# data like '127.0.0.1 whatever'.try:addr = _socket.inet_aton(ipname)except OSError:# not an IPv4 addresspasselse:if _socket.inet_ntoa(addr) == ipname:# only accept injective ipnamesreturn addrelse:# refuse for short IPv4 notation and additional trailing dataraise ValueError("{!r} is not a quad-dotted IPv4 address.".format(ipname))try:return _socket.inet_pton(_socket.AF_INET6, ipname)except OSError:raise ValueError("{!r} is neither an IPv4 nor an IP6 ""address.".format(ipname))except AttributeError:# AF_INET6 not availablepassraise ValueError("{!r} is not an IPv4 address.".format(ipname))def _ipaddress_match(cert_ipaddress, host_ip):"""Exact matching of IP addresses.RFC 6125 explicitly doesn't define an algorithm for this(section 1.7.2 - "Out of Scope")."""# OpenSSL may add a trailing newline to a subjectAltName's IP address,# commonly woth IPv6 addresses. Strip off trailing \n.ip = _inet_paton(cert_ipaddress.rstrip())return ip == host_ipdef match_hostname(cert, hostname):"""Verify that *cert* (in decoded format as returned bySSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125rules are followed.The function matches IP addresses rather than dNSNames if hostname is avalid ipaddress string. IPv4 addresses are supported on all platforms.IPv6 addresses are supported on platforms with IPv6 support (AF_INET6and inet_pton).CertificateError is raised on failure. On success, the functionreturns nothing."""if not cert:raise ValueError("empty or no certificate, match_hostname needs a ""SSL socket or SSL context with either ""CERT_OPTIONAL or CERT_REQUIRED")try:host_ip = _inet_paton(hostname)except ValueError:# Not an IP address (common case)host_ip = Nonednsnames = []san = cert.get('subjectAltName', ())for key, value in san:if key == 'DNS':if host_ip is None and _dnsname_match(value, hostname):returndnsnames.append(value)elif key == 'IP Address':if host_ip is not None and _ipaddress_match(value, host_ip):returndnsnames.append(value)if not dnsnames:# The subject is only checked when there is no dNSName entry# in subjectAltNamefor sub in cert.get('subject', ()):for key, value in sub:# XXX according to RFC 2818, the most specific Common Name# must be used.if key == 'commonName':if _dnsname_match(value, hostname):returndnsnames.append(value)if len(dnsnames) > 1:raise CertificateError("hostname %r ""doesn't match either of %s"% (hostname, ', '.join(map(repr, dnsnames))))elif len(dnsnames) == 1:raise CertificateError("hostname %r ""doesn't match %r"% (hostname, dnsnames[0]))else:raise CertificateError("no appropriate commonName or ""subjectAltName fields were found")DefaultVerifyPaths = namedtuple("DefaultVerifyPaths","cafile capath openssl_cafile_env openssl_cafile openssl_capath_env ""openssl_capath")def get_default_verify_paths():"""Return paths to default cafile and capath."""parts = _ssl.get_default_verify_paths()# environment vars shadow pathscafile = os.environ.get(parts[0], parts[1])capath = os.environ.get(parts[2], parts[3])return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,capath if os.path.isdir(capath) else None,*parts)class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):"""ASN.1 object identifier lookup"""__slots__ = ()def __new__(cls, oid):return super().__new__(cls, *_txt2obj(oid, name=False))@classmethoddef fromnid(cls, nid):"""Create _ASN1Object from OpenSSL numeric ID"""return super().__new__(cls, *_nid2obj(nid))@classmethoddef fromname(cls, name):"""Create _ASN1Object from short name, long name or OID"""return super().__new__(cls, *_txt2obj(name, name=True))class Purpose(_ASN1Object, _Enum):"""SSLContext purpose flags with X509v3 Extended Key Usage objects"""SERVER_AUTH = '1.3.6.1.5.5.7.3.1'CLIENT_AUTH = '1.3.6.1.5.5.7.3.2'class SSLContext(_SSLContext):"""An SSLContext holds various SSL-related configuration options anddata, such as certificates and possibly a private key."""_windows_cert_stores = ("CA", "ROOT")sslsocket_class = None # SSLSocket is assigned later.sslobject_class = None # SSLObject is assigned later.def __new__(cls, protocol=PROTOCOL_TLS, *args, **kwargs):self = _SSLContext.__new__(cls, protocol)return selfdef _encode_hostname(self, hostname):if hostname is None:return Noneelif isinstance(hostname, str):return hostname.encode('idna').decode('ascii')else:return hostname.decode('ascii')def wrap_socket(self, sock, server_side=False,do_handshake_on_connect=True,suppress_ragged_eofs=True,server_hostname=None, session=None):# SSLSocket class handles server_hostname encoding before it calls# ctx._wrap_socket()return self.sslsocket_class._create(sock=sock,server_side=server_side,do_handshake_on_connect=do_handshake_on_connect,suppress_ragged_eofs=suppress_ragged_eofs,server_hostname=server_hostname,context=self,session=session)def wrap_bio(self, incoming, outgoing, server_side=False,server_hostname=None, session=None):# Need to encode server_hostname here because _wrap_bio() can only# handle ASCII str.return self.sslobject_class._create(incoming, outgoing, server_side=server_side,server_hostname=self._encode_hostname(server_hostname),session=session, context=self,)def set_npn_protocols(self, npn_protocols):protos = bytearray()for protocol in npn_protocols:b = bytes(protocol, 'ascii')if len(b) == 0 or len(b) > 255:raise SSLError('NPN protocols must be 1 to 255 in length')protos.append(len(b))protos.extend(b)self._set_npn_protocols(protos)def set_servername_callback(self, server_name_callback):if server_name_callback is None:self.sni_callback = Noneelse:if not callable(server_name_callback):raise TypeError("not a callable object")def shim_cb(sslobj, servername, sslctx):servername = self._encode_hostname(servername)return server_name_callback(sslobj, servername, sslctx)self.sni_callback = shim_cbdef set_alpn_protocols(self, alpn_protocols):protos = bytearray()for protocol in alpn_protocols:b = bytes(protocol, 'ascii')if len(b) == 0 or len(b) > 255:raise SSLError('ALPN protocols must be 1 to 255 in length')protos.append(len(b))protos.extend(b)self._set_alpn_protocols(protos)def _load_windows_store_certs(self, storename, purpose):certs = bytearray()try:for cert, encoding, trust in enum_certificates(storename):# CA certs are never PKCS#7 encodedif encoding == "x509_asn":if trust is True or purpose.oid in trust:certs.extend(cert)except PermissionError:warnings.warn("unable to enumerate Windows certificate store")if certs:self.load_verify_locations(cadata=certs)return certsdef load_default_certs(self, purpose=Purpose.SERVER_AUTH):if not isinstance(purpose, _ASN1Object):raise TypeError(purpose)if sys.platform == "win32":for storename in self._windows_cert_stores:self._load_windows_store_certs(storename, purpose)self.set_default_verify_paths()if hasattr(_SSLContext, 'minimum_version'):@propertydef minimum_version(self):return TLSVersion(super().minimum_version)@minimum_version.setterdef minimum_version(self, value):if value == TLSVersion.SSLv3:self.options &= ~Options.OP_NO_SSLv3super(SSLContext, SSLContext).minimum_version.__set__(self, value)@propertydef maximum_version(self):return TLSVersion(super().maximum_version)@maximum_version.setterdef maximum_version(self, value):super(SSLContext, SSLContext).maximum_version.__set__(self, value)@propertydef options(self):return Options(super().options)@options.setterdef options(self, value):super(SSLContext, SSLContext).options.__set__(self, value)if hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT'):@propertydef hostname_checks_common_name(self):ncs = self._host_flags & _ssl.HOSTFLAG_NEVER_CHECK_SUBJECTreturn ncs != _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT@hostname_checks_common_name.setterdef hostname_checks_common_name(self, value):if value:self._host_flags &= ~_ssl.HOSTFLAG_NEVER_CHECK_SUBJECTelse:self._host_flags |= _ssl.HOSTFLAG_NEVER_CHECK_SUBJECTelse:@propertydef hostname_checks_common_name(self):return True@propertydef _msg_callback(self):"""TLS message callbackThe message callback provides a debugging hook to analyze TLSconnections. The callback is called for any TLS protocol message(header, handshake, alert, and more), but not for application data.Due to technical limitations, the callback can't be used to filtertraffic or to abort a connection. Any exception raised in thecallback is delayed until the handshake, read, or write operationhas been performed.def msg_cb(conn, direction, version, content_type, msg_type, data):passconn:class:`SSLSocket` or :class:`SSLObject` instancedirection``read`` or ``write``version:class:`TLSVersion` enum member or int for unknown version. For aframe header, it's the header version.content_type:class:`_TLSContentType` enum member or int for unsupportedcontent type.msg_typeEither a :class:`_TLSContentType` enum number for a headermessage, a :class:`_TLSAlertType` enum member for an alertmessage, a :class:`_TLSMessageType` enum member for othermessages, or int for unsupported message types.dataRaw, decrypted message content as bytes"""inner = super()._msg_callbackif inner is not None:return inner.user_functionelse:return None@_msg_callback.setterdef _msg_callback(self, callback):if callback is None:super(SSLContext, SSLContext)._msg_callback.__set__(self, None)returnif not hasattr(callback, '__call__'):raise TypeError(f"{callback} is not callable.")def inner(conn, direction, version, content_type, msg_type, data):try:version = TLSVersion(version)except ValueError:passtry:content_type = _TLSContentType(content_type)except ValueError:passif content_type == _TLSContentType.HEADER:msg_enum = _TLSContentTypeelif content_type == _TLSContentType.ALERT:msg_enum = _TLSAlertTypeelse:msg_enum = _TLSMessageTypetry:msg_type = msg_enum(msg_type)except ValueError:passreturn callback(conn, direction, version,content_type, msg_type, data)inner.user_function = callbacksuper(SSLContext, SSLContext)._msg_callback.__set__(self, inner)@propertydef protocol(self):return _SSLMethod(super().protocol)@propertydef verify_flags(self):return VerifyFlags(super().verify_flags)@verify_flags.setterdef verify_flags(self, value):super(SSLContext, SSLContext).verify_flags.__set__(self, value)@propertydef verify_mode(self):value = super().verify_modetry:return VerifyMode(value)except ValueError:return value@verify_mode.setterdef verify_mode(self, value):super(SSLContext, SSLContext).verify_mode.__set__(self, value)def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,capath=None, cadata=None):"""Create a SSLContext object with default settings.NOTE: The protocol and settings may change anytime without priordeprecation. The values represent a fair balance between maximumcompatibility and security."""if not isinstance(purpose, _ASN1Object):raise TypeError(purpose)# SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,# OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE# by default.context = SSLContext(PROTOCOL_TLS)if purpose == Purpose.SERVER_AUTH:# verify certs and host name in client modecontext.verify_mode = CERT_REQUIREDcontext.check_hostname = Trueif cafile or capath or cadata:context.load_verify_locations(cafile, capath, cadata)elif context.verify_mode != CERT_NONE:# no explicit cafile, capath or cadata but the verify mode is# CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system# root CA certificates for the given purpose. This may fail silently.context.load_default_certs(purpose)# OpenSSL 1.1.1 keylog fileif hasattr(context, 'keylog_filename'):keylogfile = os.environ.get('SSLKEYLOGFILE')if keylogfile and not sys.flags.ignore_environment:context.keylog_filename = keylogfilereturn contextdef _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE,check_hostname=False, purpose=Purpose.SERVER_AUTH,certfile=None, keyfile=None,cafile=None, capath=None, cadata=None):"""Create a SSLContext object for Python stdlib modulesAll Python stdlib modules shall use this function to create SSLContextobjects in order to keep common settings in one place. The configurationis less restrict than create_default_context()'s to increase backwardcompatibility."""if not isinstance(purpose, _ASN1Object):raise TypeError(purpose)# SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,# OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE# by default.context = SSLContext(protocol)if not check_hostname:context.check_hostname = Falseif cert_reqs is not None:context.verify_mode = cert_reqsif check_hostname:context.check_hostname = Trueif keyfile and not certfile:raise ValueError("certfile must be specified")if certfile or keyfile:context.load_cert_chain(certfile, keyfile)# load CA root certsif cafile or capath or cadata:context.load_verify_locations(cafile, capath, cadata)elif context.verify_mode != CERT_NONE:# no explicit cafile, capath or cadata but the verify mode is# CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system# root CA certificates for the given purpose. This may fail silently.context.load_default_certs(purpose)# OpenSSL 1.1.1 keylog fileif hasattr(context, 'keylog_filename'):keylogfile = os.environ.get('SSLKEYLOGFILE')if keylogfile and not sys.flags.ignore_environment:context.keylog_filename = keylogfilereturn context# Used by http.client if no context is explicitly passed._create_default_https_context = create_default_context# Backwards compatibility alias, even though it's not a public name._create_stdlib_context = _create_unverified_contextclass SSLObject:"""This class implements an interface on top of a low-level SSL object asimplemented by OpenSSL. This object captures the state of an SSL connectionbut does not provide any network IO itself. IO needs to be performedthrough separate "BIO" objects which are OpenSSL's IO abstraction layer.This class does not have a public constructor. Instances are returned by``SSLContext.wrap_bio``. This class is typically used by framework authorsthat want to implement asynchronous IO for SSL through memory buffers.When compared to ``SSLSocket``, this object lacks the following features:* Any form of network IO, including methods such as ``recv`` and ``send``.* The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery."""def __init__(self, *args, **kwargs):raise TypeError(f"{self.__class__.__name__} does not have a public "f"constructor. Instances are returned by SSLContext.wrap_bio().")@classmethoddef _create(cls, incoming, outgoing, server_side=False,server_hostname=None, session=None, context=None):self = cls.__new__(cls)sslobj = context._wrap_bio(incoming, outgoing, server_side=server_side,server_hostname=server_hostname,owner=self, session=session)self._sslobj = sslobjreturn self@propertydef context(self):"""The SSLContext that is currently in use."""return self._sslobj.context@context.setterdef context(self, ctx):self._sslobj.context = ctx@propertydef session(self):"""The SSLSession for client socket."""return self._sslobj.session@session.setterdef session(self, session):self._sslobj.session = session@propertydef session_reused(self):"""Was the client session reused during handshake"""return self._sslobj.session_reused@propertydef server_side(self):"""Whether this is a server-side socket."""return self._sslobj.server_side@propertydef server_hostname(self):"""The currently set server hostname (for SNI), or ``None`` if noserver hostname is set."""return self._sslobj.server_hostnamedef read(self, len=1024, buffer=None):"""Read up to 'len' bytes from the SSL object and return them.If 'buffer' is provided, read into this buffer and return the number ofbytes read."""if buffer is not None:v = self._sslobj.read(len, buffer)else:v = self._sslobj.read(len)return vdef write(self, data):"""Write 'data' to the SSL object and return the number of byteswritten.The 'data' argument must support the buffer interface."""return self._sslobj.write(data)def getpeercert(self, binary_form=False):"""Returns a formatted version of the data in the certificate providedby the other end of the SSL channel.Return None if no certificate was provided, {} if a certificate wasprovided, but not validated."""return self._sslobj.getpeercert(binary_form)def selected_npn_protocol(self):"""Return the currently selected NPN protocol as a string, or ``None``if a next protocol was not negotiated or if NPN is not supported by oneof the peers."""if _ssl.HAS_NPN:return self._sslobj.selected_npn_protocol()def selected_alpn_protocol(self):"""Return the currently selected ALPN protocol as a string, or ``None``if a next protocol was not negotiated or if ALPN is not supported by oneof the peers."""if _ssl.HAS_ALPN:return self._sslobj.selected_alpn_protocol()def cipher(self):"""Return the currently selected cipher as a 3-tuple ``(name,ssl_version, secret_bits)``."""return self._sslobj.cipher()def shared_ciphers(self):"""Return a list of ciphers shared by the client during the handshake orNone if this is not a valid server connection."""return self._sslobj.shared_ciphers()def compression(self):"""Return the current compression algorithm in use, or ``None`` ifcompression was not negotiated or not supported by one of the peers."""return self._sslobj.compression()def pending(self):"""Return the number of bytes that can be read immediately."""return self._sslobj.pending()def do_handshake(self):"""Start the SSL/TLS handshake."""self._sslobj.do_handshake()def unwrap(self):"""Start the SSL shutdown handshake."""return self._sslobj.shutdown()def get_channel_binding(self, cb_type="tls-unique"):"""Get channel binding data for current connection. Raise ValueErrorif the requested `cb_type` is not supported. Return bytes of the dataor None if the data is not available (e.g. before the handshake)."""return self._sslobj.get_channel_binding(cb_type)def version(self):"""Return a string identifying the protocol version used by thecurrent SSL channel. """return self._sslobj.version()def verify_client_post_handshake(self):return self._sslobj.verify_client_post_handshake()def _sslcopydoc(func):"""Copy docstring from SSLObject to SSLSocket"""func.__doc__ = getattr(SSLObject, func.__name__).__doc__return funcclass SSLSocket(socket):"""This class implements a subtype of socket.socket that wrapsthe underlying OS socket in an SSL context when necessary, andprovides read and write methods over that channel. """def __init__(self, *args, **kwargs):raise TypeError(f"{self.__class__.__name__} does not have a public "f"constructor. Instances are returned by "f"SSLContext.wrap_socket().")@classmethoddef _create(cls, sock, server_side=False, do_handshake_on_connect=True,suppress_ragged_eofs=True, server_hostname=None,context=None, session=None):if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:raise NotImplementedError("only stream sockets are supported")if server_side:if server_hostname:raise ValueError("server_hostname can only be specified ""in client mode")if session is not None:raise ValueError("session can only be specified in ""client mode")if context.check_hostname and not server_hostname:raise ValueError("check_hostname requires server_hostname")kwargs = dict(family=sock.family, type=sock.type, proto=sock.proto,fileno=sock.fileno())self = cls.__new__(cls, **kwargs)super(SSLSocket, self).__init__(**kwargs)self.settimeout(sock.gettimeout())sock.detach()self._context = contextself._session = sessionself._closed = Falseself._sslobj = Noneself.server_side = server_sideself.server_hostname = context._encode_hostname(server_hostname)self.do_handshake_on_connect = do_handshake_on_connectself.suppress_ragged_eofs = suppress_ragged_eofs# See if we are connectedtry:self.getpeername()except OSError as e:if e.errno != errno.ENOTCONN:raiseconnected = Falseelse:connected = Trueself._connected = connectedif connected:# create the SSL objecttry:self._sslobj = self._context._wrap_socket(self, server_side, self.server_hostname,owner=self, session=self._session,)if do_handshake_on_connect:timeout = self.gettimeout()if timeout == 0.0:# non-blockingraise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")self.do_handshake()except (OSError, ValueError):self.close()raisereturn self@property@_sslcopydocdef context(self):return self._context@context.setterdef context(self, ctx):self._context = ctxself._sslobj.context = ctx@property@_sslcopydocdef session(self):if self._sslobj is not None:return self._sslobj.session@session.setterdef session(self, session):self._session = sessionif self._sslobj is not None:self._sslobj.session = session@property@_sslcopydocdef session_reused(self):if self._sslobj is not None:return self._sslobj.session_reuseddef dup(self):raise NotImplementedError("Can't dup() %s instances" %self.__class__.__name__)def _checkClosed(self, msg=None):# raise an exception here if you wish to check for spurious closespassdef _check_connected(self):if not self._connected:# getpeername() will raise ENOTCONN if the socket is really# not connected; note that we can be connected even without# _connected being set, e.g. if connect() first returned# EAGAIN.self.getpeername()def read(self, len=1024, buffer=None):"""Read up to LEN bytes and return them.Return zero-length string on EOF."""self._checkClosed()if self._sslobj is None:raise ValueError("Read on closed or unwrapped SSL socket.")try:if buffer is not None:return self._sslobj.read(len, buffer)else:return self._sslobj.read(len)except SSLError as x:if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:if buffer is not None:return 0else:return b''else:raisedef write(self, data):"""Write DATA to the underlying SSL channel. Returnsnumber of bytes of DATA actually transmitted."""self._checkClosed()if self._sslobj is None:raise ValueError("Write on closed or unwrapped SSL socket.")return self._sslobj.write(data)@_sslcopydocdef getpeercert(self, binary_form=False):self._checkClosed()self._check_connected()return self._sslobj.getpeercert(binary_form)@_sslcopydocdef selected_npn_protocol(self):self._checkClosed()if self._sslobj is None or not _ssl.HAS_NPN:return Noneelse:return self._sslobj.selected_npn_protocol()@_sslcopydocdef selected_alpn_protocol(self):self._checkClosed()if self._sslobj is None or not _ssl.HAS_ALPN:return Noneelse:return self._sslobj.selected_alpn_protocol()@_sslcopydocdef cipher(self):self._checkClosed()if self._sslobj is None:return Noneelse:return self._sslobj.cipher()@_sslcopydocdef shared_ciphers(self):self._checkClosed()if self._sslobj is None:return Noneelse:return self._sslobj.shared_ciphers()@_sslcopydocdef compression(self):self._checkClosed()if self._sslobj is None:return Noneelse:return self._sslobj.compression()def send(self, data, flags=0):self._checkClosed()if self._sslobj is not None:if flags != 0:raise ValueError("non-zero flags not allowed in calls to send() on %s" %self.__class__)return self._sslobj.write(data)else:return super().send(data, flags)def sendto(self, data, flags_or_addr, addr=None):self._checkClosed()if self._sslobj is not None:raise ValueError("sendto not allowed on instances of %s" %self.__class__)elif addr is None:return super().sendto(data, flags_or_addr)else:return super().sendto(data, flags_or_addr, addr)def sendmsg(self, *args, **kwargs):# Ensure programs don't send data unencrypted if they try to# use this method.raise NotImplementedError("sendmsg not allowed on instances of %s" %self.__class__)def sendall(self, data, flags=0):self._checkClosed()if self._sslobj is not None:if flags != 0:raise ValueError("non-zero flags not allowed in calls to sendall() on %s" %self.__class__)count = 0with memoryview(data) as view, view.cast("B") as byte_view:amount = len(byte_view)while count < amount:v = self.send(byte_view[count:])count += velse:return super().sendall(data, flags)def sendfile(self, file, offset=0, count=None):"""Send a file, possibly by using os.sendfile() if this is aclear-text socket. Return the total number of bytes sent."""if self._sslobj is not None:return self._sendfile_use_send(file, offset, count)else:# os.sendfile() works with plain sockets onlyreturn super().sendfile(file, offset, count)def recv(self, buflen=1024, flags=0):self._checkClosed()if self._sslobj is not None:if flags != 0:raise ValueError("non-zero flags not allowed in calls to recv() on %s" %self.__class__)return self.read(buflen)else:return super().recv(buflen, flags)def recv_into(self, buffer, nbytes=None, flags=0):self._checkClosed()if buffer and (nbytes is None):nbytes = len(buffer)elif nbytes is None:nbytes = 1024if self._sslobj is not None:if flags != 0:raise ValueError("non-zero flags not allowed in calls to recv_into() on %s" %self.__class__)return self.read(nbytes, buffer)else:return super().recv_into(buffer, nbytes, flags)def recvfrom(self, buflen=1024, flags=0):self._checkClosed()if self._sslobj is not None:raise ValueError("recvfrom not allowed on instances of %s" %self.__class__)else:return super().recvfrom(buflen, flags)def recvfrom_into(self, buffer, nbytes=None, flags=0):self._checkClosed()if self._sslobj is not None:raise ValueError("recvfrom_into not allowed on instances of %s" %self.__class__)else:return super().recvfrom_into(buffer, nbytes, flags)def recvmsg(self, *args, **kwargs):raise NotImplementedError("recvmsg not allowed on instances of %s" %self.__class__)def recvmsg_into(self, *args, **kwargs):raise NotImplementedError("recvmsg_into not allowed on instances of ""%s" % self.__class__)@_sslcopydocdef pending(self):self._checkClosed()if self._sslobj is not None:return self._sslobj.pending()else:return 0def shutdown(self, how):self._checkClosed()self._sslobj = Nonesuper().shutdown(how)@_sslcopydocdef unwrap(self):if self._sslobj:s = self._sslobj.shutdown()self._sslobj = Nonereturn selse:raise ValueError("No SSL wrapper around " + str(self))@_sslcopydocdef verify_client_post_handshake(self):if self._sslobj:return self._sslobj.verify_client_post_handshake()else:raise ValueError("No SSL wrapper around " + str(self))def _real_close(self):self._sslobj = Nonesuper()._real_close()@_sslcopydocdef do_handshake(self, block=False):self._check_connected()timeout = self.gettimeout()try:if timeout == 0.0 and block:self.settimeout(None)self._sslobj.do_handshake()finally:self.settimeout(timeout)def _real_connect(self, addr, connect_ex):if self.server_side:raise ValueError("can't connect in server-side mode")# Here we assume that the socket is client-side, and not# connected at the time of the call. We connect it, then wrap it.if self._connected or self._sslobj is not None:raise ValueError("attempt to connect already-connected SSLSocket!")self._sslobj = self.context._wrap_socket(self, False, self.server_hostname,owner=self, session=self._session)try:if connect_ex:rc = super().connect_ex(addr)else:rc = Nonesuper().connect(addr)if not rc:self._connected = Trueif self.do_handshake_on_connect:self.do_handshake()return rcexcept (OSError, ValueError):self._sslobj = Noneraisedef connect(self, addr):"""Connects to remote ADDR, and then wraps the connection inan SSL channel."""self._real_connect(addr, False)def connect_ex(self, addr):"""Connects to remote ADDR, and then wraps the connection inan SSL channel."""return self._real_connect(addr, True)def accept(self):"""Accepts a new connection from a remote client, and returnsa tuple containing that new connection wrapped with a server-sideSSL channel, and the address of the remote client."""newsock, addr = super().accept()newsock = self.context.wrap_socket(newsock,do_handshake_on_connect=self.do_handshake_on_connect,suppress_ragged_eofs=self.suppress_ragged_eofs,server_side=True)return newsock, addr@_sslcopydocdef get_channel_binding(self, cb_type="tls-unique"):if self._sslobj is not None:return self._sslobj.get_channel_binding(cb_type)else:if cb_type not in CHANNEL_BINDING_TYPES:raise ValueError("{0} channel binding type not implemented".format(cb_type))return None@_sslcopydocdef version(self):if self._sslobj is not None:return self._sslobj.version()else:return None# Python does not support forward declaration of types.SSLContext.sslsocket_class = SSLSocketSSLContext.sslobject_class = SSLObjectdef wrap_socket(sock, keyfile=None, certfile=None,server_side=False, cert_reqs=CERT_NONE,ssl_version=PROTOCOL_TLS, ca_certs=None,do_handshake_on_connect=True,suppress_ragged_eofs=True,ciphers=None):if server_side and not certfile:raise ValueError("certfile must be specified for server-side ""operations")if keyfile and not certfile:raise ValueError("certfile must be specified")context = SSLContext(ssl_version)context.verify_mode = cert_reqsif ca_certs:context.load_verify_locations(ca_certs)if certfile:context.load_cert_chain(certfile, keyfile)if ciphers:context.set_ciphers(ciphers)return context.wrap_socket(sock=sock, server_side=server_side,do_handshake_on_connect=do_handshake_on_connect,suppress_ragged_eofs=suppress_ragged_eofs)# some utility functionsdef cert_time_to_seconds(cert_time):"""Return the time in seconds since the Epoch, given the timestringrepresenting the "notBefore" or "notAfter" date from a certificatein ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale)."notBefore" or "notAfter" dates must use UTC (RFC 5280).Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov DecUTC should be specified as GMT (see ASN1_TIME_print())"""from time import strptimefrom calendar import timegmmonths = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMTtry:month_number = months.index(cert_time[:3].title()) + 1except ValueError:raise ValueError('time data %r does not match ''format "%%b%s"' % (cert_time, time_format))else:# found valid monthtt = strptime(cert_time[3:], time_format)# return an integer, the previous mktime()-based implementation# returned a float (fractional seconds are always zero here).return timegm((tt[0], month_number) + tt[2:6])PEM_HEADER = "-----BEGIN CERTIFICATE-----"PEM_FOOTER = "-----END CERTIFICATE-----"def DER_cert_to_PEM_cert(der_cert_bytes):"""Takes a certificate in binary DER format and returns thePEM version of it as a string."""f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict')ss = [PEM_HEADER]ss += [f[i:i+64] for i in range(0, len(f), 64)]ss.append(PEM_FOOTER + '\n')return '\n'.join(ss)def PEM_cert_to_DER_cert(pem_cert_string):"""Takes a certificate in ASCII PEM format and returns theDER-encoded version of it as a byte sequence"""if not pem_cert_string.startswith(PEM_HEADER):raise ValueError("Invalid PEM encoding; must start with %s"% PEM_HEADER)if not pem_cert_string.strip().endswith(PEM_FOOTER):raise ValueError("Invalid PEM encoding; must end with %s"% PEM_FOOTER)d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]return base64.decodebytes(d.encode('ASCII', 'strict'))def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None):"""Retrieve the certificate from the server at the specified address,and return it as a PEM-encoded string.If 'ca_certs' is specified, validate the server cert against it.If 'ssl_version' is specified, use it in the connection attempt."""host, port = addrif ca_certs is not None:cert_reqs = CERT_REQUIREDelse:cert_reqs = CERT_NONEcontext = _create_stdlib_context(ssl_version,cert_reqs=cert_reqs,cafile=ca_certs)with create_connection(addr) as sock:with context.wrap_socket(sock) as sslsock:dercert = sslsock.getpeercert(True)return DER_cert_to_PEM_cert(dercert)def get_protocol_name(protocol_code):return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。