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
);