1*cda5da8dSAndroid Build Coastguard Worker# Wrapper module for _ssl, providing some additional facilities 2*cda5da8dSAndroid Build Coastguard Worker# implemented in Python. Written by Bill Janssen. 3*cda5da8dSAndroid Build Coastguard Worker 4*cda5da8dSAndroid Build Coastguard Worker"""This module provides some more Pythonic support for SSL. 5*cda5da8dSAndroid Build Coastguard Worker 6*cda5da8dSAndroid Build Coastguard WorkerObject types: 7*cda5da8dSAndroid Build Coastguard Worker 8*cda5da8dSAndroid Build Coastguard Worker SSLSocket -- subtype of socket.socket which does SSL over the socket 9*cda5da8dSAndroid Build Coastguard Worker 10*cda5da8dSAndroid Build Coastguard WorkerExceptions: 11*cda5da8dSAndroid Build Coastguard Worker 12*cda5da8dSAndroid Build Coastguard Worker SSLError -- exception raised for I/O errors 13*cda5da8dSAndroid Build Coastguard Worker 14*cda5da8dSAndroid Build Coastguard WorkerFunctions: 15*cda5da8dSAndroid Build Coastguard Worker 16*cda5da8dSAndroid Build Coastguard Worker cert_time_to_seconds -- convert time string used for certificate 17*cda5da8dSAndroid Build Coastguard Worker notBefore and notAfter functions to integer 18*cda5da8dSAndroid Build Coastguard Worker seconds past the Epoch (the time values 19*cda5da8dSAndroid Build Coastguard Worker returned from time.time()) 20*cda5da8dSAndroid Build Coastguard Worker 21*cda5da8dSAndroid Build Coastguard Worker get_server_certificate (addr, ssl_version, ca_certs, timeout) -- Retrieve the 22*cda5da8dSAndroid Build Coastguard Worker certificate from the server at the specified 23*cda5da8dSAndroid Build Coastguard Worker address and return it as a PEM-encoded string 24*cda5da8dSAndroid Build Coastguard Worker 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard WorkerInteger constants: 27*cda5da8dSAndroid Build Coastguard Worker 28*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_ZERO_RETURN 29*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_WANT_READ 30*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_WANT_WRITE 31*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_WANT_X509_LOOKUP 32*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_SYSCALL 33*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_SSL 34*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_WANT_CONNECT 35*cda5da8dSAndroid Build Coastguard Worker 36*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_EOF 37*cda5da8dSAndroid Build Coastguard WorkerSSL_ERROR_INVALID_ERROR_CODE 38*cda5da8dSAndroid Build Coastguard Worker 39*cda5da8dSAndroid Build Coastguard WorkerThe following group define certificate requirements that one side is 40*cda5da8dSAndroid Build Coastguard Workerallowing/requiring from the other side: 41*cda5da8dSAndroid Build Coastguard Worker 42*cda5da8dSAndroid Build Coastguard WorkerCERT_NONE - no certificates from the other side are required (or will 43*cda5da8dSAndroid Build Coastguard Worker be looked at if provided) 44*cda5da8dSAndroid Build Coastguard WorkerCERT_OPTIONAL - certificates are not required, but if provided will be 45*cda5da8dSAndroid Build Coastguard Worker validated, and if validation fails, the connection will 46*cda5da8dSAndroid Build Coastguard Worker also fail 47*cda5da8dSAndroid Build Coastguard WorkerCERT_REQUIRED - certificates are required, and will be validated, and 48*cda5da8dSAndroid Build Coastguard Worker if validation fails, the connection will also fail 49*cda5da8dSAndroid Build Coastguard Worker 50*cda5da8dSAndroid Build Coastguard WorkerThe following constants identify various SSL protocol variants: 51*cda5da8dSAndroid Build Coastguard Worker 52*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_SSLv2 53*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_SSLv3 54*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_SSLv23 55*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_TLS 56*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_TLS_CLIENT 57*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_TLS_SERVER 58*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_TLSv1 59*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_TLSv1_1 60*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_TLSv1_2 61*cda5da8dSAndroid Build Coastguard Worker 62*cda5da8dSAndroid Build Coastguard WorkerThe following constants identify various SSL alert message descriptions as per 63*cda5da8dSAndroid Build Coastguard Workerhttp://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6 64*cda5da8dSAndroid Build Coastguard Worker 65*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_CLOSE_NOTIFY 66*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_UNEXPECTED_MESSAGE 67*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_BAD_RECORD_MAC 68*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_RECORD_OVERFLOW 69*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_DECOMPRESSION_FAILURE 70*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_HANDSHAKE_FAILURE 71*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_BAD_CERTIFICATE 72*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE 73*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_CERTIFICATE_REVOKED 74*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_CERTIFICATE_EXPIRED 75*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_CERTIFICATE_UNKNOWN 76*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_ILLEGAL_PARAMETER 77*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_UNKNOWN_CA 78*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_ACCESS_DENIED 79*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_DECODE_ERROR 80*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_DECRYPT_ERROR 81*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_PROTOCOL_VERSION 82*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_INSUFFICIENT_SECURITY 83*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_INTERNAL_ERROR 84*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_USER_CANCELLED 85*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_NO_RENEGOTIATION 86*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_UNSUPPORTED_EXTENSION 87*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE 88*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_UNRECOGNIZED_NAME 89*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE 90*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE 91*cda5da8dSAndroid Build Coastguard WorkerALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY 92*cda5da8dSAndroid Build Coastguard Worker""" 93*cda5da8dSAndroid Build Coastguard Worker 94*cda5da8dSAndroid Build Coastguard Workerimport sys 95*cda5da8dSAndroid Build Coastguard Workerimport os 96*cda5da8dSAndroid Build Coastguard Workerfrom collections import namedtuple 97*cda5da8dSAndroid Build Coastguard Workerfrom enum import Enum as _Enum, IntEnum as _IntEnum, IntFlag as _IntFlag 98*cda5da8dSAndroid Build Coastguard Workerfrom enum import _simple_enum 99*cda5da8dSAndroid Build Coastguard Worker 100*cda5da8dSAndroid Build Coastguard Workerimport _ssl # if we can't import it, let the error propagate 101*cda5da8dSAndroid Build Coastguard Worker 102*cda5da8dSAndroid Build Coastguard Workerfrom _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION 103*cda5da8dSAndroid Build Coastguard Workerfrom _ssl import _SSLContext, MemoryBIO, SSLSession 104*cda5da8dSAndroid Build Coastguard Workerfrom _ssl import ( 105*cda5da8dSAndroid Build Coastguard Worker SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, 106*cda5da8dSAndroid Build Coastguard Worker SSLSyscallError, SSLEOFError, SSLCertVerificationError 107*cda5da8dSAndroid Build Coastguard Worker ) 108*cda5da8dSAndroid Build Coastguard Workerfrom _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj 109*cda5da8dSAndroid Build Coastguard Workerfrom _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes 110*cda5da8dSAndroid Build Coastguard Workertry: 111*cda5da8dSAndroid Build Coastguard Worker from _ssl import RAND_egd 112*cda5da8dSAndroid Build Coastguard Workerexcept ImportError: 113*cda5da8dSAndroid Build Coastguard Worker # LibreSSL does not provide RAND_egd 114*cda5da8dSAndroid Build Coastguard Worker pass 115*cda5da8dSAndroid Build Coastguard Worker 116*cda5da8dSAndroid Build Coastguard Worker 117*cda5da8dSAndroid Build Coastguard Workerfrom _ssl import ( 118*cda5da8dSAndroid Build Coastguard Worker HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1, 119*cda5da8dSAndroid Build Coastguard Worker HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3 120*cda5da8dSAndroid Build Coastguard Worker) 121*cda5da8dSAndroid Build Coastguard Workerfrom _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION 122*cda5da8dSAndroid Build Coastguard Worker 123*cda5da8dSAndroid Build Coastguard Worker_IntEnum._convert_( 124*cda5da8dSAndroid Build Coastguard Worker '_SSLMethod', __name__, 125*cda5da8dSAndroid Build Coastguard Worker lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23', 126*cda5da8dSAndroid Build Coastguard Worker source=_ssl) 127*cda5da8dSAndroid Build Coastguard Worker 128*cda5da8dSAndroid Build Coastguard Worker_IntFlag._convert_( 129*cda5da8dSAndroid Build Coastguard Worker 'Options', __name__, 130*cda5da8dSAndroid Build Coastguard Worker lambda name: name.startswith('OP_'), 131*cda5da8dSAndroid Build Coastguard Worker source=_ssl) 132*cda5da8dSAndroid Build Coastguard Worker 133*cda5da8dSAndroid Build Coastguard Worker_IntEnum._convert_( 134*cda5da8dSAndroid Build Coastguard Worker 'AlertDescription', __name__, 135*cda5da8dSAndroid Build Coastguard Worker lambda name: name.startswith('ALERT_DESCRIPTION_'), 136*cda5da8dSAndroid Build Coastguard Worker source=_ssl) 137*cda5da8dSAndroid Build Coastguard Worker 138*cda5da8dSAndroid Build Coastguard Worker_IntEnum._convert_( 139*cda5da8dSAndroid Build Coastguard Worker 'SSLErrorNumber', __name__, 140*cda5da8dSAndroid Build Coastguard Worker lambda name: name.startswith('SSL_ERROR_'), 141*cda5da8dSAndroid Build Coastguard Worker source=_ssl) 142*cda5da8dSAndroid Build Coastguard Worker 143*cda5da8dSAndroid Build Coastguard Worker_IntFlag._convert_( 144*cda5da8dSAndroid Build Coastguard Worker 'VerifyFlags', __name__, 145*cda5da8dSAndroid Build Coastguard Worker lambda name: name.startswith('VERIFY_'), 146*cda5da8dSAndroid Build Coastguard Worker source=_ssl) 147*cda5da8dSAndroid Build Coastguard Worker 148*cda5da8dSAndroid Build Coastguard Worker_IntEnum._convert_( 149*cda5da8dSAndroid Build Coastguard Worker 'VerifyMode', __name__, 150*cda5da8dSAndroid Build Coastguard Worker lambda name: name.startswith('CERT_'), 151*cda5da8dSAndroid Build Coastguard Worker source=_ssl) 152*cda5da8dSAndroid Build Coastguard Worker 153*cda5da8dSAndroid Build Coastguard WorkerPROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS 154*cda5da8dSAndroid Build Coastguard Worker_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()} 155*cda5da8dSAndroid Build Coastguard Worker 156*cda5da8dSAndroid Build Coastguard Worker_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None) 157*cda5da8dSAndroid Build Coastguard Worker 158*cda5da8dSAndroid Build Coastguard Worker 159*cda5da8dSAndroid Build Coastguard Worker@_simple_enum(_IntEnum) 160*cda5da8dSAndroid Build Coastguard Workerclass TLSVersion: 161*cda5da8dSAndroid Build Coastguard Worker MINIMUM_SUPPORTED = _ssl.PROTO_MINIMUM_SUPPORTED 162*cda5da8dSAndroid Build Coastguard Worker SSLv3 = _ssl.PROTO_SSLv3 163*cda5da8dSAndroid Build Coastguard Worker TLSv1 = _ssl.PROTO_TLSv1 164*cda5da8dSAndroid Build Coastguard Worker TLSv1_1 = _ssl.PROTO_TLSv1_1 165*cda5da8dSAndroid Build Coastguard Worker TLSv1_2 = _ssl.PROTO_TLSv1_2 166*cda5da8dSAndroid Build Coastguard Worker TLSv1_3 = _ssl.PROTO_TLSv1_3 167*cda5da8dSAndroid Build Coastguard Worker MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED 168*cda5da8dSAndroid Build Coastguard Worker 169*cda5da8dSAndroid Build Coastguard Worker 170*cda5da8dSAndroid Build Coastguard Worker@_simple_enum(_IntEnum) 171*cda5da8dSAndroid Build Coastguard Workerclass _TLSContentType: 172*cda5da8dSAndroid Build Coastguard Worker """Content types (record layer) 173*cda5da8dSAndroid Build Coastguard Worker 174*cda5da8dSAndroid Build Coastguard Worker See RFC 8446, section B.1 175*cda5da8dSAndroid Build Coastguard Worker """ 176*cda5da8dSAndroid Build Coastguard Worker CHANGE_CIPHER_SPEC = 20 177*cda5da8dSAndroid Build Coastguard Worker ALERT = 21 178*cda5da8dSAndroid Build Coastguard Worker HANDSHAKE = 22 179*cda5da8dSAndroid Build Coastguard Worker APPLICATION_DATA = 23 180*cda5da8dSAndroid Build Coastguard Worker # pseudo content types 181*cda5da8dSAndroid Build Coastguard Worker HEADER = 0x100 182*cda5da8dSAndroid Build Coastguard Worker INNER_CONTENT_TYPE = 0x101 183*cda5da8dSAndroid Build Coastguard Worker 184*cda5da8dSAndroid Build Coastguard Worker 185*cda5da8dSAndroid Build Coastguard Worker@_simple_enum(_IntEnum) 186*cda5da8dSAndroid Build Coastguard Workerclass _TLSAlertType: 187*cda5da8dSAndroid Build Coastguard Worker """Alert types for TLSContentType.ALERT messages 188*cda5da8dSAndroid Build Coastguard Worker 189*cda5da8dSAndroid Build Coastguard Worker See RFC 8466, section B.2 190*cda5da8dSAndroid Build Coastguard Worker """ 191*cda5da8dSAndroid Build Coastguard Worker CLOSE_NOTIFY = 0 192*cda5da8dSAndroid Build Coastguard Worker UNEXPECTED_MESSAGE = 10 193*cda5da8dSAndroid Build Coastguard Worker BAD_RECORD_MAC = 20 194*cda5da8dSAndroid Build Coastguard Worker DECRYPTION_FAILED = 21 195*cda5da8dSAndroid Build Coastguard Worker RECORD_OVERFLOW = 22 196*cda5da8dSAndroid Build Coastguard Worker DECOMPRESSION_FAILURE = 30 197*cda5da8dSAndroid Build Coastguard Worker HANDSHAKE_FAILURE = 40 198*cda5da8dSAndroid Build Coastguard Worker NO_CERTIFICATE = 41 199*cda5da8dSAndroid Build Coastguard Worker BAD_CERTIFICATE = 42 200*cda5da8dSAndroid Build Coastguard Worker UNSUPPORTED_CERTIFICATE = 43 201*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_REVOKED = 44 202*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_EXPIRED = 45 203*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_UNKNOWN = 46 204*cda5da8dSAndroid Build Coastguard Worker ILLEGAL_PARAMETER = 47 205*cda5da8dSAndroid Build Coastguard Worker UNKNOWN_CA = 48 206*cda5da8dSAndroid Build Coastguard Worker ACCESS_DENIED = 49 207*cda5da8dSAndroid Build Coastguard Worker DECODE_ERROR = 50 208*cda5da8dSAndroid Build Coastguard Worker DECRYPT_ERROR = 51 209*cda5da8dSAndroid Build Coastguard Worker EXPORT_RESTRICTION = 60 210*cda5da8dSAndroid Build Coastguard Worker PROTOCOL_VERSION = 70 211*cda5da8dSAndroid Build Coastguard Worker INSUFFICIENT_SECURITY = 71 212*cda5da8dSAndroid Build Coastguard Worker INTERNAL_ERROR = 80 213*cda5da8dSAndroid Build Coastguard Worker INAPPROPRIATE_FALLBACK = 86 214*cda5da8dSAndroid Build Coastguard Worker USER_CANCELED = 90 215*cda5da8dSAndroid Build Coastguard Worker NO_RENEGOTIATION = 100 216*cda5da8dSAndroid Build Coastguard Worker MISSING_EXTENSION = 109 217*cda5da8dSAndroid Build Coastguard Worker UNSUPPORTED_EXTENSION = 110 218*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_UNOBTAINABLE = 111 219*cda5da8dSAndroid Build Coastguard Worker UNRECOGNIZED_NAME = 112 220*cda5da8dSAndroid Build Coastguard Worker BAD_CERTIFICATE_STATUS_RESPONSE = 113 221*cda5da8dSAndroid Build Coastguard Worker BAD_CERTIFICATE_HASH_VALUE = 114 222*cda5da8dSAndroid Build Coastguard Worker UNKNOWN_PSK_IDENTITY = 115 223*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_REQUIRED = 116 224*cda5da8dSAndroid Build Coastguard Worker NO_APPLICATION_PROTOCOL = 120 225*cda5da8dSAndroid Build Coastguard Worker 226*cda5da8dSAndroid Build Coastguard Worker 227*cda5da8dSAndroid Build Coastguard Worker@_simple_enum(_IntEnum) 228*cda5da8dSAndroid Build Coastguard Workerclass _TLSMessageType: 229*cda5da8dSAndroid Build Coastguard Worker """Message types (handshake protocol) 230*cda5da8dSAndroid Build Coastguard Worker 231*cda5da8dSAndroid Build Coastguard Worker See RFC 8446, section B.3 232*cda5da8dSAndroid Build Coastguard Worker """ 233*cda5da8dSAndroid Build Coastguard Worker HELLO_REQUEST = 0 234*cda5da8dSAndroid Build Coastguard Worker CLIENT_HELLO = 1 235*cda5da8dSAndroid Build Coastguard Worker SERVER_HELLO = 2 236*cda5da8dSAndroid Build Coastguard Worker HELLO_VERIFY_REQUEST = 3 237*cda5da8dSAndroid Build Coastguard Worker NEWSESSION_TICKET = 4 238*cda5da8dSAndroid Build Coastguard Worker END_OF_EARLY_DATA = 5 239*cda5da8dSAndroid Build Coastguard Worker HELLO_RETRY_REQUEST = 6 240*cda5da8dSAndroid Build Coastguard Worker ENCRYPTED_EXTENSIONS = 8 241*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE = 11 242*cda5da8dSAndroid Build Coastguard Worker SERVER_KEY_EXCHANGE = 12 243*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_REQUEST = 13 244*cda5da8dSAndroid Build Coastguard Worker SERVER_DONE = 14 245*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_VERIFY = 15 246*cda5da8dSAndroid Build Coastguard Worker CLIENT_KEY_EXCHANGE = 16 247*cda5da8dSAndroid Build Coastguard Worker FINISHED = 20 248*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_URL = 21 249*cda5da8dSAndroid Build Coastguard Worker CERTIFICATE_STATUS = 22 250*cda5da8dSAndroid Build Coastguard Worker SUPPLEMENTAL_DATA = 23 251*cda5da8dSAndroid Build Coastguard Worker KEY_UPDATE = 24 252*cda5da8dSAndroid Build Coastguard Worker NEXT_PROTO = 67 253*cda5da8dSAndroid Build Coastguard Worker MESSAGE_HASH = 254 254*cda5da8dSAndroid Build Coastguard Worker CHANGE_CIPHER_SPEC = 0x0101 255*cda5da8dSAndroid Build Coastguard Worker 256*cda5da8dSAndroid Build Coastguard Worker 257*cda5da8dSAndroid Build Coastguard Workerif sys.platform == "win32": 258*cda5da8dSAndroid Build Coastguard Worker from _ssl import enum_certificates, enum_crls 259*cda5da8dSAndroid Build Coastguard Worker 260*cda5da8dSAndroid Build Coastguard Workerfrom socket import socket, SOCK_STREAM, create_connection 261*cda5da8dSAndroid Build Coastguard Workerfrom socket import SOL_SOCKET, SO_TYPE, _GLOBAL_DEFAULT_TIMEOUT 262*cda5da8dSAndroid Build Coastguard Workerimport socket as _socket 263*cda5da8dSAndroid Build Coastguard Workerimport base64 # for DER-to-PEM translation 264*cda5da8dSAndroid Build Coastguard Workerimport errno 265*cda5da8dSAndroid Build Coastguard Workerimport warnings 266*cda5da8dSAndroid Build Coastguard Worker 267*cda5da8dSAndroid Build Coastguard Worker 268*cda5da8dSAndroid Build Coastguard Workersocket_error = OSError # keep that public name in module namespace 269*cda5da8dSAndroid Build Coastguard Worker 270*cda5da8dSAndroid Build Coastguard WorkerCHANNEL_BINDING_TYPES = ['tls-unique'] 271*cda5da8dSAndroid Build Coastguard Worker 272*cda5da8dSAndroid Build Coastguard WorkerHAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT') 273*cda5da8dSAndroid Build Coastguard Worker 274*cda5da8dSAndroid Build Coastguard Worker 275*cda5da8dSAndroid Build Coastguard Worker_RESTRICTED_SERVER_CIPHERS = _DEFAULT_CIPHERS 276*cda5da8dSAndroid Build Coastguard Worker 277*cda5da8dSAndroid Build Coastguard WorkerCertificateError = SSLCertVerificationError 278*cda5da8dSAndroid Build Coastguard Worker 279*cda5da8dSAndroid Build Coastguard Worker 280*cda5da8dSAndroid Build Coastguard Workerdef _dnsname_match(dn, hostname): 281*cda5da8dSAndroid Build Coastguard Worker """Matching according to RFC 6125, section 6.4.3 282*cda5da8dSAndroid Build Coastguard Worker 283*cda5da8dSAndroid Build Coastguard Worker - Hostnames are compared lower-case. 284*cda5da8dSAndroid Build Coastguard Worker - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE). 285*cda5da8dSAndroid Build Coastguard Worker - Partial wildcards like 'www*.example.org', multiple wildcards, sole 286*cda5da8dSAndroid Build Coastguard Worker wildcard or wildcards in labels other then the left-most label are not 287*cda5da8dSAndroid Build Coastguard Worker supported and a CertificateError is raised. 288*cda5da8dSAndroid Build Coastguard Worker - A wildcard must match at least one character. 289*cda5da8dSAndroid Build Coastguard Worker """ 290*cda5da8dSAndroid Build Coastguard Worker if not dn: 291*cda5da8dSAndroid Build Coastguard Worker return False 292*cda5da8dSAndroid Build Coastguard Worker 293*cda5da8dSAndroid Build Coastguard Worker wildcards = dn.count('*') 294*cda5da8dSAndroid Build Coastguard Worker # speed up common case w/o wildcards 295*cda5da8dSAndroid Build Coastguard Worker if not wildcards: 296*cda5da8dSAndroid Build Coastguard Worker return dn.lower() == hostname.lower() 297*cda5da8dSAndroid Build Coastguard Worker 298*cda5da8dSAndroid Build Coastguard Worker if wildcards > 1: 299*cda5da8dSAndroid Build Coastguard Worker raise CertificateError( 300*cda5da8dSAndroid Build Coastguard Worker "too many wildcards in certificate DNS name: {!r}.".format(dn)) 301*cda5da8dSAndroid Build Coastguard Worker 302*cda5da8dSAndroid Build Coastguard Worker dn_leftmost, sep, dn_remainder = dn.partition('.') 303*cda5da8dSAndroid Build Coastguard Worker 304*cda5da8dSAndroid Build Coastguard Worker if '*' in dn_remainder: 305*cda5da8dSAndroid Build Coastguard Worker # Only match wildcard in leftmost segment. 306*cda5da8dSAndroid Build Coastguard Worker raise CertificateError( 307*cda5da8dSAndroid Build Coastguard Worker "wildcard can only be present in the leftmost label: " 308*cda5da8dSAndroid Build Coastguard Worker "{!r}.".format(dn)) 309*cda5da8dSAndroid Build Coastguard Worker 310*cda5da8dSAndroid Build Coastguard Worker if not sep: 311*cda5da8dSAndroid Build Coastguard Worker # no right side 312*cda5da8dSAndroid Build Coastguard Worker raise CertificateError( 313*cda5da8dSAndroid Build Coastguard Worker "sole wildcard without additional labels are not support: " 314*cda5da8dSAndroid Build Coastguard Worker "{!r}.".format(dn)) 315*cda5da8dSAndroid Build Coastguard Worker 316*cda5da8dSAndroid Build Coastguard Worker if dn_leftmost != '*': 317*cda5da8dSAndroid Build Coastguard Worker # no partial wildcard matching 318*cda5da8dSAndroid Build Coastguard Worker raise CertificateError( 319*cda5da8dSAndroid Build Coastguard Worker "partial wildcards in leftmost label are not supported: " 320*cda5da8dSAndroid Build Coastguard Worker "{!r}.".format(dn)) 321*cda5da8dSAndroid Build Coastguard Worker 322*cda5da8dSAndroid Build Coastguard Worker hostname_leftmost, sep, hostname_remainder = hostname.partition('.') 323*cda5da8dSAndroid Build Coastguard Worker if not hostname_leftmost or not sep: 324*cda5da8dSAndroid Build Coastguard Worker # wildcard must match at least one char 325*cda5da8dSAndroid Build Coastguard Worker return False 326*cda5da8dSAndroid Build Coastguard Worker return dn_remainder.lower() == hostname_remainder.lower() 327*cda5da8dSAndroid Build Coastguard Worker 328*cda5da8dSAndroid Build Coastguard Worker 329*cda5da8dSAndroid Build Coastguard Workerdef _inet_paton(ipname): 330*cda5da8dSAndroid Build Coastguard Worker """Try to convert an IP address to packed binary form 331*cda5da8dSAndroid Build Coastguard Worker 332*cda5da8dSAndroid Build Coastguard Worker Supports IPv4 addresses on all platforms and IPv6 on platforms with IPv6 333*cda5da8dSAndroid Build Coastguard Worker support. 334*cda5da8dSAndroid Build Coastguard Worker """ 335*cda5da8dSAndroid Build Coastguard Worker # inet_aton() also accepts strings like '1', '127.1', some also trailing 336*cda5da8dSAndroid Build Coastguard Worker # data like '127.0.0.1 whatever'. 337*cda5da8dSAndroid Build Coastguard Worker try: 338*cda5da8dSAndroid Build Coastguard Worker addr = _socket.inet_aton(ipname) 339*cda5da8dSAndroid Build Coastguard Worker except OSError: 340*cda5da8dSAndroid Build Coastguard Worker # not an IPv4 address 341*cda5da8dSAndroid Build Coastguard Worker pass 342*cda5da8dSAndroid Build Coastguard Worker else: 343*cda5da8dSAndroid Build Coastguard Worker if _socket.inet_ntoa(addr) == ipname: 344*cda5da8dSAndroid Build Coastguard Worker # only accept injective ipnames 345*cda5da8dSAndroid Build Coastguard Worker return addr 346*cda5da8dSAndroid Build Coastguard Worker else: 347*cda5da8dSAndroid Build Coastguard Worker # refuse for short IPv4 notation and additional trailing data 348*cda5da8dSAndroid Build Coastguard Worker raise ValueError( 349*cda5da8dSAndroid Build Coastguard Worker "{!r} is not a quad-dotted IPv4 address.".format(ipname) 350*cda5da8dSAndroid Build Coastguard Worker ) 351*cda5da8dSAndroid Build Coastguard Worker 352*cda5da8dSAndroid Build Coastguard Worker try: 353*cda5da8dSAndroid Build Coastguard Worker return _socket.inet_pton(_socket.AF_INET6, ipname) 354*cda5da8dSAndroid Build Coastguard Worker except OSError: 355*cda5da8dSAndroid Build Coastguard Worker raise ValueError("{!r} is neither an IPv4 nor an IP6 " 356*cda5da8dSAndroid Build Coastguard Worker "address.".format(ipname)) 357*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 358*cda5da8dSAndroid Build Coastguard Worker # AF_INET6 not available 359*cda5da8dSAndroid Build Coastguard Worker pass 360*cda5da8dSAndroid Build Coastguard Worker 361*cda5da8dSAndroid Build Coastguard Worker raise ValueError("{!r} is not an IPv4 address.".format(ipname)) 362*cda5da8dSAndroid Build Coastguard Worker 363*cda5da8dSAndroid Build Coastguard Worker 364*cda5da8dSAndroid Build Coastguard Workerdef _ipaddress_match(cert_ipaddress, host_ip): 365*cda5da8dSAndroid Build Coastguard Worker """Exact matching of IP addresses. 366*cda5da8dSAndroid Build Coastguard Worker 367*cda5da8dSAndroid Build Coastguard Worker RFC 6125 explicitly doesn't define an algorithm for this 368*cda5da8dSAndroid Build Coastguard Worker (section 1.7.2 - "Out of Scope"). 369*cda5da8dSAndroid Build Coastguard Worker """ 370*cda5da8dSAndroid Build Coastguard Worker # OpenSSL may add a trailing newline to a subjectAltName's IP address, 371*cda5da8dSAndroid Build Coastguard Worker # commonly with IPv6 addresses. Strip off trailing \n. 372*cda5da8dSAndroid Build Coastguard Worker ip = _inet_paton(cert_ipaddress.rstrip()) 373*cda5da8dSAndroid Build Coastguard Worker return ip == host_ip 374*cda5da8dSAndroid Build Coastguard Worker 375*cda5da8dSAndroid Build Coastguard Worker 376*cda5da8dSAndroid Build Coastguard Workerdef match_hostname(cert, hostname): 377*cda5da8dSAndroid Build Coastguard Worker """Verify that *cert* (in decoded format as returned by 378*cda5da8dSAndroid Build Coastguard Worker SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 379*cda5da8dSAndroid Build Coastguard Worker rules are followed. 380*cda5da8dSAndroid Build Coastguard Worker 381*cda5da8dSAndroid Build Coastguard Worker The function matches IP addresses rather than dNSNames if hostname is a 382*cda5da8dSAndroid Build Coastguard Worker valid ipaddress string. IPv4 addresses are supported on all platforms. 383*cda5da8dSAndroid Build Coastguard Worker IPv6 addresses are supported on platforms with IPv6 support (AF_INET6 384*cda5da8dSAndroid Build Coastguard Worker and inet_pton). 385*cda5da8dSAndroid Build Coastguard Worker 386*cda5da8dSAndroid Build Coastguard Worker CertificateError is raised on failure. On success, the function 387*cda5da8dSAndroid Build Coastguard Worker returns nothing. 388*cda5da8dSAndroid Build Coastguard Worker """ 389*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 390*cda5da8dSAndroid Build Coastguard Worker "ssl.match_hostname() is deprecated", 391*cda5da8dSAndroid Build Coastguard Worker category=DeprecationWarning, 392*cda5da8dSAndroid Build Coastguard Worker stacklevel=2 393*cda5da8dSAndroid Build Coastguard Worker ) 394*cda5da8dSAndroid Build Coastguard Worker if not cert: 395*cda5da8dSAndroid Build Coastguard Worker raise ValueError("empty or no certificate, match_hostname needs a " 396*cda5da8dSAndroid Build Coastguard Worker "SSL socket or SSL context with either " 397*cda5da8dSAndroid Build Coastguard Worker "CERT_OPTIONAL or CERT_REQUIRED") 398*cda5da8dSAndroid Build Coastguard Worker try: 399*cda5da8dSAndroid Build Coastguard Worker host_ip = _inet_paton(hostname) 400*cda5da8dSAndroid Build Coastguard Worker except ValueError: 401*cda5da8dSAndroid Build Coastguard Worker # Not an IP address (common case) 402*cda5da8dSAndroid Build Coastguard Worker host_ip = None 403*cda5da8dSAndroid Build Coastguard Worker dnsnames = [] 404*cda5da8dSAndroid Build Coastguard Worker san = cert.get('subjectAltName', ()) 405*cda5da8dSAndroid Build Coastguard Worker for key, value in san: 406*cda5da8dSAndroid Build Coastguard Worker if key == 'DNS': 407*cda5da8dSAndroid Build Coastguard Worker if host_ip is None and _dnsname_match(value, hostname): 408*cda5da8dSAndroid Build Coastguard Worker return 409*cda5da8dSAndroid Build Coastguard Worker dnsnames.append(value) 410*cda5da8dSAndroid Build Coastguard Worker elif key == 'IP Address': 411*cda5da8dSAndroid Build Coastguard Worker if host_ip is not None and _ipaddress_match(value, host_ip): 412*cda5da8dSAndroid Build Coastguard Worker return 413*cda5da8dSAndroid Build Coastguard Worker dnsnames.append(value) 414*cda5da8dSAndroid Build Coastguard Worker if not dnsnames: 415*cda5da8dSAndroid Build Coastguard Worker # The subject is only checked when there is no dNSName entry 416*cda5da8dSAndroid Build Coastguard Worker # in subjectAltName 417*cda5da8dSAndroid Build Coastguard Worker for sub in cert.get('subject', ()): 418*cda5da8dSAndroid Build Coastguard Worker for key, value in sub: 419*cda5da8dSAndroid Build Coastguard Worker # XXX according to RFC 2818, the most specific Common Name 420*cda5da8dSAndroid Build Coastguard Worker # must be used. 421*cda5da8dSAndroid Build Coastguard Worker if key == 'commonName': 422*cda5da8dSAndroid Build Coastguard Worker if _dnsname_match(value, hostname): 423*cda5da8dSAndroid Build Coastguard Worker return 424*cda5da8dSAndroid Build Coastguard Worker dnsnames.append(value) 425*cda5da8dSAndroid Build Coastguard Worker if len(dnsnames) > 1: 426*cda5da8dSAndroid Build Coastguard Worker raise CertificateError("hostname %r " 427*cda5da8dSAndroid Build Coastguard Worker "doesn't match either of %s" 428*cda5da8dSAndroid Build Coastguard Worker % (hostname, ', '.join(map(repr, dnsnames)))) 429*cda5da8dSAndroid Build Coastguard Worker elif len(dnsnames) == 1: 430*cda5da8dSAndroid Build Coastguard Worker raise CertificateError("hostname %r " 431*cda5da8dSAndroid Build Coastguard Worker "doesn't match %r" 432*cda5da8dSAndroid Build Coastguard Worker % (hostname, dnsnames[0])) 433*cda5da8dSAndroid Build Coastguard Worker else: 434*cda5da8dSAndroid Build Coastguard Worker raise CertificateError("no appropriate commonName or " 435*cda5da8dSAndroid Build Coastguard Worker "subjectAltName fields were found") 436*cda5da8dSAndroid Build Coastguard Worker 437*cda5da8dSAndroid Build Coastguard Worker 438*cda5da8dSAndroid Build Coastguard WorkerDefaultVerifyPaths = namedtuple("DefaultVerifyPaths", 439*cda5da8dSAndroid Build Coastguard Worker "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env " 440*cda5da8dSAndroid Build Coastguard Worker "openssl_capath") 441*cda5da8dSAndroid Build Coastguard Worker 442*cda5da8dSAndroid Build Coastguard Workerdef get_default_verify_paths(): 443*cda5da8dSAndroid Build Coastguard Worker """Return paths to default cafile and capath. 444*cda5da8dSAndroid Build Coastguard Worker """ 445*cda5da8dSAndroid Build Coastguard Worker parts = _ssl.get_default_verify_paths() 446*cda5da8dSAndroid Build Coastguard Worker 447*cda5da8dSAndroid Build Coastguard Worker # environment vars shadow paths 448*cda5da8dSAndroid Build Coastguard Worker cafile = os.environ.get(parts[0], parts[1]) 449*cda5da8dSAndroid Build Coastguard Worker capath = os.environ.get(parts[2], parts[3]) 450*cda5da8dSAndroid Build Coastguard Worker 451*cda5da8dSAndroid Build Coastguard Worker return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None, 452*cda5da8dSAndroid Build Coastguard Worker capath if os.path.isdir(capath) else None, 453*cda5da8dSAndroid Build Coastguard Worker *parts) 454*cda5da8dSAndroid Build Coastguard Worker 455*cda5da8dSAndroid Build Coastguard Worker 456*cda5da8dSAndroid Build Coastguard Workerclass _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")): 457*cda5da8dSAndroid Build Coastguard Worker """ASN.1 object identifier lookup 458*cda5da8dSAndroid Build Coastguard Worker """ 459*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 460*cda5da8dSAndroid Build Coastguard Worker 461*cda5da8dSAndroid Build Coastguard Worker def __new__(cls, oid): 462*cda5da8dSAndroid Build Coastguard Worker return super().__new__(cls, *_txt2obj(oid, name=False)) 463*cda5da8dSAndroid Build Coastguard Worker 464*cda5da8dSAndroid Build Coastguard Worker @classmethod 465*cda5da8dSAndroid Build Coastguard Worker def fromnid(cls, nid): 466*cda5da8dSAndroid Build Coastguard Worker """Create _ASN1Object from OpenSSL numeric ID 467*cda5da8dSAndroid Build Coastguard Worker """ 468*cda5da8dSAndroid Build Coastguard Worker return super().__new__(cls, *_nid2obj(nid)) 469*cda5da8dSAndroid Build Coastguard Worker 470*cda5da8dSAndroid Build Coastguard Worker @classmethod 471*cda5da8dSAndroid Build Coastguard Worker def fromname(cls, name): 472*cda5da8dSAndroid Build Coastguard Worker """Create _ASN1Object from short name, long name or OID 473*cda5da8dSAndroid Build Coastguard Worker """ 474*cda5da8dSAndroid Build Coastguard Worker return super().__new__(cls, *_txt2obj(name, name=True)) 475*cda5da8dSAndroid Build Coastguard Worker 476*cda5da8dSAndroid Build Coastguard Worker 477*cda5da8dSAndroid Build Coastguard Workerclass Purpose(_ASN1Object, _Enum): 478*cda5da8dSAndroid Build Coastguard Worker """SSLContext purpose flags with X509v3 Extended Key Usage objects 479*cda5da8dSAndroid Build Coastguard Worker """ 480*cda5da8dSAndroid Build Coastguard Worker SERVER_AUTH = '1.3.6.1.5.5.7.3.1' 481*cda5da8dSAndroid Build Coastguard Worker CLIENT_AUTH = '1.3.6.1.5.5.7.3.2' 482*cda5da8dSAndroid Build Coastguard Worker 483*cda5da8dSAndroid Build Coastguard Worker 484*cda5da8dSAndroid Build Coastguard Workerclass SSLContext(_SSLContext): 485*cda5da8dSAndroid Build Coastguard Worker """An SSLContext holds various SSL-related configuration options and 486*cda5da8dSAndroid Build Coastguard Worker data, such as certificates and possibly a private key.""" 487*cda5da8dSAndroid Build Coastguard Worker _windows_cert_stores = ("CA", "ROOT") 488*cda5da8dSAndroid Build Coastguard Worker 489*cda5da8dSAndroid Build Coastguard Worker sslsocket_class = None # SSLSocket is assigned later. 490*cda5da8dSAndroid Build Coastguard Worker sslobject_class = None # SSLObject is assigned later. 491*cda5da8dSAndroid Build Coastguard Worker 492*cda5da8dSAndroid Build Coastguard Worker def __new__(cls, protocol=None, *args, **kwargs): 493*cda5da8dSAndroid Build Coastguard Worker if protocol is None: 494*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 495*cda5da8dSAndroid Build Coastguard Worker "ssl.SSLContext() without protocol argument is deprecated.", 496*cda5da8dSAndroid Build Coastguard Worker category=DeprecationWarning, 497*cda5da8dSAndroid Build Coastguard Worker stacklevel=2 498*cda5da8dSAndroid Build Coastguard Worker ) 499*cda5da8dSAndroid Build Coastguard Worker protocol = PROTOCOL_TLS 500*cda5da8dSAndroid Build Coastguard Worker self = _SSLContext.__new__(cls, protocol) 501*cda5da8dSAndroid Build Coastguard Worker return self 502*cda5da8dSAndroid Build Coastguard Worker 503*cda5da8dSAndroid Build Coastguard Worker def _encode_hostname(self, hostname): 504*cda5da8dSAndroid Build Coastguard Worker if hostname is None: 505*cda5da8dSAndroid Build Coastguard Worker return None 506*cda5da8dSAndroid Build Coastguard Worker elif isinstance(hostname, str): 507*cda5da8dSAndroid Build Coastguard Worker return hostname.encode('idna').decode('ascii') 508*cda5da8dSAndroid Build Coastguard Worker else: 509*cda5da8dSAndroid Build Coastguard Worker return hostname.decode('ascii') 510*cda5da8dSAndroid Build Coastguard Worker 511*cda5da8dSAndroid Build Coastguard Worker def wrap_socket(self, sock, server_side=False, 512*cda5da8dSAndroid Build Coastguard Worker do_handshake_on_connect=True, 513*cda5da8dSAndroid Build Coastguard Worker suppress_ragged_eofs=True, 514*cda5da8dSAndroid Build Coastguard Worker server_hostname=None, session=None): 515*cda5da8dSAndroid Build Coastguard Worker # SSLSocket class handles server_hostname encoding before it calls 516*cda5da8dSAndroid Build Coastguard Worker # ctx._wrap_socket() 517*cda5da8dSAndroid Build Coastguard Worker return self.sslsocket_class._create( 518*cda5da8dSAndroid Build Coastguard Worker sock=sock, 519*cda5da8dSAndroid Build Coastguard Worker server_side=server_side, 520*cda5da8dSAndroid Build Coastguard Worker do_handshake_on_connect=do_handshake_on_connect, 521*cda5da8dSAndroid Build Coastguard Worker suppress_ragged_eofs=suppress_ragged_eofs, 522*cda5da8dSAndroid Build Coastguard Worker server_hostname=server_hostname, 523*cda5da8dSAndroid Build Coastguard Worker context=self, 524*cda5da8dSAndroid Build Coastguard Worker session=session 525*cda5da8dSAndroid Build Coastguard Worker ) 526*cda5da8dSAndroid Build Coastguard Worker 527*cda5da8dSAndroid Build Coastguard Worker def wrap_bio(self, incoming, outgoing, server_side=False, 528*cda5da8dSAndroid Build Coastguard Worker server_hostname=None, session=None): 529*cda5da8dSAndroid Build Coastguard Worker # Need to encode server_hostname here because _wrap_bio() can only 530*cda5da8dSAndroid Build Coastguard Worker # handle ASCII str. 531*cda5da8dSAndroid Build Coastguard Worker return self.sslobject_class._create( 532*cda5da8dSAndroid Build Coastguard Worker incoming, outgoing, server_side=server_side, 533*cda5da8dSAndroid Build Coastguard Worker server_hostname=self._encode_hostname(server_hostname), 534*cda5da8dSAndroid Build Coastguard Worker session=session, context=self, 535*cda5da8dSAndroid Build Coastguard Worker ) 536*cda5da8dSAndroid Build Coastguard Worker 537*cda5da8dSAndroid Build Coastguard Worker def set_npn_protocols(self, npn_protocols): 538*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 539*cda5da8dSAndroid Build Coastguard Worker "ssl NPN is deprecated, use ALPN instead", 540*cda5da8dSAndroid Build Coastguard Worker DeprecationWarning, 541*cda5da8dSAndroid Build Coastguard Worker stacklevel=2 542*cda5da8dSAndroid Build Coastguard Worker ) 543*cda5da8dSAndroid Build Coastguard Worker protos = bytearray() 544*cda5da8dSAndroid Build Coastguard Worker for protocol in npn_protocols: 545*cda5da8dSAndroid Build Coastguard Worker b = bytes(protocol, 'ascii') 546*cda5da8dSAndroid Build Coastguard Worker if len(b) == 0 or len(b) > 255: 547*cda5da8dSAndroid Build Coastguard Worker raise SSLError('NPN protocols must be 1 to 255 in length') 548*cda5da8dSAndroid Build Coastguard Worker protos.append(len(b)) 549*cda5da8dSAndroid Build Coastguard Worker protos.extend(b) 550*cda5da8dSAndroid Build Coastguard Worker 551*cda5da8dSAndroid Build Coastguard Worker self._set_npn_protocols(protos) 552*cda5da8dSAndroid Build Coastguard Worker 553*cda5da8dSAndroid Build Coastguard Worker def set_servername_callback(self, server_name_callback): 554*cda5da8dSAndroid Build Coastguard Worker if server_name_callback is None: 555*cda5da8dSAndroid Build Coastguard Worker self.sni_callback = None 556*cda5da8dSAndroid Build Coastguard Worker else: 557*cda5da8dSAndroid Build Coastguard Worker if not callable(server_name_callback): 558*cda5da8dSAndroid Build Coastguard Worker raise TypeError("not a callable object") 559*cda5da8dSAndroid Build Coastguard Worker 560*cda5da8dSAndroid Build Coastguard Worker def shim_cb(sslobj, servername, sslctx): 561*cda5da8dSAndroid Build Coastguard Worker servername = self._encode_hostname(servername) 562*cda5da8dSAndroid Build Coastguard Worker return server_name_callback(sslobj, servername, sslctx) 563*cda5da8dSAndroid Build Coastguard Worker 564*cda5da8dSAndroid Build Coastguard Worker self.sni_callback = shim_cb 565*cda5da8dSAndroid Build Coastguard Worker 566*cda5da8dSAndroid Build Coastguard Worker def set_alpn_protocols(self, alpn_protocols): 567*cda5da8dSAndroid Build Coastguard Worker protos = bytearray() 568*cda5da8dSAndroid Build Coastguard Worker for protocol in alpn_protocols: 569*cda5da8dSAndroid Build Coastguard Worker b = bytes(protocol, 'ascii') 570*cda5da8dSAndroid Build Coastguard Worker if len(b) == 0 or len(b) > 255: 571*cda5da8dSAndroid Build Coastguard Worker raise SSLError('ALPN protocols must be 1 to 255 in length') 572*cda5da8dSAndroid Build Coastguard Worker protos.append(len(b)) 573*cda5da8dSAndroid Build Coastguard Worker protos.extend(b) 574*cda5da8dSAndroid Build Coastguard Worker 575*cda5da8dSAndroid Build Coastguard Worker self._set_alpn_protocols(protos) 576*cda5da8dSAndroid Build Coastguard Worker 577*cda5da8dSAndroid Build Coastguard Worker def _load_windows_store_certs(self, storename, purpose): 578*cda5da8dSAndroid Build Coastguard Worker certs = bytearray() 579*cda5da8dSAndroid Build Coastguard Worker try: 580*cda5da8dSAndroid Build Coastguard Worker for cert, encoding, trust in enum_certificates(storename): 581*cda5da8dSAndroid Build Coastguard Worker # CA certs are never PKCS#7 encoded 582*cda5da8dSAndroid Build Coastguard Worker if encoding == "x509_asn": 583*cda5da8dSAndroid Build Coastguard Worker if trust is True or purpose.oid in trust: 584*cda5da8dSAndroid Build Coastguard Worker certs.extend(cert) 585*cda5da8dSAndroid Build Coastguard Worker except PermissionError: 586*cda5da8dSAndroid Build Coastguard Worker warnings.warn("unable to enumerate Windows certificate store") 587*cda5da8dSAndroid Build Coastguard Worker if certs: 588*cda5da8dSAndroid Build Coastguard Worker self.load_verify_locations(cadata=certs) 589*cda5da8dSAndroid Build Coastguard Worker return certs 590*cda5da8dSAndroid Build Coastguard Worker 591*cda5da8dSAndroid Build Coastguard Worker def load_default_certs(self, purpose=Purpose.SERVER_AUTH): 592*cda5da8dSAndroid Build Coastguard Worker if not isinstance(purpose, _ASN1Object): 593*cda5da8dSAndroid Build Coastguard Worker raise TypeError(purpose) 594*cda5da8dSAndroid Build Coastguard Worker if sys.platform == "win32": 595*cda5da8dSAndroid Build Coastguard Worker for storename in self._windows_cert_stores: 596*cda5da8dSAndroid Build Coastguard Worker self._load_windows_store_certs(storename, purpose) 597*cda5da8dSAndroid Build Coastguard Worker self.set_default_verify_paths() 598*cda5da8dSAndroid Build Coastguard Worker 599*cda5da8dSAndroid Build Coastguard Worker if hasattr(_SSLContext, 'minimum_version'): 600*cda5da8dSAndroid Build Coastguard Worker @property 601*cda5da8dSAndroid Build Coastguard Worker def minimum_version(self): 602*cda5da8dSAndroid Build Coastguard Worker return TLSVersion(super().minimum_version) 603*cda5da8dSAndroid Build Coastguard Worker 604*cda5da8dSAndroid Build Coastguard Worker @minimum_version.setter 605*cda5da8dSAndroid Build Coastguard Worker def minimum_version(self, value): 606*cda5da8dSAndroid Build Coastguard Worker if value == TLSVersion.SSLv3: 607*cda5da8dSAndroid Build Coastguard Worker self.options &= ~Options.OP_NO_SSLv3 608*cda5da8dSAndroid Build Coastguard Worker super(SSLContext, SSLContext).minimum_version.__set__(self, value) 609*cda5da8dSAndroid Build Coastguard Worker 610*cda5da8dSAndroid Build Coastguard Worker @property 611*cda5da8dSAndroid Build Coastguard Worker def maximum_version(self): 612*cda5da8dSAndroid Build Coastguard Worker return TLSVersion(super().maximum_version) 613*cda5da8dSAndroid Build Coastguard Worker 614*cda5da8dSAndroid Build Coastguard Worker @maximum_version.setter 615*cda5da8dSAndroid Build Coastguard Worker def maximum_version(self, value): 616*cda5da8dSAndroid Build Coastguard Worker super(SSLContext, SSLContext).maximum_version.__set__(self, value) 617*cda5da8dSAndroid Build Coastguard Worker 618*cda5da8dSAndroid Build Coastguard Worker @property 619*cda5da8dSAndroid Build Coastguard Worker def options(self): 620*cda5da8dSAndroid Build Coastguard Worker return Options(super().options) 621*cda5da8dSAndroid Build Coastguard Worker 622*cda5da8dSAndroid Build Coastguard Worker @options.setter 623*cda5da8dSAndroid Build Coastguard Worker def options(self, value): 624*cda5da8dSAndroid Build Coastguard Worker super(SSLContext, SSLContext).options.__set__(self, value) 625*cda5da8dSAndroid Build Coastguard Worker 626*cda5da8dSAndroid Build Coastguard Worker if hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT'): 627*cda5da8dSAndroid Build Coastguard Worker @property 628*cda5da8dSAndroid Build Coastguard Worker def hostname_checks_common_name(self): 629*cda5da8dSAndroid Build Coastguard Worker ncs = self._host_flags & _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT 630*cda5da8dSAndroid Build Coastguard Worker return ncs != _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT 631*cda5da8dSAndroid Build Coastguard Worker 632*cda5da8dSAndroid Build Coastguard Worker @hostname_checks_common_name.setter 633*cda5da8dSAndroid Build Coastguard Worker def hostname_checks_common_name(self, value): 634*cda5da8dSAndroid Build Coastguard Worker if value: 635*cda5da8dSAndroid Build Coastguard Worker self._host_flags &= ~_ssl.HOSTFLAG_NEVER_CHECK_SUBJECT 636*cda5da8dSAndroid Build Coastguard Worker else: 637*cda5da8dSAndroid Build Coastguard Worker self._host_flags |= _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT 638*cda5da8dSAndroid Build Coastguard Worker else: 639*cda5da8dSAndroid Build Coastguard Worker @property 640*cda5da8dSAndroid Build Coastguard Worker def hostname_checks_common_name(self): 641*cda5da8dSAndroid Build Coastguard Worker return True 642*cda5da8dSAndroid Build Coastguard Worker 643*cda5da8dSAndroid Build Coastguard Worker @property 644*cda5da8dSAndroid Build Coastguard Worker def _msg_callback(self): 645*cda5da8dSAndroid Build Coastguard Worker """TLS message callback 646*cda5da8dSAndroid Build Coastguard Worker 647*cda5da8dSAndroid Build Coastguard Worker The message callback provides a debugging hook to analyze TLS 648*cda5da8dSAndroid Build Coastguard Worker connections. The callback is called for any TLS protocol message 649*cda5da8dSAndroid Build Coastguard Worker (header, handshake, alert, and more), but not for application data. 650*cda5da8dSAndroid Build Coastguard Worker Due to technical limitations, the callback can't be used to filter 651*cda5da8dSAndroid Build Coastguard Worker traffic or to abort a connection. Any exception raised in the 652*cda5da8dSAndroid Build Coastguard Worker callback is delayed until the handshake, read, or write operation 653*cda5da8dSAndroid Build Coastguard Worker has been performed. 654*cda5da8dSAndroid Build Coastguard Worker 655*cda5da8dSAndroid Build Coastguard Worker def msg_cb(conn, direction, version, content_type, msg_type, data): 656*cda5da8dSAndroid Build Coastguard Worker pass 657*cda5da8dSAndroid Build Coastguard Worker 658*cda5da8dSAndroid Build Coastguard Worker conn 659*cda5da8dSAndroid Build Coastguard Worker :class:`SSLSocket` or :class:`SSLObject` instance 660*cda5da8dSAndroid Build Coastguard Worker direction 661*cda5da8dSAndroid Build Coastguard Worker ``read`` or ``write`` 662*cda5da8dSAndroid Build Coastguard Worker version 663*cda5da8dSAndroid Build Coastguard Worker :class:`TLSVersion` enum member or int for unknown version. For a 664*cda5da8dSAndroid Build Coastguard Worker frame header, it's the header version. 665*cda5da8dSAndroid Build Coastguard Worker content_type 666*cda5da8dSAndroid Build Coastguard Worker :class:`_TLSContentType` enum member or int for unsupported 667*cda5da8dSAndroid Build Coastguard Worker content type. 668*cda5da8dSAndroid Build Coastguard Worker msg_type 669*cda5da8dSAndroid Build Coastguard Worker Either a :class:`_TLSContentType` enum number for a header 670*cda5da8dSAndroid Build Coastguard Worker message, a :class:`_TLSAlertType` enum member for an alert 671*cda5da8dSAndroid Build Coastguard Worker message, a :class:`_TLSMessageType` enum member for other 672*cda5da8dSAndroid Build Coastguard Worker messages, or int for unsupported message types. 673*cda5da8dSAndroid Build Coastguard Worker data 674*cda5da8dSAndroid Build Coastguard Worker Raw, decrypted message content as bytes 675*cda5da8dSAndroid Build Coastguard Worker """ 676*cda5da8dSAndroid Build Coastguard Worker inner = super()._msg_callback 677*cda5da8dSAndroid Build Coastguard Worker if inner is not None: 678*cda5da8dSAndroid Build Coastguard Worker return inner.user_function 679*cda5da8dSAndroid Build Coastguard Worker else: 680*cda5da8dSAndroid Build Coastguard Worker return None 681*cda5da8dSAndroid Build Coastguard Worker 682*cda5da8dSAndroid Build Coastguard Worker @_msg_callback.setter 683*cda5da8dSAndroid Build Coastguard Worker def _msg_callback(self, callback): 684*cda5da8dSAndroid Build Coastguard Worker if callback is None: 685*cda5da8dSAndroid Build Coastguard Worker super(SSLContext, SSLContext)._msg_callback.__set__(self, None) 686*cda5da8dSAndroid Build Coastguard Worker return 687*cda5da8dSAndroid Build Coastguard Worker 688*cda5da8dSAndroid Build Coastguard Worker if not hasattr(callback, '__call__'): 689*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{callback} is not callable.") 690*cda5da8dSAndroid Build Coastguard Worker 691*cda5da8dSAndroid Build Coastguard Worker def inner(conn, direction, version, content_type, msg_type, data): 692*cda5da8dSAndroid Build Coastguard Worker try: 693*cda5da8dSAndroid Build Coastguard Worker version = TLSVersion(version) 694*cda5da8dSAndroid Build Coastguard Worker except ValueError: 695*cda5da8dSAndroid Build Coastguard Worker pass 696*cda5da8dSAndroid Build Coastguard Worker 697*cda5da8dSAndroid Build Coastguard Worker try: 698*cda5da8dSAndroid Build Coastguard Worker content_type = _TLSContentType(content_type) 699*cda5da8dSAndroid Build Coastguard Worker except ValueError: 700*cda5da8dSAndroid Build Coastguard Worker pass 701*cda5da8dSAndroid Build Coastguard Worker 702*cda5da8dSAndroid Build Coastguard Worker if content_type == _TLSContentType.HEADER: 703*cda5da8dSAndroid Build Coastguard Worker msg_enum = _TLSContentType 704*cda5da8dSAndroid Build Coastguard Worker elif content_type == _TLSContentType.ALERT: 705*cda5da8dSAndroid Build Coastguard Worker msg_enum = _TLSAlertType 706*cda5da8dSAndroid Build Coastguard Worker else: 707*cda5da8dSAndroid Build Coastguard Worker msg_enum = _TLSMessageType 708*cda5da8dSAndroid Build Coastguard Worker try: 709*cda5da8dSAndroid Build Coastguard Worker msg_type = msg_enum(msg_type) 710*cda5da8dSAndroid Build Coastguard Worker except ValueError: 711*cda5da8dSAndroid Build Coastguard Worker pass 712*cda5da8dSAndroid Build Coastguard Worker 713*cda5da8dSAndroid Build Coastguard Worker return callback(conn, direction, version, 714*cda5da8dSAndroid Build Coastguard Worker content_type, msg_type, data) 715*cda5da8dSAndroid Build Coastguard Worker 716*cda5da8dSAndroid Build Coastguard Worker inner.user_function = callback 717*cda5da8dSAndroid Build Coastguard Worker 718*cda5da8dSAndroid Build Coastguard Worker super(SSLContext, SSLContext)._msg_callback.__set__(self, inner) 719*cda5da8dSAndroid Build Coastguard Worker 720*cda5da8dSAndroid Build Coastguard Worker @property 721*cda5da8dSAndroid Build Coastguard Worker def protocol(self): 722*cda5da8dSAndroid Build Coastguard Worker return _SSLMethod(super().protocol) 723*cda5da8dSAndroid Build Coastguard Worker 724*cda5da8dSAndroid Build Coastguard Worker @property 725*cda5da8dSAndroid Build Coastguard Worker def verify_flags(self): 726*cda5da8dSAndroid Build Coastguard Worker return VerifyFlags(super().verify_flags) 727*cda5da8dSAndroid Build Coastguard Worker 728*cda5da8dSAndroid Build Coastguard Worker @verify_flags.setter 729*cda5da8dSAndroid Build Coastguard Worker def verify_flags(self, value): 730*cda5da8dSAndroid Build Coastguard Worker super(SSLContext, SSLContext).verify_flags.__set__(self, value) 731*cda5da8dSAndroid Build Coastguard Worker 732*cda5da8dSAndroid Build Coastguard Worker @property 733*cda5da8dSAndroid Build Coastguard Worker def verify_mode(self): 734*cda5da8dSAndroid Build Coastguard Worker value = super().verify_mode 735*cda5da8dSAndroid Build Coastguard Worker try: 736*cda5da8dSAndroid Build Coastguard Worker return VerifyMode(value) 737*cda5da8dSAndroid Build Coastguard Worker except ValueError: 738*cda5da8dSAndroid Build Coastguard Worker return value 739*cda5da8dSAndroid Build Coastguard Worker 740*cda5da8dSAndroid Build Coastguard Worker @verify_mode.setter 741*cda5da8dSAndroid Build Coastguard Worker def verify_mode(self, value): 742*cda5da8dSAndroid Build Coastguard Worker super(SSLContext, SSLContext).verify_mode.__set__(self, value) 743*cda5da8dSAndroid Build Coastguard Worker 744*cda5da8dSAndroid Build Coastguard Worker 745*cda5da8dSAndroid Build Coastguard Workerdef create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, 746*cda5da8dSAndroid Build Coastguard Worker capath=None, cadata=None): 747*cda5da8dSAndroid Build Coastguard Worker """Create a SSLContext object with default settings. 748*cda5da8dSAndroid Build Coastguard Worker 749*cda5da8dSAndroid Build Coastguard Worker NOTE: The protocol and settings may change anytime without prior 750*cda5da8dSAndroid Build Coastguard Worker deprecation. The values represent a fair balance between maximum 751*cda5da8dSAndroid Build Coastguard Worker compatibility and security. 752*cda5da8dSAndroid Build Coastguard Worker """ 753*cda5da8dSAndroid Build Coastguard Worker if not isinstance(purpose, _ASN1Object): 754*cda5da8dSAndroid Build Coastguard Worker raise TypeError(purpose) 755*cda5da8dSAndroid Build Coastguard Worker 756*cda5da8dSAndroid Build Coastguard Worker # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION, 757*cda5da8dSAndroid Build Coastguard Worker # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE 758*cda5da8dSAndroid Build Coastguard Worker # by default. 759*cda5da8dSAndroid Build Coastguard Worker if purpose == Purpose.SERVER_AUTH: 760*cda5da8dSAndroid Build Coastguard Worker # verify certs and host name in client mode 761*cda5da8dSAndroid Build Coastguard Worker context = SSLContext(PROTOCOL_TLS_CLIENT) 762*cda5da8dSAndroid Build Coastguard Worker context.verify_mode = CERT_REQUIRED 763*cda5da8dSAndroid Build Coastguard Worker context.check_hostname = True 764*cda5da8dSAndroid Build Coastguard Worker elif purpose == Purpose.CLIENT_AUTH: 765*cda5da8dSAndroid Build Coastguard Worker context = SSLContext(PROTOCOL_TLS_SERVER) 766*cda5da8dSAndroid Build Coastguard Worker else: 767*cda5da8dSAndroid Build Coastguard Worker raise ValueError(purpose) 768*cda5da8dSAndroid Build Coastguard Worker 769*cda5da8dSAndroid Build Coastguard Worker if cafile or capath or cadata: 770*cda5da8dSAndroid Build Coastguard Worker context.load_verify_locations(cafile, capath, cadata) 771*cda5da8dSAndroid Build Coastguard Worker elif context.verify_mode != CERT_NONE: 772*cda5da8dSAndroid Build Coastguard Worker # no explicit cafile, capath or cadata but the verify mode is 773*cda5da8dSAndroid Build Coastguard Worker # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system 774*cda5da8dSAndroid Build Coastguard Worker # root CA certificates for the given purpose. This may fail silently. 775*cda5da8dSAndroid Build Coastguard Worker context.load_default_certs(purpose) 776*cda5da8dSAndroid Build Coastguard Worker # OpenSSL 1.1.1 keylog file 777*cda5da8dSAndroid Build Coastguard Worker if hasattr(context, 'keylog_filename'): 778*cda5da8dSAndroid Build Coastguard Worker keylogfile = os.environ.get('SSLKEYLOGFILE') 779*cda5da8dSAndroid Build Coastguard Worker if keylogfile and not sys.flags.ignore_environment: 780*cda5da8dSAndroid Build Coastguard Worker context.keylog_filename = keylogfile 781*cda5da8dSAndroid Build Coastguard Worker return context 782*cda5da8dSAndroid Build Coastguard Worker 783*cda5da8dSAndroid Build Coastguard Workerdef _create_unverified_context(protocol=None, *, cert_reqs=CERT_NONE, 784*cda5da8dSAndroid Build Coastguard Worker check_hostname=False, purpose=Purpose.SERVER_AUTH, 785*cda5da8dSAndroid Build Coastguard Worker certfile=None, keyfile=None, 786*cda5da8dSAndroid Build Coastguard Worker cafile=None, capath=None, cadata=None): 787*cda5da8dSAndroid Build Coastguard Worker """Create a SSLContext object for Python stdlib modules 788*cda5da8dSAndroid Build Coastguard Worker 789*cda5da8dSAndroid Build Coastguard Worker All Python stdlib modules shall use this function to create SSLContext 790*cda5da8dSAndroid Build Coastguard Worker objects in order to keep common settings in one place. The configuration 791*cda5da8dSAndroid Build Coastguard Worker is less restrict than create_default_context()'s to increase backward 792*cda5da8dSAndroid Build Coastguard Worker compatibility. 793*cda5da8dSAndroid Build Coastguard Worker """ 794*cda5da8dSAndroid Build Coastguard Worker if not isinstance(purpose, _ASN1Object): 795*cda5da8dSAndroid Build Coastguard Worker raise TypeError(purpose) 796*cda5da8dSAndroid Build Coastguard Worker 797*cda5da8dSAndroid Build Coastguard Worker # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION, 798*cda5da8dSAndroid Build Coastguard Worker # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE 799*cda5da8dSAndroid Build Coastguard Worker # by default. 800*cda5da8dSAndroid Build Coastguard Worker if purpose == Purpose.SERVER_AUTH: 801*cda5da8dSAndroid Build Coastguard Worker # verify certs and host name in client mode 802*cda5da8dSAndroid Build Coastguard Worker if protocol is None: 803*cda5da8dSAndroid Build Coastguard Worker protocol = PROTOCOL_TLS_CLIENT 804*cda5da8dSAndroid Build Coastguard Worker elif purpose == Purpose.CLIENT_AUTH: 805*cda5da8dSAndroid Build Coastguard Worker if protocol is None: 806*cda5da8dSAndroid Build Coastguard Worker protocol = PROTOCOL_TLS_SERVER 807*cda5da8dSAndroid Build Coastguard Worker else: 808*cda5da8dSAndroid Build Coastguard Worker raise ValueError(purpose) 809*cda5da8dSAndroid Build Coastguard Worker 810*cda5da8dSAndroid Build Coastguard Worker context = SSLContext(protocol) 811*cda5da8dSAndroid Build Coastguard Worker context.check_hostname = check_hostname 812*cda5da8dSAndroid Build Coastguard Worker if cert_reqs is not None: 813*cda5da8dSAndroid Build Coastguard Worker context.verify_mode = cert_reqs 814*cda5da8dSAndroid Build Coastguard Worker if check_hostname: 815*cda5da8dSAndroid Build Coastguard Worker context.check_hostname = True 816*cda5da8dSAndroid Build Coastguard Worker 817*cda5da8dSAndroid Build Coastguard Worker if keyfile and not certfile: 818*cda5da8dSAndroid Build Coastguard Worker raise ValueError("certfile must be specified") 819*cda5da8dSAndroid Build Coastguard Worker if certfile or keyfile: 820*cda5da8dSAndroid Build Coastguard Worker context.load_cert_chain(certfile, keyfile) 821*cda5da8dSAndroid Build Coastguard Worker 822*cda5da8dSAndroid Build Coastguard Worker # load CA root certs 823*cda5da8dSAndroid Build Coastguard Worker if cafile or capath or cadata: 824*cda5da8dSAndroid Build Coastguard Worker context.load_verify_locations(cafile, capath, cadata) 825*cda5da8dSAndroid Build Coastguard Worker elif context.verify_mode != CERT_NONE: 826*cda5da8dSAndroid Build Coastguard Worker # no explicit cafile, capath or cadata but the verify mode is 827*cda5da8dSAndroid Build Coastguard Worker # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system 828*cda5da8dSAndroid Build Coastguard Worker # root CA certificates for the given purpose. This may fail silently. 829*cda5da8dSAndroid Build Coastguard Worker context.load_default_certs(purpose) 830*cda5da8dSAndroid Build Coastguard Worker # OpenSSL 1.1.1 keylog file 831*cda5da8dSAndroid Build Coastguard Worker if hasattr(context, 'keylog_filename'): 832*cda5da8dSAndroid Build Coastguard Worker keylogfile = os.environ.get('SSLKEYLOGFILE') 833*cda5da8dSAndroid Build Coastguard Worker if keylogfile and not sys.flags.ignore_environment: 834*cda5da8dSAndroid Build Coastguard Worker context.keylog_filename = keylogfile 835*cda5da8dSAndroid Build Coastguard Worker return context 836*cda5da8dSAndroid Build Coastguard Worker 837*cda5da8dSAndroid Build Coastguard Worker# Used by http.client if no context is explicitly passed. 838*cda5da8dSAndroid Build Coastguard Worker_create_default_https_context = create_default_context 839*cda5da8dSAndroid Build Coastguard Worker 840*cda5da8dSAndroid Build Coastguard Worker 841*cda5da8dSAndroid Build Coastguard Worker# Backwards compatibility alias, even though it's not a public name. 842*cda5da8dSAndroid Build Coastguard Worker_create_stdlib_context = _create_unverified_context 843*cda5da8dSAndroid Build Coastguard Worker 844*cda5da8dSAndroid Build Coastguard Worker 845*cda5da8dSAndroid Build Coastguard Workerclass SSLObject: 846*cda5da8dSAndroid Build Coastguard Worker """This class implements an interface on top of a low-level SSL object as 847*cda5da8dSAndroid Build Coastguard Worker implemented by OpenSSL. This object captures the state of an SSL connection 848*cda5da8dSAndroid Build Coastguard Worker but does not provide any network IO itself. IO needs to be performed 849*cda5da8dSAndroid Build Coastguard Worker through separate "BIO" objects which are OpenSSL's IO abstraction layer. 850*cda5da8dSAndroid Build Coastguard Worker 851*cda5da8dSAndroid Build Coastguard Worker This class does not have a public constructor. Instances are returned by 852*cda5da8dSAndroid Build Coastguard Worker ``SSLContext.wrap_bio``. This class is typically used by framework authors 853*cda5da8dSAndroid Build Coastguard Worker that want to implement asynchronous IO for SSL through memory buffers. 854*cda5da8dSAndroid Build Coastguard Worker 855*cda5da8dSAndroid Build Coastguard Worker When compared to ``SSLSocket``, this object lacks the following features: 856*cda5da8dSAndroid Build Coastguard Worker 857*cda5da8dSAndroid Build Coastguard Worker * Any form of network IO, including methods such as ``recv`` and ``send``. 858*cda5da8dSAndroid Build Coastguard Worker * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery. 859*cda5da8dSAndroid Build Coastguard Worker """ 860*cda5da8dSAndroid Build Coastguard Worker def __init__(self, *args, **kwargs): 861*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 862*cda5da8dSAndroid Build Coastguard Worker f"{self.__class__.__name__} does not have a public " 863*cda5da8dSAndroid Build Coastguard Worker f"constructor. Instances are returned by SSLContext.wrap_bio()." 864*cda5da8dSAndroid Build Coastguard Worker ) 865*cda5da8dSAndroid Build Coastguard Worker 866*cda5da8dSAndroid Build Coastguard Worker @classmethod 867*cda5da8dSAndroid Build Coastguard Worker def _create(cls, incoming, outgoing, server_side=False, 868*cda5da8dSAndroid Build Coastguard Worker server_hostname=None, session=None, context=None): 869*cda5da8dSAndroid Build Coastguard Worker self = cls.__new__(cls) 870*cda5da8dSAndroid Build Coastguard Worker sslobj = context._wrap_bio( 871*cda5da8dSAndroid Build Coastguard Worker incoming, outgoing, server_side=server_side, 872*cda5da8dSAndroid Build Coastguard Worker server_hostname=server_hostname, 873*cda5da8dSAndroid Build Coastguard Worker owner=self, session=session 874*cda5da8dSAndroid Build Coastguard Worker ) 875*cda5da8dSAndroid Build Coastguard Worker self._sslobj = sslobj 876*cda5da8dSAndroid Build Coastguard Worker return self 877*cda5da8dSAndroid Build Coastguard Worker 878*cda5da8dSAndroid Build Coastguard Worker @property 879*cda5da8dSAndroid Build Coastguard Worker def context(self): 880*cda5da8dSAndroid Build Coastguard Worker """The SSLContext that is currently in use.""" 881*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.context 882*cda5da8dSAndroid Build Coastguard Worker 883*cda5da8dSAndroid Build Coastguard Worker @context.setter 884*cda5da8dSAndroid Build Coastguard Worker def context(self, ctx): 885*cda5da8dSAndroid Build Coastguard Worker self._sslobj.context = ctx 886*cda5da8dSAndroid Build Coastguard Worker 887*cda5da8dSAndroid Build Coastguard Worker @property 888*cda5da8dSAndroid Build Coastguard Worker def session(self): 889*cda5da8dSAndroid Build Coastguard Worker """The SSLSession for client socket.""" 890*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.session 891*cda5da8dSAndroid Build Coastguard Worker 892*cda5da8dSAndroid Build Coastguard Worker @session.setter 893*cda5da8dSAndroid Build Coastguard Worker def session(self, session): 894*cda5da8dSAndroid Build Coastguard Worker self._sslobj.session = session 895*cda5da8dSAndroid Build Coastguard Worker 896*cda5da8dSAndroid Build Coastguard Worker @property 897*cda5da8dSAndroid Build Coastguard Worker def session_reused(self): 898*cda5da8dSAndroid Build Coastguard Worker """Was the client session reused during handshake""" 899*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.session_reused 900*cda5da8dSAndroid Build Coastguard Worker 901*cda5da8dSAndroid Build Coastguard Worker @property 902*cda5da8dSAndroid Build Coastguard Worker def server_side(self): 903*cda5da8dSAndroid Build Coastguard Worker """Whether this is a server-side socket.""" 904*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.server_side 905*cda5da8dSAndroid Build Coastguard Worker 906*cda5da8dSAndroid Build Coastguard Worker @property 907*cda5da8dSAndroid Build Coastguard Worker def server_hostname(self): 908*cda5da8dSAndroid Build Coastguard Worker """The currently set server hostname (for SNI), or ``None`` if no 909*cda5da8dSAndroid Build Coastguard Worker server hostname is set.""" 910*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.server_hostname 911*cda5da8dSAndroid Build Coastguard Worker 912*cda5da8dSAndroid Build Coastguard Worker def read(self, len=1024, buffer=None): 913*cda5da8dSAndroid Build Coastguard Worker """Read up to 'len' bytes from the SSL object and return them. 914*cda5da8dSAndroid Build Coastguard Worker 915*cda5da8dSAndroid Build Coastguard Worker If 'buffer' is provided, read into this buffer and return the number of 916*cda5da8dSAndroid Build Coastguard Worker bytes read. 917*cda5da8dSAndroid Build Coastguard Worker """ 918*cda5da8dSAndroid Build Coastguard Worker if buffer is not None: 919*cda5da8dSAndroid Build Coastguard Worker v = self._sslobj.read(len, buffer) 920*cda5da8dSAndroid Build Coastguard Worker else: 921*cda5da8dSAndroid Build Coastguard Worker v = self._sslobj.read(len) 922*cda5da8dSAndroid Build Coastguard Worker return v 923*cda5da8dSAndroid Build Coastguard Worker 924*cda5da8dSAndroid Build Coastguard Worker def write(self, data): 925*cda5da8dSAndroid Build Coastguard Worker """Write 'data' to the SSL object and return the number of bytes 926*cda5da8dSAndroid Build Coastguard Worker written. 927*cda5da8dSAndroid Build Coastguard Worker 928*cda5da8dSAndroid Build Coastguard Worker The 'data' argument must support the buffer interface. 929*cda5da8dSAndroid Build Coastguard Worker """ 930*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.write(data) 931*cda5da8dSAndroid Build Coastguard Worker 932*cda5da8dSAndroid Build Coastguard Worker def getpeercert(self, binary_form=False): 933*cda5da8dSAndroid Build Coastguard Worker """Returns a formatted version of the data in the certificate provided 934*cda5da8dSAndroid Build Coastguard Worker by the other end of the SSL channel. 935*cda5da8dSAndroid Build Coastguard Worker 936*cda5da8dSAndroid Build Coastguard Worker Return None if no certificate was provided, {} if a certificate was 937*cda5da8dSAndroid Build Coastguard Worker provided, but not validated. 938*cda5da8dSAndroid Build Coastguard Worker """ 939*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.getpeercert(binary_form) 940*cda5da8dSAndroid Build Coastguard Worker 941*cda5da8dSAndroid Build Coastguard Worker def selected_npn_protocol(self): 942*cda5da8dSAndroid Build Coastguard Worker """Return the currently selected NPN protocol as a string, or ``None`` 943*cda5da8dSAndroid Build Coastguard Worker if a next protocol was not negotiated or if NPN is not supported by one 944*cda5da8dSAndroid Build Coastguard Worker of the peers.""" 945*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 946*cda5da8dSAndroid Build Coastguard Worker "ssl NPN is deprecated, use ALPN instead", 947*cda5da8dSAndroid Build Coastguard Worker DeprecationWarning, 948*cda5da8dSAndroid Build Coastguard Worker stacklevel=2 949*cda5da8dSAndroid Build Coastguard Worker ) 950*cda5da8dSAndroid Build Coastguard Worker 951*cda5da8dSAndroid Build Coastguard Worker def selected_alpn_protocol(self): 952*cda5da8dSAndroid Build Coastguard Worker """Return the currently selected ALPN protocol as a string, or ``None`` 953*cda5da8dSAndroid Build Coastguard Worker if a next protocol was not negotiated or if ALPN is not supported by one 954*cda5da8dSAndroid Build Coastguard Worker of the peers.""" 955*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.selected_alpn_protocol() 956*cda5da8dSAndroid Build Coastguard Worker 957*cda5da8dSAndroid Build Coastguard Worker def cipher(self): 958*cda5da8dSAndroid Build Coastguard Worker """Return the currently selected cipher as a 3-tuple ``(name, 959*cda5da8dSAndroid Build Coastguard Worker ssl_version, secret_bits)``.""" 960*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.cipher() 961*cda5da8dSAndroid Build Coastguard Worker 962*cda5da8dSAndroid Build Coastguard Worker def shared_ciphers(self): 963*cda5da8dSAndroid Build Coastguard Worker """Return a list of ciphers shared by the client during the handshake or 964*cda5da8dSAndroid Build Coastguard Worker None if this is not a valid server connection. 965*cda5da8dSAndroid Build Coastguard Worker """ 966*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.shared_ciphers() 967*cda5da8dSAndroid Build Coastguard Worker 968*cda5da8dSAndroid Build Coastguard Worker def compression(self): 969*cda5da8dSAndroid Build Coastguard Worker """Return the current compression algorithm in use, or ``None`` if 970*cda5da8dSAndroid Build Coastguard Worker compression was not negotiated or not supported by one of the peers.""" 971*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.compression() 972*cda5da8dSAndroid Build Coastguard Worker 973*cda5da8dSAndroid Build Coastguard Worker def pending(self): 974*cda5da8dSAndroid Build Coastguard Worker """Return the number of bytes that can be read immediately.""" 975*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.pending() 976*cda5da8dSAndroid Build Coastguard Worker 977*cda5da8dSAndroid Build Coastguard Worker def do_handshake(self): 978*cda5da8dSAndroid Build Coastguard Worker """Start the SSL/TLS handshake.""" 979*cda5da8dSAndroid Build Coastguard Worker self._sslobj.do_handshake() 980*cda5da8dSAndroid Build Coastguard Worker 981*cda5da8dSAndroid Build Coastguard Worker def unwrap(self): 982*cda5da8dSAndroid Build Coastguard Worker """Start the SSL shutdown handshake.""" 983*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.shutdown() 984*cda5da8dSAndroid Build Coastguard Worker 985*cda5da8dSAndroid Build Coastguard Worker def get_channel_binding(self, cb_type="tls-unique"): 986*cda5da8dSAndroid Build Coastguard Worker """Get channel binding data for current connection. Raise ValueError 987*cda5da8dSAndroid Build Coastguard Worker if the requested `cb_type` is not supported. Return bytes of the data 988*cda5da8dSAndroid Build Coastguard Worker or None if the data is not available (e.g. before the handshake).""" 989*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.get_channel_binding(cb_type) 990*cda5da8dSAndroid Build Coastguard Worker 991*cda5da8dSAndroid Build Coastguard Worker def version(self): 992*cda5da8dSAndroid Build Coastguard Worker """Return a string identifying the protocol version used by the 993*cda5da8dSAndroid Build Coastguard Worker current SSL channel. """ 994*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.version() 995*cda5da8dSAndroid Build Coastguard Worker 996*cda5da8dSAndroid Build Coastguard Worker def verify_client_post_handshake(self): 997*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.verify_client_post_handshake() 998*cda5da8dSAndroid Build Coastguard Worker 999*cda5da8dSAndroid Build Coastguard Worker 1000*cda5da8dSAndroid Build Coastguard Workerdef _sslcopydoc(func): 1001*cda5da8dSAndroid Build Coastguard Worker """Copy docstring from SSLObject to SSLSocket""" 1002*cda5da8dSAndroid Build Coastguard Worker func.__doc__ = getattr(SSLObject, func.__name__).__doc__ 1003*cda5da8dSAndroid Build Coastguard Worker return func 1004*cda5da8dSAndroid Build Coastguard Worker 1005*cda5da8dSAndroid Build Coastguard Worker 1006*cda5da8dSAndroid Build Coastguard Workerclass SSLSocket(socket): 1007*cda5da8dSAndroid Build Coastguard Worker """This class implements a subtype of socket.socket that wraps 1008*cda5da8dSAndroid Build Coastguard Worker the underlying OS socket in an SSL context when necessary, and 1009*cda5da8dSAndroid Build Coastguard Worker provides read and write methods over that channel. """ 1010*cda5da8dSAndroid Build Coastguard Worker 1011*cda5da8dSAndroid Build Coastguard Worker def __init__(self, *args, **kwargs): 1012*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 1013*cda5da8dSAndroid Build Coastguard Worker f"{self.__class__.__name__} does not have a public " 1014*cda5da8dSAndroid Build Coastguard Worker f"constructor. Instances are returned by " 1015*cda5da8dSAndroid Build Coastguard Worker f"SSLContext.wrap_socket()." 1016*cda5da8dSAndroid Build Coastguard Worker ) 1017*cda5da8dSAndroid Build Coastguard Worker 1018*cda5da8dSAndroid Build Coastguard Worker @classmethod 1019*cda5da8dSAndroid Build Coastguard Worker def _create(cls, sock, server_side=False, do_handshake_on_connect=True, 1020*cda5da8dSAndroid Build Coastguard Worker suppress_ragged_eofs=True, server_hostname=None, 1021*cda5da8dSAndroid Build Coastguard Worker context=None, session=None): 1022*cda5da8dSAndroid Build Coastguard Worker if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM: 1023*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError("only stream sockets are supported") 1024*cda5da8dSAndroid Build Coastguard Worker if server_side: 1025*cda5da8dSAndroid Build Coastguard Worker if server_hostname: 1026*cda5da8dSAndroid Build Coastguard Worker raise ValueError("server_hostname can only be specified " 1027*cda5da8dSAndroid Build Coastguard Worker "in client mode") 1028*cda5da8dSAndroid Build Coastguard Worker if session is not None: 1029*cda5da8dSAndroid Build Coastguard Worker raise ValueError("session can only be specified in " 1030*cda5da8dSAndroid Build Coastguard Worker "client mode") 1031*cda5da8dSAndroid Build Coastguard Worker if context.check_hostname and not server_hostname: 1032*cda5da8dSAndroid Build Coastguard Worker raise ValueError("check_hostname requires server_hostname") 1033*cda5da8dSAndroid Build Coastguard Worker 1034*cda5da8dSAndroid Build Coastguard Worker kwargs = dict( 1035*cda5da8dSAndroid Build Coastguard Worker family=sock.family, type=sock.type, proto=sock.proto, 1036*cda5da8dSAndroid Build Coastguard Worker fileno=sock.fileno() 1037*cda5da8dSAndroid Build Coastguard Worker ) 1038*cda5da8dSAndroid Build Coastguard Worker self = cls.__new__(cls, **kwargs) 1039*cda5da8dSAndroid Build Coastguard Worker super(SSLSocket, self).__init__(**kwargs) 1040*cda5da8dSAndroid Build Coastguard Worker self.settimeout(sock.gettimeout()) 1041*cda5da8dSAndroid Build Coastguard Worker sock.detach() 1042*cda5da8dSAndroid Build Coastguard Worker 1043*cda5da8dSAndroid Build Coastguard Worker self._context = context 1044*cda5da8dSAndroid Build Coastguard Worker self._session = session 1045*cda5da8dSAndroid Build Coastguard Worker self._closed = False 1046*cda5da8dSAndroid Build Coastguard Worker self._sslobj = None 1047*cda5da8dSAndroid Build Coastguard Worker self.server_side = server_side 1048*cda5da8dSAndroid Build Coastguard Worker self.server_hostname = context._encode_hostname(server_hostname) 1049*cda5da8dSAndroid Build Coastguard Worker self.do_handshake_on_connect = do_handshake_on_connect 1050*cda5da8dSAndroid Build Coastguard Worker self.suppress_ragged_eofs = suppress_ragged_eofs 1051*cda5da8dSAndroid Build Coastguard Worker 1052*cda5da8dSAndroid Build Coastguard Worker # See if we are connected 1053*cda5da8dSAndroid Build Coastguard Worker try: 1054*cda5da8dSAndroid Build Coastguard Worker self.getpeername() 1055*cda5da8dSAndroid Build Coastguard Worker except OSError as e: 1056*cda5da8dSAndroid Build Coastguard Worker if e.errno != errno.ENOTCONN: 1057*cda5da8dSAndroid Build Coastguard Worker raise 1058*cda5da8dSAndroid Build Coastguard Worker connected = False 1059*cda5da8dSAndroid Build Coastguard Worker else: 1060*cda5da8dSAndroid Build Coastguard Worker connected = True 1061*cda5da8dSAndroid Build Coastguard Worker 1062*cda5da8dSAndroid Build Coastguard Worker self._connected = connected 1063*cda5da8dSAndroid Build Coastguard Worker if connected: 1064*cda5da8dSAndroid Build Coastguard Worker # create the SSL object 1065*cda5da8dSAndroid Build Coastguard Worker try: 1066*cda5da8dSAndroid Build Coastguard Worker self._sslobj = self._context._wrap_socket( 1067*cda5da8dSAndroid Build Coastguard Worker self, server_side, self.server_hostname, 1068*cda5da8dSAndroid Build Coastguard Worker owner=self, session=self._session, 1069*cda5da8dSAndroid Build Coastguard Worker ) 1070*cda5da8dSAndroid Build Coastguard Worker if do_handshake_on_connect: 1071*cda5da8dSAndroid Build Coastguard Worker timeout = self.gettimeout() 1072*cda5da8dSAndroid Build Coastguard Worker if timeout == 0.0: 1073*cda5da8dSAndroid Build Coastguard Worker # non-blocking 1074*cda5da8dSAndroid Build Coastguard Worker raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets") 1075*cda5da8dSAndroid Build Coastguard Worker self.do_handshake() 1076*cda5da8dSAndroid Build Coastguard Worker except (OSError, ValueError): 1077*cda5da8dSAndroid Build Coastguard Worker self.close() 1078*cda5da8dSAndroid Build Coastguard Worker raise 1079*cda5da8dSAndroid Build Coastguard Worker return self 1080*cda5da8dSAndroid Build Coastguard Worker 1081*cda5da8dSAndroid Build Coastguard Worker @property 1082*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1083*cda5da8dSAndroid Build Coastguard Worker def context(self): 1084*cda5da8dSAndroid Build Coastguard Worker return self._context 1085*cda5da8dSAndroid Build Coastguard Worker 1086*cda5da8dSAndroid Build Coastguard Worker @context.setter 1087*cda5da8dSAndroid Build Coastguard Worker def context(self, ctx): 1088*cda5da8dSAndroid Build Coastguard Worker self._context = ctx 1089*cda5da8dSAndroid Build Coastguard Worker self._sslobj.context = ctx 1090*cda5da8dSAndroid Build Coastguard Worker 1091*cda5da8dSAndroid Build Coastguard Worker @property 1092*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1093*cda5da8dSAndroid Build Coastguard Worker def session(self): 1094*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1095*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.session 1096*cda5da8dSAndroid Build Coastguard Worker 1097*cda5da8dSAndroid Build Coastguard Worker @session.setter 1098*cda5da8dSAndroid Build Coastguard Worker def session(self, session): 1099*cda5da8dSAndroid Build Coastguard Worker self._session = session 1100*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1101*cda5da8dSAndroid Build Coastguard Worker self._sslobj.session = session 1102*cda5da8dSAndroid Build Coastguard Worker 1103*cda5da8dSAndroid Build Coastguard Worker @property 1104*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1105*cda5da8dSAndroid Build Coastguard Worker def session_reused(self): 1106*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1107*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.session_reused 1108*cda5da8dSAndroid Build Coastguard Worker 1109*cda5da8dSAndroid Build Coastguard Worker def dup(self): 1110*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError("Can't dup() %s instances" % 1111*cda5da8dSAndroid Build Coastguard Worker self.__class__.__name__) 1112*cda5da8dSAndroid Build Coastguard Worker 1113*cda5da8dSAndroid Build Coastguard Worker def _checkClosed(self, msg=None): 1114*cda5da8dSAndroid Build Coastguard Worker # raise an exception here if you wish to check for spurious closes 1115*cda5da8dSAndroid Build Coastguard Worker pass 1116*cda5da8dSAndroid Build Coastguard Worker 1117*cda5da8dSAndroid Build Coastguard Worker def _check_connected(self): 1118*cda5da8dSAndroid Build Coastguard Worker if not self._connected: 1119*cda5da8dSAndroid Build Coastguard Worker # getpeername() will raise ENOTCONN if the socket is really 1120*cda5da8dSAndroid Build Coastguard Worker # not connected; note that we can be connected even without 1121*cda5da8dSAndroid Build Coastguard Worker # _connected being set, e.g. if connect() first returned 1122*cda5da8dSAndroid Build Coastguard Worker # EAGAIN. 1123*cda5da8dSAndroid Build Coastguard Worker self.getpeername() 1124*cda5da8dSAndroid Build Coastguard Worker 1125*cda5da8dSAndroid Build Coastguard Worker def read(self, len=1024, buffer=None): 1126*cda5da8dSAndroid Build Coastguard Worker """Read up to LEN bytes and return them. 1127*cda5da8dSAndroid Build Coastguard Worker Return zero-length string on EOF.""" 1128*cda5da8dSAndroid Build Coastguard Worker 1129*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1130*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is None: 1131*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Read on closed or unwrapped SSL socket.") 1132*cda5da8dSAndroid Build Coastguard Worker try: 1133*cda5da8dSAndroid Build Coastguard Worker if buffer is not None: 1134*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.read(len, buffer) 1135*cda5da8dSAndroid Build Coastguard Worker else: 1136*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.read(len) 1137*cda5da8dSAndroid Build Coastguard Worker except SSLError as x: 1138*cda5da8dSAndroid Build Coastguard Worker if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: 1139*cda5da8dSAndroid Build Coastguard Worker if buffer is not None: 1140*cda5da8dSAndroid Build Coastguard Worker return 0 1141*cda5da8dSAndroid Build Coastguard Worker else: 1142*cda5da8dSAndroid Build Coastguard Worker return b'' 1143*cda5da8dSAndroid Build Coastguard Worker else: 1144*cda5da8dSAndroid Build Coastguard Worker raise 1145*cda5da8dSAndroid Build Coastguard Worker 1146*cda5da8dSAndroid Build Coastguard Worker def write(self, data): 1147*cda5da8dSAndroid Build Coastguard Worker """Write DATA to the underlying SSL channel. Returns 1148*cda5da8dSAndroid Build Coastguard Worker number of bytes of DATA actually transmitted.""" 1149*cda5da8dSAndroid Build Coastguard Worker 1150*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1151*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is None: 1152*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Write on closed or unwrapped SSL socket.") 1153*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.write(data) 1154*cda5da8dSAndroid Build Coastguard Worker 1155*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1156*cda5da8dSAndroid Build Coastguard Worker def getpeercert(self, binary_form=False): 1157*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1158*cda5da8dSAndroid Build Coastguard Worker self._check_connected() 1159*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.getpeercert(binary_form) 1160*cda5da8dSAndroid Build Coastguard Worker 1161*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1162*cda5da8dSAndroid Build Coastguard Worker def selected_npn_protocol(self): 1163*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1164*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 1165*cda5da8dSAndroid Build Coastguard Worker "ssl NPN is deprecated, use ALPN instead", 1166*cda5da8dSAndroid Build Coastguard Worker DeprecationWarning, 1167*cda5da8dSAndroid Build Coastguard Worker stacklevel=2 1168*cda5da8dSAndroid Build Coastguard Worker ) 1169*cda5da8dSAndroid Build Coastguard Worker return None 1170*cda5da8dSAndroid Build Coastguard Worker 1171*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1172*cda5da8dSAndroid Build Coastguard Worker def selected_alpn_protocol(self): 1173*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1174*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is None or not _ssl.HAS_ALPN: 1175*cda5da8dSAndroid Build Coastguard Worker return None 1176*cda5da8dSAndroid Build Coastguard Worker else: 1177*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.selected_alpn_protocol() 1178*cda5da8dSAndroid Build Coastguard Worker 1179*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1180*cda5da8dSAndroid Build Coastguard Worker def cipher(self): 1181*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1182*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is None: 1183*cda5da8dSAndroid Build Coastguard Worker return None 1184*cda5da8dSAndroid Build Coastguard Worker else: 1185*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.cipher() 1186*cda5da8dSAndroid Build Coastguard Worker 1187*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1188*cda5da8dSAndroid Build Coastguard Worker def shared_ciphers(self): 1189*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1190*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is None: 1191*cda5da8dSAndroid Build Coastguard Worker return None 1192*cda5da8dSAndroid Build Coastguard Worker else: 1193*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.shared_ciphers() 1194*cda5da8dSAndroid Build Coastguard Worker 1195*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1196*cda5da8dSAndroid Build Coastguard Worker def compression(self): 1197*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1198*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is None: 1199*cda5da8dSAndroid Build Coastguard Worker return None 1200*cda5da8dSAndroid Build Coastguard Worker else: 1201*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.compression() 1202*cda5da8dSAndroid Build Coastguard Worker 1203*cda5da8dSAndroid Build Coastguard Worker def send(self, data, flags=0): 1204*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1205*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1206*cda5da8dSAndroid Build Coastguard Worker if flags != 0: 1207*cda5da8dSAndroid Build Coastguard Worker raise ValueError( 1208*cda5da8dSAndroid Build Coastguard Worker "non-zero flags not allowed in calls to send() on %s" % 1209*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1210*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.write(data) 1211*cda5da8dSAndroid Build Coastguard Worker else: 1212*cda5da8dSAndroid Build Coastguard Worker return super().send(data, flags) 1213*cda5da8dSAndroid Build Coastguard Worker 1214*cda5da8dSAndroid Build Coastguard Worker def sendto(self, data, flags_or_addr, addr=None): 1215*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1216*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1217*cda5da8dSAndroid Build Coastguard Worker raise ValueError("sendto not allowed on instances of %s" % 1218*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1219*cda5da8dSAndroid Build Coastguard Worker elif addr is None: 1220*cda5da8dSAndroid Build Coastguard Worker return super().sendto(data, flags_or_addr) 1221*cda5da8dSAndroid Build Coastguard Worker else: 1222*cda5da8dSAndroid Build Coastguard Worker return super().sendto(data, flags_or_addr, addr) 1223*cda5da8dSAndroid Build Coastguard Worker 1224*cda5da8dSAndroid Build Coastguard Worker def sendmsg(self, *args, **kwargs): 1225*cda5da8dSAndroid Build Coastguard Worker # Ensure programs don't send data unencrypted if they try to 1226*cda5da8dSAndroid Build Coastguard Worker # use this method. 1227*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError("sendmsg not allowed on instances of %s" % 1228*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1229*cda5da8dSAndroid Build Coastguard Worker 1230*cda5da8dSAndroid Build Coastguard Worker def sendall(self, data, flags=0): 1231*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1232*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1233*cda5da8dSAndroid Build Coastguard Worker if flags != 0: 1234*cda5da8dSAndroid Build Coastguard Worker raise ValueError( 1235*cda5da8dSAndroid Build Coastguard Worker "non-zero flags not allowed in calls to sendall() on %s" % 1236*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1237*cda5da8dSAndroid Build Coastguard Worker count = 0 1238*cda5da8dSAndroid Build Coastguard Worker with memoryview(data) as view, view.cast("B") as byte_view: 1239*cda5da8dSAndroid Build Coastguard Worker amount = len(byte_view) 1240*cda5da8dSAndroid Build Coastguard Worker while count < amount: 1241*cda5da8dSAndroid Build Coastguard Worker v = self.send(byte_view[count:]) 1242*cda5da8dSAndroid Build Coastguard Worker count += v 1243*cda5da8dSAndroid Build Coastguard Worker else: 1244*cda5da8dSAndroid Build Coastguard Worker return super().sendall(data, flags) 1245*cda5da8dSAndroid Build Coastguard Worker 1246*cda5da8dSAndroid Build Coastguard Worker def sendfile(self, file, offset=0, count=None): 1247*cda5da8dSAndroid Build Coastguard Worker """Send a file, possibly by using os.sendfile() if this is a 1248*cda5da8dSAndroid Build Coastguard Worker clear-text socket. Return the total number of bytes sent. 1249*cda5da8dSAndroid Build Coastguard Worker """ 1250*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1251*cda5da8dSAndroid Build Coastguard Worker return self._sendfile_use_send(file, offset, count) 1252*cda5da8dSAndroid Build Coastguard Worker else: 1253*cda5da8dSAndroid Build Coastguard Worker # os.sendfile() works with plain sockets only 1254*cda5da8dSAndroid Build Coastguard Worker return super().sendfile(file, offset, count) 1255*cda5da8dSAndroid Build Coastguard Worker 1256*cda5da8dSAndroid Build Coastguard Worker def recv(self, buflen=1024, flags=0): 1257*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1258*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1259*cda5da8dSAndroid Build Coastguard Worker if flags != 0: 1260*cda5da8dSAndroid Build Coastguard Worker raise ValueError( 1261*cda5da8dSAndroid Build Coastguard Worker "non-zero flags not allowed in calls to recv() on %s" % 1262*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1263*cda5da8dSAndroid Build Coastguard Worker return self.read(buflen) 1264*cda5da8dSAndroid Build Coastguard Worker else: 1265*cda5da8dSAndroid Build Coastguard Worker return super().recv(buflen, flags) 1266*cda5da8dSAndroid Build Coastguard Worker 1267*cda5da8dSAndroid Build Coastguard Worker def recv_into(self, buffer, nbytes=None, flags=0): 1268*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1269*cda5da8dSAndroid Build Coastguard Worker if buffer and (nbytes is None): 1270*cda5da8dSAndroid Build Coastguard Worker nbytes = len(buffer) 1271*cda5da8dSAndroid Build Coastguard Worker elif nbytes is None: 1272*cda5da8dSAndroid Build Coastguard Worker nbytes = 1024 1273*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1274*cda5da8dSAndroid Build Coastguard Worker if flags != 0: 1275*cda5da8dSAndroid Build Coastguard Worker raise ValueError( 1276*cda5da8dSAndroid Build Coastguard Worker "non-zero flags not allowed in calls to recv_into() on %s" % 1277*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1278*cda5da8dSAndroid Build Coastguard Worker return self.read(nbytes, buffer) 1279*cda5da8dSAndroid Build Coastguard Worker else: 1280*cda5da8dSAndroid Build Coastguard Worker return super().recv_into(buffer, nbytes, flags) 1281*cda5da8dSAndroid Build Coastguard Worker 1282*cda5da8dSAndroid Build Coastguard Worker def recvfrom(self, buflen=1024, flags=0): 1283*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1284*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1285*cda5da8dSAndroid Build Coastguard Worker raise ValueError("recvfrom not allowed on instances of %s" % 1286*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1287*cda5da8dSAndroid Build Coastguard Worker else: 1288*cda5da8dSAndroid Build Coastguard Worker return super().recvfrom(buflen, flags) 1289*cda5da8dSAndroid Build Coastguard Worker 1290*cda5da8dSAndroid Build Coastguard Worker def recvfrom_into(self, buffer, nbytes=None, flags=0): 1291*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1292*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1293*cda5da8dSAndroid Build Coastguard Worker raise ValueError("recvfrom_into not allowed on instances of %s" % 1294*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1295*cda5da8dSAndroid Build Coastguard Worker else: 1296*cda5da8dSAndroid Build Coastguard Worker return super().recvfrom_into(buffer, nbytes, flags) 1297*cda5da8dSAndroid Build Coastguard Worker 1298*cda5da8dSAndroid Build Coastguard Worker def recvmsg(self, *args, **kwargs): 1299*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError("recvmsg not allowed on instances of %s" % 1300*cda5da8dSAndroid Build Coastguard Worker self.__class__) 1301*cda5da8dSAndroid Build Coastguard Worker 1302*cda5da8dSAndroid Build Coastguard Worker def recvmsg_into(self, *args, **kwargs): 1303*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError("recvmsg_into not allowed on instances of " 1304*cda5da8dSAndroid Build Coastguard Worker "%s" % self.__class__) 1305*cda5da8dSAndroid Build Coastguard Worker 1306*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1307*cda5da8dSAndroid Build Coastguard Worker def pending(self): 1308*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1309*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1310*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.pending() 1311*cda5da8dSAndroid Build Coastguard Worker else: 1312*cda5da8dSAndroid Build Coastguard Worker return 0 1313*cda5da8dSAndroid Build Coastguard Worker 1314*cda5da8dSAndroid Build Coastguard Worker def shutdown(self, how): 1315*cda5da8dSAndroid Build Coastguard Worker self._checkClosed() 1316*cda5da8dSAndroid Build Coastguard Worker self._sslobj = None 1317*cda5da8dSAndroid Build Coastguard Worker super().shutdown(how) 1318*cda5da8dSAndroid Build Coastguard Worker 1319*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1320*cda5da8dSAndroid Build Coastguard Worker def unwrap(self): 1321*cda5da8dSAndroid Build Coastguard Worker if self._sslobj: 1322*cda5da8dSAndroid Build Coastguard Worker s = self._sslobj.shutdown() 1323*cda5da8dSAndroid Build Coastguard Worker self._sslobj = None 1324*cda5da8dSAndroid Build Coastguard Worker return s 1325*cda5da8dSAndroid Build Coastguard Worker else: 1326*cda5da8dSAndroid Build Coastguard Worker raise ValueError("No SSL wrapper around " + str(self)) 1327*cda5da8dSAndroid Build Coastguard Worker 1328*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1329*cda5da8dSAndroid Build Coastguard Worker def verify_client_post_handshake(self): 1330*cda5da8dSAndroid Build Coastguard Worker if self._sslobj: 1331*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.verify_client_post_handshake() 1332*cda5da8dSAndroid Build Coastguard Worker else: 1333*cda5da8dSAndroid Build Coastguard Worker raise ValueError("No SSL wrapper around " + str(self)) 1334*cda5da8dSAndroid Build Coastguard Worker 1335*cda5da8dSAndroid Build Coastguard Worker def _real_close(self): 1336*cda5da8dSAndroid Build Coastguard Worker self._sslobj = None 1337*cda5da8dSAndroid Build Coastguard Worker super()._real_close() 1338*cda5da8dSAndroid Build Coastguard Worker 1339*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1340*cda5da8dSAndroid Build Coastguard Worker def do_handshake(self, block=False): 1341*cda5da8dSAndroid Build Coastguard Worker self._check_connected() 1342*cda5da8dSAndroid Build Coastguard Worker timeout = self.gettimeout() 1343*cda5da8dSAndroid Build Coastguard Worker try: 1344*cda5da8dSAndroid Build Coastguard Worker if timeout == 0.0 and block: 1345*cda5da8dSAndroid Build Coastguard Worker self.settimeout(None) 1346*cda5da8dSAndroid Build Coastguard Worker self._sslobj.do_handshake() 1347*cda5da8dSAndroid Build Coastguard Worker finally: 1348*cda5da8dSAndroid Build Coastguard Worker self.settimeout(timeout) 1349*cda5da8dSAndroid Build Coastguard Worker 1350*cda5da8dSAndroid Build Coastguard Worker def _real_connect(self, addr, connect_ex): 1351*cda5da8dSAndroid Build Coastguard Worker if self.server_side: 1352*cda5da8dSAndroid Build Coastguard Worker raise ValueError("can't connect in server-side mode") 1353*cda5da8dSAndroid Build Coastguard Worker # Here we assume that the socket is client-side, and not 1354*cda5da8dSAndroid Build Coastguard Worker # connected at the time of the call. We connect it, then wrap it. 1355*cda5da8dSAndroid Build Coastguard Worker if self._connected or self._sslobj is not None: 1356*cda5da8dSAndroid Build Coastguard Worker raise ValueError("attempt to connect already-connected SSLSocket!") 1357*cda5da8dSAndroid Build Coastguard Worker self._sslobj = self.context._wrap_socket( 1358*cda5da8dSAndroid Build Coastguard Worker self, False, self.server_hostname, 1359*cda5da8dSAndroid Build Coastguard Worker owner=self, session=self._session 1360*cda5da8dSAndroid Build Coastguard Worker ) 1361*cda5da8dSAndroid Build Coastguard Worker try: 1362*cda5da8dSAndroid Build Coastguard Worker if connect_ex: 1363*cda5da8dSAndroid Build Coastguard Worker rc = super().connect_ex(addr) 1364*cda5da8dSAndroid Build Coastguard Worker else: 1365*cda5da8dSAndroid Build Coastguard Worker rc = None 1366*cda5da8dSAndroid Build Coastguard Worker super().connect(addr) 1367*cda5da8dSAndroid Build Coastguard Worker if not rc: 1368*cda5da8dSAndroid Build Coastguard Worker self._connected = True 1369*cda5da8dSAndroid Build Coastguard Worker if self.do_handshake_on_connect: 1370*cda5da8dSAndroid Build Coastguard Worker self.do_handshake() 1371*cda5da8dSAndroid Build Coastguard Worker return rc 1372*cda5da8dSAndroid Build Coastguard Worker except (OSError, ValueError): 1373*cda5da8dSAndroid Build Coastguard Worker self._sslobj = None 1374*cda5da8dSAndroid Build Coastguard Worker raise 1375*cda5da8dSAndroid Build Coastguard Worker 1376*cda5da8dSAndroid Build Coastguard Worker def connect(self, addr): 1377*cda5da8dSAndroid Build Coastguard Worker """Connects to remote ADDR, and then wraps the connection in 1378*cda5da8dSAndroid Build Coastguard Worker an SSL channel.""" 1379*cda5da8dSAndroid Build Coastguard Worker self._real_connect(addr, False) 1380*cda5da8dSAndroid Build Coastguard Worker 1381*cda5da8dSAndroid Build Coastguard Worker def connect_ex(self, addr): 1382*cda5da8dSAndroid Build Coastguard Worker """Connects to remote ADDR, and then wraps the connection in 1383*cda5da8dSAndroid Build Coastguard Worker an SSL channel.""" 1384*cda5da8dSAndroid Build Coastguard Worker return self._real_connect(addr, True) 1385*cda5da8dSAndroid Build Coastguard Worker 1386*cda5da8dSAndroid Build Coastguard Worker def accept(self): 1387*cda5da8dSAndroid Build Coastguard Worker """Accepts a new connection from a remote client, and returns 1388*cda5da8dSAndroid Build Coastguard Worker a tuple containing that new connection wrapped with a server-side 1389*cda5da8dSAndroid Build Coastguard Worker SSL channel, and the address of the remote client.""" 1390*cda5da8dSAndroid Build Coastguard Worker 1391*cda5da8dSAndroid Build Coastguard Worker newsock, addr = super().accept() 1392*cda5da8dSAndroid Build Coastguard Worker newsock = self.context.wrap_socket(newsock, 1393*cda5da8dSAndroid Build Coastguard Worker do_handshake_on_connect=self.do_handshake_on_connect, 1394*cda5da8dSAndroid Build Coastguard Worker suppress_ragged_eofs=self.suppress_ragged_eofs, 1395*cda5da8dSAndroid Build Coastguard Worker server_side=True) 1396*cda5da8dSAndroid Build Coastguard Worker return newsock, addr 1397*cda5da8dSAndroid Build Coastguard Worker 1398*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1399*cda5da8dSAndroid Build Coastguard Worker def get_channel_binding(self, cb_type="tls-unique"): 1400*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1401*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.get_channel_binding(cb_type) 1402*cda5da8dSAndroid Build Coastguard Worker else: 1403*cda5da8dSAndroid Build Coastguard Worker if cb_type not in CHANNEL_BINDING_TYPES: 1404*cda5da8dSAndroid Build Coastguard Worker raise ValueError( 1405*cda5da8dSAndroid Build Coastguard Worker "{0} channel binding type not implemented".format(cb_type) 1406*cda5da8dSAndroid Build Coastguard Worker ) 1407*cda5da8dSAndroid Build Coastguard Worker return None 1408*cda5da8dSAndroid Build Coastguard Worker 1409*cda5da8dSAndroid Build Coastguard Worker @_sslcopydoc 1410*cda5da8dSAndroid Build Coastguard Worker def version(self): 1411*cda5da8dSAndroid Build Coastguard Worker if self._sslobj is not None: 1412*cda5da8dSAndroid Build Coastguard Worker return self._sslobj.version() 1413*cda5da8dSAndroid Build Coastguard Worker else: 1414*cda5da8dSAndroid Build Coastguard Worker return None 1415*cda5da8dSAndroid Build Coastguard Worker 1416*cda5da8dSAndroid Build Coastguard Worker 1417*cda5da8dSAndroid Build Coastguard Worker# Python does not support forward declaration of types. 1418*cda5da8dSAndroid Build Coastguard WorkerSSLContext.sslsocket_class = SSLSocket 1419*cda5da8dSAndroid Build Coastguard WorkerSSLContext.sslobject_class = SSLObject 1420*cda5da8dSAndroid Build Coastguard Worker 1421*cda5da8dSAndroid Build Coastguard Worker 1422*cda5da8dSAndroid Build Coastguard Workerdef wrap_socket(sock, keyfile=None, certfile=None, 1423*cda5da8dSAndroid Build Coastguard Worker server_side=False, cert_reqs=CERT_NONE, 1424*cda5da8dSAndroid Build Coastguard Worker ssl_version=PROTOCOL_TLS, ca_certs=None, 1425*cda5da8dSAndroid Build Coastguard Worker do_handshake_on_connect=True, 1426*cda5da8dSAndroid Build Coastguard Worker suppress_ragged_eofs=True, 1427*cda5da8dSAndroid Build Coastguard Worker ciphers=None): 1428*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 1429*cda5da8dSAndroid Build Coastguard Worker "ssl.wrap_socket() is deprecated, use SSLContext.wrap_socket()", 1430*cda5da8dSAndroid Build Coastguard Worker category=DeprecationWarning, 1431*cda5da8dSAndroid Build Coastguard Worker stacklevel=2 1432*cda5da8dSAndroid Build Coastguard Worker ) 1433*cda5da8dSAndroid Build Coastguard Worker if server_side and not certfile: 1434*cda5da8dSAndroid Build Coastguard Worker raise ValueError("certfile must be specified for server-side " 1435*cda5da8dSAndroid Build Coastguard Worker "operations") 1436*cda5da8dSAndroid Build Coastguard Worker if keyfile and not certfile: 1437*cda5da8dSAndroid Build Coastguard Worker raise ValueError("certfile must be specified") 1438*cda5da8dSAndroid Build Coastguard Worker context = SSLContext(ssl_version) 1439*cda5da8dSAndroid Build Coastguard Worker context.verify_mode = cert_reqs 1440*cda5da8dSAndroid Build Coastguard Worker if ca_certs: 1441*cda5da8dSAndroid Build Coastguard Worker context.load_verify_locations(ca_certs) 1442*cda5da8dSAndroid Build Coastguard Worker if certfile: 1443*cda5da8dSAndroid Build Coastguard Worker context.load_cert_chain(certfile, keyfile) 1444*cda5da8dSAndroid Build Coastguard Worker if ciphers: 1445*cda5da8dSAndroid Build Coastguard Worker context.set_ciphers(ciphers) 1446*cda5da8dSAndroid Build Coastguard Worker return context.wrap_socket( 1447*cda5da8dSAndroid Build Coastguard Worker sock=sock, server_side=server_side, 1448*cda5da8dSAndroid Build Coastguard Worker do_handshake_on_connect=do_handshake_on_connect, 1449*cda5da8dSAndroid Build Coastguard Worker suppress_ragged_eofs=suppress_ragged_eofs 1450*cda5da8dSAndroid Build Coastguard Worker ) 1451*cda5da8dSAndroid Build Coastguard Worker 1452*cda5da8dSAndroid Build Coastguard Worker# some utility functions 1453*cda5da8dSAndroid Build Coastguard Worker 1454*cda5da8dSAndroid Build Coastguard Workerdef cert_time_to_seconds(cert_time): 1455*cda5da8dSAndroid Build Coastguard Worker """Return the time in seconds since the Epoch, given the timestring 1456*cda5da8dSAndroid Build Coastguard Worker representing the "notBefore" or "notAfter" date from a certificate 1457*cda5da8dSAndroid Build Coastguard Worker in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale). 1458*cda5da8dSAndroid Build Coastguard Worker 1459*cda5da8dSAndroid Build Coastguard Worker "notBefore" or "notAfter" dates must use UTC (RFC 5280). 1460*cda5da8dSAndroid Build Coastguard Worker 1461*cda5da8dSAndroid Build Coastguard Worker Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 1462*cda5da8dSAndroid Build Coastguard Worker UTC should be specified as GMT (see ASN1_TIME_print()) 1463*cda5da8dSAndroid Build Coastguard Worker """ 1464*cda5da8dSAndroid Build Coastguard Worker from time import strptime 1465*cda5da8dSAndroid Build Coastguard Worker from calendar import timegm 1466*cda5da8dSAndroid Build Coastguard Worker 1467*cda5da8dSAndroid Build Coastguard Worker months = ( 1468*cda5da8dSAndroid Build Coastguard Worker "Jan","Feb","Mar","Apr","May","Jun", 1469*cda5da8dSAndroid Build Coastguard Worker "Jul","Aug","Sep","Oct","Nov","Dec" 1470*cda5da8dSAndroid Build Coastguard Worker ) 1471*cda5da8dSAndroid Build Coastguard Worker time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT 1472*cda5da8dSAndroid Build Coastguard Worker try: 1473*cda5da8dSAndroid Build Coastguard Worker month_number = months.index(cert_time[:3].title()) + 1 1474*cda5da8dSAndroid Build Coastguard Worker except ValueError: 1475*cda5da8dSAndroid Build Coastguard Worker raise ValueError('time data %r does not match ' 1476*cda5da8dSAndroid Build Coastguard Worker 'format "%%b%s"' % (cert_time, time_format)) 1477*cda5da8dSAndroid Build Coastguard Worker else: 1478*cda5da8dSAndroid Build Coastguard Worker # found valid month 1479*cda5da8dSAndroid Build Coastguard Worker tt = strptime(cert_time[3:], time_format) 1480*cda5da8dSAndroid Build Coastguard Worker # return an integer, the previous mktime()-based implementation 1481*cda5da8dSAndroid Build Coastguard Worker # returned a float (fractional seconds are always zero here). 1482*cda5da8dSAndroid Build Coastguard Worker return timegm((tt[0], month_number) + tt[2:6]) 1483*cda5da8dSAndroid Build Coastguard Worker 1484*cda5da8dSAndroid Build Coastguard WorkerPEM_HEADER = "-----BEGIN CERTIFICATE-----" 1485*cda5da8dSAndroid Build Coastguard WorkerPEM_FOOTER = "-----END CERTIFICATE-----" 1486*cda5da8dSAndroid Build Coastguard Worker 1487*cda5da8dSAndroid Build Coastguard Workerdef DER_cert_to_PEM_cert(der_cert_bytes): 1488*cda5da8dSAndroid Build Coastguard Worker """Takes a certificate in binary DER format and returns the 1489*cda5da8dSAndroid Build Coastguard Worker PEM version of it as a string.""" 1490*cda5da8dSAndroid Build Coastguard Worker 1491*cda5da8dSAndroid Build Coastguard Worker f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict') 1492*cda5da8dSAndroid Build Coastguard Worker ss = [PEM_HEADER] 1493*cda5da8dSAndroid Build Coastguard Worker ss += [f[i:i+64] for i in range(0, len(f), 64)] 1494*cda5da8dSAndroid Build Coastguard Worker ss.append(PEM_FOOTER + '\n') 1495*cda5da8dSAndroid Build Coastguard Worker return '\n'.join(ss) 1496*cda5da8dSAndroid Build Coastguard Worker 1497*cda5da8dSAndroid Build Coastguard Workerdef PEM_cert_to_DER_cert(pem_cert_string): 1498*cda5da8dSAndroid Build Coastguard Worker """Takes a certificate in ASCII PEM format and returns the 1499*cda5da8dSAndroid Build Coastguard Worker DER-encoded version of it as a byte sequence""" 1500*cda5da8dSAndroid Build Coastguard Worker 1501*cda5da8dSAndroid Build Coastguard Worker if not pem_cert_string.startswith(PEM_HEADER): 1502*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Invalid PEM encoding; must start with %s" 1503*cda5da8dSAndroid Build Coastguard Worker % PEM_HEADER) 1504*cda5da8dSAndroid Build Coastguard Worker if not pem_cert_string.strip().endswith(PEM_FOOTER): 1505*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Invalid PEM encoding; must end with %s" 1506*cda5da8dSAndroid Build Coastguard Worker % PEM_FOOTER) 1507*cda5da8dSAndroid Build Coastguard Worker d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] 1508*cda5da8dSAndroid Build Coastguard Worker return base64.decodebytes(d.encode('ASCII', 'strict')) 1509*cda5da8dSAndroid Build Coastguard Worker 1510*cda5da8dSAndroid Build Coastguard Workerdef get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, 1511*cda5da8dSAndroid Build Coastguard Worker ca_certs=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): 1512*cda5da8dSAndroid Build Coastguard Worker """Retrieve the certificate from the server at the specified address, 1513*cda5da8dSAndroid Build Coastguard Worker and return it as a PEM-encoded string. 1514*cda5da8dSAndroid Build Coastguard Worker If 'ca_certs' is specified, validate the server cert against it. 1515*cda5da8dSAndroid Build Coastguard Worker If 'ssl_version' is specified, use it in the connection attempt. 1516*cda5da8dSAndroid Build Coastguard Worker If 'timeout' is specified, use it in the connection attempt. 1517*cda5da8dSAndroid Build Coastguard Worker """ 1518*cda5da8dSAndroid Build Coastguard Worker 1519*cda5da8dSAndroid Build Coastguard Worker host, port = addr 1520*cda5da8dSAndroid Build Coastguard Worker if ca_certs is not None: 1521*cda5da8dSAndroid Build Coastguard Worker cert_reqs = CERT_REQUIRED 1522*cda5da8dSAndroid Build Coastguard Worker else: 1523*cda5da8dSAndroid Build Coastguard Worker cert_reqs = CERT_NONE 1524*cda5da8dSAndroid Build Coastguard Worker context = _create_stdlib_context(ssl_version, 1525*cda5da8dSAndroid Build Coastguard Worker cert_reqs=cert_reqs, 1526*cda5da8dSAndroid Build Coastguard Worker cafile=ca_certs) 1527*cda5da8dSAndroid Build Coastguard Worker with create_connection(addr, timeout=timeout) as sock: 1528*cda5da8dSAndroid Build Coastguard Worker with context.wrap_socket(sock, server_hostname=host) as sslsock: 1529*cda5da8dSAndroid Build Coastguard Worker dercert = sslsock.getpeercert(True) 1530*cda5da8dSAndroid Build Coastguard Worker return DER_cert_to_PEM_cert(dercert) 1531*cda5da8dSAndroid Build Coastguard Worker 1532*cda5da8dSAndroid Build Coastguard Workerdef get_protocol_name(protocol_code): 1533*cda5da8dSAndroid Build Coastguard Worker return _PROTOCOL_NAMES.get(protocol_code, '<unknown>') 1534