2  * Copyright (c) 1999-2001,2005-2014 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * sslContext.c - SSLContext accessors 
  28 #include "SecureTransport.h" 
  30 #include "SSLRecordInternal.h" 
  31 #include "SecureTransportPriv.h" 
  33 #include "sslCipherSpecs.h" 
  34 #include "sslContext.h" 
  35 #include "sslCrypto.h" 
  37 #include "sslKeychain.h" 
  38 #include "sslMemory.h" 
  40 #include "tlsCallbacks.h" 
  42 #include <AssertMacros.h> 
  43 #include <CoreFoundation/CFData.h> 
  44 #include <CoreFoundation/CFPreferences.h> 
  45 #include <Security/SecCertificate.h> 
  46 #include <Security/SecCertificatePriv.h> 
  47 #include <Security/SecTrust.h> 
  48 #include <Security/SecTrustSettingsPriv.h> 
  49 #include <Security/oidsalg.h> 
  50 #include "utilities/SecCFRelease.h" 
  51 #include "utilities/SecCFWrappers.h" 
  56 #include <Security/SecCertificateInternal.h> 
  58 #include <Security/oidsalg.h> 
  59 #include <Security/oidscert.h> 
  60 #include <Security/SecTrustSettingsPriv.h> 
  64 static void sslFreeDnList(SSLContext 
*ctx
) 
  66     DNListElem      
*dn
, *nextDN
; 
  68     dn 
= ctx
->acceptableDNList
; 
  71         SSLFreeBuffer(&dn
->derDN
); 
  76     ctx
->acceptableDNList 
= NULL
; 
  79 Boolean 
sslIsSessionActive(const SSLContext 
*ctx
) 
  85                 case SSL_HdskStateUninit
: 
  86                 case SSL_HdskStateGracefulClose
: 
  87                 case SSL_HdskStateErrorClose
: 
  96  * Minimum and maximum supported versions 
  98 //#define MINIMUM_STREAM_VERSION  SSL_Version_2_0 /* Disabled */ 
  99 #define MINIMUM_STREAM_VERSION  SSL_Version_3_0 
 100 #define MAXIMUM_STREAM_VERSION  TLS_Version_1_2 
 101 #define MINIMUM_DATAGRAM_VERSION  DTLS_Version_1_0 
 103 /* This should be changed when we start supporting DTLS_Version_1_x */ 
 104 #define MAXIMUM_DATAGRAM_VERSION  DTLS_Version_1_0 
 106 #define SSL_ENABLE_ECDSA_SIGN_AUTH                      1 
 107 #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH          0 
 108 #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH        0 
 110 #define DEFAULT_DTLS_TIMEOUT    1 
 111 #define DEFAULT_DTLS_MTU        1400 
 112 #define MIN_ALLOWED_DTLS_MTU    64      /* this ensure than there will be no integer 
 113                                             underflow when calculating max write size */ 
 115 /* Preferences values */ 
 116 CFIndex kMinDhGroupSizeDefaultValue
; 
 117 CFIndex kMinProtocolVersionDefaultValue
; 
 118 CFStringRef kSSLSessionConfigDefaultValue
; 
 119 Boolean kSSLDisableRecordSplittingDefaultValue
; 
 121 static tls_cache_t g_session_cache 
= NULL
; 
 125  * Instead of using CFPropertyListReadFromFile we use a 
 126  * CFPropertyListCreateWithStream directly 
 127  * here. CFPropertyListReadFromFile() uses 
 128  * CFURLCopyResourcePropertyForKey() and CF pulls in CoreServices for 
 129  * CFURLCopyResourcePropertyForKey() and that doesn't work in install 
 132 static CFPropertyListRef
 
 133 CopyPlistFromFile(CFURLRef url
) 
 135     CFDictionaryRef d 
= NULL
; 
 136     CFReadStreamRef s 
= CFReadStreamCreateWithFile(kCFAllocatorDefault
, url
); 
 137     if (s 
&& CFReadStreamOpen(s
)) { 
 138         d 
= (CFDictionaryRef
)CFPropertyListCreateWithStream(kCFAllocatorDefault
, s
, 0, kCFPropertyListImmutable
, NULL
, NULL
); 
 148 CFTypeRef 
SSLPreferencesCopyValue(CFStringRef key
, CFPropertyListRef managed_prefs
) 
 150     CFTypeRef value 
= (CFTypeRef
) CFPreferencesCopyAppValue(CFSTR("SSLSessionConfig"), kCFPreferencesCurrentApplication
); 
 152     if(!value 
&& managed_prefs
) { 
 153         value 
=  CFDictionaryGetValue(managed_prefs
, key
); 
 162 CFIndex 
SSLPreferencesGetInteger(CFStringRef key
, CFPropertyListRef managed_prefs
) 
 164     CFTypeRef value 
= SSLPreferencesCopyValue(key
, managed_prefs
); 
 165     CFIndex int_value 
= 0; 
 166     if (isNumber(value
)) { 
 167         CFNumberGetValue(value
, kCFNumberCFIndexType
, &int_value
); 
 169     CFReleaseSafe(value
); 
 174 Boolean 
SSLPreferencesGetBoolean(CFStringRef key
, CFPropertyListRef managed_prefs
) 
 176     CFTypeRef value 
= SSLPreferencesCopyValue(key
, managed_prefs
); 
 177     Boolean bool_value 
= FALSE
; 
 178     if (isBoolean(value
)) { 
 179         bool_value 
= CFBooleanGetValue(value
); 
 182     CFReleaseSafe(value
); 
 187 CFStringRef 
SSLPreferencesCopyString(CFStringRef key
, CFPropertyListRef managed_prefs
) 
 189     CFTypeRef value 
= SSLPreferencesCopyValue(key
, managed_prefs
); 
 190     if (isString(value
)) { 
 193         CFReleaseSafe(value
); 
 198 static void _SSLContextReadDefault() 
 200     CFPropertyListRef managed_prefs 
= NULL
; 
 203     /* on iOS, we also look for preferences from mobile's Managed Preferences */ 
 204     /* Note that if the process is running as mobile, the above call will already have read the Managed Preference plist. 
 205      As a result, if you have some preferences set manually with defaults, which preference applies may be different for mobile vs not-mobile. */ 
 206     CFURLRef prefURL 
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, CFSTR("/Library/Managed Preferences/mobile/.GlobalPreferences.plist"), kCFURLPOSIXPathStyle
, false); 
 208         managed_prefs 
= CopyPlistFromFile(prefURL
); 
 210     CFReleaseSafe(prefURL
); 
 213     /* Disable record splitting */ 
 214     /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */ 
 215     kSSLDisableRecordSplittingDefaultValue 
= SSLPreferencesGetBoolean(CFSTR("SSLDisableRecordSplitting"), managed_prefs
); 
 217     /* Min DH Group Size */ 
 218     kMinDhGroupSizeDefaultValue 
= SSLPreferencesGetInteger(CFSTR("SSLMinDhGroupSize"), managed_prefs
); 
 220     /* Default Min Prototcol Version */ 
 221     kMinProtocolVersionDefaultValue 
= SSLPreferencesGetInteger(CFSTR("SSLMinProtocolVersion"), managed_prefs
); 
 224     kSSLSessionConfigDefaultValue 
= SSLPreferencesCopyString(CFSTR("SSLSessionConfig"), managed_prefs
); 
 226     CFReleaseSafe(managed_prefs
); 
 229 /* This functions initialize global variables, run once per process */ 
 230 static void SSLContextOnce(void) 
 232     _SSLContextReadDefault(); 
 233     g_session_cache 
= tls_cache_create(); 
 236 CFGiblisWithHashFor(SSLContext
) 
 239 SSLNewContext                           (Boolean                        isServer
, 
 240                                                          SSLContextRef          
*contextPtr
)    /* RETURNED */ 
 242         if(contextPtr 
== NULL
) { 
 246         *contextPtr 
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
); 
 248         if (*contextPtr 
== NULL
) 
 249                 return errSecAllocate
; 
 251         return errSecSuccess
; 
 254 SSLContextRef 
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
) 
 257     SSLRecordContextRef recCtx
; 
 259     ctx 
= SSLCreateContextWithRecordFuncs(alloc
, protocolSide
, connectionType
, &SSLRecordLayerInternal
); 
 264     recCtx 
= SSLCreateInternalRecordLayer(ctx
); 
 270     SSLSetRecordContext(ctx
, recCtx
); 
 275 SSLContextRef 
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
, const struct SSLRecordFuncs 
*recFuncs
) 
 277         SSLContext  
*ctx 
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
); 
 283         /* subsequent errors to errOut: */ 
 284     memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
)); 
 287     ctx
->hdsk 
= tls_handshake_create(connectionType
==kSSLDatagramType
, protocolSide
==kSSLServerSide
); 
 288     if(ctx
->hdsk 
== NULL
) { 
 293     static dispatch_once_t onceToken
; 
 294     dispatch_once(&onceToken
, ^{ 
 298     ctx
->cache 
= g_session_cache
; 
 300     tls_handshake_set_callbacks(ctx
->hdsk
, 
 301                                 &tls_handshake_callbacks
, 
 304     ctx
->isDTLS 
= (connectionType
==kSSLDatagramType
); 
 306     ctx
->state 
= SSL_HdskStateUninit
; 
 307     ctx
->timeout_duration 
= DEFAULT_DTLS_TIMEOUT
; 
 308     ctx
->mtu 
= DEFAULT_DTLS_MTU
; 
 310     tls_handshake_get_min_protocol_version(ctx
->hdsk
, &ctx
->minProtocolVersion
); 
 311     tls_handshake_get_max_protocol_version(ctx
->hdsk
, &ctx
->maxProtocolVersion
); 
 313     if(protocolSide 
== kSSLClientSide
) { 
 314         tls_handshake_set_sct_enable(ctx
->hdsk
, true); 
 315         tls_handshake_set_ocsp_enable(ctx
->hdsk
, true); 
 318         ctx
->negProtocolVersion 
= SSL_Version_Undetermined
; 
 319     ctx
->protocolSide 
= protocolSide
; 
 320     ctx
->recFuncs 
= recFuncs
; 
 322         /* Initial cert verify state: verify with default system roots */ 
 323         ctx
->enableCertVerify 
= true; 
 325         /* Default for RSA blinding is ENABLED */ 
 326         ctx
->rsaBlindingEnable 
= true; 
 328         /* Default for sending one-byte app data record is ENABLED */ 
 329     ctx
->oneByteRecordEnable 
= !kSSLDisableRecordSplittingDefaultValue
; 
 331     /* Dont enable fallback behavior by default */ 
 332     ctx
->fallbackEnabled 
= false; 
 334     if(kSSLSessionConfigDefaultValue
) { 
 335         SSLSetSessionConfig(ctx
, kSSLSessionConfigDefaultValue
); 
 338     if(kMinDhGroupSizeDefaultValue
) { 
 339         tls_handshake_set_min_dh_group_size(ctx
->hdsk
, (unsigned)kMinDhGroupSizeDefaultValue
); 
 342     if(kMinProtocolVersionDefaultValue
) { 
 343         SSLSetProtocolVersionMin(ctx
, (unsigned)kMinProtocolVersionDefaultValue
); 
 346         /* default for anonymous ciphers is DISABLED */ 
 347         ctx
->anonCipherEnable 
= false; 
 349     ctx
->breakOnServerAuth 
= false; 
 350     ctx
->breakOnCertRequest 
= false; 
 351     ctx
->breakOnClientAuth 
= false; 
 352     ctx
->signalServerAuth 
= false; 
 353     ctx
->signalCertRequest 
= false; 
 354     ctx
->signalClientAuth 
= false; 
 360 SSLNewDatagramContext       (Boolean                    isServer
, 
 361                                                          SSLContextRef          
*contextPtr
)    /* RETURNED */ 
 363         if (contextPtr 
== NULL
) 
 365         *contextPtr 
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
); 
 366         if (*contextPtr 
== NULL
) 
 367                 return errSecAllocate
; 
 368     return errSecSuccess
; 
 372  * Dispose of an SSLContext. (private) 
 373  * This function is invoked after our dispatch queue is safely released, 
 374  * or directly from SSLDisposeContext if there is no dispatch queue. 
 377 SSLDisposeContext                               (SSLContextRef context
) 
 379     if(context 
== NULL
) { 
 383         return errSecSuccess
; 
 386 CFStringRef 
SSLContextCopyFormatDescription(CFTypeRef arg
, CFDictionaryRef formatOptions
) 
 388     SSLContext
* ctx 
= (SSLContext
*) arg
; 
 393                 CFStringRef result 
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
); 
 398 Boolean 
SSLContextCompare(CFTypeRef a
, CFTypeRef b
) 
 403 CFHashCode 
SSLContextHash(CFTypeRef arg
) 
 405         return (CFHashCode
) arg
; 
 408 void SSLContextDestroy(CFTypeRef arg
) 
 410         SSLContext
* ctx 
= (SSLContext
*) arg
; 
 412     /* destroy the coreTLS handshake object */ 
 413     tls_handshake_destroy(ctx
->hdsk
); 
 415     /* Only destroy if we were using the internal record layer */ 
 416     if(ctx
->recFuncs
==&SSLRecordLayerInternal
) 
 417         SSLDestroyInternalRecordLayer(ctx
->recCtx
); 
 419     SSLFreeBuffer(&ctx
->sessionTicket
); 
 420     SSLFreeBuffer(&ctx
->sessionID
); 
 421     SSLFreeBuffer(&ctx
->peerID
); 
 422     SSLFreeBuffer(&ctx
->resumableSession
); 
 423     SSLFreeBuffer(&ctx
->receivedDataBuffer
); 
 425     CFReleaseSafe(ctx
->acceptableCAs
); 
 426 #if !TARGET_OS_IPHONE 
 427     CFReleaseSafe(ctx
->trustedLeafCerts
); 
 429     CFReleaseSafe(ctx
->localCertArray
); 
 430     CFReleaseSafe(ctx
->encryptCertArray
); 
 431     CFReleaseSafe(ctx
->trustedCerts
); 
 432     CFReleaseSafe(ctx
->peerSecTrust
); 
 436     SSLFreeBuffer(&ctx
->ownVerifyData
); 
 437     SSLFreeBuffer(&ctx
->peerVerifyData
); 
 439     SSLFreeBuffer(&ctx
->pskIdentity
); 
 440     SSLFreeBuffer(&ctx
->pskSharedSecret
); 
 442     SSLFreeBuffer(&ctx
->dhParamsEncoded
); 
 445         tls_cache_cleanup(ctx
->cache
); 
 447     memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
)); 
 451  * Determine the state of an SSL session. 
 454 SSLGetSessionState                      (SSLContextRef          context
, 
 455                                                          SSLSessionState        
*state
)         /* RETURNED */ 
 457         SSLSessionState rtnState 
= kSSLIdle
; 
 459         if(context 
== NULL
) { 
 463         switch(context
->state
) { 
 464                 case SSL_HdskStateUninit
: 
 467                 case SSL_HdskStateGracefulClose
: 
 468                         rtnState 
= kSSLClosed
; 
 470                 case SSL_HdskStateErrorClose
: 
 471                 case SSL_HdskStateNoNotifyClose
: 
 472                         rtnState 
= kSSLAborted
; 
 474                 case SSL_HdskStateReady
: 
 475                         rtnState 
= kSSLConnected
; 
 477         case SSL_HdskStatePending
: 
 478                         rtnState 
= kSSLHandshake
; 
 482         return errSecSuccess
; 
 486  * Set options for an SSL session. 
 489 SSLSetSessionOption                     (SSLContextRef          context
, 
 490                                                          SSLSessionOption       option
, 
 493     if(context 
== NULL
) { 
 496     if(sslIsSessionActive(context
)) { 
 497         /* can't do this with an active session */ 
 501         case kSSLSessionOptionBreakOnServerAuth
: 
 502             context
->breakOnServerAuth 
= value
; 
 503             context
->enableCertVerify 
= !value
; 
 505         case kSSLSessionOptionBreakOnCertRequested
: 
 506             context
->breakOnCertRequest 
= value
; 
 508         case kSSLSessionOptionBreakOnClientAuth
: 
 509             context
->breakOnClientAuth 
= value
; 
 510             context
->enableCertVerify 
= !value
; 
 512         case kSSLSessionOptionSendOneByteRecord
: 
 513             /* Only call the record layer function if the value changed */ 
 514             if(value 
!= context
->oneByteRecordEnable
) 
 515                 context
->recFuncs
->setOption(context
->recCtx
, kSSLRecordOptionSendOneByteRecord
, value
); 
 516             context
->oneByteRecordEnable 
= value
; 
 518         case kSSLSessionOptionFalseStart
: 
 519             context
->falseStartEnabled 
= value
; 
 521         case kSSLSessionOptionFallback
: 
 522             tls_handshake_set_fallback(context
->hdsk
, value
); 
 523             context
->fallbackEnabled 
= value
; 
 525         case kSSLSessionOptionBreakOnClientHello
: 
 526             context
->breakOnClientHello 
= value
; 
 528         case kSSLSessionOptionAllowServerIdentityChange
: 
 529             tls_handshake_set_server_identity_change(context
->hdsk
, value
); 
 531         case kSSLSessionOptionAllowRenegotiation
: 
 532             tls_handshake_set_renegotiation(context
->hdsk
, value
); 
 538     return errSecSuccess
; 
 542  * Determine current value for the specified option in an SSL session. 
 545 SSLGetSessionOption                     (SSLContextRef          context
, 
 546                                                          SSLSessionOption       option
, 
 549     if(context 
== NULL 
|| value 
== NULL
) { 
 553         case kSSLSessionOptionBreakOnServerAuth
: 
 554             *value 
= context
->breakOnServerAuth
; 
 556         case kSSLSessionOptionBreakOnCertRequested
: 
 557             *value 
= context
->breakOnCertRequest
; 
 559         case kSSLSessionOptionBreakOnClientAuth
: 
 560             *value 
= context
->breakOnClientAuth
; 
 562         case kSSLSessionOptionSendOneByteRecord
: 
 563             *value 
= context
->oneByteRecordEnable
; 
 565         case kSSLSessionOptionFalseStart
: 
 566             *value 
= context
->falseStartEnabled
; 
 568         case kSSLSessionOptionBreakOnClientHello
: 
 569             *value 
= context
->breakOnClientHello
; 
 571         case kSSLSessionOptionAllowServerIdentityChange
: 
 572             tls_handshake_get_server_identity_change(context
->hdsk
, (bool *)value
); 
 578     return errSecSuccess
; 
 582 SSLSetRecordContext         (SSLContextRef          ctx
, 
 583                              SSLRecordContextRef    recCtx
) 
 588         if(sslIsSessionActive(ctx
)) { 
 589                 /* can't do this with an active session */ 
 592     ctx
->recCtx 
= recCtx
; 
 593     return errSecSuccess
; 
 597 SSLSetIOFuncs                           (SSLContextRef          ctx
, 
 598                                                          SSLReadFunc            readFunc
, 
 599                                                          SSLWriteFunc           writeFunc
) 
 604     if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) { 
 605         /* Can Only do this with the internal record layer */ 
 609         if(sslIsSessionActive(ctx
)) { 
 610                 /* can't do this with an active session */ 
 614     ctx
->ioCtx
.read
=readFunc
; 
 615     ctx
->ioCtx
.write
=writeFunc
; 
 621 SSLSetNPNFunc(SSLContextRef      context
, 
 625     if (context 
== NULL
) { 
 628         if (sslIsSessionActive(context
)) { 
 631     context
->npnFunc 
= npnFunc
; 
 632     context
->npnFuncInfo 
= info
; 
 633     if(context
->protocolSide
==kSSLClientSide
) { 
 634         tls_handshake_set_npn_enable(context
->hdsk
, npnFunc
!=NULL
); 
 639 SSLSetNPNData(SSLContextRef      context
, 
 643     if (context 
== NULL 
|| data 
== NULL 
|| length 
== 0) { 
 653     npn_data
.data 
= (uint8_t *)data
; 
 654     npn_data
.length 
= length
; 
 656     return tls_handshake_set_npn_data(context
->hdsk
, npn_data
); 
 660 SSLGetNPNData(SSLContextRef      context
, 
 663         if (context 
== NULL 
|| length 
== NULL
) 
 666     const tls_buffer 
*npn_data
; 
 668     npn_data 
= tls_handshake_get_peer_npn_data(context
->hdsk
); 
 671         *length 
= npn_data
->length
; 
 672         return npn_data
->data
; 
 681 SSLSetALPNFunc(SSLContextRef      context
, 
 682                SSLALPNFunc        alpnFunc
, 
 685     if (context 
== NULL
) { 
 688     if (sslIsSessionActive(context
)) { 
 691     context
->alpnFunc 
= alpnFunc
; 
 692     context
->alpnFuncInfo 
= info
; 
 693     if(context
->protocolSide
==kSSLServerSide
) { 
 699 SSLSetALPNData(SSLContextRef      context
, 
 703     if (context 
== NULL 
|| data 
== NULL 
|| length 
== 0) { 
 711     tls_buffer alpn_data
; 
 713     alpn_data
.data 
= (uint8_t *)data
; 
 714     alpn_data
.length 
= length
; 
 716     return tls_handshake_set_alpn_data(context
->hdsk
, alpn_data
); 
 720 SSLGetALPNData(SSLContextRef      context
, 
 723     if (context 
== NULL 
|| length 
== NULL
) 
 726     const tls_buffer 
*alpn_data
; 
 728     alpn_data 
= tls_handshake_get_peer_alpn_data(context
->hdsk
); 
 731         *length 
= alpn_data
->length
; 
 732         return alpn_data
->data
; 
 741 SSLSetConnection                        (SSLContextRef          ctx
, 
 742                                                          SSLConnectionRef       connection
) 
 747     if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) { 
 748         /* Can Only do this with the internal record layer */ 
 752         if(sslIsSessionActive(ctx
)) { 
 753                 /* can't do this with an active session */ 
 757     /* Need to keep a copy of it this layer for the Get function */ 
 758     ctx
->ioCtx
.ioRef 
= connection
; 
 764 SSLGetConnection                        (SSLContextRef          ctx
, 
 765                                                          SSLConnectionRef       
*connection
) 
 767         if((ctx 
== NULL
) || (connection 
== NULL
)) { 
 770         *connection 
= ctx
->ioCtx
.ioRef
; 
 771         return errSecSuccess
; 
 775 SSLSetPeerDomainName            (SSLContextRef          ctx
, 
 776                                                          const char                     *peerName
, 
 782         if(sslIsSessionActive(ctx
)) { 
 783                 /* can't do this with an active session */ 
 787     if(ctx
->protocolSide 
== kSSLClientSide
) { 
 788         return tls_handshake_set_peer_hostname(ctx
->hdsk
, peerName
, peerNameLen
); 
 790         return 0; // This should probably return an error, but historically didnt. 
 795  * Determine the buffer size needed for SSLGetPeerDomainName(). 
 798 SSLGetPeerDomainNameLength      (SSLContextRef          ctx
, 
 799                                                          size_t                         *peerNameLen
)   // RETURNED 
 804     const char *hostname
; 
 806     return tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, peerNameLen
); 
 810 SSLGetPeerDomainName            (SSLContextRef          ctx
, 
 811                                                          char                           *peerName
,              // returned here 
 812                                                          size_t                         *peerNameLen
)   // IN/OUT 
 814     const char *hostname
; 
 823     err
=tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
); 
 827     } else if(*peerNameLen
<len
) { 
 828         return errSSLBufferOverflow
; 
 830         memcpy(peerName
, hostname
, len
); 
 837 SSLCopyRequestedPeerNameLength  (SSLContextRef          ctx
, 
 838                                  size_t                         *peerNameLen
)   // RETURNED 
 840     const tls_buffer 
*hostname
; 
 844     hostname 
= tls_handshake_get_sni_hostname(ctx
->hdsk
); 
 848         *peerNameLen 
= hostname
->length
; 
 854 SSLCopyRequestedPeerName    (SSLContextRef              ctx
, 
 855                              char                               *peerName
,              // returned here 
 856                              size_t                             *peerNameLen
)   // IN/OUT 
 858     const tls_buffer 
*hostname
; 
 864     hostname 
= tls_handshake_get_sni_hostname(ctx
->hdsk
); 
 868     } else if(*peerNameLen 
< hostname
->length
) { 
 869         return errSSLBufferOverflow
; 
 871         memcpy(peerName
, hostname
->data
, hostname
->length
); 
 872         *peerNameLen 
= hostname
->length
; 
 879 SSLSetDatagramHelloCookie   (SSLContextRef      ctx
, 
 889     if(!ctx
->isDTLS
) return errSecParam
; 
 891         if((ctx 
== NULL
) || (cookieLen
>32)) { 
 894         if(sslIsSessionActive(ctx
)) { 
 895                 /* can't do this with an active session */ 
 899         /* free possible existing cookie */ 
 900         if(ctx
->dtlsCookie
.data
) { 
 901         SSLFreeBuffer(&ctx
->dtlsCookie
); 
 905     if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
))) 
 908         memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
); 
 909     return errSecSuccess
; 
 913 SSLSetMaxDatagramRecordSize (SSLContextRef              ctx
, 
 917     if(ctx 
== NULL
) return errSecParam
; 
 918     if(!ctx
->isDTLS
) return errSecParam
; 
 920     tls_handshake_set_mtu(ctx
->hdsk
, maxSize
); 
 922     return errSecSuccess
; 
 926 SSLGetMaxDatagramRecordSize (SSLContextRef              ctx
, 
 929     if(ctx 
== NULL
) return errSecParam
; 
 930     if(!ctx
->isDTLS
) return errSecParam
; 
 934     return errSecSuccess
; 
 939  Keys to to math below: 
 941  A DTLS record looks like this: | header (13 bytes) | fragment | 
 943  For Null cipher, fragment is clear text as follows: 
 946  For block cipher, fragment size must be a multiple of the cipher block size, and is the 
 947  encryption of the following plaintext : 
 948  | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) | 
 950  The maximum content length in that case is achieved for 0 padding bytes. 
 955 SSLGetDatagramWriteSize         (SSLContextRef ctx
, 
 958     if(ctx 
== NULL
) return errSecParam
; 
 959     if(!ctx
->isDTLS
) return errSecParam
; 
 960     if(bufSize 
== NULL
) return errSecParam
; 
 962     size_t max_fragment_size 
= ctx
->mtu
-13; /* 13 = dtls record header */ 
 965     SSLCipherSpecParams 
*currCipher 
= &ctx
->selectedCipherSpecParams
; 
 967     size_t blockSize 
= currCipher
->blockSize
; 
 968     size_t macSize 
= currCipher
->macSize
; 
 970     size_t blockSize 
= 16; 
 975         /* max_fragment_size must be a multiple of blocksize */ 
 976         max_fragment_size 
= max_fragment_size 
& ~(blockSize
-1); 
 977         max_fragment_size 
-= blockSize
; /* 1 block for IV */ 
 978         max_fragment_size 
-= 1; /* 1 byte for pad length */ 
 981     /* less the mac size */ 
 982     max_fragment_size 
-= macSize
; 
 984     /* Thats just a sanity check */ 
 985     assert(max_fragment_size
<ctx
->mtu
); 
 987     *bufSize 
= max_fragment_size
; 
 989     return errSecSuccess
; 
 993  All the complexity around protocol version is to support legacy APIs. 
 994  Eventually that should go away: 
 995  <rdar://problem/20842025> Remove deprecated SecureTransport function related to protocol version selection. 
 998 static tls_protocol_version 
SSLProtocolToProtocolVersion(SSLProtocol protocol
) { 
1000         case kSSLProtocol2
:             return SSL_Version_2_0
; 
1001         case kSSLProtocol3
:             return tls_protocol_version_SSL_3
; 
1002         case kTLSProtocol1
:             return tls_protocol_version_TLS_1_0
; 
1003         case kTLSProtocol11
:            return tls_protocol_version_TLS_1_1
; 
1004         case kTLSProtocol12
:            return tls_protocol_version_TLS_1_2
; 
1005         case kDTLSProtocol1
:            return tls_protocol_version_DTLS_1_0
; 
1006         default:                        return tls_protocol_version_Undertermined
; 
1010 /* concert between private SSLProtocolVersion and public SSLProtocol */ 
1011 static SSLProtocol 
SSLProtocolVersionToProtocol(SSLProtocolVersion version
) 
1014                 case tls_protocol_version_SSL_3
:     return kSSLProtocol3
; 
1015                 case tls_protocol_version_TLS_1_0
:   return kTLSProtocol1
; 
1016                 case tls_protocol_version_TLS_1_1
:   return kTLSProtocol11
; 
1017                 case tls_protocol_version_TLS_1_2
:   return kTLSProtocol12
; 
1018                 case tls_protocol_version_DTLS_1_0
:  return kDTLSProtocol1
; 
1020                         sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n", 
1023                 case tls_protocol_version_Undertermined
:  return kSSLProtocolUnknown
; 
1028 SSLSetProtocolVersionMin  (SSLContextRef      ctx
, 
1029                            SSLProtocol        minVersion
) 
1031     if(ctx 
== NULL
) return errSecParam
; 
1033     tls_protocol_version version 
= SSLProtocolToProtocolVersion(minVersion
); 
1035         if (version 
> MINIMUM_DATAGRAM_VERSION 
|| 
1036             version 
< MAXIMUM_DATAGRAM_VERSION
) 
1037             return errSSLIllegalParam
; 
1038         if (version 
< ctx
->maxProtocolVersion
) 
1039             ctx
->maxProtocolVersion 
= version
; 
1041         if (version 
< MINIMUM_STREAM_VERSION 
|| version 
> MAXIMUM_STREAM_VERSION
) 
1042             return errSSLIllegalParam
; 
1043         if (version 
> ctx
->maxProtocolVersion
) 
1044             ctx
->maxProtocolVersion 
= version
; 
1046     ctx
->minProtocolVersion 
= version
; 
1048     tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
); 
1049     tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
); 
1051     return errSecSuccess
; 
1055 SSLGetProtocolVersionMin  (SSLContextRef      ctx
, 
1056                            SSLProtocol        
*minVersion
) 
1058     if(ctx 
== NULL
) return errSecParam
; 
1060     *minVersion 
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
); 
1061     return errSecSuccess
; 
1065 SSLSetProtocolVersionMax  (SSLContextRef      ctx
, 
1066                            SSLProtocol        maxVersion
) 
1068     if(ctx 
== NULL
) return errSecParam
; 
1070     SSLProtocolVersion version 
= SSLProtocolToProtocolVersion(maxVersion
); 
1072         if (version 
> MINIMUM_DATAGRAM_VERSION 
|| 
1073             version 
< MAXIMUM_DATAGRAM_VERSION
) 
1074             return errSSLIllegalParam
; 
1075         if (version 
> ctx
->minProtocolVersion
) 
1076             ctx
->minProtocolVersion 
= version
; 
1078         if (version 
< MINIMUM_STREAM_VERSION 
|| version 
> MAXIMUM_STREAM_VERSION
) 
1079             return errSSLIllegalParam
; 
1080         if (version 
< ctx
->minProtocolVersion
) 
1081             ctx
->minProtocolVersion 
= version
; 
1083     ctx
->maxProtocolVersion 
= version
; 
1085     tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
); 
1086     tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
); 
1088     return errSecSuccess
; 
1092 SSLGetProtocolVersionMax  (SSLContextRef      ctx
, 
1093                            SSLProtocol        
*maxVersion
) 
1095     if(ctx 
== NULL
) return errSecParam
; 
1097     *maxVersion 
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
); 
1098     return errSecSuccess
; 
1101 #define max(x,y) ((x)<(y)?(y):(x)) 
1104 SSLSetProtocolVersionEnabled(SSLContextRef     ctx
, 
1105                                                          SSLProtocol            protocol
, 
1111         if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) { 
1112                 /* Can't do this with an active session, nor with a DTLS session */ 
1113                 return errSecBadReq
; 
1115     if (protocol 
== kSSLProtocolAll
) { 
1117             ctx
->minProtocolVersion 
= MINIMUM_STREAM_VERSION
; 
1118             ctx
->maxProtocolVersion 
= MAXIMUM_STREAM_VERSION
; 
1120             ctx
->minProtocolVersion 
= SSL_Version_Undetermined
; 
1121             ctx
->maxProtocolVersion 
= SSL_Version_Undetermined
; 
1124                 SSLProtocolVersion version 
= SSLProtocolToProtocolVersion(protocol
); 
1126                         if (version 
< MINIMUM_STREAM_VERSION 
|| version 
> MAXIMUM_STREAM_VERSION
) { 
1129             if (version 
> ctx
->maxProtocolVersion
) { 
1130                 ctx
->maxProtocolVersion 
= version
; 
1131                 if (ctx
->minProtocolVersion 
== SSL_Version_Undetermined
) 
1132                     ctx
->minProtocolVersion 
= version
; 
1134             if (version 
< ctx
->minProtocolVersion
) { 
1135                 ctx
->minProtocolVersion 
= version
; 
1138                         if (version 
< SSL_Version_2_0 
|| version 
> MAXIMUM_STREAM_VERSION
) { 
1141                         /* Disabling a protocol version now resets the minimum acceptable 
1142                          * version to the next higher version. This means it's no longer 
1143                          * possible to enable a discontiguous set of protocol versions. 
1145                         SSLProtocolVersion nextVersion
; 
1147                                 case SSL_Version_2_0
: 
1148                                         nextVersion 
= SSL_Version_3_0
; 
1150                                 case SSL_Version_3_0
: 
1151                                         nextVersion 
= TLS_Version_1_0
; 
1153                                 case TLS_Version_1_0
: 
1154                                         nextVersion 
= TLS_Version_1_1
; 
1156                                 case TLS_Version_1_1
: 
1157                                         nextVersion 
= TLS_Version_1_2
; 
1159                                 case TLS_Version_1_2
: 
1161                                         nextVersion 
= SSL_Version_Undetermined
; 
1164                         ctx
->minProtocolVersion 
= max(ctx
->minProtocolVersion
, nextVersion
); 
1165                         if (ctx
->minProtocolVersion 
> ctx
->maxProtocolVersion
) { 
1166                                 ctx
->minProtocolVersion 
= SSL_Version_Undetermined
; 
1167                                 ctx
->maxProtocolVersion 
= SSL_Version_Undetermined
; 
1172     tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
); 
1173     tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
); 
1175         return errSecSuccess
; 
1179 SSLGetProtocolVersionEnabled(SSLContextRef              ctx
, 
1180                                                          SSLProtocol            protocol
, 
1181                                                          Boolean                        
*enable
)                /* RETURNED */ 
1187                 /* Can't do this with a DTLS session */ 
1188                 return errSecBadReq
; 
1194         case kTLSProtocol11
: 
1195         case kTLSProtocol12
: 
1197             SSLProtocolVersion version 
= SSLProtocolToProtocolVersion(protocol
); 
1198                         *enable 
= (ctx
->minProtocolVersion 
<= version
 
1199                        && ctx
->maxProtocolVersion 
>= version
); 
1202                 case kSSLProtocolAll
: 
1203             *enable 
= (ctx
->minProtocolVersion 
<= MINIMUM_STREAM_VERSION
 
1204                        && ctx
->maxProtocolVersion 
>= MAXIMUM_STREAM_VERSION
); 
1209         return errSecSuccess
; 
1214 SSLSetProtocolVersion           (SSLContextRef          ctx
, 
1215                                                          SSLProtocol            version
) 
1220         if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) { 
1221                 /* Can't do this with an active session, nor with a DTLS session */ 
1222                 return errSecBadReq
; 
1227                         /* this tells us to do our best, up to 3.0 */ 
1228             ctx
->minProtocolVersion 
= MINIMUM_STREAM_VERSION
; 
1229             ctx
->maxProtocolVersion 
= SSL_Version_3_0
; 
1231                 case kSSLProtocol3Only
: 
1232             ctx
->minProtocolVersion 
= SSL_Version_3_0
; 
1233             ctx
->maxProtocolVersion 
= SSL_Version_3_0
; 
1236                         /* this tells us to do our best, up to TLS, but allows 3.0 */ 
1237             ctx
->minProtocolVersion 
= MINIMUM_STREAM_VERSION
; 
1238             ctx
->maxProtocolVersion 
= TLS_Version_1_0
; 
1240         case kTLSProtocol1Only
: 
1241             ctx
->minProtocolVersion 
= TLS_Version_1_0
; 
1242             ctx
->maxProtocolVersion 
= TLS_Version_1_0
; 
1244         case kTLSProtocol11
: 
1245                         /* This tells us to do our best, up to TLS 1.1, currently also 
1246                allows 3.0 or TLS 1.0 */ 
1247             ctx
->minProtocolVersion 
= MINIMUM_STREAM_VERSION
; 
1248             ctx
->maxProtocolVersion 
= TLS_Version_1_1
; 
1250         case kTLSProtocol12
: 
1251         case kSSLProtocolAll
: 
1252                 case kSSLProtocolUnknown
: 
1253                         /* This tells us to do our best, up to TLS 1.2, currently also 
1254                allows 3.0 or TLS 1.0 or TLS 1.1 */ 
1255             ctx
->minProtocolVersion 
= MINIMUM_STREAM_VERSION
; 
1256             ctx
->maxProtocolVersion 
= MAXIMUM_STREAM_VERSION
; 
1262     tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
); 
1263     tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
); 
1265     return errSecSuccess
; 
1270 SSLGetProtocolVersion           (SSLContextRef          ctx
, 
1271                                                          SSLProtocol            
*protocol
)              /* RETURNED */ 
1276         /* translate array of booleans to public value; not all combinations 
1277          * are legal (i.e., meaningful) for this call */ 
1278     if (ctx
->maxProtocolVersion 
== MAXIMUM_STREAM_VERSION
) { 
1279         if(ctx
->minProtocolVersion 
== MINIMUM_STREAM_VERSION
) { 
1280             /* traditional 'all enabled' */ 
1281             *protocol 
= kSSLProtocolAll
; 
1282             return errSecSuccess
; 
1284         } else if (ctx
->maxProtocolVersion 
== TLS_Version_1_1
) { 
1285         if(ctx
->minProtocolVersion 
== MINIMUM_STREAM_VERSION
) { 
1286             /* traditional 'all enabled' */ 
1287             *protocol 
= kTLSProtocol11
; 
1288             return errSecSuccess
; 
1290         } else if (ctx
->maxProtocolVersion 
== TLS_Version_1_0
) { 
1291         if(ctx
->minProtocolVersion 
== MINIMUM_STREAM_VERSION
) { 
1292             /* TLS1.1 and below enabled */ 
1293             *protocol 
= kTLSProtocol1
; 
1294             return errSecSuccess
; 
1295         } else if(ctx
->minProtocolVersion 
== TLS_Version_1_0
) { 
1296                 *protocol 
= kTLSProtocol1Only
; 
1298         } else if(ctx
->maxProtocolVersion 
== SSL_Version_3_0
) { 
1299         if(ctx
->minProtocolVersion 
== MINIMUM_STREAM_VERSION
) { 
1300             /* Could also return kSSLProtocol3Only since 
1301                MINIMUM_STREAM_VERSION == SSL_Version_3_0. */ 
1302             *protocol 
= kSSLProtocol3
; 
1303                         return errSecSuccess
; 
1311 SSLGetNegotiatedProtocolVersion         (SSLContextRef          ctx
, 
1312                                                                          SSLProtocol            
*protocol
) /* RETURNED */ 
1317         *protocol 
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
); 
1318         return errSecSuccess
; 
1322 SSLSetEnableCertVerify          (SSLContextRef          ctx
, 
1323                                                          Boolean                        enableVerify
) 
1328         sslCertDebug("SSLSetEnableCertVerify %s", 
1329                 enableVerify 
? "true" : "false"); 
1330         if(sslIsSessionActive(ctx
)) { 
1331                 /* can't do this with an active session */ 
1332                 return errSecBadReq
; 
1334         ctx
->enableCertVerify 
= enableVerify
; 
1335         return errSecSuccess
; 
1339 SSLGetEnableCertVerify          (SSLContextRef          ctx
, 
1340                                                         Boolean                         
*enableVerify
) 
1345         *enableVerify 
= ctx
->enableCertVerify
; 
1346         return errSecSuccess
; 
1350 SSLSetAllowsExpiredCerts(SSLContextRef          ctx
, 
1351                                                  Boolean                        allowExpired
) 
1353     /* This has been deprecated since 10.9, and non-functional since at least 10.10 */ 
1358 SSLGetAllowsExpiredCerts        (SSLContextRef          ctx
, 
1359                                                          Boolean                        
*allowExpired
) 
1361     /* This has been deprecated since 10.9, and non-functional since at least 10.10 */ 
1362     return errSecUnimplemented
; 
1366 SSLSetAllowsExpiredRoots(SSLContextRef          ctx
, 
1367                                                  Boolean                        allowExpired
) 
1369     /* This has been deprecated since 10.9, and non-functional since at least 10.10 */ 
1374 SSLGetAllowsExpiredRoots        (SSLContextRef          ctx
, 
1375                                                          Boolean                        
*allowExpired
) 
1377     /* This has been deprecated since 10.9, and non-functional since at least 10.10 */ 
1378     return errSecUnimplemented
; 
1381 OSStatus 
SSLSetAllowsAnyRoot( 
1388         sslCertDebug("SSLSetAllowsAnyRoot %s",  anyRoot 
? "true" : "false"); 
1389         ctx
->allowAnyRoot 
= anyRoot
; 
1390         return errSecSuccess
; 
1394 SSLGetAllowsAnyRoot( 
1401         *anyRoot 
= ctx
->allowAnyRoot
; 
1402         return errSecSuccess
; 
1405 #if !TARGET_OS_IPHONE 
1406 /* obtain the system roots sets for this app, policy SSL */ 
1407 static OSStatus 
sslDefaultSystemRoots( 
1409         CFArrayRef 
*systemRoots
)                                // created and RETURNED 
1412     const char *hostname
; 
1415     tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
); 
1417         return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
, 
1420                 (ctx
->protocolSide 
== kSSLServerSide
) ? 
1421                         /* server verifies, client encrypts */ 
1422                         CSSM_KEYUSE_VERIFY 
: CSSM_KEYUSE_ENCRYPT
, 
1425 #endif /* OS X only */ 
1428 SSLSetTrustedRoots                      (SSLContextRef          ctx
, 
1429                                                          CFArrayRef             trustedRoots
, 
1430                                                          Boolean                        replaceExisting
) 
1432         if (sslIsSessionActive(ctx
)) { 
1433                 /* can't do this with an active session */ 
1434                 return errSecBadReq
; 
1436         sslCertDebug("SSLSetTrustedRoot  numCerts %d  replaceExist %s", 
1437                 (int)CFArrayGetCount(trustedRoots
), replaceExisting 
? "true" : "false"); 
1439     if (replaceExisting
) { 
1440         ctx
->trustedCertsOnly 
= true; 
1441         CFReleaseNull(ctx
->trustedCerts
); 
1444     if (ctx
->trustedCerts
) { 
1445         CFIndex count 
= CFArrayGetCount(trustedRoots
); 
1446         CFRange range 
= { 0, count 
}; 
1447         CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
); 
1449         require(ctx
->trustedCerts 
= 
1450             CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
), 
1454     return errSecSuccess
; 
1457     return errSecAllocate
; 
1461 SSLCopyTrustedRoots                     (SSLContextRef          ctx
, 
1462                                                          CFArrayRef             
*trustedRoots
)  /* RETURNED */ 
1464         if(ctx 
== NULL 
|| trustedRoots 
== NULL
) { 
1467         if(ctx
->trustedCerts 
!= NULL
) { 
1468                 *trustedRoots 
= ctx
->trustedCerts
; 
1469                 CFRetain(ctx
->trustedCerts
); 
1470                 return errSecSuccess
; 
1472 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) 
1473         /* use default system roots */ 
1474     return sslDefaultSystemRoots(ctx
, trustedRoots
); 
1476     *trustedRoots 
= NULL
; 
1477     return errSecSuccess
; 
1481 #if !TARGET_OS_IPHONE 
1483 SSLSetTrustedLeafCertificates   (SSLContextRef          ctx
, 
1484                                                                  CFArrayRef             trustedCerts
) 
1489         if(sslIsSessionActive(ctx
)) { 
1490                 /* can't do this with an active session */ 
1491                 return errSecBadReq
; 
1494         if(ctx
->trustedLeafCerts
) { 
1495                 CFRelease(ctx
->trustedLeafCerts
); 
1497         ctx
->trustedLeafCerts 
= CFRetainSafe(trustedCerts
); 
1498         return errSecSuccess
; 
1502 SSLCopyTrustedLeafCertificates  (SSLContextRef          ctx
, 
1503                                                                  CFArrayRef             
*trustedCerts
)  /* RETURNED */ 
1508         if(ctx
->trustedLeafCerts 
!= NULL
) { 
1509                 *trustedCerts 
= ctx
->trustedLeafCerts
; 
1510                 CFRetain(ctx
->trustedCerts
); 
1511                 return errSecSuccess
; 
1513         *trustedCerts 
= NULL
; 
1514         return errSecSuccess
; 
1519 SSLSetClientSideAuthenticate    (SSLContext                     
*ctx
, 
1520                                                                  SSLAuthenticate        auth
) 
1525         if(sslIsSessionActive(ctx
)) { 
1526                 /* can't do this with an active session */ 
1527                 return errSecBadReq
; 
1529         ctx
->clientAuth 
= auth
; 
1531                 case kNeverAuthenticate
: 
1532             tls_handshake_set_client_auth(ctx
->hdsk
, false); 
1534                 case kAlwaysAuthenticate
: 
1535                 case kTryAuthenticate
: 
1536             tls_handshake_set_client_auth(ctx
->hdsk
, true); 
1539         return errSecSuccess
; 
1543 SSLGetClientSideAuthenticate    (SSLContext                     
*ctx
, 
1544                                                                  SSLAuthenticate        
*auth
)  /* RETURNED */ 
1546         if(ctx 
== NULL 
|| auth 
== NULL
) { 
1549         *auth 
= ctx
->clientAuth
; 
1550         return errSecSuccess
; 
1554 SSLGetClientCertificateState    (SSLContextRef                          ctx
, 
1555                                                                  SSLClientCertificateState      
*clientState
) 
1560     if(ctx
->protocolSide 
== kSSLClientSide
) { 
1562        switch(ctx
->clientCertState
) { 
1563            case kSSLClientCertNone
: 
1564                *clientState 
= kSSLClientCertNone
; 
1566            case kSSLClientCertRequested
: 
1567                if(ctx
->localCertArray
) { 
1568                    *clientState 
= kSSLClientCertSent
; 
1570                    *clientState 
= kSSLClientCertRequested
; 
1574                /* Anything else is an internal error */ 
1575                sslErrorLog("TLS client has invalid internal clientCertState (%d)\n", ctx
->clientCertState
); 
1576                return errSSLInternal
; 
1580         switch(ctx
->clientCertState
) { 
1581             case kSSLClientCertNone
: 
1582             case kSSLClientCertRejected
: 
1583                 *clientState 
= ctx
->clientCertState
; 
1585             case kSSLClientCertRequested
: 
1586                 if(ctx
->peerSecTrust
) { 
1587                     *clientState 
= kSSLClientCertSent
; 
1589                     *clientState 
= kSSLClientCertRequested
; 
1593                 /* Anything else is an internal error */ 
1594                 sslErrorLog("TLS server has invalid internal clientCertState (%d)\n", ctx
->clientCertState
); 
1595                 return errSSLInternal
; 
1598         return errSecSuccess
; 
1601 #include <tls_helpers.h> 
1604 SSLSetCertificate                       (SSLContextRef          ctx
, 
1605                                                          CFArrayRef                     _Nullable certRefs
) 
1609          * -- free localCerts if we have any 
1610          * -- Get raw cert data, convert to ctx->localCert 
1611          * -- get pub, priv keys from certRef[0] 
1612          * -- validate cert chain 
1618     CFReleaseNull(ctx
->localCertArray
); 
1619         if(certRefs 
== NULL
) { 
1620                 return errSecSuccess
; // we have cleared the cert, as requested 
1623     ortn 
= tls_helper_set_identity_from_array(ctx
->hdsk
, certRefs
); 
1626         ctx
->localCertArray 
= certRefs
; 
1634 SSLSetEncryptionCertificate     (SSLContextRef          ctx
, 
1635                                                          CFArrayRef                     certRefs
) 
1640         if(sslIsSessionActive(ctx
)) { 
1641                 /* can't do this with an active session */ 
1642                 return errSecBadReq
; 
1644     CFReleaseNull(ctx
->encryptCertArray
); 
1645     ctx
->encryptCertArray 
= certRefs
; 
1647         return errSecSuccess
; 
1650 OSStatus 
SSLGetCertificate(SSLContextRef                ctx
, 
1651                                                    CFArrayRef                   
*certRefs
) 
1656         *certRefs 
= ctx
->localCertArray
; 
1657         return errSecSuccess
; 
1660 OSStatus 
SSLGetEncryptionCertificate(SSLContextRef              ctx
, 
1661                                                                      CFArrayRef                 
*certRefs
) 
1666         *certRefs 
= ctx
->encryptCertArray
; 
1667         return errSecSuccess
; 
1671 SSLSetPeerID                            (SSLContext             
*ctx
, 
1677         /* copy peerId to context->peerId */ 
1683         if(sslIsSessionActive(ctx
) && 
1684         /* kSSLClientCertRequested implies client side */ 
1685         (ctx
->clientCertState 
!= kSSLClientCertRequested
)) 
1687                 return errSecBadReq
; 
1689         SSLFreeBuffer(&ctx
->peerID
); 
1690         serr 
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
); 
1694     tls_handshake_set_resumption(ctx
->hdsk
, true); 
1695         memmove(ctx
->peerID
.data
, peerID
, peerIDLen
); 
1696         return errSecSuccess
; 
1700 SSLGetPeerID                            (SSLContextRef          ctx
, 
1701                                                          const void             **peerID
, 
1704         *peerID 
= ctx
->peerID
.data
;                     // may be NULL 
1705         *peerIDLen 
= ctx
->peerID
.length
; 
1706         return errSecSuccess
; 
1710 SSLGetNegotiatedCipher          (SSLContextRef          ctx
, 
1711                                                          SSLCipherSuite         
*cipherSuite
) 
1717     if(!sslIsSessionActive(ctx
)) { 
1718                 return errSecBadReq
; 
1721     *cipherSuite 
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
); 
1723         return errSecSuccess
; 
1727  * Add an acceptable distinguished name (client authentication only). 
1730 SSLAddDistinguishedName( 
1741         if(sslIsSessionActive(ctx
)) { 
1742                 return errSecBadReq
; 
1745         dn 
= (DNListElem 
*)sslMalloc(sizeof(DNListElem
)); 
1747                 return errSecAllocate
; 
1749     if ((err 
= SSLAllocBuffer(&dn
->derDN
, derDNLen
))) 
1754     memcpy(dn
->derDN
.data
, derDN
, derDNLen
); 
1755     dn
->next 
= ctx
->acceptableDNList
; 
1756     ctx
->acceptableDNList 
= dn
; 
1758     tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
); 
1760     return errSecSuccess
; 
1763 /* single-cert version of SSLSetCertificateAuthorities() */ 
1765 sslAddCA(SSLContextRef          ctx
, 
1766                  SecCertificateRef      cert
) 
1768         OSStatus ortn 
= errSecParam
; 
1770     /* Get subject from certificate. */ 
1771 #if TARGET_OS_IPHONE 
1772     CFDataRef subjectName 
= NULL
; 
1773     subjectName 
= SecCertificateCopySubjectSequence(cert
); 
1774     require(subjectName
, errOut
); 
1776     CSSM_DATA_PTR subjectName 
= NULL
; 
1777     ortn 
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
); 
1778     require_noerr(ortn
, errOut
); 
1781         /* add to acceptableCAs as cert, creating array if necessary */ 
1782         if(ctx
->acceptableCAs 
== NULL
) { 
1783                 require(ctx
->acceptableCAs 
= CFArrayCreateMutable(NULL
, 0, 
1784             &kCFTypeArrayCallBacks
), errOut
); 
1785                 if(ctx
->acceptableCAs 
== NULL
) { 
1786                         return errSecAllocate
; 
1789         CFArrayAppendValue(ctx
->acceptableCAs
, cert
); 
1791         /* then add this cert's subject name to acceptableDNList */ 
1792 #if TARGET_OS_IPHONE 
1793         ortn 
= SSLAddDistinguishedName(ctx
, 
1794                                    CFDataGetBytePtr(subjectName
), 
1795                                    CFDataGetLength(subjectName
)); 
1797     ortn 
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
); 
1801 #if TARGET_OS_IPHONE 
1802     CFReleaseSafe(subjectName
); 
1808  * Add a SecCertificateRef, or a CFArray of them, to a server's list 
1809  * of acceptable Certificate Authorities (CAs) to present to the client 
1810  * when client authentication is performed. 
1813 SSLSetCertificateAuthorities(SSLContextRef              ctx
, 
1814                                                          CFTypeRef                      certificateOrArray
, 
1815                                                          Boolean                        replaceExisting
) 
1818         OSStatus ortn 
= errSecSuccess
; 
1820         if((ctx 
== NULL
) || sslIsSessionActive(ctx
) || 
1821            (ctx
->protocolSide 
!= kSSLServerSide
)) { 
1824         if(replaceExisting
) { 
1826                 if(ctx
->acceptableCAs
) { 
1827                         CFRelease(ctx
->acceptableCAs
); 
1828                         ctx
->acceptableCAs 
= NULL
; 
1831         /* else appending */ 
1833         itemType 
= CFGetTypeID(certificateOrArray
); 
1834         if(itemType 
== SecCertificateGetTypeID()) { 
1836                 ortn 
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
); 
1838         else if(itemType 
== CFArrayGetTypeID()) { 
1839                 CFArrayRef cfa 
= (CFArrayRef
)certificateOrArray
; 
1840                 CFIndex numCerts 
= CFArrayGetCount(cfa
); 
1843                 /* array of certs */ 
1844                 for(dex
=0; dex
<numCerts
; dex
++) { 
1845                         SecCertificateRef cert 
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
); 
1846                         if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) { 
1849                         ortn 
= sslAddCA(ctx
, cert
); 
1863  * Obtain the certificates specified in SSLSetCertificateAuthorities(), 
1864  * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not 
1866  * Caller must CFRelease the returned array. 
1869 SSLCopyCertificateAuthorities(SSLContextRef             ctx
, 
1870                                                           CFArrayRef            
*certificates
)  /* RETURNED */ 
1872         if((ctx 
== NULL
) || (certificates 
== NULL
)) { 
1875         if(ctx
->acceptableCAs 
== NULL
) { 
1876                 *certificates 
= NULL
; 
1877                 return errSecSuccess
; 
1879         *certificates 
= ctx
->acceptableCAs
; 
1880         CFRetain(ctx
->acceptableCAs
); 
1881         return errSecSuccess
; 
1886  * Obtain the list of acceptable distinguished names as provided by 
1887  * a server (if the SSLCotextRef is configured as a client), or as 
1888  * specified by SSLSetCertificateAuthorities() (if the SSLContextRef 
1889  * is configured as a server). 
1892 SSLCopyDistinguishedNames       (SSLContextRef          ctx
, 
1895         CFMutableArrayRef outArray 
= NULL
; 
1896         const DNListElem 
*dn
; 
1898         if((ctx 
== NULL
) || (names 
== NULL
)) { 
1901     if(ctx
->protocolSide
==kSSLServerSide
) { 
1902         dn 
= ctx
->acceptableDNList
; 
1904         dn 
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList; 
1909                 return errSecSuccess
; 
1911         outArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1914                 CFDataRef cfDn 
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
); 
1915                 CFArrayAppendValue(outArray
, cfDn
); 
1920         return errSecSuccess
; 
1925  * Request peer certificates. Valid anytime, subsequent to 
1926  * a handshake attempt. 
1929 SSLCopyPeerCertificates (SSLContextRef ctx
, CFArrayRef 
*certs
) 
1935         if (!ctx
->peerSecTrust
) { 
1937                 return errSecBadReq
; 
1940     CFIndex count 
= SecTrustGetCertificateCount(ctx
->peerSecTrust
); 
1941     CFMutableArrayRef ca 
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
); 
1943         return errSecAllocate
; 
1946     for (CFIndex ix 
= 0; ix 
< count
; ++ix
) { 
1947         CFArrayAppendValue(ca
, SecTrustGetCertificateAtIndex(ctx
->peerSecTrust
, ix
)); 
1952         return errSecSuccess
; 
1955 #if !TARGET_OS_IPHONE 
1956 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers. 
1957 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview 
1959 SSLGetPeerCertificates (SSLContextRef ctx
, 
1962 SSLGetPeerCertificates (SSLContextRef ctx
, 
1965     return errSecUnimplemented
; 
1970  * Specify Diffie-Hellman parameters. Optional; if we are configured to allow 
1971  * for D-H ciphers and a D-H cipher is negotiated, and this function has not 
1972  * been called, a set of process-wide parameters will be calculated. However 
1973  * that can take a long time (30 seconds). 
1975 OSStatus 
SSLSetDiffieHellmanParams( 
1977         const void              *dhParams
, 
1984         if(sslIsSessionActive(ctx
)) { 
1985                 return errSecBadReq
; 
1987         SSLFreeBuffer(&ctx
->dhParamsEncoded
); 
1990         ortn 
= SSLCopyBufferFromData(dhParams
, dhParamsLen
, 
1991                 &ctx
->dhParamsEncoded
); 
1996         return tls_handshake_set_dh_parameters(ctx
->hdsk
, &ctx
->dhParamsEncoded
); 
1999 #endif /* APPLE_DH */ 
2003  * Return parameter block specified in SSLSetDiffieHellmanParams. 
2004  * Returned data is not copied and belongs to the SSLContextRef. 
2006 OSStatus 
SSLGetDiffieHellmanParams( 
2008         const void              **dhParams
, 
2009         size_t                  *dhParamsLen
) 
2015         *dhParams 
= ctx
->dhParamsEncoded
.data
; 
2016         *dhParamsLen 
= ctx
->dhParamsEncoded
.length
; 
2017         return errSecSuccess
; 
2019     return errSecUnimplemented
; 
2020 #endif /* APPLE_DH */ 
2023 OSStatus 
SSLSetDHEEnabled(SSLContextRef ctx
, bool enabled
) 
2025     ctx
->dheEnabled 
= enabled
; 
2026     /* Hack a little so that only the ciphersuites change */ 
2027     tls_protocol_version min
, max
; 
2029     tls_handshake_get_min_protocol_version(ctx
->hdsk
, &min
); 
2030     tls_handshake_get_max_protocol_version(ctx
->hdsk
, &max
); 
2031     tls_handshake_get_min_dh_group_size(ctx
->hdsk
, &nbits
); 
2032     tls_handshake_set_config(ctx
->hdsk
, enabled
?tls_handshake_config_legacy_DHE
:tls_handshake_config_legacy
); 
2033     tls_handshake_set_min_protocol_version(ctx
->hdsk
, min
); 
2034     tls_handshake_set_max_protocol_version(ctx
->hdsk
, max
); 
2035     tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
); 
2040 OSStatus 
SSLGetDHEEnabled(SSLContextRef ctx
, bool *enabled
) 
2042     *enabled 
= ctx
->dheEnabled
; 
2046 OSStatus 
SSLSetMinimumDHGroupSize(SSLContextRef ctx
, unsigned nbits
) 
2048     return tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
); 
2051 OSStatus 
SSLGetMinimumDHGroupSize(SSLContextRef ctx
, unsigned *nbits
) 
2053     return tls_handshake_get_min_dh_group_size(ctx
->hdsk
, nbits
); 
2056 OSStatus 
SSLSetRsaBlinding( 
2063         ctx
->rsaBlindingEnable 
= blinding
; 
2064         return errSecSuccess
; 
2067 OSStatus 
SSLGetRsaBlinding( 
2074         *blinding 
= ctx
->rsaBlindingEnable
; 
2075         return errSecSuccess
; 
2081     SecTrustRef        
*trust
)  /* RETURNED */ 
2083         OSStatus status 
= errSecSuccess
; 
2084         if (ctx 
== NULL 
|| trust 
== NULL
) 
2087         /* Create a SecTrustRef if this was a resumed session and we 
2088            didn't have one yet. */ 
2089         if (!ctx
->peerSecTrust
) { 
2090                 status 
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
); 
2093         *trust 
= ctx
->peerSecTrust
; 
2094     if (ctx
->peerSecTrust
) 
2095         CFRetain(ctx
->peerSecTrust
); 
2100 OSStatus 
SSLGetPeerSecTrust( 
2102         SecTrustRef             
*trust
) /* RETURNED */ 
2104     OSStatus status 
= errSecSuccess
; 
2105         if (ctx 
== NULL 
|| trust 
== NULL
) 
2108         /* Create a SecTrustRef if this was a resumed session and we 
2109            didn't have one yet. */ 
2110         if (!ctx
->peerSecTrust
) { 
2111                 status 
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
); 
2114         *trust 
= ctx
->peerSecTrust
; 
2118 OSStatus 
SSLInternalMasterSecret( 
2120    void *secret
,        // mallocd by caller, SSL_MASTER_SECRET_SIZE 
2121    size_t *secretSize
)  // in/out 
2123         if((ctx 
== NULL
) || (secret 
== NULL
) || (secretSize 
== NULL
)) { 
2126     return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
); 
2129 OSStatus 
SSLInternalServerRandom( 
2131    void *randBuf
,                       // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE 
2132    size_t *randSize
)    // in/out 
2134         if((ctx 
== NULL
) || (randBuf 
== NULL
) || (randSize 
== NULL
)) { 
2137     return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
); 
2140 OSStatus 
SSLInternalClientRandom( 
2142    void *randBuf
,               // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE 
2143    size_t *randSize
)    // in/out 
2145         if((ctx 
== NULL
) || (randBuf 
== NULL
) || (randSize 
== NULL
)) { 
2148     return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
); 
2151 /* This is used by EAP 802.1x */ 
2152 OSStatus 
SSLGetCipherSizes( 
2155         size_t *symmetricKeySize
, 
2158         if((ctx 
== NULL
) || (digestSize 
== NULL
) || 
2159            (symmetricKeySize 
== NULL
) || (ivSize 
== NULL
)) { 
2163     SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
); 
2165         *digestSize 
= sslCipherSuiteGetMacSize(cipher
); 
2166         *symmetricKeySize 
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
); 
2167         *ivSize 
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
); 
2168         return errSecSuccess
; 
2172 SSLGetResumableSessionInfo( 
2174         Boolean                 
*sessionWasResumed
,             // RETURNED 
2175         void                    *sessionID
,                             // RETURNED, mallocd by caller 
2176         size_t                  *sessionIDLength
)               // IN/OUT 
2178         if((ctx 
== NULL
) || (sessionWasResumed 
== NULL
) || 
2179            (sessionID 
== NULL
) || (sessionIDLength 
== NULL
) || 
2180            (*sessionIDLength 
< MAX_SESSION_ID_LENGTH
)) { 
2184     SSLBuffer localSessionID
; 
2185     bool sessionMatch 
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
); 
2188                 *sessionWasResumed 
= true; 
2189                 if(localSessionID
.length 
> *sessionIDLength
) { 
2190                         /* really should never happen - means ID > 32 */ 
2193                 if(localSessionID
.length
) { 
2195                          * Note PAC-based session resumption can result in sessionMatch 
2198                         memmove(sessionID
, localSessionID
.data
, localSessionID
.length
); 
2200                 *sessionIDLength 
= localSessionID
.length
; 
2203                 *sessionWasResumed 
= false; 
2204                 *sessionIDLength 
= 0; 
2206         return errSecSuccess
; 
2210  * Get/set enable of anonymous ciphers. This is deprecated and now a no-op. 
2213 SSLSetAllowAnonymousCiphers( 
2217     return errSecSuccess
; 
2221 SSLGetAllowAnonymousCiphers( 
2225     return errSecSuccess
; 
2229  * Override the default session cache timeout for a cache entry created for 
2230  * the current session. 
2233 SSLSetSessionCacheTimeout( 
2235         uint32_t timeoutInSeconds
) 
2240         ctx
->sessionCacheTimeout 
= timeoutInSeconds
; 
2241         return errSecSuccess
; 
2246 void tls_handshake_master_secret_function(const void *arg
,         /* opaque to coreTLS; app-specific */ 
2247                                           void *secret
,                 /* mallocd by caller, SSL_MASTER_SECRET_SIZE */ 
2248                                           size_t *secretLength
) 
2250     SSLContextRef ctx 
= (SSLContextRef
) arg
; 
2251     ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
); 
2256  * Register a callback for obtaining the master_secret when performing 
2257  * PAC-based session resumption. 
2260 SSLInternalSetMasterSecretFunction( 
2262         SSLInternalMasterSecretFunction mFunc
, 
2263         const void *arg
)                /* opaque to SecureTransport; app-specific */ 
2269     ctx
->masterSecretArg 
= arg
; 
2270     ctx
->masterSecretCallback 
= mFunc
; 
2272     return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
); 
2276  * Provide an opaque SessionTicket for use in PAC-based session 
2277  * resumption. Client side only. The provided ticket is sent in 
2278  * the ClientHello message as a SessionTicket extension. 
2280  * We won't reject this on the server side, but server-side support 
2281  * for PAC-based session resumption is currently enabled for 
2282  * Development builds only. To fully support this for server side, 
2283  * besides the rudimentary support that's here for Development builds, 
2284  * we'd need a getter for the session ticket, so the app code can 
2285  * access the SessionTicket when its SSLInternalMasterSecretFunction 
2286  * callback is called. 
2288 OSStatus 
SSLInternalSetSessionTicket( 
2291    size_t ticketLength
) 
2296         if(sslIsSessionActive(ctx
)) { 
2297                 /* can't do this with an active session */ 
2298                 return errSecBadReq
; 
2300     return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
); 
2305  * ECDSA curve accessors. 
2309  * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake. 
2310  * Returns errSecParam if no ECDH-related ciphersuite was negotiated. 
2312 OSStatus 
SSLGetNegotiatedCurve( 
2314    SSL_ECDSA_NamedCurve 
*namedCurve
)    /* RETURNED */ 
2316         if((ctx 
== NULL
) || (namedCurve 
== NULL
)) { 
2319     unsigned int curve 
= tls_handshake_get_negotiated_curve(ctx
->hdsk
); 
2320     if(curve 
== SSL_Curve_None
) { 
2323         *namedCurve 
= curve
; 
2324         return errSecSuccess
; 
2328  * Obtain the number of currently enabled SSL_ECDSA_NamedCurves. 
2330 OSStatus 
SSLGetNumberOfECDSACurves( 
2332    unsigned *numCurves
) /* RETURNED */ 
2334         if((ctx 
== NULL
) || (numCurves 
== NULL
)) { 
2337         *numCurves 
= ctx
->ecdhNumCurves
; 
2338         return errSecSuccess
; 
2342  * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves. 
2344 OSStatus 
SSLGetECDSACurves( 
2346    SSL_ECDSA_NamedCurve 
*namedCurves
,           /* RETURNED */ 
2347    unsigned *numCurves
)                                         /* IN/OUT */ 
2349         if((ctx 
== NULL
) || (namedCurves 
== NULL
) || (numCurves 
== NULL
)) { 
2352         if(*numCurves 
< ctx
->ecdhNumCurves
) { 
2355         memmove(namedCurves
, ctx
->ecdhCurves
, 
2356                 (ctx
->ecdhNumCurves 
* sizeof(SSL_ECDSA_NamedCurve
))); 
2357         *numCurves 
= ctx
->ecdhNumCurves
; 
2358         return errSecSuccess
; 
2362  * Specify ordered list of allowable named curves. 
2364 OSStatus 
SSLSetECDSACurves( 
2366    const SSL_ECDSA_NamedCurve 
*namedCurves
, 
2369         if((ctx 
== NULL
) || (namedCurves 
== NULL
) || (numCurves 
== 0)) { 
2372         if(sslIsSessionActive(ctx
)) { 
2373                 /* can't do this with an active session */ 
2374                 return errSecBadReq
; 
2377         size_t size 
= numCurves 
* sizeof(uint16_t); 
2378         ctx
->ecdhCurves 
= (uint16_t *)sslMalloc(size
); 
2379         if(ctx
->ecdhCurves 
== NULL
) { 
2380                 ctx
->ecdhNumCurves 
= 0; 
2381                 return errSecAllocate
; 
2384     for (unsigned i
=0; i
<numCurves
; i
++) { 
2385         ctx
->ecdhCurves
[i
] = namedCurves
[i
]; 
2388         ctx
->ecdhNumCurves 
= numCurves
; 
2390     tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
); 
2391         return errSecSuccess
; 
2395  * Obtain the number of client authentication mechanisms specified by 
2396  * the server in its Certificate Request message. 
2397  * Returns errSecParam if server hasn't sent a Certificate Request message 
2398  * (i.e., client certificate state is kSSLClientCertNone). 
2400 OSStatus 
SSLGetNumberOfClientAuthTypes( 
2404         if((ctx 
== NULL
) || (ctx
->clientCertState 
== kSSLClientCertNone
)) { 
2407         *numTypes 
= ctx
->numAuthTypes
; 
2408         return errSecSuccess
; 
2412  * Obtain the client authentication mechanisms specified by 
2413  * the server in its Certificate Request message. 
2414  * Caller allocates returned array and specifies its size (in 
2415  * SSLClientAuthenticationTypes) in *numType on entry; *numTypes 
2416  * is the actual size of the returned array on successful return. 
2418 OSStatus 
SSLGetClientAuthTypes( 
2420    SSLClientAuthenticationType 
*authTypes
,              /* RETURNED */ 
2421    unsigned *numTypes
)                                                  /* IN/OUT */ 
2423         if((ctx 
== NULL
) || (ctx
->clientCertState 
== kSSLClientCertNone
)) { 
2426         memmove(authTypes
, ctx
->clientAuthTypes
, 
2427                 ctx
->numAuthTypes 
* sizeof(SSLClientAuthenticationType
)); 
2428         *numTypes 
= ctx
->numAuthTypes
; 
2429         return errSecSuccess
; 
2433  * -- DEPRECATED -- Return errSecUnimplemented. 
2435 OSStatus 
SSLGetNegotiatedClientAuthType( 
2437    SSLClientAuthenticationType 
*authType
)               /* RETURNED */ 
2439     return errSecUnimplemented
; 
2442 OSStatus 
SSLGetNumberOfSignatureAlgorithms( 
2444     unsigned *numSigAlgs
) 
2450     tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
); 
2451         return errSecSuccess
; 
2454 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
), 
2455                "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match"); 
2457 OSStatus 
SSLGetSignatureAlgorithms( 
2459     SSLSignatureAndHashAlgorithm 
*sigAlgs
,              /* RETURNED */ 
2460     unsigned *numSigAlgs
)                                                       /* IN/OUT */ 
2466     unsigned numPeerSigAlgs
; 
2467     const tls_signature_and_hash_algorithm 
*peerAlgs 
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
); 
2469         memmove(sigAlgs
, peerAlgs
, 
2470             numPeerSigAlgs 
* sizeof(SSLSignatureAndHashAlgorithm
)); 
2471         *numSigAlgs 
= numPeerSigAlgs
; 
2472     return errSecSuccess
; 
2476 OSStatus 
SSLSetPSKSharedSecret(SSLContextRef ctx
, 
2480     if(ctx 
== NULL
) return errSecParam
; 
2482     if(ctx
->pskSharedSecret
.data
) 
2483         SSLFreeBuffer(&ctx
->pskSharedSecret
); 
2485     if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
)) 
2486         return errSecAllocate
; 
2488     tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
); 
2490     return errSecSuccess
; 
2493 OSStatus 
SSLSetPSKIdentity(SSLContextRef ctx
, 
2494                            const void *pskIdentity
, 
2495                            size_t pskIdentityLen
) 
2497     if((ctx 
== NULL
) || (pskIdentity 
== NULL
) || (pskIdentityLen 
== 0)) return errSecParam
; 
2499     if(ctx
->pskIdentity
.data
) 
2500         SSLFreeBuffer(&ctx
->pskIdentity
); 
2502     if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
)) 
2503         return errSecAllocate
; 
2505     tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
); 
2507     return errSecSuccess
; 
2511 OSStatus 
SSLGetPSKIdentity(SSLContextRef ctx
, 
2512                            const void **pskIdentity
, 
2513                            size_t *pskIdentityLen
) 
2515     if((ctx 
== NULL
) || (pskIdentity 
== NULL
) || (pskIdentityLen 
== NULL
)) return errSecParam
; 
2517     *pskIdentity
=ctx
->pskIdentity
.data
; 
2518     *pskIdentityLen
=ctx
->pskIdentity
.length
; 
2520     return errSecSuccess
; 
2523 OSStatus 
SSLInternal_PRF( 
2525                          const void *vsecret
, 
2527                          const void *label
,                     // optional, NULL implies that seed contains 
2532                          void *vout
,                                    // mallocd by caller, length >= outLen 
2535     return tls_handshake_internal_prf(ctx
->hdsk
, 
2542 const CFStringRef kSSLSessionConfig_default 
= CFSTR("default"); 
2543 const CFStringRef kSSLSessionConfig_ATSv1 
= CFSTR("ATSv1"); 
2544 const CFStringRef kSSLSessionConfig_ATSv1_noPFS 
= CFSTR("ATSv1_noPFS"); 
2545 const CFStringRef kSSLSessionConfig_legacy 
= CFSTR("legacy"); 
2546 const CFStringRef kSSLSessionConfig_standard 
= CFSTR("standard"); 
2547 const CFStringRef kSSLSessionConfig_RC4_fallback 
= CFSTR("RC4_fallback"); 
2548 const CFStringRef kSSLSessionConfig_TLSv1_fallback 
= CFSTR("TLSv1_fallback"); 
2549 const CFStringRef kSSLSessionConfig_TLSv1_RC4_fallback 
= CFSTR("TLSv1_RC4_fallback"); 
2550 const CFStringRef kSSLSessionConfig_legacy_DHE 
= CFSTR("legacy_DHE"); 
2551 const CFStringRef kSSLSessionConfig_anonymous 
= CFSTR("anonymous"); 
2552 const CFStringRef kSSLSessionConfig_3DES_fallback 
= CFSTR("3DES_fallback"); 
2553 const CFStringRef kSSLSessionConfig_TLSv1_3DES_fallback 
= CFSTR("TLSv1_3DES_fallback"); 
2557 tls_handshake_config_t 
SSLSessionConfig_to_tls_handshake_config(CFStringRef config
) 
2559     if(CFEqual(config
, kSSLSessionConfig_ATSv1
)){ 
2560         return tls_handshake_config_ATSv1
; 
2561     } else if(CFEqual(config
, kSSLSessionConfig_ATSv1_noPFS
)){ 
2562         return tls_handshake_config_ATSv1_noPFS
; 
2563     } else if(CFEqual(config
, kSSLSessionConfig_standard
)){ 
2564         return tls_handshake_config_standard
; 
2565     } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_fallback
)){ 
2566         return tls_handshake_config_TLSv1_fallback
; 
2567     } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_RC4_fallback
)){ 
2568         return tls_handshake_config_TLSv1_RC4_fallback
; 
2569     } else if(CFEqual(config
, kSSLSessionConfig_RC4_fallback
)){ 
2570         return tls_handshake_config_RC4_fallback
; 
2571     } else if(CFEqual(config
, kSSLSessionConfig_3DES_fallback
)){ 
2572         return tls_handshake_config_3DES_fallback
; 
2573     } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_3DES_fallback
)){ 
2574         return tls_handshake_config_TLSv1_3DES_fallback
; 
2575     } else if(CFEqual(config
, kSSLSessionConfig_legacy
)){ 
2576         return tls_handshake_config_legacy
; 
2577     } else if(CFEqual(config
, kSSLSessionConfig_legacy_DHE
)){ 
2578         return tls_handshake_config_legacy_DHE
; 
2579     } else if(CFEqual(config
, kSSLSessionConfig_anonymous
)){ 
2580         return tls_handshake_config_anonymous
; 
2581     } else if(CFEqual(config
, kSSLSessionConfig_default
)){ 
2582         return tls_handshake_config_default
; 
2584         return tls_handshake_config_none
; 
2588 /* Set Predefined TLS Configuration */ 
2590 SSLSetSessionConfig(SSLContextRef context
, 
2593     tls_handshake_config_t cfg 
= SSLSessionConfig_to_tls_handshake_config(config
); 
2595         return tls_handshake_set_config(context
->hdsk
, cfg
);