xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/ssl.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
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