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
:
88 case SSL_HdskStateOutOfBandError
:
97 * Minimum and maximum supported versions
99 //#define MINIMUM_STREAM_VERSION SSL_Version_2_0 /* Disabled */
100 #define MINIMUM_STREAM_VERSION SSL_Version_3_0
101 #define MAXIMUM_STREAM_VERSION TLS_Version_1_2
102 #define MINIMUM_DATAGRAM_VERSION DTLS_Version_1_0
104 /* This should be changed when we start supporting DTLS_Version_1_x */
105 #define MAXIMUM_DATAGRAM_VERSION DTLS_Version_1_0
107 #define SSL_ENABLE_ECDSA_SIGN_AUTH 1
108 #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH 0
109 #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH 0
111 #define DEFAULT_DTLS_TIMEOUT 1
112 #define DEFAULT_DTLS_MTU 1400
113 #define MIN_ALLOWED_DTLS_MTU 64 /* this ensure than there will be no integer
114 underflow when calculating max write size */
116 /* Preferences values */
117 CFIndex kMinDhGroupSizeDefaultValue
;
118 CFIndex kMinProtocolVersionDefaultValue
;
119 CFStringRef kSSLSessionConfigDefaultValue
;
120 Boolean kSSLDisableRecordSplittingDefaultValue
;
122 static tls_cache_t g_session_cache
= NULL
;
126 * Instead of using CFPropertyListReadFromFile we use a
127 * CFPropertyListCreateWithStream directly
128 * here. CFPropertyListReadFromFile() uses
129 * CFURLCopyResourcePropertyForKey() and CF pulls in CoreServices for
130 * CFURLCopyResourcePropertyForKey() and that doesn't work in install
133 static CFPropertyListRef
134 CopyPlistFromFile(CFURLRef url
)
136 CFDictionaryRef d
= NULL
;
137 CFReadStreamRef s
= CFReadStreamCreateWithFile(kCFAllocatorDefault
, url
);
138 if (s
&& CFReadStreamOpen(s
)) {
139 d
= (CFDictionaryRef
)CFPropertyListCreateWithStream(kCFAllocatorDefault
, s
, 0, kCFPropertyListImmutable
, NULL
, NULL
);
149 CFTypeRef
SSLPreferencesCopyValue(CFStringRef key
, CFPropertyListRef managed_prefs
)
151 CFTypeRef value
= (CFTypeRef
) CFPreferencesCopyAppValue(CFSTR("SSLSessionConfig"), kCFPreferencesCurrentApplication
);
153 if(!value
&& managed_prefs
) {
154 value
= CFDictionaryGetValue(managed_prefs
, key
);
163 CFIndex
SSLPreferencesGetInteger(CFStringRef key
, CFPropertyListRef managed_prefs
)
165 CFTypeRef value
= SSLPreferencesCopyValue(key
, managed_prefs
);
166 CFIndex int_value
= 0;
167 if (isNumber(value
)) {
168 CFNumberGetValue(value
, kCFNumberCFIndexType
, &int_value
);
170 CFReleaseSafe(value
);
175 Boolean
SSLPreferencesGetBoolean(CFStringRef key
, CFPropertyListRef managed_prefs
)
177 CFTypeRef value
= SSLPreferencesCopyValue(key
, managed_prefs
);
178 Boolean bool_value
= FALSE
;
179 if (isBoolean(value
)) {
180 bool_value
= CFBooleanGetValue(value
);
183 CFReleaseSafe(value
);
188 CFStringRef
SSLPreferencesCopyString(CFStringRef key
, CFPropertyListRef managed_prefs
)
190 CFTypeRef value
= SSLPreferencesCopyValue(key
, managed_prefs
);
191 if (isString(value
)) {
194 CFReleaseSafe(value
);
199 static void _SSLContextReadDefault()
201 CFPropertyListRef managed_prefs
= NULL
;
204 /* on iOS, we also look for preferences from mobile's Managed Preferences */
205 /* Note that if the process is running as mobile, the above call will already have read the Managed Preference plist.
206 As a result, if you have some preferences set manually with defaults, which preference applies may be different for mobile vs not-mobile. */
207 CFURLRef prefURL
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, CFSTR("/Library/Managed Preferences/mobile/.GlobalPreferences.plist"), kCFURLPOSIXPathStyle
, false);
209 managed_prefs
= CopyPlistFromFile(prefURL
);
211 CFReleaseSafe(prefURL
);
214 /* Disable record splitting */
215 /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
216 kSSLDisableRecordSplittingDefaultValue
= SSLPreferencesGetBoolean(CFSTR("SSLDisableRecordSplitting"), managed_prefs
);
218 /* Min DH Group Size */
219 kMinDhGroupSizeDefaultValue
= SSLPreferencesGetInteger(CFSTR("SSLMinDhGroupSize"), managed_prefs
);
221 /* Default Min Prototcol Version */
222 kMinProtocolVersionDefaultValue
= SSLPreferencesGetInteger(CFSTR("SSLMinProtocolVersion"), managed_prefs
);
225 kSSLSessionConfigDefaultValue
= SSLPreferencesCopyString(CFSTR("SSLSessionConfig"), managed_prefs
);
227 CFReleaseSafe(managed_prefs
);
230 /* This functions initialize global variables, run once per process */
231 static void SSLContextOnce(void)
233 _SSLContextReadDefault();
234 g_session_cache
= tls_cache_create();
237 CFGiblisWithHashFor(SSLContext
)
240 SSLNewContext (Boolean isServer
,
241 SSLContextRef
*contextPtr
) /* RETURNED */
243 if(contextPtr
== NULL
) {
247 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
249 if (*contextPtr
== NULL
)
250 return errSecAllocate
;
252 return errSecSuccess
;
255 SSLContextRef
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
)
258 SSLRecordContextRef recCtx
;
260 ctx
= SSLCreateContextWithRecordFuncs(alloc
, protocolSide
, connectionType
, &SSLRecordLayerInternal
);
265 recCtx
= SSLCreateInternalRecordLayer(ctx
);
271 SSLSetRecordContext(ctx
, recCtx
);
276 SSLContextRef
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
, const struct SSLRecordFuncs
*recFuncs
)
278 SSLContext
*ctx
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
);
284 /* subsequent errors to errOut: */
285 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
288 ctx
->hdsk
= tls_handshake_create(connectionType
==kSSLDatagramType
, protocolSide
==kSSLServerSide
);
289 if(ctx
->hdsk
== NULL
) {
294 static dispatch_once_t onceToken
;
295 dispatch_once(&onceToken
, ^{
299 ctx
->cache
= g_session_cache
;
301 tls_handshake_set_callbacks(ctx
->hdsk
,
302 &tls_handshake_callbacks
,
305 ctx
->isDTLS
= (connectionType
==kSSLDatagramType
);
307 ctx
->state
= SSL_HdskStateUninit
;
308 ctx
->timeout_duration
= DEFAULT_DTLS_TIMEOUT
;
309 ctx
->mtu
= DEFAULT_DTLS_MTU
;
311 tls_handshake_get_min_protocol_version(ctx
->hdsk
, &ctx
->minProtocolVersion
);
312 tls_handshake_get_max_protocol_version(ctx
->hdsk
, &ctx
->maxProtocolVersion
);
314 if(protocolSide
== kSSLClientSide
) {
315 tls_handshake_set_sct_enable(ctx
->hdsk
, true);
316 tls_handshake_set_ocsp_enable(ctx
->hdsk
, true);
319 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
320 ctx
->protocolSide
= protocolSide
;
321 ctx
->recFuncs
= recFuncs
;
323 /* Initial cert verify state: verify with default system roots */
324 ctx
->enableCertVerify
= true;
326 /* Default for RSA blinding is ENABLED */
327 ctx
->rsaBlindingEnable
= true;
329 /* Default for sending one-byte app data record is ENABLED */
330 ctx
->oneByteRecordEnable
= !kSSLDisableRecordSplittingDefaultValue
;
332 /* Dont enable fallback behavior by default */
333 ctx
->fallbackEnabled
= false;
335 if(kSSLSessionConfigDefaultValue
) {
336 SSLSetSessionConfig(ctx
, kSSLSessionConfigDefaultValue
);
339 if(kMinDhGroupSizeDefaultValue
) {
340 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, (unsigned)kMinDhGroupSizeDefaultValue
);
343 if(kMinProtocolVersionDefaultValue
) {
344 SSLSetProtocolVersionMin(ctx
, (unsigned)kMinProtocolVersionDefaultValue
);
347 /* default for anonymous ciphers is DISABLED */
348 ctx
->anonCipherEnable
= false;
350 ctx
->breakOnServerAuth
= false;
351 ctx
->breakOnCertRequest
= false;
352 ctx
->breakOnClientAuth
= false;
353 ctx
->signalServerAuth
= false;
354 ctx
->signalCertRequest
= false;
355 ctx
->signalClientAuth
= false;
361 SSLNewDatagramContext (Boolean isServer
,
362 SSLContextRef
*contextPtr
) /* RETURNED */
364 if (contextPtr
== NULL
)
366 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
);
367 if (*contextPtr
== NULL
)
368 return errSecAllocate
;
369 return errSecSuccess
;
373 * Dispose of an SSLContext. (private)
374 * This function is invoked after our dispatch queue is safely released,
375 * or directly from SSLDisposeContext if there is no dispatch queue.
378 SSLDisposeContext (SSLContextRef context
)
380 if(context
== NULL
) {
384 return errSecSuccess
;
387 CFStringRef
SSLContextCopyFormatDescription(CFTypeRef arg
, CFDictionaryRef formatOptions
)
389 SSLContext
* ctx
= (SSLContext
*) arg
;
394 CFStringRef result
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
);
399 Boolean
SSLContextCompare(CFTypeRef a
, CFTypeRef b
)
404 CFHashCode
SSLContextHash(CFTypeRef arg
)
406 return (CFHashCode
) arg
;
409 void SSLContextDestroy(CFTypeRef arg
)
411 SSLContext
* ctx
= (SSLContext
*) arg
;
413 /* destroy the coreTLS handshake object */
414 tls_handshake_destroy(ctx
->hdsk
);
416 /* Only destroy if we were using the internal record layer */
417 if(ctx
->recFuncs
==&SSLRecordLayerInternal
)
418 SSLDestroyInternalRecordLayer(ctx
->recCtx
);
420 SSLFreeBuffer(&ctx
->sessionTicket
);
421 SSLFreeBuffer(&ctx
->sessionID
);
422 SSLFreeBuffer(&ctx
->peerID
);
423 SSLFreeBuffer(&ctx
->resumableSession
);
424 SSLFreeBuffer(&ctx
->receivedDataBuffer
);
425 SSLFreeBuffer(&ctx
->contextConfigurationBuffer
);
427 CFReleaseSafe(ctx
->acceptableCAs
);
428 #if !TARGET_OS_IPHONE
429 CFReleaseSafe(ctx
->trustedLeafCerts
);
431 CFReleaseSafe(ctx
->localCertArray
);
432 CFReleaseSafe(ctx
->encryptCertArray
);
433 CFReleaseSafe(ctx
->trustedCerts
);
434 CFReleaseSafe(ctx
->peerSecTrust
);
438 SSLFreeBuffer(&ctx
->ownVerifyData
);
439 SSLFreeBuffer(&ctx
->peerVerifyData
);
441 SSLFreeBuffer(&ctx
->pskIdentity
);
442 SSLFreeBuffer(&ctx
->pskSharedSecret
);
444 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
447 tls_cache_cleanup(ctx
->cache
);
449 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
453 * Determine the state of an SSL session.
456 SSLGetSessionState (SSLContextRef context
,
457 SSLSessionState
*state
) /* RETURNED */
459 SSLSessionState rtnState
= kSSLIdle
;
461 if(context
== NULL
) {
465 switch(context
->state
) {
466 case SSL_HdskStateUninit
:
469 case SSL_HdskStateGracefulClose
:
470 rtnState
= kSSLClosed
;
472 case SSL_HdskStateErrorClose
:
473 case SSL_HdskStateNoNotifyClose
:
474 case SSL_HdskStateOutOfBandError
:
475 rtnState
= kSSLAborted
;
477 case SSL_HdskStateReady
:
478 rtnState
= kSSLConnected
;
480 case SSL_HdskStatePending
:
481 rtnState
= kSSLHandshake
;
485 return errSecSuccess
;
489 * Set options for an SSL session.
492 SSLSetSessionOption (SSLContextRef context
,
493 SSLSessionOption option
,
496 if (context
== NULL
) {
500 if (sslIsSessionActive(context
)) {
501 /* can't do this with an active session */
506 case kSSLSessionOptionBreakOnServerAuth
:
507 context
->breakOnServerAuth
= value
;
508 context
->enableCertVerify
= !value
;
510 case kSSLSessionOptionBreakOnCertRequested
:
511 context
->breakOnCertRequest
= value
;
513 case kSSLSessionOptionBreakOnClientAuth
:
514 context
->breakOnClientAuth
= value
;
515 context
->enableCertVerify
= !value
;
517 case kSSLSessionOptionSendOneByteRecord
:
518 /* Only call the record layer function if the value changed */
519 if (value
!= context
->oneByteRecordEnable
) {
520 context
->recFuncs
->setOption(context
->recCtx
, kSSLRecordOptionSendOneByteRecord
, value
);
522 context
->oneByteRecordEnable
= value
;
524 case kSSLSessionOptionFalseStart
:
525 tls_handshake_set_false_start(context
->hdsk
, value
);
526 context
->falseStartEnabled
= value
;
528 case kSSLSessionOptionFallback
:
529 tls_handshake_set_fallback(context
->hdsk
, value
);
530 context
->fallbackEnabled
= value
;
532 case kSSLSessionOptionBreakOnClientHello
:
533 context
->breakOnClientHello
= value
;
535 case kSSLSessionOptionAllowServerIdentityChange
:
536 tls_handshake_set_server_identity_change(context
->hdsk
, value
);
537 context
->allowServerIdentityChange
= true;
539 case kSSLSessionOptionAllowRenegotiation
:
540 tls_handshake_set_renegotiation(context
->hdsk
, value
);
541 context
->allowRenegotiation
= true;
543 case kSSLSessionOptionEnableSessionTickets
:
544 tls_handshake_set_session_ticket_enabled(context
->hdsk
, value
);
545 context
->enableSessionTickets
= true;
551 return errSecSuccess
;
555 * Determine current value for the specified option in an SSL session.
558 SSLGetSessionOption (SSLContextRef context
,
559 SSLSessionOption option
,
562 if(context
== NULL
|| value
== NULL
) {
566 case kSSLSessionOptionBreakOnServerAuth
:
567 *value
= context
->breakOnServerAuth
;
569 case kSSLSessionOptionBreakOnCertRequested
:
570 *value
= context
->breakOnCertRequest
;
572 case kSSLSessionOptionBreakOnClientAuth
:
573 *value
= context
->breakOnClientAuth
;
575 case kSSLSessionOptionSendOneByteRecord
:
576 *value
= context
->oneByteRecordEnable
;
578 case kSSLSessionOptionFalseStart
:
579 *value
= context
->falseStartEnabled
;
581 case kSSLSessionOptionBreakOnClientHello
:
582 *value
= context
->breakOnClientHello
;
584 case kSSLSessionOptionAllowServerIdentityChange
:
585 tls_handshake_get_server_identity_change(context
->hdsk
, (bool *)value
);
591 return errSecSuccess
;
595 SSLSetRecordContext (SSLContextRef ctx
,
596 SSLRecordContextRef recCtx
)
601 if(sslIsSessionActive(ctx
)) {
602 /* can't do this with an active session */
605 ctx
->recCtx
= recCtx
;
606 return errSecSuccess
;
610 SSLSetIOFuncs (SSLContextRef ctx
,
611 SSLReadFunc readFunc
,
612 SSLWriteFunc writeFunc
)
617 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
618 /* Can Only do this with the internal record layer */
622 if(sslIsSessionActive(ctx
)) {
623 /* can't do this with an active session */
627 ctx
->ioCtx
.read
=readFunc
;
628 ctx
->ioCtx
.write
=writeFunc
;
634 SSLSetNPNFunc(SSLContextRef context
,
638 if (context
== NULL
) {
641 if (sslIsSessionActive(context
)) {
644 context
->npnFunc
= npnFunc
;
645 context
->npnFuncInfo
= info
;
646 if(context
->protocolSide
==kSSLClientSide
) {
647 tls_handshake_set_npn_enable(context
->hdsk
, npnFunc
!=NULL
);
652 SSLSetNPNData(SSLContextRef context
,
656 if (context
== NULL
|| data
== NULL
|| length
== 0) {
666 npn_data
.data
= (uint8_t *)data
;
667 npn_data
.length
= length
;
669 return tls_handshake_set_npn_data(context
->hdsk
, npn_data
);
673 SSLGetNPNData(SSLContextRef context
,
676 if (context
== NULL
|| length
== NULL
)
679 const tls_buffer
*npn_data
;
681 npn_data
= tls_handshake_get_peer_npn_data(context
->hdsk
);
684 *length
= npn_data
->length
;
685 return npn_data
->data
;
694 SSLSetALPNFunc(SSLContextRef context
,
695 SSLALPNFunc alpnFunc
,
698 if (context
== NULL
) {
701 if (sslIsSessionActive(context
)) {
704 context
->alpnFunc
= alpnFunc
;
705 context
->alpnFuncInfo
= info
;
706 if(context
->protocolSide
==kSSLServerSide
) {
712 SSLSetALPNData(SSLContextRef context
,
716 if (context
== NULL
|| data
== NULL
|| length
== 0) {
724 tls_buffer alpn_data
;
726 alpn_data
.data
= (uint8_t *)data
;
727 alpn_data
.length
= length
;
729 return tls_handshake_set_alpn_data(context
->hdsk
, alpn_data
);
733 SSLGetALPNData(SSLContextRef context
,
736 if (context
== NULL
|| length
== NULL
) {
740 const tls_buffer
*alpnData
= tls_handshake_get_peer_alpn_data(context
->hdsk
);
743 *length
= alpnData
->length
;
744 return alpnData
->data
;
751 SSLSetALPNProtocols(SSLContextRef context
,
752 CFArrayRef protocols
)
754 if (context
== NULL
|| protocols
== NULL
|| CFArrayGetCount(protocols
) == 0) {
758 // Per RFC 7301, the protocol name can be at most 32B long.
759 const int maxBufferLength
= 32;
761 // Append each element in the array to a mutable buffer
762 CFMutableDataRef alpnData
= CFDataCreateMutable(NULL
, 0);
763 CFArrayForEach(protocols
, ^(const void *value
) {
764 CFStringRef protocolString
= (CFStringRef
) value
;
765 uint8_t len
= CFStringGetLength(protocolString
);
766 if (len
<= maxBufferLength
) {
767 char stringBytes
[maxBufferLength
];
768 if (CFStringGetCString(protocolString
, stringBytes
, maxBufferLength
, kCFStringEncodingASCII
)) {
769 CFDataAppendBytes(alpnData
, (const UInt8
*) &len
, sizeof(len
));
770 CFDataAppendBytes(alpnData
, (const UInt8
*) stringBytes
, len
);
776 if (CFDataGetLength(alpnData
) > 255) {
781 // Pass the buffer down to coreTLS
783 payload
.data
= (uint8_t *) CFDataGetBytePtr(alpnData
);
784 payload
.length
= CFDataGetLength(alpnData
);
785 int success
= tls_handshake_set_alpn_data(context
->hdsk
, payload
);
787 // Free up memory and return
794 SSLCopyALPNProtocols(SSLContextRef context
,
795 CFArrayRef
*protocolArray
)
797 if (context
== NULL
|| protocolArray
== NULL
) {
801 CFMutableArrayRef array
= CFArrayCreateMutableForCFTypes(NULL
);
803 const tls_buffer
*alpnData
= tls_handshake_get_peer_alpn_data(context
->hdsk
);
807 // Extract each encoded parameter, wrap it in a CFStringRef, and append it to the running list
808 while (offset
< alpnData
->length
) {
809 char length
= alpnData
->data
[offset
];
812 // Make sure we don't exceed the buffer bounds
813 if (offset
+ length
> alpnData
->length
) {
814 CFReleaseNull(array
);
815 *protocolArray
= NULL
;
819 CFStringRef protocol
= CFStringCreateWithBytes(NULL
, alpnData
->data
+ offset
, length
, kCFStringEncodingASCII
, false);
821 CFArrayAppendValue(array
, protocol
);
822 CFReleaseNull(protocol
);
825 if (offset
> alpnData
->length
) {
826 CFReleaseNull(array
);
827 *protocolArray
= NULL
;
832 *protocolArray
= array
;
833 return errSecSuccess
;
835 CFReleaseNull(array
);
836 *protocolArray
= NULL
;
843 // OCSP response begin
846 SSLSetOCSPResponse(SSLContextRef context
,
849 if (context
== NULL
|| response
== NULL
) {
853 tls_buffer responsePayload
;
854 responsePayload
.data
= (uint8_t *) CFDataGetBytePtr(response
);
855 responsePayload
.length
= CFDataGetLength(response
);
857 int success
= tls_handshake_set_ocsp_response(context
->hdsk
, &responsePayload
);
864 SSLSetConnection (SSLContextRef ctx
,
865 SSLConnectionRef connection
)
870 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
871 /* Can Only do this with the internal record layer */
875 if(sslIsSessionActive(ctx
)) {
876 /* can't do this with an active session */
880 /* Need to keep a copy of it this layer for the Get function */
881 ctx
->ioCtx
.ioRef
= connection
;
887 SSLGetConnection (SSLContextRef ctx
,
888 SSLConnectionRef
*connection
)
890 if((ctx
== NULL
) || (connection
== NULL
)) {
893 *connection
= ctx
->ioCtx
.ioRef
;
894 return errSecSuccess
;
898 SSLSetPeerDomainName (SSLContextRef ctx
,
899 const char *peerName
,
905 if(sslIsSessionActive(ctx
)) {
906 /* can't do this with an active session */
910 if(ctx
->protocolSide
== kSSLClientSide
) {
911 return tls_handshake_set_peer_hostname(ctx
->hdsk
, peerName
, peerNameLen
);
913 return 0; // This should probably return an error, but historically didnt.
918 * Determine the buffer size needed for SSLGetPeerDomainName().
921 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
922 size_t *peerNameLen
) // RETURNED
927 const char *hostname
;
929 return tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, peerNameLen
);
933 SSLGetPeerDomainName (SSLContextRef ctx
,
934 char *peerName
, // returned here
935 size_t *peerNameLen
) // IN/OUT
937 const char *hostname
;
946 err
=tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
950 } else if(*peerNameLen
<len
) {
951 return errSSLBufferOverflow
;
953 memcpy(peerName
, hostname
, len
);
960 SSLCopyRequestedPeerNameLength (SSLContextRef ctx
,
961 size_t *peerNameLen
) // RETURNED
963 const tls_buffer
*hostname
;
967 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
971 *peerNameLen
= hostname
->length
;
977 SSLCopyRequestedPeerName (SSLContextRef ctx
,
978 char *peerName
, // returned here
979 size_t *peerNameLen
) // IN/OUT
981 const tls_buffer
*hostname
;
987 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
991 } else if(*peerNameLen
< hostname
->length
) {
992 return errSSLBufferOverflow
;
994 memcpy(peerName
, hostname
->data
, hostname
->length
);
995 *peerNameLen
= hostname
->length
;
1002 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
1012 if(!ctx
->isDTLS
) return errSecParam
;
1014 if((ctx
== NULL
) || (cookieLen
>32)) {
1017 if(sslIsSessionActive(ctx
)) {
1018 /* can't do this with an active session */
1019 return errSecBadReq
;
1022 /* free possible existing cookie */
1023 if(ctx
->dtlsCookie
.data
) {
1024 SSLFreeBuffer(&ctx
->dtlsCookie
);
1028 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
)))
1031 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
1032 return errSecSuccess
;
1036 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
1040 if(ctx
== NULL
) return errSecParam
;
1041 if(!ctx
->isDTLS
) return errSecParam
;
1043 tls_handshake_set_mtu(ctx
->hdsk
, maxSize
);
1045 return errSecSuccess
;
1049 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
1052 if(ctx
== NULL
) return errSecParam
;
1053 if(!ctx
->isDTLS
) return errSecParam
;
1055 *maxSize
= ctx
->mtu
;
1057 return errSecSuccess
;
1062 Keys to to math below:
1064 A DTLS record looks like this: | header (13 bytes) | fragment |
1066 For Null cipher, fragment is clear text as follows:
1069 For block cipher, fragment size must be a multiple of the cipher block size, and is the
1070 encryption of the following plaintext :
1071 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
1073 The maximum content length in that case is achieved for 0 padding bytes.
1078 SSLGetDatagramWriteSize (SSLContextRef ctx
,
1081 if(ctx
== NULL
) return errSecParam
;
1082 if(!ctx
->isDTLS
) return errSecParam
;
1083 if(bufSize
== NULL
) return errSecParam
;
1085 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
1088 SSLCipherSpecParams
*currCipher
= &ctx
->selectedCipherSpecParams
;
1090 size_t blockSize
= currCipher
->blockSize
;
1091 size_t macSize
= currCipher
->macSize
;
1093 size_t blockSize
= 16;
1094 size_t macSize
= 32;
1097 if (blockSize
> 0) {
1098 /* max_fragment_size must be a multiple of blocksize */
1099 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
1100 max_fragment_size
-= blockSize
; /* 1 block for IV */
1101 max_fragment_size
-= 1; /* 1 byte for pad length */
1104 /* less the mac size */
1105 max_fragment_size
-= macSize
;
1107 /* Thats just a sanity check */
1108 assert(max_fragment_size
<ctx
->mtu
);
1110 *bufSize
= max_fragment_size
;
1112 return errSecSuccess
;
1116 All the complexity around protocol version is to support legacy APIs.
1117 Eventually that should go away:
1118 <rdar://problem/20842025> Remove deprecated SecureTransport function related to protocol version selection.
1121 static tls_protocol_version
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
1123 case kSSLProtocol2
: return SSL_Version_2_0
;
1124 case kSSLProtocol3
: return tls_protocol_version_SSL_3
;
1125 case kTLSProtocol1
: return tls_protocol_version_TLS_1_0
;
1126 case kTLSProtocol11
: return tls_protocol_version_TLS_1_1
;
1127 case kTLSProtocol12
: return tls_protocol_version_TLS_1_2
;
1128 case kDTLSProtocol1
: return tls_protocol_version_DTLS_1_0
;
1129 default: return tls_protocol_version_Undertermined
;
1133 /* concert between private SSLProtocolVersion and public SSLProtocol */
1134 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
1137 case tls_protocol_version_SSL_3
: return kSSLProtocol3
;
1138 case tls_protocol_version_TLS_1_0
: return kTLSProtocol1
;
1139 case tls_protocol_version_TLS_1_1
: return kTLSProtocol11
;
1140 case tls_protocol_version_TLS_1_2
: return kTLSProtocol12
;
1141 case tls_protocol_version_DTLS_1_0
: return kDTLSProtocol1
;
1143 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
1146 case tls_protocol_version_Undertermined
: return kSSLProtocolUnknown
;
1151 SSLSetProtocolVersionMin (SSLContextRef ctx
,
1152 SSLProtocol minVersion
)
1154 if(ctx
== NULL
) return errSecParam
;
1156 tls_protocol_version version
= SSLProtocolToProtocolVersion(minVersion
);
1158 if (version
> MINIMUM_DATAGRAM_VERSION
||
1159 version
< MAXIMUM_DATAGRAM_VERSION
)
1160 return errSSLIllegalParam
;
1161 if (version
< ctx
->maxProtocolVersion
)
1162 ctx
->maxProtocolVersion
= version
;
1164 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1165 return errSSLIllegalParam
;
1166 if (version
> ctx
->maxProtocolVersion
)
1167 ctx
->maxProtocolVersion
= version
;
1169 ctx
->minProtocolVersion
= version
;
1171 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1172 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1174 return errSecSuccess
;
1178 SSLGetProtocolVersionMin (SSLContextRef ctx
,
1179 SSLProtocol
*minVersion
)
1181 if(ctx
== NULL
) return errSecParam
;
1183 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
1184 return errSecSuccess
;
1188 SSLSetProtocolVersionMax (SSLContextRef ctx
,
1189 SSLProtocol maxVersion
)
1191 if(ctx
== NULL
) return errSecParam
;
1193 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
1195 if (version
> MINIMUM_DATAGRAM_VERSION
||
1196 version
< MAXIMUM_DATAGRAM_VERSION
)
1197 return errSSLIllegalParam
;
1198 if (version
> ctx
->minProtocolVersion
)
1199 ctx
->minProtocolVersion
= version
;
1201 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1202 return errSSLIllegalParam
;
1203 if (version
< ctx
->minProtocolVersion
)
1204 ctx
->minProtocolVersion
= version
;
1206 ctx
->maxProtocolVersion
= version
;
1208 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1209 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1211 return errSecSuccess
;
1215 SSLGetProtocolVersionMax (SSLContextRef ctx
,
1216 SSLProtocol
*maxVersion
)
1218 if(ctx
== NULL
) return errSecParam
;
1220 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
1221 return errSecSuccess
;
1224 tls_protocol_version
1225 _SSLProtocolVersionToWireFormatValue (SSLProtocol protocol
)
1228 case kSSLProtocol3
: {
1229 return tls_protocol_version_SSL_3
;
1231 case kTLSProtocol1
: {
1232 return tls_protocol_version_TLS_1_0
;
1234 case kTLSProtocol11
: {
1235 return tls_protocol_version_TLS_1_1
;
1237 case kTLSProtocol12
: {
1238 return tls_protocol_version_TLS_1_2
;
1240 case kTLSProtocol13
: {
1241 return tls_protocol_version_TLS_1_3
;
1243 case kTLSProtocolMaxSupported
: {
1244 return tls_protocol_version_TLS_1_3
;
1246 case kDTLSProtocol1
: {
1247 return tls_protocol_version_DTLS_1_0
;
1249 case kSSLProtocolUnknown
: {
1250 return tls_protocol_version_Undertermined
;
1253 case kSSLProtocol3Only
:
1254 case kTLSProtocol1Only
:
1255 case kSSLProtocolAll
: {
1256 sslErrorLog("SSLProtocol %d is deprecated. Setting to the default value (%d)", protocol
, tls_protocol_version_Undertermined
);
1257 return tls_protocol_version_Undertermined
;
1261 return tls_protocol_version_Undertermined
;
1264 #define max(x,y) ((x)<(y)?(y):(x))
1267 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
1268 SSLProtocol protocol
,
1274 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1275 /* Can't do this with an active session, nor with a DTLS session */
1276 return errSecBadReq
;
1278 if (protocol
== kSSLProtocolAll
) {
1280 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1281 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1283 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1284 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1287 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1289 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
1292 if (version
> ctx
->maxProtocolVersion
) {
1293 ctx
->maxProtocolVersion
= version
;
1294 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
1295 ctx
->minProtocolVersion
= version
;
1297 if (version
< ctx
->minProtocolVersion
) {
1298 ctx
->minProtocolVersion
= version
;
1301 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
1304 /* Disabling a protocol version now resets the minimum acceptable
1305 * version to the next higher version. This means it's no longer
1306 * possible to enable a discontiguous set of protocol versions.
1308 SSLProtocolVersion nextVersion
;
1310 case SSL_Version_2_0
:
1311 nextVersion
= SSL_Version_3_0
;
1313 case SSL_Version_3_0
:
1314 nextVersion
= TLS_Version_1_0
;
1316 case TLS_Version_1_0
:
1317 nextVersion
= TLS_Version_1_1
;
1319 case TLS_Version_1_1
:
1320 nextVersion
= TLS_Version_1_2
;
1322 case TLS_Version_1_2
:
1324 nextVersion
= SSL_Version_Undetermined
;
1327 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
1328 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1329 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1330 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1335 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1336 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1338 return errSecSuccess
;
1342 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1343 SSLProtocol protocol
,
1344 Boolean
*enable
) /* RETURNED */
1350 /* Can't do this with a DTLS session */
1351 return errSecBadReq
;
1357 case kTLSProtocol11
:
1358 case kTLSProtocol12
:
1360 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1361 *enable
= (ctx
->minProtocolVersion
<= version
1362 && ctx
->maxProtocolVersion
>= version
);
1365 case kSSLProtocolAll
:
1366 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1367 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1372 return errSecSuccess
;
1377 SSLSetProtocolVersion (SSLContextRef ctx
,
1378 SSLProtocol version
)
1383 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1384 /* Can't do this with an active session, nor with a DTLS session */
1385 return errSecBadReq
;
1390 /* this tells us to do our best, up to 3.0 */
1391 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1392 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1394 case kSSLProtocol3Only
:
1395 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1396 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1399 /* this tells us to do our best, up to TLS, but allows 3.0 */
1400 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1401 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1403 case kTLSProtocol1Only
:
1404 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1405 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1407 case kTLSProtocol11
:
1408 /* This tells us to do our best, up to TLS 1.1, currently also
1409 allows 3.0 or TLS 1.0 */
1410 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1411 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1413 case kTLSProtocol12
:
1414 case kSSLProtocolAll
:
1415 case kSSLProtocolUnknown
:
1416 /* This tells us to do our best, up to TLS 1.2, currently also
1417 allows 3.0 or TLS 1.0 or TLS 1.1 */
1418 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1419 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1425 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1426 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1428 return errSecSuccess
;
1433 SSLGetProtocolVersion (SSLContextRef ctx
,
1434 SSLProtocol
*protocol
) /* RETURNED */
1439 /* translate array of booleans to public value; not all combinations
1440 * are legal (i.e., meaningful) for this call */
1441 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1442 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1443 /* traditional 'all enabled' */
1444 *protocol
= kSSLProtocolAll
;
1445 return errSecSuccess
;
1447 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1448 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1449 /* traditional 'all enabled' */
1450 *protocol
= kTLSProtocol11
;
1451 return errSecSuccess
;
1453 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1454 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1455 /* TLS1.1 and below enabled */
1456 *protocol
= kTLSProtocol1
;
1457 return errSecSuccess
;
1458 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1459 *protocol
= kTLSProtocol1Only
;
1461 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1462 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1463 /* Could also return kSSLProtocol3Only since
1464 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1465 *protocol
= kSSLProtocol3
;
1466 return errSecSuccess
;
1474 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1475 SSLProtocol
*protocol
) /* RETURNED */
1480 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1481 return errSecSuccess
;
1485 SSLSetEnableCertVerify (SSLContextRef ctx
,
1486 Boolean enableVerify
)
1491 sslCertDebug("SSLSetEnableCertVerify %s",
1492 enableVerify
? "true" : "false");
1493 if(sslIsSessionActive(ctx
)) {
1494 /* can't do this with an active session */
1495 return errSecBadReq
;
1497 ctx
->enableCertVerify
= enableVerify
;
1498 return errSecSuccess
;
1502 SSLGetEnableCertVerify (SSLContextRef ctx
,
1503 Boolean
*enableVerify
)
1508 *enableVerify
= ctx
->enableCertVerify
;
1509 return errSecSuccess
;
1513 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1514 Boolean allowExpired
)
1516 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1521 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1522 Boolean
*allowExpired
)
1524 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1525 return errSecUnimplemented
;
1529 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1530 Boolean allowExpired
)
1532 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1537 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1538 Boolean
*allowExpired
)
1540 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1541 return errSecUnimplemented
;
1544 OSStatus
SSLSetAllowsAnyRoot(
1551 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1552 ctx
->allowAnyRoot
= anyRoot
;
1553 return errSecSuccess
;
1557 SSLGetAllowsAnyRoot(
1564 *anyRoot
= ctx
->allowAnyRoot
;
1565 return errSecSuccess
;
1568 #if !TARGET_OS_IPHONE
1569 /* obtain the system roots sets for this app, policy SSL */
1570 static OSStatus
sslDefaultSystemRoots(
1572 CFArrayRef
*systemRoots
) // created and RETURNED
1575 const char *hostname
;
1578 tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
1580 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1583 (ctx
->protocolSide
== kSSLServerSide
) ?
1584 /* server verifies, client encrypts */
1585 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1588 #endif /* OS X only */
1591 SSLSetTrustedRoots (SSLContextRef ctx
,
1592 CFArrayRef trustedRoots
,
1593 Boolean replaceExisting
)
1595 if (sslIsSessionActive(ctx
)) {
1596 /* can't do this with an active session */
1597 return errSecBadReq
;
1599 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1600 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1602 if (replaceExisting
) {
1603 ctx
->trustedCertsOnly
= true;
1604 CFReleaseNull(ctx
->trustedCerts
);
1607 if (ctx
->trustedCerts
) {
1608 CFIndex count
= CFArrayGetCount(trustedRoots
);
1609 CFRange range
= { 0, count
};
1610 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1612 require(ctx
->trustedCerts
=
1613 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1617 return errSecSuccess
;
1620 return errSecAllocate
;
1624 SSLCopyTrustedRoots (SSLContextRef ctx
,
1625 CFArrayRef
*trustedRoots
) /* RETURNED */
1627 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1630 if(ctx
->trustedCerts
!= NULL
) {
1631 *trustedRoots
= ctx
->trustedCerts
;
1632 CFRetain(ctx
->trustedCerts
);
1633 return errSecSuccess
;
1635 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1636 /* use default system roots */
1637 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1639 *trustedRoots
= NULL
;
1640 return errSecSuccess
;
1644 #if !TARGET_OS_IPHONE
1646 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1647 CFArrayRef trustedCerts
)
1652 if(sslIsSessionActive(ctx
)) {
1653 /* can't do this with an active session */
1654 return errSecBadReq
;
1657 if(ctx
->trustedLeafCerts
) {
1658 CFRelease(ctx
->trustedLeafCerts
);
1660 ctx
->trustedLeafCerts
= CFRetainSafe(trustedCerts
);
1661 return errSecSuccess
;
1665 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1666 CFArrayRef
*trustedCerts
) /* RETURNED */
1671 if(ctx
->trustedLeafCerts
!= NULL
) {
1672 *trustedCerts
= ctx
->trustedLeafCerts
;
1673 CFRetain(ctx
->trustedCerts
);
1674 return errSecSuccess
;
1676 *trustedCerts
= NULL
;
1677 return errSecSuccess
;
1682 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1683 SSLAuthenticate auth
)
1688 if(sslIsSessionActive(ctx
)) {
1689 /* can't do this with an active session */
1690 return errSecBadReq
;
1692 ctx
->clientAuth
= auth
;
1694 case kNeverAuthenticate
:
1695 tls_handshake_set_client_auth(ctx
->hdsk
, false);
1697 case kAlwaysAuthenticate
:
1698 case kTryAuthenticate
:
1699 tls_handshake_set_client_auth(ctx
->hdsk
, true);
1702 return errSecSuccess
;
1706 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1707 SSLAuthenticate
*auth
) /* RETURNED */
1709 if(ctx
== NULL
|| auth
== NULL
) {
1712 *auth
= ctx
->clientAuth
;
1713 return errSecSuccess
;
1717 SSLGetClientCertificateState (SSLContextRef ctx
,
1718 SSLClientCertificateState
*clientState
)
1723 if(ctx
->protocolSide
== kSSLClientSide
) {
1725 switch(ctx
->clientCertState
) {
1726 case kSSLClientCertNone
:
1727 *clientState
= kSSLClientCertNone
;
1729 case kSSLClientCertRequested
:
1730 if(ctx
->localCertArray
) {
1731 *clientState
= kSSLClientCertSent
;
1733 *clientState
= kSSLClientCertRequested
;
1737 /* Anything else is an internal error */
1738 sslErrorLog("TLS client has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1739 return errSSLInternal
;
1743 switch(ctx
->clientCertState
) {
1744 case kSSLClientCertNone
:
1745 case kSSLClientCertRejected
:
1746 *clientState
= ctx
->clientCertState
;
1748 case kSSLClientCertRequested
:
1749 if(ctx
->peerSecTrust
) {
1750 *clientState
= kSSLClientCertSent
;
1752 *clientState
= kSSLClientCertRequested
;
1756 /* Anything else is an internal error */
1757 sslErrorLog("TLS server has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1758 return errSSLInternal
;
1761 return errSecSuccess
;
1764 #include <tls_helpers.h>
1767 SSLSetCertificate (SSLContextRef ctx
,
1768 CFArrayRef _Nullable certRefs
)
1772 * -- free localCerts if we have any
1773 * -- Get raw cert data, convert to ctx->localCert
1774 * -- get pub, priv keys from certRef[0]
1775 * -- validate cert chain
1781 CFReleaseNull(ctx
->localCertArray
);
1782 if(certRefs
== NULL
) {
1783 return errSecSuccess
; // we have cleared the cert, as requested
1786 ortn
= tls_helper_set_identity_from_array(ctx
->hdsk
, certRefs
);
1789 ctx
->localCertArray
= certRefs
;
1797 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1798 CFArrayRef certRefs
)
1803 if(sslIsSessionActive(ctx
)) {
1804 /* can't do this with an active session */
1805 return errSecBadReq
;
1807 CFReleaseNull(ctx
->encryptCertArray
);
1808 ctx
->encryptCertArray
= certRefs
;
1810 return errSecSuccess
;
1813 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1814 CFArrayRef
*certRefs
)
1819 *certRefs
= ctx
->localCertArray
;
1820 return errSecSuccess
;
1823 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1824 CFArrayRef
*certRefs
)
1829 *certRefs
= ctx
->encryptCertArray
;
1830 return errSecSuccess
;
1834 SSLSetPeerID (SSLContext
*ctx
,
1840 /* copy peerId to context->peerId */
1846 if(sslIsSessionActive(ctx
) &&
1847 /* kSSLClientCertRequested implies client side */
1848 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1850 return errSecBadReq
;
1852 SSLFreeBuffer(&ctx
->peerID
);
1853 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1857 tls_handshake_set_resumption(ctx
->hdsk
, true);
1858 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1859 return errSecSuccess
;
1863 SSLGetPeerID (SSLContextRef ctx
,
1864 const void **peerID
,
1867 *peerID
= ctx
->peerID
.data
; // may be NULL
1868 *peerIDLen
= ctx
->peerID
.length
;
1869 return errSecSuccess
;
1873 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1874 SSLCipherSuite
*cipherSuite
)
1880 if(!sslIsSessionActive(ctx
)) {
1881 return errSecBadReq
;
1884 *cipherSuite
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
1886 return errSecSuccess
;
1890 * Add an acceptable distinguished name (client authentication only).
1893 SSLAddDistinguishedName(
1904 if(sslIsSessionActive(ctx
)) {
1905 return errSecBadReq
;
1908 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1910 return errSecAllocate
;
1912 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1917 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1918 dn
->next
= ctx
->acceptableDNList
;
1919 ctx
->acceptableDNList
= dn
;
1921 tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
);
1923 return errSecSuccess
;
1926 /* single-cert version of SSLSetCertificateAuthorities() */
1928 sslAddCA(SSLContextRef ctx
,
1929 SecCertificateRef cert
)
1931 OSStatus ortn
= errSecParam
;
1933 /* Get subject from certificate. */
1934 #if TARGET_OS_IPHONE
1935 CFDataRef subjectName
= NULL
;
1936 subjectName
= SecCertificateCopySubjectSequence(cert
);
1937 require(subjectName
, errOut
);
1939 CSSM_DATA_PTR subjectName
= NULL
;
1940 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1941 require_noerr(ortn
, errOut
);
1944 /* add to acceptableCAs as cert, creating array if necessary */
1945 if(ctx
->acceptableCAs
== NULL
) {
1946 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1947 &kCFTypeArrayCallBacks
), errOut
);
1948 if(ctx
->acceptableCAs
== NULL
) {
1949 return errSecAllocate
;
1952 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1954 /* then add this cert's subject name to acceptableDNList */
1955 #if TARGET_OS_IPHONE
1956 ortn
= SSLAddDistinguishedName(ctx
,
1957 CFDataGetBytePtr(subjectName
),
1958 CFDataGetLength(subjectName
));
1960 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1964 #if TARGET_OS_IPHONE
1965 CFReleaseSafe(subjectName
);
1971 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1972 * of acceptable Certificate Authorities (CAs) to present to the client
1973 * when client authentication is performed.
1976 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1977 CFTypeRef certificateOrArray
,
1978 Boolean replaceExisting
)
1981 OSStatus ortn
= errSecSuccess
;
1983 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1984 (ctx
->protocolSide
!= kSSLServerSide
)) {
1987 if(replaceExisting
) {
1989 if(ctx
->acceptableCAs
) {
1990 CFRelease(ctx
->acceptableCAs
);
1991 ctx
->acceptableCAs
= NULL
;
1994 /* else appending */
1996 itemType
= CFGetTypeID(certificateOrArray
);
1997 if(itemType
== SecCertificateGetTypeID()) {
1999 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
2001 else if(itemType
== CFArrayGetTypeID()) {
2002 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
2003 CFIndex numCerts
= CFArrayGetCount(cfa
);
2006 /* array of certs */
2007 for(dex
=0; dex
<numCerts
; dex
++) {
2008 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
2009 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
2012 ortn
= sslAddCA(ctx
, cert
);
2026 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
2027 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
2029 * Caller must CFRelease the returned array.
2032 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
2033 CFArrayRef
*certificates
) /* RETURNED */
2035 if((ctx
== NULL
) || (certificates
== NULL
)) {
2038 if(ctx
->acceptableCAs
== NULL
) {
2039 *certificates
= NULL
;
2040 return errSecSuccess
;
2042 *certificates
= ctx
->acceptableCAs
;
2043 CFRetain(ctx
->acceptableCAs
);
2044 return errSecSuccess
;
2049 * Obtain the list of acceptable distinguished names as provided by
2050 * a server (if the SSLCotextRef is configured as a client), or as
2051 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
2052 * is configured as a server).
2055 SSLCopyDistinguishedNames (SSLContextRef ctx
,
2058 CFMutableArrayRef outArray
= NULL
;
2059 const DNListElem
*dn
;
2061 if((ctx
== NULL
) || (names
== NULL
)) {
2064 if(ctx
->protocolSide
==kSSLServerSide
) {
2065 dn
= ctx
->acceptableDNList
;
2067 dn
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList;
2072 return errSecSuccess
;
2074 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2077 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
2078 CFArrayAppendValue(outArray
, cfDn
);
2083 return errSecSuccess
;
2088 * Request peer certificates. Valid anytime, subsequent to
2089 * a handshake attempt.
2092 SSLCopyPeerCertificates (SSLContextRef ctx
, CFArrayRef
*certs
)
2098 if (!ctx
->peerSecTrust
) {
2100 return errSecBadReq
;
2103 CFIndex count
= SecTrustGetCertificateCount(ctx
->peerSecTrust
);
2104 CFMutableArrayRef ca
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
2106 return errSecAllocate
;
2109 for (CFIndex ix
= 0; ix
< count
; ++ix
) {
2110 CFArrayAppendValue(ca
, SecTrustGetCertificateAtIndex(ctx
->peerSecTrust
, ix
));
2115 return errSecSuccess
;
2118 #if !TARGET_OS_IPHONE
2119 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
2120 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
2122 SSLGetPeerCertificates (SSLContextRef ctx
,
2125 SSLGetPeerCertificates (SSLContextRef ctx
,
2128 return errSecUnimplemented
;
2133 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
2134 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
2135 * been called, a set of process-wide parameters will be calculated. However
2136 * that can take a long time (30 seconds).
2138 OSStatus
SSLSetDiffieHellmanParams(
2140 const void *dhParams
,
2147 if(sslIsSessionActive(ctx
)) {
2148 return errSecBadReq
;
2150 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
2153 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
2154 &ctx
->dhParamsEncoded
);
2159 return tls_handshake_set_dh_parameters(ctx
->hdsk
, &ctx
->dhParamsEncoded
);
2162 #endif /* APPLE_DH */
2166 * Return parameter block specified in SSLSetDiffieHellmanParams.
2167 * Returned data is not copied and belongs to the SSLContextRef.
2169 OSStatus
SSLGetDiffieHellmanParams(
2171 const void **dhParams
,
2172 size_t *dhParamsLen
)
2178 *dhParams
= ctx
->dhParamsEncoded
.data
;
2179 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
2180 return errSecSuccess
;
2182 return errSecUnimplemented
;
2183 #endif /* APPLE_DH */
2186 OSStatus
SSLSetDHEEnabled(SSLContextRef ctx
, bool enabled
)
2188 ctx
->dheEnabled
= enabled
;
2189 /* Hack a little so that only the ciphersuites change */
2190 tls_protocol_version min
, max
;
2192 tls_handshake_get_min_protocol_version(ctx
->hdsk
, &min
);
2193 tls_handshake_get_max_protocol_version(ctx
->hdsk
, &max
);
2194 tls_handshake_get_min_dh_group_size(ctx
->hdsk
, &nbits
);
2195 tls_handshake_set_config(ctx
->hdsk
, enabled
?tls_handshake_config_legacy_DHE
:tls_handshake_config_legacy
);
2196 tls_handshake_set_min_protocol_version(ctx
->hdsk
, min
);
2197 tls_handshake_set_max_protocol_version(ctx
->hdsk
, max
);
2198 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2203 OSStatus
SSLGetDHEEnabled(SSLContextRef ctx
, bool *enabled
)
2205 *enabled
= ctx
->dheEnabled
;
2209 OSStatus
SSLSetMinimumDHGroupSize(SSLContextRef ctx
, unsigned nbits
)
2211 return tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2214 OSStatus
SSLGetMinimumDHGroupSize(SSLContextRef ctx
, unsigned *nbits
)
2216 return tls_handshake_get_min_dh_group_size(ctx
->hdsk
, nbits
);
2219 OSStatus
SSLSetRsaBlinding(
2226 ctx
->rsaBlindingEnable
= blinding
;
2227 return errSecSuccess
;
2230 OSStatus
SSLGetRsaBlinding(
2237 *blinding
= ctx
->rsaBlindingEnable
;
2238 return errSecSuccess
;
2244 SecTrustRef
*trust
) /* RETURNED */
2246 OSStatus status
= errSecSuccess
;
2247 if (ctx
== NULL
|| trust
== NULL
)
2250 /* Create a SecTrustRef if this was a resumed session and we
2251 didn't have one yet. */
2252 if (!ctx
->peerSecTrust
) {
2253 status
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
);
2256 *trust
= ctx
->peerSecTrust
;
2257 if (ctx
->peerSecTrust
)
2258 CFRetain(ctx
->peerSecTrust
);
2263 OSStatus
SSLGetPeerSecTrust(
2265 SecTrustRef
*trust
) /* RETURNED */
2267 OSStatus status
= errSecSuccess
;
2268 if (ctx
== NULL
|| trust
== NULL
)
2271 /* Create a SecTrustRef if this was a resumed session and we
2272 didn't have one yet. */
2273 if (!ctx
->peerSecTrust
) {
2274 status
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
);
2277 *trust
= ctx
->peerSecTrust
;
2281 OSStatus
SSLInternalMasterSecret(
2283 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
2284 size_t *secretSize
) // in/out
2286 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
2289 return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
);
2292 OSStatus
SSLInternalServerRandom(
2294 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2295 size_t *randSize
) // in/out
2297 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2300 return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
);
2303 OSStatus
SSLInternalClientRandom(
2305 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2306 size_t *randSize
) // in/out
2308 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2311 return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
);
2314 /* This is used by EAP 802.1x */
2315 OSStatus
SSLGetCipherSizes(
2318 size_t *symmetricKeySize
,
2321 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2322 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2326 SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
2328 *digestSize
= sslCipherSuiteGetMacSize(cipher
);
2329 *symmetricKeySize
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
);
2330 *ivSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
);
2331 return errSecSuccess
;
2335 SSLGetResumableSessionInfo(
2337 Boolean
*sessionWasResumed
, // RETURNED
2338 void *sessionID
, // RETURNED, mallocd by caller
2339 size_t *sessionIDLength
) // IN/OUT
2341 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2342 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2343 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2347 SSLBuffer localSessionID
;
2348 bool sessionMatch
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
);
2351 *sessionWasResumed
= true;
2352 if(localSessionID
.length
> *sessionIDLength
) {
2353 /* really should never happen - means ID > 32 */
2356 if(localSessionID
.length
) {
2358 * Note PAC-based session resumption can result in sessionMatch
2361 memmove(sessionID
, localSessionID
.data
, localSessionID
.length
);
2363 *sessionIDLength
= localSessionID
.length
;
2366 *sessionWasResumed
= false;
2367 *sessionIDLength
= 0;
2369 return errSecSuccess
;
2373 * Get/set enable of anonymous ciphers. This is deprecated and now a no-op.
2376 SSLSetAllowAnonymousCiphers(
2380 return errSecSuccess
;
2384 SSLGetAllowAnonymousCiphers(
2388 return errSecSuccess
;
2392 * Override the default session cache timeout for a cache entry created for
2393 * the current session.
2396 SSLSetSessionCacheTimeout(
2398 uint32_t timeoutInSeconds
)
2403 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2404 return errSecSuccess
;
2409 void tls_handshake_master_secret_function(const void *arg
, /* opaque to coreTLS; app-specific */
2410 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2411 size_t *secretLength
)
2413 SSLContextRef ctx
= (SSLContextRef
) arg
;
2414 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
);
2419 * Register a callback for obtaining the master_secret when performing
2420 * PAC-based session resumption.
2423 SSLInternalSetMasterSecretFunction(
2425 SSLInternalMasterSecretFunction mFunc
,
2426 const void *arg
) /* opaque to SecureTransport; app-specific */
2432 ctx
->masterSecretArg
= arg
;
2433 ctx
->masterSecretCallback
= mFunc
;
2435 return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
);
2439 * Provide an opaque SessionTicket for use in PAC-based session
2440 * resumption. Client side only. The provided ticket is sent in
2441 * the ClientHello message as a SessionTicket extension.
2443 * We won't reject this on the server side, but server-side support
2444 * for PAC-based session resumption is currently enabled for
2445 * Development builds only. To fully support this for server side,
2446 * besides the rudimentary support that's here for Development builds,
2447 * we'd need a getter for the session ticket, so the app code can
2448 * access the SessionTicket when its SSLInternalMasterSecretFunction
2449 * callback is called.
2451 OSStatus
SSLInternalSetSessionTicket(
2454 size_t ticketLength
)
2459 if(sslIsSessionActive(ctx
)) {
2460 /* can't do this with an active session */
2461 return errSecBadReq
;
2463 return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
);
2468 * ECDSA curve accessors.
2472 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2473 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2475 OSStatus
SSLGetNegotiatedCurve(
2477 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2479 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2482 unsigned int curve
= tls_handshake_get_negotiated_curve(ctx
->hdsk
);
2483 if(curve
== SSL_Curve_None
) {
2486 *namedCurve
= curve
;
2487 return errSecSuccess
;
2491 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2493 OSStatus
SSLGetNumberOfECDSACurves(
2495 unsigned *numCurves
) /* RETURNED */
2497 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2500 *numCurves
= ctx
->ecdhNumCurves
;
2501 return errSecSuccess
;
2505 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2507 OSStatus
SSLGetECDSACurves(
2509 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2510 unsigned *numCurves
) /* IN/OUT */
2512 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2515 if(*numCurves
< ctx
->ecdhNumCurves
) {
2518 memmove(namedCurves
, ctx
->ecdhCurves
,
2519 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2520 *numCurves
= ctx
->ecdhNumCurves
;
2521 return errSecSuccess
;
2525 * Specify ordered list of allowable named curves.
2527 OSStatus
SSLSetECDSACurves(
2529 const SSL_ECDSA_NamedCurve
*namedCurves
,
2532 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2535 if(sslIsSessionActive(ctx
)) {
2536 /* can't do this with an active session */
2537 return errSecBadReq
;
2540 size_t size
= numCurves
* sizeof(uint16_t);
2541 ctx
->ecdhCurves
= (uint16_t *)sslMalloc(size
);
2542 if(ctx
->ecdhCurves
== NULL
) {
2543 ctx
->ecdhNumCurves
= 0;
2544 return errSecAllocate
;
2547 for (unsigned i
=0; i
<numCurves
; i
++) {
2548 ctx
->ecdhCurves
[i
] = namedCurves
[i
];
2551 ctx
->ecdhNumCurves
= numCurves
;
2553 tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
);
2554 return errSecSuccess
;
2558 * Obtain the number of client authentication mechanisms specified by
2559 * the server in its Certificate Request message.
2560 * Returns errSecParam if server hasn't sent a Certificate Request message
2561 * (i.e., client certificate state is kSSLClientCertNone).
2563 OSStatus
SSLGetNumberOfClientAuthTypes(
2567 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2570 *numTypes
= ctx
->numAuthTypes
;
2571 return errSecSuccess
;
2575 * Obtain the client authentication mechanisms specified by
2576 * the server in its Certificate Request message.
2577 * Caller allocates returned array and specifies its size (in
2578 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2579 * is the actual size of the returned array on successful return.
2581 OSStatus
SSLGetClientAuthTypes(
2583 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2584 unsigned *numTypes
) /* IN/OUT */
2586 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2589 memmove(authTypes
, ctx
->clientAuthTypes
,
2590 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2591 *numTypes
= ctx
->numAuthTypes
;
2592 return errSecSuccess
;
2596 * -- DEPRECATED -- Return errSecUnimplemented.
2598 OSStatus
SSLGetNegotiatedClientAuthType(
2600 SSLClientAuthenticationType
*authType
) /* RETURNED */
2602 return errSecUnimplemented
;
2605 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2607 unsigned *numSigAlgs
)
2613 tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
);
2614 return errSecSuccess
;
2617 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
),
2618 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2620 OSStatus
SSLGetSignatureAlgorithms(
2622 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2623 unsigned *numSigAlgs
) /* IN/OUT */
2629 unsigned numPeerSigAlgs
;
2630 const tls_signature_and_hash_algorithm
*peerAlgs
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
);
2632 memmove(sigAlgs
, peerAlgs
,
2633 numPeerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2634 *numSigAlgs
= numPeerSigAlgs
;
2635 return errSecSuccess
;
2639 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2643 if(ctx
== NULL
) return errSecParam
;
2645 if(ctx
->pskSharedSecret
.data
)
2646 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2648 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2649 return errSecAllocate
;
2651 tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
);
2653 return errSecSuccess
;
2656 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2657 const void *pskIdentity
,
2658 size_t pskIdentityLen
)
2660 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2662 if(ctx
->pskIdentity
.data
)
2663 SSLFreeBuffer(&ctx
->pskIdentity
);
2665 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2666 return errSecAllocate
;
2668 tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
);
2670 return errSecSuccess
;
2674 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2675 const void **pskIdentity
,
2676 size_t *pskIdentityLen
)
2678 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2680 *pskIdentity
=ctx
->pskIdentity
.data
;
2681 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2683 return errSecSuccess
;
2686 OSStatus
SSLInternal_PRF(
2688 const void *vsecret
,
2690 const void *label
, // optional, NULL implies that seed contains
2695 void *vout
, // mallocd by caller, length >= outLen
2698 return tls_handshake_internal_prf(ctx
->hdsk
,
2705 const CFStringRef kSSLSessionConfig_default
= CFSTR("default");
2706 const CFStringRef kSSLSessionConfig_ATSv1
= CFSTR("ATSv1");
2707 const CFStringRef kSSLSessionConfig_ATSv1_noPFS
= CFSTR("ATSv1_noPFS");
2708 const CFStringRef kSSLSessionConfig_legacy
= CFSTR("legacy");
2709 const CFStringRef kSSLSessionConfig_standard
= CFSTR("standard");
2710 const CFStringRef kSSLSessionConfig_RC4_fallback
= CFSTR("RC4_fallback");
2711 const CFStringRef kSSLSessionConfig_TLSv1_fallback
= CFSTR("TLSv1_fallback");
2712 const CFStringRef kSSLSessionConfig_TLSv1_RC4_fallback
= CFSTR("TLSv1_RC4_fallback");
2713 const CFStringRef kSSLSessionConfig_legacy_DHE
= CFSTR("legacy_DHE");
2714 const CFStringRef kSSLSessionConfig_anonymous
= CFSTR("anonymous");
2715 const CFStringRef kSSLSessionConfig_3DES_fallback
= CFSTR("3DES_fallback");
2716 const CFStringRef kSSLSessionConfig_TLSv1_3DES_fallback
= CFSTR("TLSv1_3DES_fallback");
2720 tls_handshake_config_t
SSLSessionConfig_to_tls_handshake_config(CFStringRef config
)
2722 if(CFEqual(config
, kSSLSessionConfig_ATSv1
)){
2723 return tls_handshake_config_ATSv1
;
2724 } else if(CFEqual(config
, kSSLSessionConfig_ATSv1_noPFS
)){
2725 return tls_handshake_config_ATSv1_noPFS
;
2726 } else if(CFEqual(config
, kSSLSessionConfig_standard
)){
2727 return tls_handshake_config_standard
;
2728 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_fallback
)){
2729 return tls_handshake_config_TLSv1_fallback
;
2730 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_RC4_fallback
)){
2731 return tls_handshake_config_TLSv1_RC4_fallback
;
2732 } else if(CFEqual(config
, kSSLSessionConfig_RC4_fallback
)){
2733 return tls_handshake_config_RC4_fallback
;
2734 } else if(CFEqual(config
, kSSLSessionConfig_3DES_fallback
)){
2735 return tls_handshake_config_3DES_fallback
;
2736 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_3DES_fallback
)){
2737 return tls_handshake_config_TLSv1_3DES_fallback
;
2738 } else if(CFEqual(config
, kSSLSessionConfig_legacy
)){
2739 return tls_handshake_config_legacy
;
2740 } else if(CFEqual(config
, kSSLSessionConfig_legacy_DHE
)){
2741 return tls_handshake_config_legacy_DHE
;
2742 } else if(CFEqual(config
, kSSLSessionConfig_anonymous
)){
2743 return tls_handshake_config_anonymous
;
2744 } else if(CFEqual(config
, kSSLSessionConfig_default
)){
2745 return tls_handshake_config_default
;
2747 return tls_handshake_config_none
;
2751 /* Set Predefined TLS Configuration */
2753 SSLSetSessionConfig(SSLContextRef context
,
2756 tls_handshake_config_t cfg
= SSLSessionConfig_to_tls_handshake_config(config
);
2758 return tls_handshake_set_config(context
->hdsk
, cfg
);
2765 SSLGetSessionConfigurationIdentifier(SSLContext
*ctx
, SSLBuffer
*buffer
)
2767 if (buffer
== NULL
) {
2771 // Don't recompute the buffer if we've done it before and cached the result.
2772 // Just copy out the result.
2773 if (ctx
->contextConfigurationBuffer
.data
!= NULL
) {
2774 buffer
->length
= ctx
->contextConfigurationBuffer
.length
;
2775 buffer
->data
= (uint8_t *) malloc(buffer
->length
);
2776 if (buffer
->data
== NULL
) {
2777 return errSecAllocate
;
2779 memcpy(buffer
->data
, ctx
->contextConfigurationBuffer
.data
, buffer
->length
);
2780 return errSecSuccess
;
2783 // Allocate the buffer, freeing up any data that was previously stored
2784 // 10 here is the number of attributes we're adding below. Change it as needed.
2785 buffer
->length
= 10 * sizeof(Boolean
);
2789 buffer
->data
= malloc(buffer
->length
);
2790 if (buffer
->data
== NULL
) {
2791 return errSecAllocate
;
2794 // Copy in the session configuration options
2796 memcpy(buffer
->data
+ offset
, &ctx
->breakOnServerAuth
, sizeof(ctx
->breakOnServerAuth
));
2797 offset
+= sizeof(ctx
->breakOnServerAuth
);
2799 memcpy(buffer
->data
+ offset
, &ctx
->breakOnCertRequest
, sizeof(ctx
->breakOnCertRequest
));
2800 offset
+= sizeof(ctx
->breakOnCertRequest
);
2802 memcpy(buffer
->data
+ offset
, &ctx
->breakOnClientAuth
, sizeof(ctx
->breakOnClientAuth
));
2803 offset
+= sizeof(ctx
->breakOnClientAuth
);
2805 memcpy(buffer
->data
+ offset
, &ctx
->signalServerAuth
, sizeof(ctx
->signalServerAuth
));
2806 offset
+= sizeof(ctx
->signalServerAuth
);
2808 memcpy(buffer
->data
+ offset
, &ctx
->signalCertRequest
, sizeof(ctx
->signalCertRequest
));
2809 offset
+= sizeof(ctx
->signalCertRequest
);
2811 memcpy(buffer
->data
+ offset
, &ctx
->signalClientAuth
, sizeof(ctx
->signalClientAuth
));
2812 offset
+= sizeof(ctx
->signalClientAuth
);
2814 memcpy(buffer
->data
+ offset
, &ctx
->breakOnClientHello
, sizeof(ctx
->breakOnClientHello
));
2815 offset
+= sizeof(ctx
->breakOnClientHello
);
2817 memcpy(buffer
->data
+ offset
, &ctx
->allowServerIdentityChange
, sizeof(ctx
->allowServerIdentityChange
));
2818 offset
+= sizeof(ctx
->allowServerIdentityChange
);
2820 memcpy(buffer
->data
+ offset
, &ctx
->allowRenegotiation
, sizeof(ctx
->allowRenegotiation
));
2821 offset
+= sizeof(ctx
->allowRenegotiation
);
2823 memcpy(buffer
->data
+ offset
, &ctx
->enableSessionTickets
, sizeof(ctx
->enableSessionTickets
));
2824 offset
+= sizeof(ctx
->enableSessionTickets
);
2826 // Sanity check on the length
2827 if (offset
!= buffer
->length
) {
2829 return errSecInternal
;
2832 // Save the configuration buffer for later use
2833 ctx
->contextConfigurationBuffer
.length
= buffer
->length
;
2834 ctx
->contextConfigurationBuffer
.data
= (uint8_t *) malloc(buffer
->length
);
2835 memcpy(ctx
->contextConfigurationBuffer
.data
, buffer
->data
, buffer
->length
);
2837 return errSecSuccess
;