2 This module uses ctypes to bind a whole bunch of functions and constants from
3 SecureTransport. The goal here is to provide the low-level API to
4 SecureTransport. These are essentially the C-level functions and constants, and
5 they're pretty gross to work with.
7 This code is a bastardised version of the code found in Will Bond's oscrypto
8 library. An enormous debt is owed to him for blazing this trail for us. For
9 that reason, this code should be considered to be covered both by urllib3's
10 license and by oscrypto's:
12 Copyright (c) 2015-2016 Will Bond <will@wbond.net>
14 Permission is hereby granted, free of charge, to any person obtaining a
15 copy of this software and associated documentation files (the "Software"),
16 to deal in the Software without restriction, including without limitation
17 the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 and/or sell copies of the Software, and to permit persons to whom the
19 Software is furnished to do so, subject to the following conditions:
21 The above copyright notice and this permission notice shall be included in
22 all copies or substantial portions of the Software.
24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 DEALINGS IN THE SOFTWARE.
32 from __future__ import absolute_import
49 from ctypes.util import find_library
51 from ...packages.six import raise_from
53 if platform.system() != "Darwin":
54 raise ImportError("Only macOS is supported")
56 version = platform.mac_ver()[0]
57 version_info = tuple(map(int, version.split(".")))
58 if version_info < (10, 8):
60 "Only OS X 10.8 and newer are supported, not %s.%s"
61 % (version_info[0], version_info[1])
65 def load_cdll(name, macos10_16_path):
66 """Loads a CDLL by name, falling back to known path on 10.16+"""
68 # Big Sur is technically 11 but we use 10.16 due to the Big Sur
69 # beta being labeled as 10.16.
70 if version_info >= (10, 16):
71 path = macos10_16_path
73 path = find_library(name)
75 raise OSError # Caught and reraised as 'ImportError'
76 return CDLL(path, use_errno=True)
78 raise_from(ImportError("The library %s failed to load" % name), None)
82 "Security", "/System/Library/Frameworks/Security.framework/Security"
84 CoreFoundation = load_cdll(
86 "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation",
92 CFStringEncoding = c_uint32
96 CFMutableArray = c_void_p
97 CFDictionary = c_void_p
102 CFTypeRef = POINTER(CFType)
103 CFAllocatorRef = c_void_p
107 CFDataRef = POINTER(CFData)
108 CFStringRef = POINTER(CFString)
109 CFArrayRef = POINTER(CFArray)
110 CFMutableArrayRef = POINTER(CFMutableArray)
111 CFDictionaryRef = POINTER(CFDictionary)
112 CFArrayCallBacks = c_void_p
113 CFDictionaryKeyCallBacks = c_void_p
114 CFDictionaryValueCallBacks = c_void_p
116 SecCertificateRef = POINTER(c_void_p)
117 SecExternalFormat = c_uint32
118 SecExternalItemType = c_uint32
119 SecIdentityRef = POINTER(c_void_p)
120 SecItemImportExportFlags = c_uint32
121 SecItemImportExportKeyParameters = c_void_p
122 SecKeychainRef = POINTER(c_void_p)
123 SSLProtocol = c_uint32
124 SSLCipherSuite = c_uint32
125 SSLContextRef = POINTER(c_void_p)
126 SecTrustRef = POINTER(c_void_p)
127 SSLConnectionRef = c_uint32
128 SecTrustResultType = c_uint32
129 SecTrustOptionFlags = c_uint32
130 SSLProtocolSide = c_uint32
131 SSLConnectionType = c_uint32
132 SSLSessionOption = c_uint32
136 Security.SecItemImport.argtypes = [
139 POINTER(SecExternalFormat),
140 POINTER(SecExternalItemType),
141 SecItemImportExportFlags,
142 POINTER(SecItemImportExportKeyParameters),
146 Security.SecItemImport.restype = OSStatus
148 Security.SecCertificateGetTypeID.argtypes = []
149 Security.SecCertificateGetTypeID.restype = CFTypeID
151 Security.SecIdentityGetTypeID.argtypes = []
152 Security.SecIdentityGetTypeID.restype = CFTypeID
154 Security.SecKeyGetTypeID.argtypes = []
155 Security.SecKeyGetTypeID.restype = CFTypeID
157 Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef]
158 Security.SecCertificateCreateWithData.restype = SecCertificateRef
160 Security.SecCertificateCopyData.argtypes = [SecCertificateRef]
161 Security.SecCertificateCopyData.restype = CFDataRef
163 Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
164 Security.SecCopyErrorMessageString.restype = CFStringRef
166 Security.SecIdentityCreateWithCertificate.argtypes = [
169 POINTER(SecIdentityRef),
171 Security.SecIdentityCreateWithCertificate.restype = OSStatus
173 Security.SecKeychainCreate.argtypes = [
179 POINTER(SecKeychainRef),
181 Security.SecKeychainCreate.restype = OSStatus
183 Security.SecKeychainDelete.argtypes = [SecKeychainRef]
184 Security.SecKeychainDelete.restype = OSStatus
186 Security.SecPKCS12Import.argtypes = [
191 Security.SecPKCS12Import.restype = OSStatus
193 SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t))
194 SSLWriteFunc = CFUNCTYPE(
195 OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)
198 Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc]
199 Security.SSLSetIOFuncs.restype = OSStatus
201 Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t]
202 Security.SSLSetPeerID.restype = OSStatus
204 Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef]
205 Security.SSLSetCertificate.restype = OSStatus
207 Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean]
208 Security.SSLSetCertificateAuthorities.restype = OSStatus
210 Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef]
211 Security.SSLSetConnection.restype = OSStatus
213 Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t]
214 Security.SSLSetPeerDomainName.restype = OSStatus
216 Security.SSLHandshake.argtypes = [SSLContextRef]
217 Security.SSLHandshake.restype = OSStatus
219 Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
220 Security.SSLRead.restype = OSStatus
222 Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
223 Security.SSLWrite.restype = OSStatus
225 Security.SSLClose.argtypes = [SSLContextRef]
226 Security.SSLClose.restype = OSStatus
228 Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)]
229 Security.SSLGetNumberSupportedCiphers.restype = OSStatus
231 Security.SSLGetSupportedCiphers.argtypes = [
233 POINTER(SSLCipherSuite),
236 Security.SSLGetSupportedCiphers.restype = OSStatus
238 Security.SSLSetEnabledCiphers.argtypes = [
240 POINTER(SSLCipherSuite),
243 Security.SSLSetEnabledCiphers.restype = OSStatus
245 Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)]
246 Security.SSLGetNumberEnabledCiphers.restype = OSStatus
248 Security.SSLGetEnabledCiphers.argtypes = [
250 POINTER(SSLCipherSuite),
253 Security.SSLGetEnabledCiphers.restype = OSStatus
255 Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)]
256 Security.SSLGetNegotiatedCipher.restype = OSStatus
258 Security.SSLGetNegotiatedProtocolVersion.argtypes = [
260 POINTER(SSLProtocol),
262 Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus
264 Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)]
265 Security.SSLCopyPeerTrust.restype = OSStatus
267 Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef]
268 Security.SecTrustSetAnchorCertificates.restype = OSStatus
270 Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean]
271 Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus
273 Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)]
274 Security.SecTrustEvaluate.restype = OSStatus
276 Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef]
277 Security.SecTrustGetCertificateCount.restype = CFIndex
279 Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex]
280 Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef
282 Security.SSLCreateContext.argtypes = [
287 Security.SSLCreateContext.restype = SSLContextRef
289 Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean]
290 Security.SSLSetSessionOption.restype = OSStatus
292 Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol]
293 Security.SSLSetProtocolVersionMin.restype = OSStatus
295 Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol]
296 Security.SSLSetProtocolVersionMax.restype = OSStatus
299 Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef]
300 Security.SSLSetALPNProtocols.restype = OSStatus
301 except AttributeError:
302 # Supported only in 10.12+
305 Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
306 Security.SecCopyErrorMessageString.restype = CFStringRef
308 Security.SSLReadFunc = SSLReadFunc
309 Security.SSLWriteFunc = SSLWriteFunc
310 Security.SSLContextRef = SSLContextRef
311 Security.SSLProtocol = SSLProtocol
312 Security.SSLCipherSuite = SSLCipherSuite
313 Security.SecIdentityRef = SecIdentityRef
314 Security.SecKeychainRef = SecKeychainRef
315 Security.SecTrustRef = SecTrustRef
316 Security.SecTrustResultType = SecTrustResultType
317 Security.SecExternalFormat = SecExternalFormat
318 Security.OSStatus = OSStatus
320 Security.kSecImportExportPassphrase = CFStringRef.in_dll(
321 Security, "kSecImportExportPassphrase"
323 Security.kSecImportItemIdentity = CFStringRef.in_dll(
324 Security, "kSecImportItemIdentity"
327 # CoreFoundation time!
328 CoreFoundation.CFRetain.argtypes = [CFTypeRef]
329 CoreFoundation.CFRetain.restype = CFTypeRef
331 CoreFoundation.CFRelease.argtypes = [CFTypeRef]
332 CoreFoundation.CFRelease.restype = None
334 CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef]
335 CoreFoundation.CFGetTypeID.restype = CFTypeID
337 CoreFoundation.CFStringCreateWithCString.argtypes = [
342 CoreFoundation.CFStringCreateWithCString.restype = CFStringRef
344 CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding]
345 CoreFoundation.CFStringGetCStringPtr.restype = c_char_p
347 CoreFoundation.CFStringGetCString.argtypes = [
353 CoreFoundation.CFStringGetCString.restype = c_bool
355 CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex]
356 CoreFoundation.CFDataCreate.restype = CFDataRef
358 CoreFoundation.CFDataGetLength.argtypes = [CFDataRef]
359 CoreFoundation.CFDataGetLength.restype = CFIndex
361 CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef]
362 CoreFoundation.CFDataGetBytePtr.restype = c_void_p
364 CoreFoundation.CFDictionaryCreate.argtypes = [
369 CFDictionaryKeyCallBacks,
370 CFDictionaryValueCallBacks,
372 CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef
374 CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef]
375 CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef
377 CoreFoundation.CFArrayCreate.argtypes = [
383 CoreFoundation.CFArrayCreate.restype = CFArrayRef
385 CoreFoundation.CFArrayCreateMutable.argtypes = [
390 CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef
392 CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p]
393 CoreFoundation.CFArrayAppendValue.restype = None
395 CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef]
396 CoreFoundation.CFArrayGetCount.restype = CFIndex
398 CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
399 CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p
401 CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll(
402 CoreFoundation, "kCFAllocatorDefault"
404 CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(
405 CoreFoundation, "kCFTypeArrayCallBacks"
407 CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll(
408 CoreFoundation, "kCFTypeDictionaryKeyCallBacks"
410 CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll(
411 CoreFoundation, "kCFTypeDictionaryValueCallBacks"
414 CoreFoundation.CFTypeRef = CFTypeRef
415 CoreFoundation.CFArrayRef = CFArrayRef
416 CoreFoundation.CFStringRef = CFStringRef
417 CoreFoundation.CFDictionaryRef = CFDictionaryRef
419 except (AttributeError):
420 raise ImportError("Error initializing ctypes")
423 class CFConst(object):
425 A class object that acts as essentially a namespace for CoreFoundation
429 kCFStringEncodingUTF8 = CFStringEncoding(0x08000100)
432 class SecurityConst(object):
434 A class object that acts as essentially a namespace for Security constants.
437 kSSLSessionOptionBreakOnServerAuth = 0
444 # SecureTransport does not support TLS 1.3 even if there's a constant for it
446 kTLSProtocolMaxSupported = 999
451 kSecFormatPEMSequence = 10
453 kSecTrustResultInvalid = 0
454 kSecTrustResultProceed = 1
455 # This gap is present on purpose: this was kSecTrustResultConfirm, which
457 kSecTrustResultDeny = 3
458 kSecTrustResultUnspecified = 4
459 kSecTrustResultRecoverableTrustFailure = 5
460 kSecTrustResultFatalTrustFailure = 6
461 kSecTrustResultOtherError = 7
463 errSSLProtocol = -9800
464 errSSLWouldBlock = -9803
465 errSSLClosedGraceful = -9805
466 errSSLClosedNoNotify = -9816
467 errSSLClosedAbort = -9806
469 errSSLXCertChainInvalid = -9807
471 errSSLInternal = -9810
472 errSSLCertExpired = -9814
473 errSSLCertNotYetValid = -9815
474 errSSLUnknownRootCert = -9812
475 errSSLNoRootCert = -9813
476 errSSLHostNameMismatch = -9843
477 errSSLPeerHandshakeFail = -9824
478 errSSLPeerUserCancelled = -9839
479 errSSLWeakPeerEphemeralDHKey = -9850
480 errSSLServerAuthCompleted = -9841
481 errSSLRecordOverflow = -9847
483 errSecVerifyFailed = -67808
484 errSecNoTrustSettings = -25263
485 errSecItemNotFound = -25300
486 errSecInvalidTrustSettings = -25262
488 # Cipher suites. We only pick the ones our default cipher string allows.
489 # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values
490 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C
491 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030
492 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B
493 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F
494 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9
495 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8
496 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F
497 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E
498 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024
499 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028
500 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A
501 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014
502 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
503 TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
504 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023
505 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027
506 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009
507 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013
508 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
509 TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
510 TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D
511 TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C
512 TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D
513 TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C
514 TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
515 TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F
516 TLS_AES_128_GCM_SHA256 = 0x1301
517 TLS_AES_256_GCM_SHA384 = 0x1302
518 TLS_AES_128_CCM_8_SHA256 = 0x1305
519 TLS_AES_128_CCM_SHA256 = 0x1304