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
);
160 CFIndex
SSLPreferencesGetInteger(CFStringRef key
, CFPropertyListRef managed_prefs
)
162 CFTypeRef value
= SSLPreferencesCopyValue(key
, managed_prefs
);
163 CFIndex int_value
= 0;
164 if (isNumber(value
)) {
165 CFNumberGetValue(value
, kCFNumberCFIndexType
, &int_value
);
167 CFReleaseSafe(value
);
172 Boolean
SSLPreferencesGetBoolean(CFStringRef key
, CFPropertyListRef managed_prefs
)
174 CFTypeRef value
= SSLPreferencesCopyValue(key
, managed_prefs
);
175 Boolean bool_value
= FALSE
;
176 if (isBoolean(value
)) {
177 bool_value
= CFBooleanGetValue(value
);
180 CFReleaseSafe(value
);
185 CFStringRef
SSLPreferencesCopyString(CFStringRef key
, CFPropertyListRef managed_prefs
)
187 CFTypeRef value
= SSLPreferencesCopyValue(key
, managed_prefs
);
188 if (isString(value
)) {
191 CFReleaseSafe(value
);
196 static void _SSLContextReadDefault()
198 CFPropertyListRef managed_prefs
= NULL
;
201 /* on iOS, we also look for preferences from mobile's Managed Preferences */
202 /* Note that if the process is running as mobile, the above call will already have read the Managed Preference plist.
203 As a result, if you have some preferences set manually with defaults, which preference applies may be different for mobile vs not-mobile. */
204 CFURLRef prefURL
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, CFSTR("/Library/Managed Preferences/mobile/.GlobalPreferences.plist"), kCFURLPOSIXPathStyle
, false);
206 managed_prefs
= CopyPlistFromFile(prefURL
);
208 CFReleaseSafe(prefURL
);
211 /* Disable record splitting */
212 /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
213 kSSLDisableRecordSplittingDefaultValue
= SSLPreferencesGetBoolean(CFSTR("SSLDisableRecordSplitting"), managed_prefs
);
215 /* Min DH Group Size */
216 kMinDhGroupSizeDefaultValue
= SSLPreferencesGetInteger(CFSTR("SSLMinDhGroupSize"), managed_prefs
);
218 /* Default Min Prototcol Version */
219 kMinProtocolVersionDefaultValue
= SSLPreferencesGetInteger(CFSTR("SSLMinProtocolVersion"), managed_prefs
);
222 kSSLSessionConfigDefaultValue
= SSLPreferencesCopyString(CFSTR("SSLSessionConfig"), managed_prefs
);
224 CFReleaseSafe(managed_prefs
);
227 /* This functions initialize global variables, run once per process */
228 static void SSLContextOnce(void)
230 _SSLContextReadDefault();
231 g_session_cache
= tls_cache_create();
234 CFGiblisWithHashFor(SSLContext
)
237 SSLNewContext (Boolean isServer
,
238 SSLContextRef
*contextPtr
) /* RETURNED */
240 if(contextPtr
== NULL
) {
244 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
246 if (*contextPtr
== NULL
)
247 return errSecAllocate
;
249 return errSecSuccess
;
252 SSLContextRef
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
)
255 SSLRecordContextRef recCtx
;
257 ctx
= SSLCreateContextWithRecordFuncs(alloc
, protocolSide
, connectionType
, &SSLRecordLayerInternal
);
262 recCtx
= SSLCreateInternalRecordLayer(ctx
);
268 SSLSetRecordContext(ctx
, recCtx
);
273 SSLContextRef
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
, const struct SSLRecordFuncs
*recFuncs
)
275 SSLContext
*ctx
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
);
281 /* subsequent errors to errOut: */
282 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
285 ctx
->hdsk
= tls_handshake_create(connectionType
==kSSLDatagramType
, protocolSide
==kSSLServerSide
);
286 if(ctx
->hdsk
== NULL
) {
291 static dispatch_once_t onceToken
;
292 dispatch_once(&onceToken
, ^{
296 ctx
->cache
= g_session_cache
;
298 tls_handshake_set_callbacks(ctx
->hdsk
,
299 &tls_handshake_callbacks
,
302 ctx
->isDTLS
= (connectionType
==kSSLDatagramType
);
304 ctx
->state
= SSL_HdskStateUninit
;
305 ctx
->timeout_duration
= DEFAULT_DTLS_TIMEOUT
;
306 ctx
->mtu
= DEFAULT_DTLS_MTU
;
308 tls_handshake_get_min_protocol_version(ctx
->hdsk
, &ctx
->minProtocolVersion
);
309 tls_handshake_get_max_protocol_version(ctx
->hdsk
, &ctx
->maxProtocolVersion
);
311 if(protocolSide
== kSSLClientSide
) {
312 tls_handshake_set_sct_enable(ctx
->hdsk
, true);
313 tls_handshake_set_ocsp_enable(ctx
->hdsk
, true);
316 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
317 ctx
->protocolSide
= protocolSide
;
318 ctx
->recFuncs
= recFuncs
;
320 /* Initial cert verify state: verify with default system roots */
321 ctx
->enableCertVerify
= true;
323 /* Default for RSA blinding is ENABLED */
324 ctx
->rsaBlindingEnable
= true;
326 /* Default for sending one-byte app data record is ENABLED */
327 ctx
->oneByteRecordEnable
= !kSSLDisableRecordSplittingDefaultValue
;
329 /* Dont enable fallback behavior by default */
330 ctx
->fallbackEnabled
= false;
332 if(kSSLSessionConfigDefaultValue
) {
333 SSLSetSessionConfig(ctx
, kSSLSessionConfigDefaultValue
);
336 if(kMinDhGroupSizeDefaultValue
) {
337 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, (unsigned)kMinDhGroupSizeDefaultValue
);
340 if(kMinProtocolVersionDefaultValue
) {
341 SSLSetProtocolVersionMin(ctx
, (unsigned)kMinProtocolVersionDefaultValue
);
344 /* default for anonymous ciphers is DISABLED */
345 ctx
->anonCipherEnable
= false;
347 ctx
->breakOnServerAuth
= false;
348 ctx
->breakOnCertRequest
= false;
349 ctx
->breakOnClientAuth
= false;
350 ctx
->signalServerAuth
= false;
351 ctx
->signalCertRequest
= false;
352 ctx
->signalClientAuth
= false;
358 SSLNewDatagramContext (Boolean isServer
,
359 SSLContextRef
*contextPtr
) /* RETURNED */
361 if (contextPtr
== NULL
)
363 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
);
364 if (*contextPtr
== NULL
)
365 return errSecAllocate
;
366 return errSecSuccess
;
370 * Dispose of an SSLContext. (private)
371 * This function is invoked after our dispatch queue is safely released,
372 * or directly from SSLDisposeContext if there is no dispatch queue.
375 SSLDisposeContext (SSLContextRef context
)
377 if(context
== NULL
) {
381 return errSecSuccess
;
384 CFStringRef
SSLContextCopyFormatDescription(CFTypeRef arg
, CFDictionaryRef formatOptions
)
386 SSLContext
* ctx
= (SSLContext
*) arg
;
391 CFStringRef result
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
);
396 Boolean
SSLContextCompare(CFTypeRef a
, CFTypeRef b
)
401 CFHashCode
SSLContextHash(CFTypeRef arg
)
403 return (CFHashCode
) arg
;
406 void SSLContextDestroy(CFTypeRef arg
)
408 SSLContext
* ctx
= (SSLContext
*) arg
;
410 /* destroy the coreTLS handshake object */
411 tls_handshake_destroy(ctx
->hdsk
);
413 /* Only destroy if we were using the internal record layer */
414 if(ctx
->recFuncs
==&SSLRecordLayerInternal
)
415 SSLDestroyInternalRecordLayer(ctx
->recCtx
);
417 SSLFreeBuffer(&ctx
->sessionTicket
);
418 SSLFreeBuffer(&ctx
->sessionID
);
419 SSLFreeBuffer(&ctx
->peerID
);
420 SSLFreeBuffer(&ctx
->resumableSession
);
421 SSLFreeBuffer(&ctx
->receivedDataBuffer
);
423 CFReleaseSafe(ctx
->acceptableCAs
);
424 #if !TARGET_OS_IPHONE
425 CFReleaseSafe(ctx
->trustedLeafCerts
);
427 CFReleaseSafe(ctx
->localCertArray
);
428 CFReleaseSafe(ctx
->encryptCertArray
);
429 CFReleaseSafe(ctx
->trustedCerts
);
430 CFReleaseSafe(ctx
->peerSecTrust
);
434 SSLFreeBuffer(&ctx
->ownVerifyData
);
435 SSLFreeBuffer(&ctx
->peerVerifyData
);
437 SSLFreeBuffer(&ctx
->pskIdentity
);
438 SSLFreeBuffer(&ctx
->pskSharedSecret
);
440 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
443 tls_cache_cleanup(ctx
->cache
);
445 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
449 * Determine the state of an SSL session.
452 SSLGetSessionState (SSLContextRef context
,
453 SSLSessionState
*state
) /* RETURNED */
455 SSLSessionState rtnState
= kSSLIdle
;
457 if(context
== NULL
) {
461 switch(context
->state
) {
462 case SSL_HdskStateUninit
:
465 case SSL_HdskStateGracefulClose
:
466 rtnState
= kSSLClosed
;
468 case SSL_HdskStateErrorClose
:
469 case SSL_HdskStateNoNotifyClose
:
470 rtnState
= kSSLAborted
;
472 case SSL_HdskStateReady
:
473 rtnState
= kSSLConnected
;
475 case SSL_HdskStatePending
:
476 rtnState
= kSSLHandshake
;
480 return errSecSuccess
;
484 * Set options for an SSL session.
487 SSLSetSessionOption (SSLContextRef context
,
488 SSLSessionOption option
,
491 if(context
== NULL
) {
494 if(sslIsSessionActive(context
)) {
495 /* can't do this with an active session */
499 case kSSLSessionOptionBreakOnServerAuth
:
500 context
->breakOnServerAuth
= value
;
501 context
->enableCertVerify
= !value
;
503 case kSSLSessionOptionBreakOnCertRequested
:
504 context
->breakOnCertRequest
= value
;
506 case kSSLSessionOptionBreakOnClientAuth
:
507 context
->breakOnClientAuth
= value
;
508 context
->enableCertVerify
= !value
;
510 case kSSLSessionOptionSendOneByteRecord
:
511 /* Only call the record layer function if the value changed */
512 if(value
!= context
->oneByteRecordEnable
)
513 context
->recFuncs
->setOption(context
->recCtx
, kSSLRecordOptionSendOneByteRecord
, value
);
514 context
->oneByteRecordEnable
= value
;
516 case kSSLSessionOptionFalseStart
:
517 context
->falseStartEnabled
= value
;
519 case kSSLSessionOptionFallback
:
520 tls_handshake_set_fallback(context
->hdsk
, value
);
521 context
->fallbackEnabled
= value
;
523 case kSSLSessionOptionBreakOnClientHello
:
524 context
->breakOnClientHello
= value
;
526 case kSSLSessionOptionAllowServerIdentityChange
:
527 tls_handshake_set_server_identity_change(context
->hdsk
, value
);
529 case kSSLSessionOptionAllowRenegotiation
:
530 tls_handshake_set_renegotiation(context
->hdsk
, value
);
536 return errSecSuccess
;
540 * Determine current value for the specified option in an SSL session.
543 SSLGetSessionOption (SSLContextRef context
,
544 SSLSessionOption option
,
547 if(context
== NULL
|| value
== NULL
) {
551 case kSSLSessionOptionBreakOnServerAuth
:
552 *value
= context
->breakOnServerAuth
;
554 case kSSLSessionOptionBreakOnCertRequested
:
555 *value
= context
->breakOnCertRequest
;
557 case kSSLSessionOptionBreakOnClientAuth
:
558 *value
= context
->breakOnClientAuth
;
560 case kSSLSessionOptionSendOneByteRecord
:
561 *value
= context
->oneByteRecordEnable
;
563 case kSSLSessionOptionFalseStart
:
564 *value
= context
->falseStartEnabled
;
566 case kSSLSessionOptionBreakOnClientHello
:
567 *value
= context
->breakOnClientHello
;
569 case kSSLSessionOptionAllowServerIdentityChange
:
570 tls_handshake_get_server_identity_change(context
->hdsk
, (bool *)value
);
576 return errSecSuccess
;
580 SSLSetRecordContext (SSLContextRef ctx
,
581 SSLRecordContextRef recCtx
)
586 if(sslIsSessionActive(ctx
)) {
587 /* can't do this with an active session */
590 ctx
->recCtx
= recCtx
;
591 return errSecSuccess
;
595 SSLSetIOFuncs (SSLContextRef ctx
,
596 SSLReadFunc readFunc
,
597 SSLWriteFunc writeFunc
)
602 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
603 /* Can Only do this with the internal record layer */
607 if(sslIsSessionActive(ctx
)) {
608 /* can't do this with an active session */
612 ctx
->ioCtx
.read
=readFunc
;
613 ctx
->ioCtx
.write
=writeFunc
;
619 SSLSetNPNFunc(SSLContextRef context
,
623 if (context
== NULL
) {
626 if (sslIsSessionActive(context
)) {
629 context
->npnFunc
= npnFunc
;
630 context
->npnFuncInfo
= info
;
631 if(context
->protocolSide
==kSSLClientSide
) {
632 tls_handshake_set_npn_enable(context
->hdsk
, npnFunc
!=NULL
);
637 SSLSetNPNData(SSLContextRef context
,
641 if (context
== NULL
|| data
== NULL
|| length
== 0) {
651 npn_data
.data
= (uint8_t *)data
;
652 npn_data
.length
= length
;
654 return tls_handshake_set_npn_data(context
->hdsk
, npn_data
);
658 SSLGetNPNData(SSLContextRef context
,
661 if (context
== NULL
|| length
== NULL
)
664 const tls_buffer
*npn_data
;
666 npn_data
= tls_handshake_get_peer_npn_data(context
->hdsk
);
669 *length
= npn_data
->length
;
670 return npn_data
->data
;
679 SSLSetALPNFunc(SSLContextRef context
,
680 SSLALPNFunc alpnFunc
,
683 if (context
== NULL
) {
686 if (sslIsSessionActive(context
)) {
689 context
->alpnFunc
= alpnFunc
;
690 context
->alpnFuncInfo
= info
;
691 if(context
->protocolSide
==kSSLServerSide
) {
697 SSLSetALPNData(SSLContextRef context
,
701 if (context
== NULL
|| data
== NULL
|| length
== 0) {
709 tls_buffer alpn_data
;
711 alpn_data
.data
= (uint8_t *)data
;
712 alpn_data
.length
= length
;
714 return tls_handshake_set_alpn_data(context
->hdsk
, alpn_data
);
718 SSLGetALPNData(SSLContextRef context
,
721 if (context
== NULL
|| length
== NULL
)
724 const tls_buffer
*alpn_data
;
726 alpn_data
= tls_handshake_get_peer_alpn_data(context
->hdsk
);
729 *length
= alpn_data
->length
;
730 return alpn_data
->data
;
739 SSLSetConnection (SSLContextRef ctx
,
740 SSLConnectionRef connection
)
745 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
746 /* Can Only do this with the internal record layer */
750 if(sslIsSessionActive(ctx
)) {
751 /* can't do this with an active session */
755 /* Need to keep a copy of it this layer for the Get function */
756 ctx
->ioCtx
.ioRef
= connection
;
762 SSLGetConnection (SSLContextRef ctx
,
763 SSLConnectionRef
*connection
)
765 if((ctx
== NULL
) || (connection
== NULL
)) {
768 *connection
= ctx
->ioCtx
.ioRef
;
769 return errSecSuccess
;
773 SSLSetPeerDomainName (SSLContextRef ctx
,
774 const char *peerName
,
780 if(sslIsSessionActive(ctx
)) {
781 /* can't do this with an active session */
785 if(ctx
->protocolSide
== kSSLClientSide
) {
786 return tls_handshake_set_peer_hostname(ctx
->hdsk
, peerName
, peerNameLen
);
788 return 0; // This should probably return an error, but historically didnt.
793 * Determine the buffer size needed for SSLGetPeerDomainName().
796 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
797 size_t *peerNameLen
) // RETURNED
802 const char *hostname
;
804 return tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, peerNameLen
);
808 SSLGetPeerDomainName (SSLContextRef ctx
,
809 char *peerName
, // returned here
810 size_t *peerNameLen
) // IN/OUT
812 const char *hostname
;
821 err
=tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
825 } else if(*peerNameLen
<len
) {
826 return errSSLBufferOverflow
;
828 memcpy(peerName
, hostname
, len
);
835 SSLCopyRequestedPeerNameLength (SSLContextRef ctx
,
836 size_t *peerNameLen
) // RETURNED
838 const tls_buffer
*hostname
;
842 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
846 *peerNameLen
= hostname
->length
;
852 SSLCopyRequestedPeerName (SSLContextRef ctx
,
853 char *peerName
, // returned here
854 size_t *peerNameLen
) // IN/OUT
856 const tls_buffer
*hostname
;
862 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
866 } else if(*peerNameLen
< hostname
->length
) {
867 return errSSLBufferOverflow
;
869 memcpy(peerName
, hostname
->data
, hostname
->length
);
870 *peerNameLen
= hostname
->length
;
877 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
887 if(!ctx
->isDTLS
) return errSecParam
;
889 if((ctx
== NULL
) || (cookieLen
>32)) {
892 if(sslIsSessionActive(ctx
)) {
893 /* can't do this with an active session */
897 /* free possible existing cookie */
898 if(ctx
->dtlsCookie
.data
) {
899 SSLFreeBuffer(&ctx
->dtlsCookie
);
903 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
)))
906 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
907 return errSecSuccess
;
911 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
915 if(ctx
== NULL
) return errSecParam
;
916 if(!ctx
->isDTLS
) return errSecParam
;
918 tls_handshake_set_mtu(ctx
->hdsk
, maxSize
);
920 return errSecSuccess
;
924 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
927 if(ctx
== NULL
) return errSecParam
;
928 if(!ctx
->isDTLS
) return errSecParam
;
932 return errSecSuccess
;
937 Keys to to math below:
939 A DTLS record looks like this: | header (13 bytes) | fragment |
941 For Null cipher, fragment is clear text as follows:
944 For block cipher, fragment size must be a multiple of the cipher block size, and is the
945 encryption of the following plaintext :
946 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
948 The maximum content length in that case is achieved for 0 padding bytes.
953 SSLGetDatagramWriteSize (SSLContextRef ctx
,
956 if(ctx
== NULL
) return errSecParam
;
957 if(!ctx
->isDTLS
) return errSecParam
;
958 if(bufSize
== NULL
) return errSecParam
;
960 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
963 SSLCipherSpecParams
*currCipher
= &ctx
->selectedCipherSpecParams
;
965 size_t blockSize
= currCipher
->blockSize
;
966 size_t macSize
= currCipher
->macSize
;
968 size_t blockSize
= 16;
973 /* max_fragment_size must be a multiple of blocksize */
974 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
975 max_fragment_size
-= blockSize
; /* 1 block for IV */
976 max_fragment_size
-= 1; /* 1 byte for pad length */
979 /* less the mac size */
980 max_fragment_size
-= macSize
;
982 /* Thats just a sanity check */
983 assert(max_fragment_size
<ctx
->mtu
);
985 *bufSize
= max_fragment_size
;
987 return errSecSuccess
;
991 All the complexity around protocol version is to support legacy APIs.
992 Eventually that should go away:
993 <rdar://problem/20842025> Remove deprecated SecureTransport function related to protocol version selection.
996 static tls_protocol_version
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
998 case kSSLProtocol2
: return SSL_Version_2_0
;
999 case kSSLProtocol3
: return tls_protocol_version_SSL_3
;
1000 case kTLSProtocol1
: return tls_protocol_version_TLS_1_0
;
1001 case kTLSProtocol11
: return tls_protocol_version_TLS_1_1
;
1002 case kTLSProtocol12
: return tls_protocol_version_TLS_1_2
;
1003 case kDTLSProtocol1
: return tls_protocol_version_DTLS_1_0
;
1004 default: return tls_protocol_version_Undertermined
;
1008 /* concert between private SSLProtocolVersion and public SSLProtocol */
1009 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
1012 case tls_protocol_version_SSL_3
: return kSSLProtocol3
;
1013 case tls_protocol_version_TLS_1_0
: return kTLSProtocol1
;
1014 case tls_protocol_version_TLS_1_1
: return kTLSProtocol11
;
1015 case tls_protocol_version_TLS_1_2
: return kTLSProtocol12
;
1016 case tls_protocol_version_DTLS_1_0
: return kDTLSProtocol1
;
1018 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
1021 case tls_protocol_version_Undertermined
: return kSSLProtocolUnknown
;
1026 SSLSetProtocolVersionMin (SSLContextRef ctx
,
1027 SSLProtocol minVersion
)
1029 if(ctx
== NULL
) return errSecParam
;
1031 tls_protocol_version version
= SSLProtocolToProtocolVersion(minVersion
);
1033 if (version
> MINIMUM_DATAGRAM_VERSION
||
1034 version
< MAXIMUM_DATAGRAM_VERSION
)
1035 return errSSLIllegalParam
;
1036 if (version
< ctx
->maxProtocolVersion
)
1037 ctx
->maxProtocolVersion
= version
;
1039 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1040 return errSSLIllegalParam
;
1041 if (version
> ctx
->maxProtocolVersion
)
1042 ctx
->maxProtocolVersion
= version
;
1044 ctx
->minProtocolVersion
= version
;
1046 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1047 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1049 return errSecSuccess
;
1053 SSLGetProtocolVersionMin (SSLContextRef ctx
,
1054 SSLProtocol
*minVersion
)
1056 if(ctx
== NULL
) return errSecParam
;
1058 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
1059 return errSecSuccess
;
1063 SSLSetProtocolVersionMax (SSLContextRef ctx
,
1064 SSLProtocol maxVersion
)
1066 if(ctx
== NULL
) return errSecParam
;
1068 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
1070 if (version
> MINIMUM_DATAGRAM_VERSION
||
1071 version
< MAXIMUM_DATAGRAM_VERSION
)
1072 return errSSLIllegalParam
;
1073 if (version
> ctx
->minProtocolVersion
)
1074 ctx
->minProtocolVersion
= version
;
1076 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1077 return errSSLIllegalParam
;
1078 if (version
< ctx
->minProtocolVersion
)
1079 ctx
->minProtocolVersion
= version
;
1081 ctx
->maxProtocolVersion
= version
;
1083 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1084 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1086 return errSecSuccess
;
1090 SSLGetProtocolVersionMax (SSLContextRef ctx
,
1091 SSLProtocol
*maxVersion
)
1093 if(ctx
== NULL
) return errSecParam
;
1095 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
1096 return errSecSuccess
;
1099 #define max(x,y) ((x)<(y)?(y):(x))
1102 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
1103 SSLProtocol protocol
,
1109 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1110 /* Can't do this with an active session, nor with a DTLS session */
1111 return errSecBadReq
;
1113 if (protocol
== kSSLProtocolAll
) {
1115 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1116 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1118 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1119 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1122 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1124 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
1127 if (version
> ctx
->maxProtocolVersion
) {
1128 ctx
->maxProtocolVersion
= version
;
1129 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
1130 ctx
->minProtocolVersion
= version
;
1132 if (version
< ctx
->minProtocolVersion
) {
1133 ctx
->minProtocolVersion
= version
;
1136 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
1139 /* Disabling a protocol version now resets the minimum acceptable
1140 * version to the next higher version. This means it's no longer
1141 * possible to enable a discontiguous set of protocol versions.
1143 SSLProtocolVersion nextVersion
;
1145 case SSL_Version_2_0
:
1146 nextVersion
= SSL_Version_3_0
;
1148 case SSL_Version_3_0
:
1149 nextVersion
= TLS_Version_1_0
;
1151 case TLS_Version_1_0
:
1152 nextVersion
= TLS_Version_1_1
;
1154 case TLS_Version_1_1
:
1155 nextVersion
= TLS_Version_1_2
;
1157 case TLS_Version_1_2
:
1159 nextVersion
= SSL_Version_Undetermined
;
1162 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
1163 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1164 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1165 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1170 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1171 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1173 return errSecSuccess
;
1177 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1178 SSLProtocol protocol
,
1179 Boolean
*enable
) /* RETURNED */
1185 /* Can't do this with a DTLS session */
1186 return errSecBadReq
;
1192 case kTLSProtocol11
:
1193 case kTLSProtocol12
:
1195 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1196 *enable
= (ctx
->minProtocolVersion
<= version
1197 && ctx
->maxProtocolVersion
>= version
);
1200 case kSSLProtocolAll
:
1201 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1202 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1207 return errSecSuccess
;
1212 SSLSetProtocolVersion (SSLContextRef ctx
,
1213 SSLProtocol version
)
1218 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1219 /* Can't do this with an active session, nor with a DTLS session */
1220 return errSecBadReq
;
1225 /* this tells us to do our best, up to 3.0 */
1226 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1227 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1229 case kSSLProtocol3Only
:
1230 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1231 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1234 /* this tells us to do our best, up to TLS, but allows 3.0 */
1235 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1236 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1238 case kTLSProtocol1Only
:
1239 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1240 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1242 case kTLSProtocol11
:
1243 /* This tells us to do our best, up to TLS 1.1, currently also
1244 allows 3.0 or TLS 1.0 */
1245 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1246 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1248 case kTLSProtocol12
:
1249 case kSSLProtocolAll
:
1250 case kSSLProtocolUnknown
:
1251 /* This tells us to do our best, up to TLS 1.2, currently also
1252 allows 3.0 or TLS 1.0 or TLS 1.1 */
1253 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1254 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1260 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1261 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1263 return errSecSuccess
;
1268 SSLGetProtocolVersion (SSLContextRef ctx
,
1269 SSLProtocol
*protocol
) /* RETURNED */
1274 /* translate array of booleans to public value; not all combinations
1275 * are legal (i.e., meaningful) for this call */
1276 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1277 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1278 /* traditional 'all enabled' */
1279 *protocol
= kSSLProtocolAll
;
1280 return errSecSuccess
;
1282 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1283 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1284 /* traditional 'all enabled' */
1285 *protocol
= kTLSProtocol11
;
1286 return errSecSuccess
;
1288 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1289 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1290 /* TLS1.1 and below enabled */
1291 *protocol
= kTLSProtocol1
;
1292 return errSecSuccess
;
1293 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1294 *protocol
= kTLSProtocol1Only
;
1296 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1297 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1298 /* Could also return kSSLProtocol3Only since
1299 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1300 *protocol
= kSSLProtocol3
;
1301 return errSecSuccess
;
1309 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1310 SSLProtocol
*protocol
) /* RETURNED */
1315 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1316 return errSecSuccess
;
1320 SSLSetEnableCertVerify (SSLContextRef ctx
,
1321 Boolean enableVerify
)
1326 sslCertDebug("SSLSetEnableCertVerify %s",
1327 enableVerify
? "true" : "false");
1328 if(sslIsSessionActive(ctx
)) {
1329 /* can't do this with an active session */
1330 return errSecBadReq
;
1332 ctx
->enableCertVerify
= enableVerify
;
1333 return errSecSuccess
;
1337 SSLGetEnableCertVerify (SSLContextRef ctx
,
1338 Boolean
*enableVerify
)
1343 *enableVerify
= ctx
->enableCertVerify
;
1344 return errSecSuccess
;
1348 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1349 Boolean allowExpired
)
1351 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1356 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1357 Boolean
*allowExpired
)
1359 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1360 return errSecUnimplemented
;
1364 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1365 Boolean allowExpired
)
1367 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1372 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1373 Boolean
*allowExpired
)
1375 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1376 return errSecUnimplemented
;
1379 OSStatus
SSLSetAllowsAnyRoot(
1386 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1387 ctx
->allowAnyRoot
= anyRoot
;
1388 return errSecSuccess
;
1392 SSLGetAllowsAnyRoot(
1399 *anyRoot
= ctx
->allowAnyRoot
;
1400 return errSecSuccess
;
1403 #if !TARGET_OS_IPHONE
1404 /* obtain the system roots sets for this app, policy SSL */
1405 static OSStatus
sslDefaultSystemRoots(
1407 CFArrayRef
*systemRoots
) // created and RETURNED
1410 const char *hostname
;
1413 tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
1415 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1418 (ctx
->protocolSide
== kSSLServerSide
) ?
1419 /* server verifies, client encrypts */
1420 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1423 #endif /* OS X only */
1426 SSLSetTrustedRoots (SSLContextRef ctx
,
1427 CFArrayRef trustedRoots
,
1428 Boolean replaceExisting
)
1430 if (sslIsSessionActive(ctx
)) {
1431 /* can't do this with an active session */
1432 return errSecBadReq
;
1434 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1435 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1437 if (replaceExisting
) {
1438 ctx
->trustedCertsOnly
= true;
1439 CFReleaseNull(ctx
->trustedCerts
);
1442 if (ctx
->trustedCerts
) {
1443 CFIndex count
= CFArrayGetCount(trustedRoots
);
1444 CFRange range
= { 0, count
};
1445 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1447 require(ctx
->trustedCerts
=
1448 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1452 return errSecSuccess
;
1455 return errSecAllocate
;
1459 SSLCopyTrustedRoots (SSLContextRef ctx
,
1460 CFArrayRef
*trustedRoots
) /* RETURNED */
1462 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1465 if(ctx
->trustedCerts
!= NULL
) {
1466 *trustedRoots
= ctx
->trustedCerts
;
1467 CFRetain(ctx
->trustedCerts
);
1468 return errSecSuccess
;
1470 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1471 /* use default system roots */
1472 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1474 *trustedRoots
= NULL
;
1475 return errSecSuccess
;
1479 #if !TARGET_OS_IPHONE
1481 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1482 CFArrayRef trustedCerts
)
1487 if(sslIsSessionActive(ctx
)) {
1488 /* can't do this with an active session */
1489 return errSecBadReq
;
1492 if(ctx
->trustedLeafCerts
) {
1493 CFRelease(ctx
->trustedLeafCerts
);
1495 ctx
->trustedLeafCerts
= CFRetainSafe(trustedCerts
);
1496 return errSecSuccess
;
1500 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1501 CFArrayRef
*trustedCerts
) /* RETURNED */
1506 if(ctx
->trustedLeafCerts
!= NULL
) {
1507 *trustedCerts
= ctx
->trustedLeafCerts
;
1508 CFRetain(ctx
->trustedCerts
);
1509 return errSecSuccess
;
1511 *trustedCerts
= NULL
;
1512 return errSecSuccess
;
1517 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1518 SSLAuthenticate auth
)
1523 if(sslIsSessionActive(ctx
)) {
1524 /* can't do this with an active session */
1525 return errSecBadReq
;
1527 ctx
->clientAuth
= auth
;
1529 case kNeverAuthenticate
:
1530 tls_handshake_set_client_auth(ctx
->hdsk
, false);
1532 case kAlwaysAuthenticate
:
1533 case kTryAuthenticate
:
1534 tls_handshake_set_client_auth(ctx
->hdsk
, true);
1537 return errSecSuccess
;
1541 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1542 SSLAuthenticate
*auth
) /* RETURNED */
1544 if(ctx
== NULL
|| auth
== NULL
) {
1547 *auth
= ctx
->clientAuth
;
1548 return errSecSuccess
;
1552 SSLGetClientCertificateState (SSLContextRef ctx
,
1553 SSLClientCertificateState
*clientState
)
1558 if(ctx
->protocolSide
== kSSLClientSide
) {
1560 switch(ctx
->clientCertState
) {
1561 case kSSLClientCertNone
:
1562 *clientState
= kSSLClientCertNone
;
1564 case kSSLClientCertRequested
:
1565 if(ctx
->localCertArray
) {
1566 *clientState
= kSSLClientCertSent
;
1568 *clientState
= kSSLClientCertRequested
;
1572 /* Anything else is an internal error */
1573 sslErrorLog("TLS client has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1574 return errSSLInternal
;
1578 switch(ctx
->clientCertState
) {
1579 case kSSLClientCertNone
:
1580 case kSSLClientCertRejected
:
1581 *clientState
= ctx
->clientCertState
;
1583 case kSSLClientCertRequested
:
1584 if(ctx
->peerSecTrust
) {
1585 *clientState
= kSSLClientCertSent
;
1587 *clientState
= kSSLClientCertRequested
;
1591 /* Anything else is an internal error */
1592 sslErrorLog("TLS server has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1593 return errSSLInternal
;
1596 return errSecSuccess
;
1599 #include <tls_helpers.h>
1602 SSLSetCertificate (SSLContextRef ctx
,
1603 CFArrayRef _Nullable certRefs
)
1607 * -- free localCerts if we have any
1608 * -- Get raw cert data, convert to ctx->localCert
1609 * -- get pub, priv keys from certRef[0]
1610 * -- validate cert chain
1616 CFReleaseNull(ctx
->localCertArray
);
1617 if(certRefs
== NULL
) {
1618 return errSecSuccess
; // we have cleared the cert, as requested
1621 ortn
= tls_helper_set_identity_from_array(ctx
->hdsk
, certRefs
);
1624 ctx
->localCertArray
= certRefs
;
1632 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1633 CFArrayRef certRefs
)
1638 if(sslIsSessionActive(ctx
)) {
1639 /* can't do this with an active session */
1640 return errSecBadReq
;
1642 CFReleaseNull(ctx
->encryptCertArray
);
1643 ctx
->encryptCertArray
= certRefs
;
1645 return errSecSuccess
;
1648 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1649 CFArrayRef
*certRefs
)
1654 *certRefs
= ctx
->localCertArray
;
1655 return errSecSuccess
;
1658 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1659 CFArrayRef
*certRefs
)
1664 *certRefs
= ctx
->encryptCertArray
;
1665 return errSecSuccess
;
1669 SSLSetPeerID (SSLContext
*ctx
,
1675 /* copy peerId to context->peerId */
1681 if(sslIsSessionActive(ctx
) &&
1682 /* kSSLClientCertRequested implies client side */
1683 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1685 return errSecBadReq
;
1687 SSLFreeBuffer(&ctx
->peerID
);
1688 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1692 tls_handshake_set_resumption(ctx
->hdsk
, true);
1693 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1694 return errSecSuccess
;
1698 SSLGetPeerID (SSLContextRef ctx
,
1699 const void **peerID
,
1702 *peerID
= ctx
->peerID
.data
; // may be NULL
1703 *peerIDLen
= ctx
->peerID
.length
;
1704 return errSecSuccess
;
1708 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1709 SSLCipherSuite
*cipherSuite
)
1715 if(!sslIsSessionActive(ctx
)) {
1716 return errSecBadReq
;
1719 *cipherSuite
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
1721 return errSecSuccess
;
1725 * Add an acceptable distinguished name (client authentication only).
1728 SSLAddDistinguishedName(
1739 if(sslIsSessionActive(ctx
)) {
1740 return errSecBadReq
;
1743 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1745 return errSecAllocate
;
1747 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1752 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1753 dn
->next
= ctx
->acceptableDNList
;
1754 ctx
->acceptableDNList
= dn
;
1756 tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
);
1758 return errSecSuccess
;
1761 /* single-cert version of SSLSetCertificateAuthorities() */
1763 sslAddCA(SSLContextRef ctx
,
1764 SecCertificateRef cert
)
1766 OSStatus ortn
= errSecParam
;
1768 /* Get subject from certificate. */
1769 #if TARGET_OS_IPHONE
1770 CFDataRef subjectName
= NULL
;
1771 subjectName
= SecCertificateCopySubjectSequence(cert
);
1772 require(subjectName
, errOut
);
1774 CSSM_DATA_PTR subjectName
= NULL
;
1775 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1776 require_noerr(ortn
, errOut
);
1779 /* add to acceptableCAs as cert, creating array if necessary */
1780 if(ctx
->acceptableCAs
== NULL
) {
1781 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1782 &kCFTypeArrayCallBacks
), errOut
);
1783 if(ctx
->acceptableCAs
== NULL
) {
1784 return errSecAllocate
;
1787 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1789 /* then add this cert's subject name to acceptableDNList */
1790 #if TARGET_OS_IPHONE
1791 ortn
= SSLAddDistinguishedName(ctx
,
1792 CFDataGetBytePtr(subjectName
),
1793 CFDataGetLength(subjectName
));
1795 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1799 #if TARGET_OS_IPHONE
1800 CFReleaseSafe(subjectName
);
1806 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1807 * of acceptable Certificate Authorities (CAs) to present to the client
1808 * when client authentication is performed.
1811 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1812 CFTypeRef certificateOrArray
,
1813 Boolean replaceExisting
)
1816 OSStatus ortn
= errSecSuccess
;
1818 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1819 (ctx
->protocolSide
!= kSSLServerSide
)) {
1822 if(replaceExisting
) {
1824 if(ctx
->acceptableCAs
) {
1825 CFRelease(ctx
->acceptableCAs
);
1826 ctx
->acceptableCAs
= NULL
;
1829 /* else appending */
1831 itemType
= CFGetTypeID(certificateOrArray
);
1832 if(itemType
== SecCertificateGetTypeID()) {
1834 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
1836 else if(itemType
== CFArrayGetTypeID()) {
1837 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
1838 CFIndex numCerts
= CFArrayGetCount(cfa
);
1841 /* array of certs */
1842 for(dex
=0; dex
<numCerts
; dex
++) {
1843 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
1844 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
1847 ortn
= sslAddCA(ctx
, cert
);
1861 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1862 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1864 * Caller must CFRelease the returned array.
1867 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
1868 CFArrayRef
*certificates
) /* RETURNED */
1870 if((ctx
== NULL
) || (certificates
== NULL
)) {
1873 if(ctx
->acceptableCAs
== NULL
) {
1874 *certificates
= NULL
;
1875 return errSecSuccess
;
1877 *certificates
= ctx
->acceptableCAs
;
1878 CFRetain(ctx
->acceptableCAs
);
1879 return errSecSuccess
;
1884 * Obtain the list of acceptable distinguished names as provided by
1885 * a server (if the SSLCotextRef is configured as a client), or as
1886 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1887 * is configured as a server).
1890 SSLCopyDistinguishedNames (SSLContextRef ctx
,
1893 CFMutableArrayRef outArray
= NULL
;
1894 const DNListElem
*dn
;
1896 if((ctx
== NULL
) || (names
== NULL
)) {
1899 if(ctx
->protocolSide
==kSSLServerSide
) {
1900 dn
= ctx
->acceptableDNList
;
1902 dn
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList;
1907 return errSecSuccess
;
1909 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1912 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
1913 CFArrayAppendValue(outArray
, cfDn
);
1918 return errSecSuccess
;
1923 * Request peer certificates. Valid anytime, subsequent to
1924 * a handshake attempt.
1927 SSLCopyPeerCertificates (SSLContextRef ctx
, CFArrayRef
*certs
)
1933 if (!ctx
->peerSecTrust
) {
1935 return errSecBadReq
;
1938 CFIndex count
= SecTrustGetCertificateCount(ctx
->peerSecTrust
);
1939 CFMutableArrayRef ca
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
1941 return errSecAllocate
;
1944 for (CFIndex ix
= 0; ix
< count
; ++ix
) {
1945 CFArrayAppendValue(ca
, SecTrustGetCertificateAtIndex(ctx
->peerSecTrust
, ix
));
1950 return errSecSuccess
;
1953 #if !TARGET_OS_IPHONE
1954 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
1955 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
1957 SSLGetPeerCertificates (SSLContextRef ctx
,
1960 SSLGetPeerCertificates (SSLContextRef ctx
,
1963 return errSecUnimplemented
;
1968 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1969 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1970 * been called, a set of process-wide parameters will be calculated. However
1971 * that can take a long time (30 seconds).
1973 OSStatus
SSLSetDiffieHellmanParams(
1975 const void *dhParams
,
1982 if(sslIsSessionActive(ctx
)) {
1983 return errSecBadReq
;
1985 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
1988 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
1989 &ctx
->dhParamsEncoded
);
1994 return tls_handshake_set_dh_parameters(ctx
->hdsk
, &ctx
->dhParamsEncoded
);
1997 #endif /* APPLE_DH */
2001 * Return parameter block specified in SSLSetDiffieHellmanParams.
2002 * Returned data is not copied and belongs to the SSLContextRef.
2004 OSStatus
SSLGetDiffieHellmanParams(
2006 const void **dhParams
,
2007 size_t *dhParamsLen
)
2013 *dhParams
= ctx
->dhParamsEncoded
.data
;
2014 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
2015 return errSecSuccess
;
2017 return errSecUnimplemented
;
2018 #endif /* APPLE_DH */
2021 OSStatus
SSLSetDHEEnabled(SSLContextRef ctx
, bool enabled
)
2023 ctx
->dheEnabled
= enabled
;
2024 /* Hack a little so that only the ciphersuites change */
2025 tls_protocol_version min
, max
;
2027 tls_handshake_get_min_protocol_version(ctx
->hdsk
, &min
);
2028 tls_handshake_get_max_protocol_version(ctx
->hdsk
, &max
);
2029 tls_handshake_get_min_dh_group_size(ctx
->hdsk
, &nbits
);
2030 tls_handshake_set_config(ctx
->hdsk
, enabled
?tls_handshake_config_legacy_DHE
:tls_handshake_config_legacy
);
2031 tls_handshake_set_min_protocol_version(ctx
->hdsk
, min
);
2032 tls_handshake_set_max_protocol_version(ctx
->hdsk
, max
);
2033 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2038 OSStatus
SSLGetDHEEnabled(SSLContextRef ctx
, bool *enabled
)
2040 *enabled
= ctx
->dheEnabled
;
2044 OSStatus
SSLSetMinimumDHGroupSize(SSLContextRef ctx
, unsigned nbits
)
2046 return tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2049 OSStatus
SSLGetMinimumDHGroupSize(SSLContextRef ctx
, unsigned *nbits
)
2051 return tls_handshake_get_min_dh_group_size(ctx
->hdsk
, nbits
);
2054 OSStatus
SSLSetRsaBlinding(
2061 ctx
->rsaBlindingEnable
= blinding
;
2062 return errSecSuccess
;
2065 OSStatus
SSLGetRsaBlinding(
2072 *blinding
= ctx
->rsaBlindingEnable
;
2073 return errSecSuccess
;
2079 SecTrustRef
*trust
) /* RETURNED */
2081 OSStatus status
= errSecSuccess
;
2082 if (ctx
== NULL
|| trust
== NULL
)
2085 /* Create a SecTrustRef if this was a resumed session and we
2086 didn't have one yet. */
2087 if (!ctx
->peerSecTrust
) {
2088 status
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
);
2091 *trust
= ctx
->peerSecTrust
;
2092 if (ctx
->peerSecTrust
)
2093 CFRetain(ctx
->peerSecTrust
);
2098 OSStatus
SSLGetPeerSecTrust(
2100 SecTrustRef
*trust
) /* RETURNED */
2102 OSStatus status
= errSecSuccess
;
2103 if (ctx
== NULL
|| trust
== NULL
)
2106 /* Create a SecTrustRef if this was a resumed session and we
2107 didn't have one yet. */
2108 if (!ctx
->peerSecTrust
) {
2109 status
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
);
2112 *trust
= ctx
->peerSecTrust
;
2116 OSStatus
SSLInternalMasterSecret(
2118 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
2119 size_t *secretSize
) // in/out
2121 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
2124 return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
);
2127 OSStatus
SSLInternalServerRandom(
2129 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2130 size_t *randSize
) // in/out
2132 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2135 return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
);
2138 OSStatus
SSLInternalClientRandom(
2140 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2141 size_t *randSize
) // in/out
2143 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2146 return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
);
2149 /* This is used by EAP 802.1x */
2150 OSStatus
SSLGetCipherSizes(
2153 size_t *symmetricKeySize
,
2156 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2157 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2161 SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
2163 *digestSize
= sslCipherSuiteGetMacSize(cipher
);
2164 *symmetricKeySize
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
);
2165 *ivSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
);
2166 return errSecSuccess
;
2170 SSLGetResumableSessionInfo(
2172 Boolean
*sessionWasResumed
, // RETURNED
2173 void *sessionID
, // RETURNED, mallocd by caller
2174 size_t *sessionIDLength
) // IN/OUT
2176 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2177 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2178 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2182 SSLBuffer localSessionID
;
2183 bool sessionMatch
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
);
2186 *sessionWasResumed
= true;
2187 if(localSessionID
.length
> *sessionIDLength
) {
2188 /* really should never happen - means ID > 32 */
2191 if(localSessionID
.length
) {
2193 * Note PAC-based session resumption can result in sessionMatch
2196 memmove(sessionID
, localSessionID
.data
, localSessionID
.length
);
2198 *sessionIDLength
= localSessionID
.length
;
2201 *sessionWasResumed
= false;
2202 *sessionIDLength
= 0;
2204 return errSecSuccess
;
2208 * Get/set enable of anonymous ciphers. This is deprecated and now a no-op.
2211 SSLSetAllowAnonymousCiphers(
2215 return errSecSuccess
;
2219 SSLGetAllowAnonymousCiphers(
2223 return errSecSuccess
;
2227 * Override the default session cache timeout for a cache entry created for
2228 * the current session.
2231 SSLSetSessionCacheTimeout(
2233 uint32_t timeoutInSeconds
)
2238 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2239 return errSecSuccess
;
2244 void tls_handshake_master_secret_function(const void *arg
, /* opaque to coreTLS; app-specific */
2245 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2246 size_t *secretLength
)
2248 SSLContextRef ctx
= (SSLContextRef
) arg
;
2249 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
);
2254 * Register a callback for obtaining the master_secret when performing
2255 * PAC-based session resumption.
2258 SSLInternalSetMasterSecretFunction(
2260 SSLInternalMasterSecretFunction mFunc
,
2261 const void *arg
) /* opaque to SecureTransport; app-specific */
2267 ctx
->masterSecretArg
= arg
;
2268 ctx
->masterSecretCallback
= mFunc
;
2270 return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
);
2274 * Provide an opaque SessionTicket for use in PAC-based session
2275 * resumption. Client side only. The provided ticket is sent in
2276 * the ClientHello message as a SessionTicket extension.
2278 * We won't reject this on the server side, but server-side support
2279 * for PAC-based session resumption is currently enabled for
2280 * Development builds only. To fully support this for server side,
2281 * besides the rudimentary support that's here for Development builds,
2282 * we'd need a getter for the session ticket, so the app code can
2283 * access the SessionTicket when its SSLInternalMasterSecretFunction
2284 * callback is called.
2286 OSStatus
SSLInternalSetSessionTicket(
2289 size_t ticketLength
)
2294 if(sslIsSessionActive(ctx
)) {
2295 /* can't do this with an active session */
2296 return errSecBadReq
;
2298 return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
);
2303 * ECDSA curve accessors.
2307 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2308 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2310 OSStatus
SSLGetNegotiatedCurve(
2312 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2314 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2317 unsigned int curve
= tls_handshake_get_negotiated_curve(ctx
->hdsk
);
2318 if(curve
== SSL_Curve_None
) {
2321 *namedCurve
= curve
;
2322 return errSecSuccess
;
2326 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2328 OSStatus
SSLGetNumberOfECDSACurves(
2330 unsigned *numCurves
) /* RETURNED */
2332 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2335 *numCurves
= ctx
->ecdhNumCurves
;
2336 return errSecSuccess
;
2340 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2342 OSStatus
SSLGetECDSACurves(
2344 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2345 unsigned *numCurves
) /* IN/OUT */
2347 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2350 if(*numCurves
< ctx
->ecdhNumCurves
) {
2353 memmove(namedCurves
, ctx
->ecdhCurves
,
2354 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2355 *numCurves
= ctx
->ecdhNumCurves
;
2356 return errSecSuccess
;
2360 * Specify ordered list of allowable named curves.
2362 OSStatus
SSLSetECDSACurves(
2364 const SSL_ECDSA_NamedCurve
*namedCurves
,
2367 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2370 if(sslIsSessionActive(ctx
)) {
2371 /* can't do this with an active session */
2372 return errSecBadReq
;
2375 size_t size
= numCurves
* sizeof(uint16_t);
2376 ctx
->ecdhCurves
= (uint16_t *)sslMalloc(size
);
2377 if(ctx
->ecdhCurves
== NULL
) {
2378 ctx
->ecdhNumCurves
= 0;
2379 return errSecAllocate
;
2382 for (unsigned i
=0; i
<numCurves
; i
++) {
2383 ctx
->ecdhCurves
[i
] = namedCurves
[i
];
2386 ctx
->ecdhNumCurves
= numCurves
;
2388 tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
);
2389 return errSecSuccess
;
2393 * Obtain the number of client authentication mechanisms specified by
2394 * the server in its Certificate Request message.
2395 * Returns errSecParam if server hasn't sent a Certificate Request message
2396 * (i.e., client certificate state is kSSLClientCertNone).
2398 OSStatus
SSLGetNumberOfClientAuthTypes(
2402 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2405 *numTypes
= ctx
->numAuthTypes
;
2406 return errSecSuccess
;
2410 * Obtain the client authentication mechanisms specified by
2411 * the server in its Certificate Request message.
2412 * Caller allocates returned array and specifies its size (in
2413 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2414 * is the actual size of the returned array on successful return.
2416 OSStatus
SSLGetClientAuthTypes(
2418 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2419 unsigned *numTypes
) /* IN/OUT */
2421 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2424 memmove(authTypes
, ctx
->clientAuthTypes
,
2425 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2426 *numTypes
= ctx
->numAuthTypes
;
2427 return errSecSuccess
;
2431 * -- DEPRECATED -- Return errSecUnimplemented.
2433 OSStatus
SSLGetNegotiatedClientAuthType(
2435 SSLClientAuthenticationType
*authType
) /* RETURNED */
2437 return errSecUnimplemented
;
2440 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2442 unsigned *numSigAlgs
)
2448 tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
);
2449 return errSecSuccess
;
2452 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
),
2453 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2455 OSStatus
SSLGetSignatureAlgorithms(
2457 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2458 unsigned *numSigAlgs
) /* IN/OUT */
2464 unsigned numPeerSigAlgs
;
2465 const tls_signature_and_hash_algorithm
*peerAlgs
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
);
2467 memmove(sigAlgs
, peerAlgs
,
2468 numPeerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2469 *numSigAlgs
= numPeerSigAlgs
;
2470 return errSecSuccess
;
2474 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2478 if(ctx
== NULL
) return errSecParam
;
2480 if(ctx
->pskSharedSecret
.data
)
2481 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2483 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2484 return errSecAllocate
;
2486 tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
);
2488 return errSecSuccess
;
2491 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2492 const void *pskIdentity
,
2493 size_t pskIdentityLen
)
2495 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2497 if(ctx
->pskIdentity
.data
)
2498 SSLFreeBuffer(&ctx
->pskIdentity
);
2500 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2501 return errSecAllocate
;
2503 tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
);
2505 return errSecSuccess
;
2509 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2510 const void **pskIdentity
,
2511 size_t *pskIdentityLen
)
2513 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2515 *pskIdentity
=ctx
->pskIdentity
.data
;
2516 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2518 return errSecSuccess
;
2521 OSStatus
SSLInternal_PRF(
2523 const void *vsecret
,
2525 const void *label
, // optional, NULL implies that seed contains
2530 void *vout
, // mallocd by caller, length >= outLen
2533 return tls_handshake_internal_prf(ctx
->hdsk
,
2540 const CFStringRef kSSLSessionConfig_default
= CFSTR("default");
2541 const CFStringRef kSSLSessionConfig_ATSv1
= CFSTR("ATSv1");
2542 const CFStringRef kSSLSessionConfig_ATSv1_noPFS
= CFSTR("ATSv1_noPFS");
2543 const CFStringRef kSSLSessionConfig_legacy
= CFSTR("legacy");
2544 const CFStringRef kSSLSessionConfig_standard
= CFSTR("standard");
2545 const CFStringRef kSSLSessionConfig_RC4_fallback
= CFSTR("RC4_fallback");
2546 const CFStringRef kSSLSessionConfig_TLSv1_fallback
= CFSTR("TLSv1_fallback");
2547 const CFStringRef kSSLSessionConfig_TLSv1_RC4_fallback
= CFSTR("TLSv1_RC4_fallback");
2548 const CFStringRef kSSLSessionConfig_legacy_DHE
= CFSTR("legacy_DHE");
2549 const CFStringRef kSSLSessionConfig_anonymous
= CFSTR("anonymous");
2552 tls_handshake_config_t
SSLSessionConfig_to_tls_handshake_config(CFStringRef config
)
2554 if(CFEqual(config
, kSSLSessionConfig_ATSv1
)){
2555 return tls_handshake_config_ATSv1
;
2556 } else if(CFEqual(config
, kSSLSessionConfig_ATSv1_noPFS
)){
2557 return tls_handshake_config_ATSv1_noPFS
;
2558 } else if(CFEqual(config
, kSSLSessionConfig_standard
)){
2559 return tls_handshake_config_standard
;
2560 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_fallback
)){
2561 return tls_handshake_config_TLSv1_fallback
;
2562 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_RC4_fallback
)){
2563 return tls_handshake_config_TLSv1_RC4_fallback
;
2564 } else if(CFEqual(config
, kSSLSessionConfig_RC4_fallback
)){
2565 return tls_handshake_config_RC4_fallback
;
2566 } else if(CFEqual(config
, kSSLSessionConfig_legacy
)){
2567 return tls_handshake_config_legacy
;
2568 } else if(CFEqual(config
, kSSLSessionConfig_legacy_DHE
)){
2569 return tls_handshake_config_legacy_DHE
;
2570 } else if(CFEqual(config
, kSSLSessionConfig_anonymous
)){
2571 return tls_handshake_config_anonymous
;
2572 } else if(CFEqual(config
, kSSLSessionConfig_default
)){
2573 return tls_handshake_config_default
;
2575 return tls_handshake_config_none
;
2579 /* Set Predefined TLS Configuration */
2581 SSLSetSessionConfig(SSLContextRef context
,
2584 tls_handshake_config_t cfg
= SSLSessionConfig_to_tls_handshake_config(config
);
2586 return tls_handshake_set_config(context
->hdsk
, cfg
);