1# coding: utf-8 2# Modified Work: Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. 3# This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license. 4# Copyright 2008-2016 Andrey Petrov and contributors 5 6""" 7This module uses ctypes to bind a whole bunch of functions and constants from 8SecureTransport. The goal here is to provide the low-level API to 9SecureTransport. These are essentially the C-level functions and constants, and 10they're pretty gross to work with. 11 12This code is a bastardised version of the code found in Will Bond's oscrypto 13library. An enormous debt is owed to him for blazing this trail for us. For 14that reason, this code should be considered to be covered both by urllib3's 15license and by oscrypto's: 16 17 Copyright (c) 2015-2016 Will Bond <will@wbond.net> 18 19 Permission is hereby granted, free of charge, to any person obtaining a 20 copy of this software and associated documentation files (the "Software"), 21 to deal in the Software without restriction, including without limitation 22 the rights to use, copy, modify, merge, publish, distribute, sublicense, 23 and/or sell copies of the Software, and to permit persons to whom the 24 Software is furnished to do so, subject to the following conditions: 25 26 The above copyright notice and this permission notice shall be included in 27 all copies or substantial portions of the Software. 28 29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 34 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 35 DEALINGS IN THE SOFTWARE. 36""" 37from __future__ import absolute_import 38 39import platform 40from ctypes import ( 41 CDLL, 42 CFUNCTYPE, 43 POINTER, 44 c_bool, 45 c_byte, 46 c_char_p, 47 c_int32, 48 c_long, 49 c_size_t, 50 c_uint32, 51 c_ulong, 52 c_void_p, 53) 54from ctypes.util import find_library 55 56from oci._vendor.urllib3.packages.six import raise_from 57 58if platform.system() != "Darwin": 59 raise ImportError("Only macOS is supported") 60 61version = platform.mac_ver()[0] 62version_info = tuple(map(int, version.split("."))) 63if version_info < (10, 8): 64 raise OSError( 65 "Only OS X 10.8 and newer are supported, not %s.%s" 66 % (version_info[0], version_info[1]) 67 ) 68 69 70def load_cdll(name, macos10_16_path): 71 """Loads a CDLL by name, falling back to known path on 10.16+""" 72 try: 73 # Big Sur is technically 11 but we use 10.16 due to the Big Sur 74 # beta being labeled as 10.16. 75 if version_info >= (10, 16): 76 path = macos10_16_path 77 else: 78 path = find_library(name) 79 if not path: 80 raise OSError # Caught and reraised as 'ImportError' 81 return CDLL(path, use_errno=True) 82 except OSError: 83 raise_from(ImportError("The library %s failed to load" % name), None) 84 85 86Security = load_cdll( 87 "Security", "/System/Library/Frameworks/Security.framework/Security" 88) 89CoreFoundation = load_cdll( 90 "CoreFoundation", 91 "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", 92) 93 94 95Boolean = c_bool 96CFIndex = c_long 97CFStringEncoding = c_uint32 98CFData = c_void_p 99CFString = c_void_p 100CFArray = c_void_p 101CFMutableArray = c_void_p 102CFDictionary = c_void_p 103CFError = c_void_p 104CFType = c_void_p 105CFTypeID = c_ulong 106 107CFTypeRef = POINTER(CFType) 108CFAllocatorRef = c_void_p 109 110OSStatus = c_int32 111 112CFDataRef = POINTER(CFData) 113CFStringRef = POINTER(CFString) 114CFArrayRef = POINTER(CFArray) 115CFMutableArrayRef = POINTER(CFMutableArray) 116CFDictionaryRef = POINTER(CFDictionary) 117CFArrayCallBacks = c_void_p 118CFDictionaryKeyCallBacks = c_void_p 119CFDictionaryValueCallBacks = c_void_p 120 121SecCertificateRef = POINTER(c_void_p) 122SecExternalFormat = c_uint32 123SecExternalItemType = c_uint32 124SecIdentityRef = POINTER(c_void_p) 125SecItemImportExportFlags = c_uint32 126SecItemImportExportKeyParameters = c_void_p 127SecKeychainRef = POINTER(c_void_p) 128SSLProtocol = c_uint32 129SSLCipherSuite = c_uint32 130SSLContextRef = POINTER(c_void_p) 131SecTrustRef = POINTER(c_void_p) 132SSLConnectionRef = c_uint32 133SecTrustResultType = c_uint32 134SecTrustOptionFlags = c_uint32 135SSLProtocolSide = c_uint32 136SSLConnectionType = c_uint32 137SSLSessionOption = c_uint32 138 139 140try: 141 Security.SecItemImport.argtypes = [ 142 CFDataRef, 143 CFStringRef, 144 POINTER(SecExternalFormat), 145 POINTER(SecExternalItemType), 146 SecItemImportExportFlags, 147 POINTER(SecItemImportExportKeyParameters), 148 SecKeychainRef, 149 POINTER(CFArrayRef), 150 ] 151 Security.SecItemImport.restype = OSStatus 152 153 Security.SecCertificateGetTypeID.argtypes = [] 154 Security.SecCertificateGetTypeID.restype = CFTypeID 155 156 Security.SecIdentityGetTypeID.argtypes = [] 157 Security.SecIdentityGetTypeID.restype = CFTypeID 158 159 Security.SecKeyGetTypeID.argtypes = [] 160 Security.SecKeyGetTypeID.restype = CFTypeID 161 162 Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef] 163 Security.SecCertificateCreateWithData.restype = SecCertificateRef 164 165 Security.SecCertificateCopyData.argtypes = [SecCertificateRef] 166 Security.SecCertificateCopyData.restype = CFDataRef 167 168 Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] 169 Security.SecCopyErrorMessageString.restype = CFStringRef 170 171 Security.SecIdentityCreateWithCertificate.argtypes = [ 172 CFTypeRef, 173 SecCertificateRef, 174 POINTER(SecIdentityRef), 175 ] 176 Security.SecIdentityCreateWithCertificate.restype = OSStatus 177 178 Security.SecKeychainCreate.argtypes = [ 179 c_char_p, 180 c_uint32, 181 c_void_p, 182 Boolean, 183 c_void_p, 184 POINTER(SecKeychainRef), 185 ] 186 Security.SecKeychainCreate.restype = OSStatus 187 188 Security.SecKeychainDelete.argtypes = [SecKeychainRef] 189 Security.SecKeychainDelete.restype = OSStatus 190 191 Security.SecPKCS12Import.argtypes = [ 192 CFDataRef, 193 CFDictionaryRef, 194 POINTER(CFArrayRef), 195 ] 196 Security.SecPKCS12Import.restype = OSStatus 197 198 SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) 199 SSLWriteFunc = CFUNCTYPE( 200 OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t) 201 ) 202 203 Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc] 204 Security.SSLSetIOFuncs.restype = OSStatus 205 206 Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t] 207 Security.SSLSetPeerID.restype = OSStatus 208 209 Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef] 210 Security.SSLSetCertificate.restype = OSStatus 211 212 Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean] 213 Security.SSLSetCertificateAuthorities.restype = OSStatus 214 215 Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef] 216 Security.SSLSetConnection.restype = OSStatus 217 218 Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t] 219 Security.SSLSetPeerDomainName.restype = OSStatus 220 221 Security.SSLHandshake.argtypes = [SSLContextRef] 222 Security.SSLHandshake.restype = OSStatus 223 224 Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] 225 Security.SSLRead.restype = OSStatus 226 227 Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] 228 Security.SSLWrite.restype = OSStatus 229 230 Security.SSLClose.argtypes = [SSLContextRef] 231 Security.SSLClose.restype = OSStatus 232 233 Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)] 234 Security.SSLGetNumberSupportedCiphers.restype = OSStatus 235 236 Security.SSLGetSupportedCiphers.argtypes = [ 237 SSLContextRef, 238 POINTER(SSLCipherSuite), 239 POINTER(c_size_t), 240 ] 241 Security.SSLGetSupportedCiphers.restype = OSStatus 242 243 Security.SSLSetEnabledCiphers.argtypes = [ 244 SSLContextRef, 245 POINTER(SSLCipherSuite), 246 c_size_t, 247 ] 248 Security.SSLSetEnabledCiphers.restype = OSStatus 249 250 Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)] 251 Security.SSLGetNumberEnabledCiphers.restype = OSStatus 252 253 Security.SSLGetEnabledCiphers.argtypes = [ 254 SSLContextRef, 255 POINTER(SSLCipherSuite), 256 POINTER(c_size_t), 257 ] 258 Security.SSLGetEnabledCiphers.restype = OSStatus 259 260 Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)] 261 Security.SSLGetNegotiatedCipher.restype = OSStatus 262 263 Security.SSLGetNegotiatedProtocolVersion.argtypes = [ 264 SSLContextRef, 265 POINTER(SSLProtocol), 266 ] 267 Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus 268 269 Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)] 270 Security.SSLCopyPeerTrust.restype = OSStatus 271 272 Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef] 273 Security.SecTrustSetAnchorCertificates.restype = OSStatus 274 275 Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean] 276 Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus 277 278 Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)] 279 Security.SecTrustEvaluate.restype = OSStatus 280 281 Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef] 282 Security.SecTrustGetCertificateCount.restype = CFIndex 283 284 Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex] 285 Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef 286 287 Security.SSLCreateContext.argtypes = [ 288 CFAllocatorRef, 289 SSLProtocolSide, 290 SSLConnectionType, 291 ] 292 Security.SSLCreateContext.restype = SSLContextRef 293 294 Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean] 295 Security.SSLSetSessionOption.restype = OSStatus 296 297 Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol] 298 Security.SSLSetProtocolVersionMin.restype = OSStatus 299 300 Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol] 301 Security.SSLSetProtocolVersionMax.restype = OSStatus 302 303 try: 304 Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef] 305 Security.SSLSetALPNProtocols.restype = OSStatus 306 except AttributeError: 307 # Supported only in 10.12+ 308 pass 309 310 Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] 311 Security.SecCopyErrorMessageString.restype = CFStringRef 312 313 Security.SSLReadFunc = SSLReadFunc 314 Security.SSLWriteFunc = SSLWriteFunc 315 Security.SSLContextRef = SSLContextRef 316 Security.SSLProtocol = SSLProtocol 317 Security.SSLCipherSuite = SSLCipherSuite 318 Security.SecIdentityRef = SecIdentityRef 319 Security.SecKeychainRef = SecKeychainRef 320 Security.SecTrustRef = SecTrustRef 321 Security.SecTrustResultType = SecTrustResultType 322 Security.SecExternalFormat = SecExternalFormat 323 Security.OSStatus = OSStatus 324 325 Security.kSecImportExportPassphrase = CFStringRef.in_dll( 326 Security, "kSecImportExportPassphrase" 327 ) 328 Security.kSecImportItemIdentity = CFStringRef.in_dll( 329 Security, "kSecImportItemIdentity" 330 ) 331 332 # CoreFoundation time! 333 CoreFoundation.CFRetain.argtypes = [CFTypeRef] 334 CoreFoundation.CFRetain.restype = CFTypeRef 335 336 CoreFoundation.CFRelease.argtypes = [CFTypeRef] 337 CoreFoundation.CFRelease.restype = None 338 339 CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef] 340 CoreFoundation.CFGetTypeID.restype = CFTypeID 341 342 CoreFoundation.CFStringCreateWithCString.argtypes = [ 343 CFAllocatorRef, 344 c_char_p, 345 CFStringEncoding, 346 ] 347 CoreFoundation.CFStringCreateWithCString.restype = CFStringRef 348 349 CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding] 350 CoreFoundation.CFStringGetCStringPtr.restype = c_char_p 351 352 CoreFoundation.CFStringGetCString.argtypes = [ 353 CFStringRef, 354 c_char_p, 355 CFIndex, 356 CFStringEncoding, 357 ] 358 CoreFoundation.CFStringGetCString.restype = c_bool 359 360 CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex] 361 CoreFoundation.CFDataCreate.restype = CFDataRef 362 363 CoreFoundation.CFDataGetLength.argtypes = [CFDataRef] 364 CoreFoundation.CFDataGetLength.restype = CFIndex 365 366 CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef] 367 CoreFoundation.CFDataGetBytePtr.restype = c_void_p 368 369 CoreFoundation.CFDictionaryCreate.argtypes = [ 370 CFAllocatorRef, 371 POINTER(CFTypeRef), 372 POINTER(CFTypeRef), 373 CFIndex, 374 CFDictionaryKeyCallBacks, 375 CFDictionaryValueCallBacks, 376 ] 377 CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef 378 379 CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef] 380 CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef 381 382 CoreFoundation.CFArrayCreate.argtypes = [ 383 CFAllocatorRef, 384 POINTER(CFTypeRef), 385 CFIndex, 386 CFArrayCallBacks, 387 ] 388 CoreFoundation.CFArrayCreate.restype = CFArrayRef 389 390 CoreFoundation.CFArrayCreateMutable.argtypes = [ 391 CFAllocatorRef, 392 CFIndex, 393 CFArrayCallBacks, 394 ] 395 CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef 396 397 CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p] 398 CoreFoundation.CFArrayAppendValue.restype = None 399 400 CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef] 401 CoreFoundation.CFArrayGetCount.restype = CFIndex 402 403 CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex] 404 CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p 405 406 CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( 407 CoreFoundation, "kCFAllocatorDefault" 408 ) 409 CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll( 410 CoreFoundation, "kCFTypeArrayCallBacks" 411 ) 412 CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( 413 CoreFoundation, "kCFTypeDictionaryKeyCallBacks" 414 ) 415 CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( 416 CoreFoundation, "kCFTypeDictionaryValueCallBacks" 417 ) 418 419 CoreFoundation.CFTypeRef = CFTypeRef 420 CoreFoundation.CFArrayRef = CFArrayRef 421 CoreFoundation.CFStringRef = CFStringRef 422 CoreFoundation.CFDictionaryRef = CFDictionaryRef 423 424except (AttributeError): 425 raise ImportError("Error initializing ctypes") 426 427 428class CFConst(object): 429 """ 430 A class object that acts as essentially a namespace for CoreFoundation 431 constants. 432 """ 433 434 kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) 435 436 437class SecurityConst(object): 438 """ 439 A class object that acts as essentially a namespace for Security constants. 440 """ 441 442 kSSLSessionOptionBreakOnServerAuth = 0 443 444 kSSLProtocol2 = 1 445 kSSLProtocol3 = 2 446 kTLSProtocol1 = 4 447 kTLSProtocol11 = 7 448 kTLSProtocol12 = 8 449 # SecureTransport does not support TLS 1.3 even if there's a constant for it 450 kTLSProtocol13 = 10 451 kTLSProtocolMaxSupported = 999 452 453 kSSLClientSide = 1 454 kSSLStreamType = 0 455 456 kSecFormatPEMSequence = 10 457 458 kSecTrustResultInvalid = 0 459 kSecTrustResultProceed = 1 460 # This gap is present on purpose: this was kSecTrustResultConfirm, which 461 # is deprecated. 462 kSecTrustResultDeny = 3 463 kSecTrustResultUnspecified = 4 464 kSecTrustResultRecoverableTrustFailure = 5 465 kSecTrustResultFatalTrustFailure = 6 466 kSecTrustResultOtherError = 7 467 468 errSSLProtocol = -9800 469 errSSLWouldBlock = -9803 470 errSSLClosedGraceful = -9805 471 errSSLClosedNoNotify = -9816 472 errSSLClosedAbort = -9806 473 474 errSSLXCertChainInvalid = -9807 475 errSSLCrypto = -9809 476 errSSLInternal = -9810 477 errSSLCertExpired = -9814 478 errSSLCertNotYetValid = -9815 479 errSSLUnknownRootCert = -9812 480 errSSLNoRootCert = -9813 481 errSSLHostNameMismatch = -9843 482 errSSLPeerHandshakeFail = -9824 483 errSSLPeerUserCancelled = -9839 484 errSSLWeakPeerEphemeralDHKey = -9850 485 errSSLServerAuthCompleted = -9841 486 errSSLRecordOverflow = -9847 487 488 errSecVerifyFailed = -67808 489 errSecNoTrustSettings = -25263 490 errSecItemNotFound = -25300 491 errSecInvalidTrustSettings = -25262 492 493 # Cipher suites. We only pick the ones our default cipher string allows. 494 # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values 495 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C 496 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 497 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B 498 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F 499 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9 500 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8 501 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F 502 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E 503 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 504 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 505 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A 506 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 507 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B 508 TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 509 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 510 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 511 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 512 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 513 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 514 TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 515 TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D 516 TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C 517 TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D 518 TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C 519 TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 520 TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F 521 TLS_AES_128_GCM_SHA256 = 0x1301 522 TLS_AES_256_GCM_SHA384 = 0x1302 523 TLS_AES_128_CCM_8_SHA256 = 0x1305 524 TLS_AES_128_CCM_SHA256 = 0x1304 525