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
> (SSLProtocolVersion
)ctx
->minProtocolVersion
)
1199 ctx
->minProtocolVersion
= version
;
1201 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1202 return errSSLIllegalParam
;
1203 if (version
< (SSLProtocolVersion
)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 kDTLSProtocol12
: {
1250 return tls_protocol_version_DTLS_1_2
;
1252 case kSSLProtocolUnknown
: {
1253 return tls_protocol_version_Undertermined
;
1256 case kSSLProtocol3Only
:
1257 case kTLSProtocol1Only
:
1258 case kSSLProtocolAll
: {
1259 sslErrorLog("SSLProtocol %d is deprecated. Setting to the default value (%d)", protocol
, tls_protocol_version_Undertermined
);
1260 return tls_protocol_version_Undertermined
;
1264 return tls_protocol_version_Undertermined
;
1267 #define max(x,y) ((x)<(y)?(y):(x))
1270 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
1271 SSLProtocol protocol
,
1277 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1278 /* Can't do this with an active session, nor with a DTLS session */
1279 return errSecBadReq
;
1281 if (protocol
== kSSLProtocolAll
) {
1283 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1284 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1286 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1287 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1290 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1292 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
1295 if (version
> (SSLProtocolVersion
)ctx
->maxProtocolVersion
) {
1296 ctx
->maxProtocolVersion
= version
;
1297 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
1298 ctx
->minProtocolVersion
= version
;
1300 if (version
< (SSLProtocolVersion
)ctx
->minProtocolVersion
) {
1301 ctx
->minProtocolVersion
= version
;
1304 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
1307 /* Disabling a protocol version now resets the minimum acceptable
1308 * version to the next higher version. This means it's no longer
1309 * possible to enable a discontiguous set of protocol versions.
1311 SSLProtocolVersion nextVersion
;
1313 case SSL_Version_2_0
:
1314 nextVersion
= SSL_Version_3_0
;
1316 case SSL_Version_3_0
:
1317 nextVersion
= TLS_Version_1_0
;
1319 case TLS_Version_1_0
:
1320 nextVersion
= TLS_Version_1_1
;
1322 case TLS_Version_1_1
:
1323 nextVersion
= TLS_Version_1_2
;
1325 case TLS_Version_1_2
:
1327 nextVersion
= SSL_Version_Undetermined
;
1330 ctx
->minProtocolVersion
= (tls_protocol_version
)max((SSLProtocolVersion
)ctx
->minProtocolVersion
, nextVersion
);
1331 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1332 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1333 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1338 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1339 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1341 return errSecSuccess
;
1345 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1346 SSLProtocol protocol
,
1347 Boolean
*enable
) /* RETURNED */
1353 /* Can't do this with a DTLS session */
1354 return errSecBadReq
;
1360 case kTLSProtocol11
:
1361 case kTLSProtocol12
:
1363 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1364 *enable
= ((SSLProtocolVersion
)ctx
->minProtocolVersion
<= version
1365 && (SSLProtocolVersion
)ctx
->maxProtocolVersion
>= version
);
1368 case kSSLProtocolAll
:
1369 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1370 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1375 return errSecSuccess
;
1380 SSLSetProtocolVersion (SSLContextRef ctx
,
1381 SSLProtocol version
)
1386 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1387 /* Can't do this with an active session, nor with a DTLS session */
1388 return errSecBadReq
;
1393 /* this tells us to do our best, up to 3.0 */
1394 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1395 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1397 case kSSLProtocol3Only
:
1398 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1399 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1402 /* this tells us to do our best, up to TLS, but allows 3.0 */
1403 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1404 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1406 case kTLSProtocol1Only
:
1407 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1408 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1410 case kTLSProtocol11
:
1411 /* This tells us to do our best, up to TLS 1.1, currently also
1412 allows 3.0 or TLS 1.0 */
1413 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1414 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1416 case kTLSProtocol12
:
1417 case kSSLProtocolAll
:
1418 case kSSLProtocolUnknown
:
1419 /* This tells us to do our best, up to TLS 1.2, currently also
1420 allows 3.0 or TLS 1.0 or TLS 1.1 */
1421 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1422 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1428 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1429 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1431 return errSecSuccess
;
1436 SSLGetProtocolVersion (SSLContextRef ctx
,
1437 SSLProtocol
*protocol
) /* RETURNED */
1442 /* translate array of booleans to public value; not all combinations
1443 * are legal (i.e., meaningful) for this call */
1444 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1445 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1446 /* traditional 'all enabled' */
1447 *protocol
= kSSLProtocolAll
;
1448 return errSecSuccess
;
1450 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1451 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1452 /* traditional 'all enabled' */
1453 *protocol
= kTLSProtocol11
;
1454 return errSecSuccess
;
1456 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1457 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1458 /* TLS1.1 and below enabled */
1459 *protocol
= kTLSProtocol1
;
1460 return errSecSuccess
;
1461 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1462 *protocol
= kTLSProtocol1Only
;
1464 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1465 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1466 /* Could also return kSSLProtocol3Only since
1467 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1468 *protocol
= kSSLProtocol3
;
1469 return errSecSuccess
;
1477 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1478 SSLProtocol
*protocol
) /* RETURNED */
1483 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1484 return errSecSuccess
;
1488 SSLSetEnableCertVerify (SSLContextRef ctx
,
1489 Boolean enableVerify
)
1494 sslCertDebug("SSLSetEnableCertVerify %s",
1495 enableVerify
? "true" : "false");
1496 if(sslIsSessionActive(ctx
)) {
1497 /* can't do this with an active session */
1498 return errSecBadReq
;
1500 ctx
->enableCertVerify
= enableVerify
;
1501 return errSecSuccess
;
1505 SSLGetEnableCertVerify (SSLContextRef ctx
,
1506 Boolean
*enableVerify
)
1511 *enableVerify
= ctx
->enableCertVerify
;
1512 return errSecSuccess
;
1516 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1517 Boolean allowExpired
)
1519 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1524 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1525 Boolean
*allowExpired
)
1527 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1528 return errSecUnimplemented
;
1532 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1533 Boolean allowExpired
)
1535 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1540 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1541 Boolean
*allowExpired
)
1543 /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1544 return errSecUnimplemented
;
1547 OSStatus
SSLSetAllowsAnyRoot(
1554 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1555 ctx
->allowAnyRoot
= anyRoot
;
1556 return errSecSuccess
;
1560 SSLGetAllowsAnyRoot(
1567 *anyRoot
= ctx
->allowAnyRoot
;
1568 return errSecSuccess
;
1571 #if !TARGET_OS_IPHONE
1572 /* obtain the system roots sets for this app, policy SSL */
1573 static OSStatus
sslDefaultSystemRoots(
1575 CFArrayRef
*systemRoots
) // created and RETURNED
1578 const char *hostname
;
1581 tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
1583 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1586 (ctx
->protocolSide
== kSSLServerSide
) ?
1587 /* server verifies, client encrypts */
1588 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1591 #endif /* OS X only */
1594 SSLSetTrustedRoots (SSLContextRef ctx
,
1595 CFArrayRef trustedRoots
,
1596 Boolean replaceExisting
)
1598 if (sslIsSessionActive(ctx
)) {
1599 /* can't do this with an active session */
1600 return errSecBadReq
;
1602 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1603 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1605 if (replaceExisting
) {
1606 ctx
->trustedCertsOnly
= true;
1607 CFReleaseNull(ctx
->trustedCerts
);
1610 if (ctx
->trustedCerts
) {
1611 CFIndex count
= CFArrayGetCount(trustedRoots
);
1612 CFRange range
= { 0, count
};
1613 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1615 require(ctx
->trustedCerts
=
1616 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1620 return errSecSuccess
;
1623 return errSecAllocate
;
1627 SSLCopyTrustedRoots (SSLContextRef ctx
,
1628 CFArrayRef
*trustedRoots
) /* RETURNED */
1630 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1633 if(ctx
->trustedCerts
!= NULL
) {
1634 *trustedRoots
= ctx
->trustedCerts
;
1635 CFRetain(ctx
->trustedCerts
);
1636 return errSecSuccess
;
1639 /* use default system roots */
1640 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1642 *trustedRoots
= NULL
;
1643 return errSecSuccess
;
1647 #if !TARGET_OS_IPHONE
1649 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1650 CFArrayRef trustedCerts
)
1655 if(sslIsSessionActive(ctx
)) {
1656 /* can't do this with an active session */
1657 return errSecBadReq
;
1660 if(ctx
->trustedLeafCerts
) {
1661 CFRelease(ctx
->trustedLeafCerts
);
1663 ctx
->trustedLeafCerts
= CFRetainSafe(trustedCerts
);
1664 return errSecSuccess
;
1668 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1669 CFArrayRef
*trustedCerts
) /* RETURNED */
1674 if(ctx
->trustedLeafCerts
!= NULL
) {
1675 *trustedCerts
= ctx
->trustedLeafCerts
;
1676 CFRetain(ctx
->trustedCerts
);
1677 return errSecSuccess
;
1679 *trustedCerts
= NULL
;
1680 return errSecSuccess
;
1685 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1686 SSLAuthenticate auth
)
1691 if(sslIsSessionActive(ctx
)) {
1692 /* can't do this with an active session */
1693 return errSecBadReq
;
1695 ctx
->clientAuth
= auth
;
1697 case kNeverAuthenticate
:
1698 tls_handshake_set_client_auth(ctx
->hdsk
, false);
1700 case kAlwaysAuthenticate
:
1701 case kTryAuthenticate
:
1702 tls_handshake_set_client_auth(ctx
->hdsk
, true);
1705 return errSecSuccess
;
1709 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1710 SSLAuthenticate
*auth
) /* RETURNED */
1712 if(ctx
== NULL
|| auth
== NULL
) {
1715 *auth
= ctx
->clientAuth
;
1716 return errSecSuccess
;
1720 SSLGetClientCertificateState (SSLContextRef ctx
,
1721 SSLClientCertificateState
*clientState
)
1726 if(ctx
->protocolSide
== kSSLClientSide
) {
1728 switch(ctx
->clientCertState
) {
1729 case kSSLClientCertNone
:
1730 *clientState
= kSSLClientCertNone
;
1732 case kSSLClientCertRequested
:
1733 if(ctx
->localCertArray
) {
1734 *clientState
= kSSLClientCertSent
;
1736 *clientState
= kSSLClientCertRequested
;
1740 /* Anything else is an internal error */
1741 sslErrorLog("TLS client has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1742 return errSSLInternal
;
1746 switch(ctx
->clientCertState
) {
1747 case kSSLClientCertNone
:
1748 case kSSLClientCertRejected
:
1749 *clientState
= ctx
->clientCertState
;
1751 case kSSLClientCertRequested
:
1752 if(ctx
->peerSecTrust
) {
1753 *clientState
= kSSLClientCertSent
;
1755 *clientState
= kSSLClientCertRequested
;
1759 /* Anything else is an internal error */
1760 sslErrorLog("TLS server has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1761 return errSSLInternal
;
1764 return errSecSuccess
;
1767 #include <tls_helpers.h>
1770 SSLSetCertificate (SSLContextRef ctx
,
1771 CFArrayRef _Nullable certRefs
)
1775 * -- free localCerts if we have any
1776 * -- Get raw cert data, convert to ctx->localCert
1777 * -- get pub, priv keys from certRef[0]
1778 * -- validate cert chain
1784 CFReleaseNull(ctx
->localCertArray
);
1785 if(certRefs
== NULL
) {
1786 return errSecSuccess
; // we have cleared the cert, as requested
1789 ortn
= tls_helper_set_identity_from_array(ctx
->hdsk
, certRefs
);
1792 ctx
->localCertArray
= certRefs
;
1800 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1801 CFArrayRef certRefs
)
1806 if(sslIsSessionActive(ctx
)) {
1807 /* can't do this with an active session */
1808 return errSecBadReq
;
1810 CFReleaseNull(ctx
->encryptCertArray
);
1811 ctx
->encryptCertArray
= certRefs
;
1813 return errSecSuccess
;
1816 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1817 CFArrayRef
*certRefs
)
1822 *certRefs
= ctx
->localCertArray
;
1823 return errSecSuccess
;
1826 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1827 CFArrayRef
*certRefs
)
1832 *certRefs
= ctx
->encryptCertArray
;
1833 return errSecSuccess
;
1837 SSLSetPeerID (SSLContext
*ctx
,
1843 /* copy peerId to context->peerId */
1849 if(sslIsSessionActive(ctx
) &&
1850 /* kSSLClientCertRequested implies client side */
1851 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1853 return errSecBadReq
;
1855 SSLFreeBuffer(&ctx
->peerID
);
1856 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1860 tls_handshake_set_resumption(ctx
->hdsk
, true);
1861 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1862 return errSecSuccess
;
1866 SSLGetPeerID (SSLContextRef ctx
,
1867 const void **peerID
,
1870 *peerID
= ctx
->peerID
.data
; // may be NULL
1871 *peerIDLen
= ctx
->peerID
.length
;
1872 return errSecSuccess
;
1876 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1877 SSLCipherSuite
*cipherSuite
)
1883 if(!sslIsSessionActive(ctx
)) {
1884 return errSecBadReq
;
1887 *cipherSuite
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
1889 return errSecSuccess
;
1893 * Add an acceptable distinguished name (client authentication only).
1896 SSLAddDistinguishedName(
1907 if(sslIsSessionActive(ctx
)) {
1908 return errSecBadReq
;
1911 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1913 return errSecAllocate
;
1915 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1920 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1921 dn
->next
= ctx
->acceptableDNList
;
1922 ctx
->acceptableDNList
= dn
;
1924 tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
);
1926 return errSecSuccess
;
1929 /* single-cert version of SSLSetCertificateAuthorities() */
1931 sslAddCA(SSLContextRef ctx
,
1932 SecCertificateRef cert
)
1934 OSStatus ortn
= errSecParam
;
1936 /* Get subject from certificate. */
1937 #if TARGET_OS_IPHONE
1938 CFDataRef subjectName
= NULL
;
1939 subjectName
= SecCertificateCopySubjectSequence(cert
);
1940 require(subjectName
, errOut
);
1942 CSSM_DATA_PTR subjectName
= NULL
;
1943 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1944 require_noerr(ortn
, errOut
);
1947 /* add to acceptableCAs as cert, creating array if necessary */
1948 if(ctx
->acceptableCAs
== NULL
) {
1949 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1950 &kCFTypeArrayCallBacks
), errOut
);
1951 if(ctx
->acceptableCAs
== NULL
) {
1952 return errSecAllocate
;
1955 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1957 /* then add this cert's subject name to acceptableDNList */
1958 #if TARGET_OS_IPHONE
1959 ortn
= SSLAddDistinguishedName(ctx
,
1960 CFDataGetBytePtr(subjectName
),
1961 CFDataGetLength(subjectName
));
1963 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1967 #if TARGET_OS_IPHONE
1968 CFReleaseSafe(subjectName
);
1974 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1975 * of acceptable Certificate Authorities (CAs) to present to the client
1976 * when client authentication is performed.
1979 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1980 CFTypeRef certificateOrArray
,
1981 Boolean replaceExisting
)
1984 OSStatus ortn
= errSecSuccess
;
1986 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1987 (ctx
->protocolSide
!= kSSLServerSide
)) {
1990 if(replaceExisting
) {
1992 if(ctx
->acceptableCAs
) {
1993 CFRelease(ctx
->acceptableCAs
);
1994 ctx
->acceptableCAs
= NULL
;
1997 /* else appending */
1999 itemType
= CFGetTypeID(certificateOrArray
);
2000 if(itemType
== SecCertificateGetTypeID()) {
2002 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
2004 else if(itemType
== CFArrayGetTypeID()) {
2005 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
2006 CFIndex numCerts
= CFArrayGetCount(cfa
);
2009 /* array of certs */
2010 for(dex
=0; dex
<numCerts
; dex
++) {
2011 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
2012 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
2015 ortn
= sslAddCA(ctx
, cert
);
2029 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
2030 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
2032 * Caller must CFRelease the returned array.
2035 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
2036 CFArrayRef
*certificates
) /* RETURNED */
2038 if((ctx
== NULL
) || (certificates
== NULL
)) {
2041 if(ctx
->acceptableCAs
== NULL
) {
2042 *certificates
= NULL
;
2043 return errSecSuccess
;
2045 *certificates
= ctx
->acceptableCAs
;
2046 CFRetain(ctx
->acceptableCAs
);
2047 return errSecSuccess
;
2052 * Obtain the list of acceptable distinguished names as provided by
2053 * a server (if the SSLCotextRef is configured as a client), or as
2054 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
2055 * is configured as a server).
2058 SSLCopyDistinguishedNames (SSLContextRef ctx
,
2061 CFMutableArrayRef outArray
= NULL
;
2062 const DNListElem
*dn
;
2064 if((ctx
== NULL
) || (names
== NULL
)) {
2067 if(ctx
->protocolSide
==kSSLServerSide
) {
2068 dn
= ctx
->acceptableDNList
;
2070 dn
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList;
2075 return errSecSuccess
;
2077 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2080 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
2081 CFArrayAppendValue(outArray
, cfDn
);
2086 return errSecSuccess
;
2091 * Request peer certificates. Valid anytime, subsequent to
2092 * a handshake attempt.
2095 SSLCopyPeerCertificates (SSLContextRef ctx
, CFArrayRef
*certs
)
2101 if (!ctx
->peerSecTrust
) {
2103 return errSecBadReq
;
2106 CFIndex count
= SecTrustGetCertificateCount(ctx
->peerSecTrust
);
2107 CFMutableArrayRef ca
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
2109 return errSecAllocate
;
2112 for (CFIndex ix
= 0; ix
< count
; ++ix
) {
2113 CFArrayAppendValue(ca
, SecTrustGetCertificateAtIndex(ctx
->peerSecTrust
, ix
));
2118 return errSecSuccess
;
2121 #if !TARGET_OS_IPHONE
2122 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
2123 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
2125 SSLGetPeerCertificates (SSLContextRef ctx
,
2128 SSLGetPeerCertificates (SSLContextRef ctx
,
2131 return errSecUnimplemented
;
2136 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
2137 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
2138 * been called, a set of process-wide parameters will be calculated. However
2139 * that can take a long time (30 seconds).
2141 OSStatus
SSLSetDiffieHellmanParams(
2143 const void *dhParams
,
2150 if(sslIsSessionActive(ctx
)) {
2151 return errSecBadReq
;
2153 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
2156 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
2157 &ctx
->dhParamsEncoded
);
2162 return tls_handshake_set_dh_parameters(ctx
->hdsk
, &ctx
->dhParamsEncoded
);
2165 #endif /* APPLE_DH */
2169 * Return parameter block specified in SSLSetDiffieHellmanParams.
2170 * Returned data is not copied and belongs to the SSLContextRef.
2172 OSStatus
SSLGetDiffieHellmanParams(
2174 const void **dhParams
,
2175 size_t *dhParamsLen
)
2181 *dhParams
= ctx
->dhParamsEncoded
.data
;
2182 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
2183 return errSecSuccess
;
2185 return errSecUnimplemented
;
2186 #endif /* APPLE_DH */
2189 OSStatus
SSLSetDHEEnabled(SSLContextRef ctx
, bool enabled
)
2191 ctx
->dheEnabled
= enabled
;
2192 /* Hack a little so that only the ciphersuites change */
2193 tls_protocol_version min
, max
;
2195 tls_handshake_get_min_protocol_version(ctx
->hdsk
, &min
);
2196 tls_handshake_get_max_protocol_version(ctx
->hdsk
, &max
);
2197 tls_handshake_get_min_dh_group_size(ctx
->hdsk
, &nbits
);
2198 tls_handshake_set_config(ctx
->hdsk
, enabled
?tls_handshake_config_legacy_DHE
:tls_handshake_config_legacy
);
2199 tls_handshake_set_min_protocol_version(ctx
->hdsk
, min
);
2200 tls_handshake_set_max_protocol_version(ctx
->hdsk
, max
);
2201 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2206 OSStatus
SSLGetDHEEnabled(SSLContextRef ctx
, bool *enabled
)
2208 *enabled
= ctx
->dheEnabled
;
2212 OSStatus
SSLSetMinimumDHGroupSize(SSLContextRef ctx
, unsigned nbits
)
2214 return tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2217 OSStatus
SSLGetMinimumDHGroupSize(SSLContextRef ctx
, unsigned *nbits
)
2219 return tls_handshake_get_min_dh_group_size(ctx
->hdsk
, nbits
);
2222 OSStatus
SSLSetRsaBlinding(
2229 ctx
->rsaBlindingEnable
= blinding
;
2230 return errSecSuccess
;
2233 OSStatus
SSLGetRsaBlinding(
2240 *blinding
= ctx
->rsaBlindingEnable
;
2241 return errSecSuccess
;
2247 SecTrustRef
*trust
) /* RETURNED */
2249 OSStatus status
= errSecSuccess
;
2250 if (ctx
== NULL
|| trust
== NULL
)
2253 /* Create a SecTrustRef if this was a resumed session and we
2254 didn't have one yet. */
2255 if (!ctx
->peerSecTrust
) {
2256 status
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
);
2259 *trust
= ctx
->peerSecTrust
;
2260 if (ctx
->peerSecTrust
)
2261 CFRetain(ctx
->peerSecTrust
);
2266 OSStatus
SSLGetPeerSecTrust(
2268 SecTrustRef
*trust
) /* RETURNED */
2270 OSStatus status
= errSecSuccess
;
2271 if (ctx
== NULL
|| trust
== NULL
)
2274 /* Create a SecTrustRef if this was a resumed session and we
2275 didn't have one yet. */
2276 if (!ctx
->peerSecTrust
) {
2277 status
= sslCreateSecTrust(ctx
, &ctx
->peerSecTrust
);
2280 *trust
= ctx
->peerSecTrust
;
2284 OSStatus
SSLInternalMasterSecret(
2286 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
2287 size_t *secretSize
) // in/out
2289 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
2292 return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
);
2295 OSStatus
SSLInternalServerRandom(
2297 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2298 size_t *randSize
) // in/out
2300 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2303 return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
);
2306 OSStatus
SSLInternalClientRandom(
2308 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2309 size_t *randSize
) // in/out
2311 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2314 return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
);
2317 /* This is used by EAP 802.1x */
2318 OSStatus
SSLGetCipherSizes(
2321 size_t *symmetricKeySize
,
2324 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2325 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2329 SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
2331 *digestSize
= sslCipherSuiteGetMacSize(cipher
);
2332 *symmetricKeySize
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
);
2333 *ivSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
);
2334 return errSecSuccess
;
2338 SSLGetResumableSessionInfo(
2340 Boolean
*sessionWasResumed
, // RETURNED
2341 void *sessionID
, // RETURNED, mallocd by caller
2342 size_t *sessionIDLength
) // IN/OUT
2344 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2345 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2346 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2350 SSLBuffer localSessionID
;
2351 bool sessionMatch
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
);
2354 *sessionWasResumed
= true;
2355 if(localSessionID
.length
> *sessionIDLength
) {
2356 /* really should never happen - means ID > 32 */
2359 if(localSessionID
.length
) {
2361 * Note PAC-based session resumption can result in sessionMatch
2364 memmove(sessionID
, localSessionID
.data
, localSessionID
.length
);
2366 *sessionIDLength
= localSessionID
.length
;
2369 *sessionWasResumed
= false;
2370 *sessionIDLength
= 0;
2372 return errSecSuccess
;
2376 * Get/set enable of anonymous ciphers. This is deprecated and now a no-op.
2379 SSLSetAllowAnonymousCiphers(
2383 return errSecSuccess
;
2387 SSLGetAllowAnonymousCiphers(
2391 return errSecSuccess
;
2395 * Override the default session cache timeout for a cache entry created for
2396 * the current session.
2399 SSLSetSessionCacheTimeout(
2401 uint32_t timeoutInSeconds
)
2406 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2407 return errSecSuccess
;
2412 void tls_handshake_master_secret_function(const void *arg
, /* opaque to coreTLS; app-specific */
2413 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2414 size_t *secretLength
)
2416 SSLContextRef ctx
= (SSLContextRef
) arg
;
2417 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
);
2422 * Register a callback for obtaining the master_secret when performing
2423 * PAC-based session resumption.
2426 SSLInternalSetMasterSecretFunction(
2428 SSLInternalMasterSecretFunction mFunc
,
2429 const void *arg
) /* opaque to SecureTransport; app-specific */
2435 ctx
->masterSecretArg
= arg
;
2436 ctx
->masterSecretCallback
= mFunc
;
2438 return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
);
2442 * Provide an opaque SessionTicket for use in PAC-based session
2443 * resumption. Client side only. The provided ticket is sent in
2444 * the ClientHello message as a SessionTicket extension.
2446 * We won't reject this on the server side, but server-side support
2447 * for PAC-based session resumption is currently enabled for
2448 * Development builds only. To fully support this for server side,
2449 * besides the rudimentary support that's here for Development builds,
2450 * we'd need a getter for the session ticket, so the app code can
2451 * access the SessionTicket when its SSLInternalMasterSecretFunction
2452 * callback is called.
2454 OSStatus
SSLInternalSetSessionTicket(
2457 size_t ticketLength
)
2462 if(sslIsSessionActive(ctx
)) {
2463 /* can't do this with an active session */
2464 return errSecBadReq
;
2466 return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
);
2471 * ECDSA curve accessors.
2475 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2476 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2478 OSStatus
SSLGetNegotiatedCurve(
2480 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2482 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2485 unsigned int curve
= tls_handshake_get_negotiated_curve(ctx
->hdsk
);
2486 if(curve
== SSL_Curve_None
) {
2489 *namedCurve
= curve
;
2490 return errSecSuccess
;
2494 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2496 OSStatus
SSLGetNumberOfECDSACurves(
2498 unsigned *numCurves
) /* RETURNED */
2500 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2503 *numCurves
= ctx
->ecdhNumCurves
;
2504 return errSecSuccess
;
2508 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2510 OSStatus
SSLGetECDSACurves(
2512 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2513 unsigned *numCurves
) /* IN/OUT */
2515 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2518 if(*numCurves
< ctx
->ecdhNumCurves
) {
2521 static_assert(sizeof(*namedCurves
) >= sizeof(*(ctx
->ecdhCurves
)),
2522 "SSL_ECDSA_NamedCurve must be large enough for SSLContext ecdhCurves.");
2523 for (unsigned i
= 0; i
< ctx
->ecdhNumCurves
; i
++) {
2524 namedCurves
[i
] = ctx
->ecdhCurves
[i
];
2526 *numCurves
= ctx
->ecdhNumCurves
;
2527 return errSecSuccess
;
2531 * Specify ordered list of allowable named curves.
2533 OSStatus
SSLSetECDSACurves(
2535 const SSL_ECDSA_NamedCurve
*namedCurves
,
2538 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2541 if(sslIsSessionActive(ctx
)) {
2542 /* can't do this with an active session */
2543 return errSecBadReq
;
2546 if (SIZE_MAX
/ sizeof(*(ctx
->ecdhCurves
)) < (size_t)numCurves
) {
2549 ctx
->ecdhCurves
= sslMalloc((size_t)numCurves
* sizeof(*(ctx
->ecdhCurves
)));
2550 if(ctx
->ecdhCurves
== NULL
) {
2551 ctx
->ecdhNumCurves
= 0;
2552 return errSecAllocate
;
2555 for (unsigned i
=0; i
<numCurves
; i
++) {
2556 if (namedCurves
[i
] > UINT16_MAX
- 1) {
2557 ctx
->ecdhCurves
[i
] = SSL_Curve_None
;
2560 ctx
->ecdhCurves
[i
] = namedCurves
[i
];
2563 ctx
->ecdhNumCurves
= numCurves
;
2565 tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
);
2566 return errSecSuccess
;
2570 * Obtain the number of client authentication mechanisms specified by
2571 * the server in its Certificate Request message.
2572 * Returns errSecParam if server hasn't sent a Certificate Request message
2573 * (i.e., client certificate state is kSSLClientCertNone).
2575 OSStatus
SSLGetNumberOfClientAuthTypes(
2579 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2582 *numTypes
= ctx
->numAuthTypes
;
2583 return errSecSuccess
;
2587 * Obtain the client authentication mechanisms specified by
2588 * the server in its Certificate Request message.
2589 * Caller allocates returned array and specifies its size (in
2590 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2591 * is the actual size of the returned array on successful return.
2593 OSStatus
SSLGetClientAuthTypes(
2595 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2596 unsigned *numTypes
) /* IN/OUT */
2598 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2601 memmove(authTypes
, ctx
->clientAuthTypes
,
2602 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2603 *numTypes
= ctx
->numAuthTypes
;
2604 return errSecSuccess
;
2608 * -- DEPRECATED -- Return errSecUnimplemented.
2610 OSStatus
SSLGetNegotiatedClientAuthType(
2612 SSLClientAuthenticationType
*authType
) /* RETURNED */
2614 return errSecUnimplemented
;
2617 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2619 unsigned *numSigAlgs
)
2625 tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
);
2626 return errSecSuccess
;
2629 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
),
2630 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2632 OSStatus
SSLGetSignatureAlgorithms(
2634 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2635 unsigned *numSigAlgs
) /* IN/OUT */
2641 unsigned numPeerSigAlgs
;
2642 const tls_signature_and_hash_algorithm
*peerAlgs
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
);
2644 memmove(sigAlgs
, peerAlgs
,
2645 numPeerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2646 *numSigAlgs
= numPeerSigAlgs
;
2647 return errSecSuccess
;
2651 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2655 if(ctx
== NULL
) return errSecParam
;
2657 if(ctx
->pskSharedSecret
.data
)
2658 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2660 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2661 return errSecAllocate
;
2663 tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
);
2665 return errSecSuccess
;
2668 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2669 const void *pskIdentity
,
2670 size_t pskIdentityLen
)
2672 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2674 if(ctx
->pskIdentity
.data
)
2675 SSLFreeBuffer(&ctx
->pskIdentity
);
2677 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2678 return errSecAllocate
;
2680 tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
);
2682 return errSecSuccess
;
2686 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2687 const void **pskIdentity
,
2688 size_t *pskIdentityLen
)
2690 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2692 *pskIdentity
=ctx
->pskIdentity
.data
;
2693 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2695 return errSecSuccess
;
2698 OSStatus
SSLInternal_PRF(
2700 const void *vsecret
,
2702 const void *label
, // optional, NULL implies that seed contains
2707 void *vout
, // mallocd by caller, length >= outLen
2710 return tls_handshake_internal_prf(ctx
->hdsk
,
2717 const CFStringRef kSSLSessionConfig_default
= CFSTR("default");
2718 const CFStringRef kSSLSessionConfig_ATSv1
= CFSTR("ATSv1");
2719 const CFStringRef kSSLSessionConfig_ATSv1_noPFS
= CFSTR("ATSv1_noPFS");
2720 const CFStringRef kSSLSessionConfig_legacy
= CFSTR("legacy");
2721 const CFStringRef kSSLSessionConfig_standard
= CFSTR("standard");
2722 const CFStringRef kSSLSessionConfig_RC4_fallback
= CFSTR("RC4_fallback");
2723 const CFStringRef kSSLSessionConfig_TLSv1_fallback
= CFSTR("TLSv1_fallback");
2724 const CFStringRef kSSLSessionConfig_TLSv1_RC4_fallback
= CFSTR("TLSv1_RC4_fallback");
2725 const CFStringRef kSSLSessionConfig_legacy_DHE
= CFSTR("legacy_DHE");
2726 const CFStringRef kSSLSessionConfig_anonymous
= CFSTR("anonymous");
2727 const CFStringRef kSSLSessionConfig_3DES_fallback
= CFSTR("3DES_fallback");
2728 const CFStringRef kSSLSessionConfig_TLSv1_3DES_fallback
= CFSTR("TLSv1_3DES_fallback");
2732 tls_handshake_config_t
SSLSessionConfig_to_tls_handshake_config(CFStringRef config
)
2734 if(CFEqual(config
, kSSLSessionConfig_ATSv1
)){
2735 return tls_handshake_config_ATSv1
;
2736 } else if(CFEqual(config
, kSSLSessionConfig_ATSv1_noPFS
)){
2737 return tls_handshake_config_ATSv1_noPFS
;
2738 } else if(CFEqual(config
, kSSLSessionConfig_standard
)){
2739 return tls_handshake_config_standard
;
2740 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_fallback
)){
2741 return tls_handshake_config_TLSv1_fallback
;
2742 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_RC4_fallback
)){
2743 return tls_handshake_config_TLSv1_RC4_fallback
;
2744 } else if(CFEqual(config
, kSSLSessionConfig_RC4_fallback
)){
2745 return tls_handshake_config_RC4_fallback
;
2746 } else if(CFEqual(config
, kSSLSessionConfig_3DES_fallback
)){
2747 return tls_handshake_config_3DES_fallback
;
2748 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_3DES_fallback
)){
2749 return tls_handshake_config_TLSv1_3DES_fallback
;
2750 } else if(CFEqual(config
, kSSLSessionConfig_legacy
)){
2751 return tls_handshake_config_legacy
;
2752 } else if(CFEqual(config
, kSSLSessionConfig_legacy_DHE
)){
2753 return tls_handshake_config_legacy_DHE
;
2754 } else if(CFEqual(config
, kSSLSessionConfig_anonymous
)){
2755 return tls_handshake_config_anonymous
;
2756 } else if(CFEqual(config
, kSSLSessionConfig_default
)){
2757 return tls_handshake_config_default
;
2759 return tls_handshake_config_none
;
2763 /* Set Predefined TLS Configuration */
2765 SSLSetSessionConfig(SSLContextRef context
,
2768 tls_handshake_config_t cfg
= SSLSessionConfig_to_tls_handshake_config(config
);
2770 return tls_handshake_set_config(context
->hdsk
, cfg
);
2777 SSLGetSessionConfigurationIdentifier(SSLContext
*ctx
, SSLBuffer
*buffer
)
2779 if (buffer
== NULL
) {
2783 // Don't recompute the buffer if we've done it before and cached the result.
2784 // Just copy out the result.
2785 if (ctx
->contextConfigurationBuffer
.data
!= NULL
) {
2786 buffer
->length
= ctx
->contextConfigurationBuffer
.length
;
2787 buffer
->data
= (uint8_t *) malloc(buffer
->length
);
2788 if (buffer
->data
== NULL
) {
2789 return errSecAllocate
;
2791 memcpy(buffer
->data
, ctx
->contextConfigurationBuffer
.data
, buffer
->length
);
2792 return errSecSuccess
;
2795 // Allocate the buffer, freeing up any data that was previously stored
2796 // 10 here is the number of attributes we're adding below. Change it as needed.
2797 buffer
->length
= 10 * sizeof(Boolean
);
2801 buffer
->data
= malloc(buffer
->length
);
2802 if (buffer
->data
== NULL
) {
2803 return errSecAllocate
;
2806 // Copy in the session configuration options
2808 memcpy(buffer
->data
+ offset
, &ctx
->breakOnServerAuth
, sizeof(ctx
->breakOnServerAuth
));
2809 offset
+= sizeof(ctx
->breakOnServerAuth
);
2811 memcpy(buffer
->data
+ offset
, &ctx
->breakOnCertRequest
, sizeof(ctx
->breakOnCertRequest
));
2812 offset
+= sizeof(ctx
->breakOnCertRequest
);
2814 memcpy(buffer
->data
+ offset
, &ctx
->breakOnClientAuth
, sizeof(ctx
->breakOnClientAuth
));
2815 offset
+= sizeof(ctx
->breakOnClientAuth
);
2817 memcpy(buffer
->data
+ offset
, &ctx
->signalServerAuth
, sizeof(ctx
->signalServerAuth
));
2818 offset
+= sizeof(ctx
->signalServerAuth
);
2820 memcpy(buffer
->data
+ offset
, &ctx
->signalCertRequest
, sizeof(ctx
->signalCertRequest
));
2821 offset
+= sizeof(ctx
->signalCertRequest
);
2823 memcpy(buffer
->data
+ offset
, &ctx
->signalClientAuth
, sizeof(ctx
->signalClientAuth
));
2824 offset
+= sizeof(ctx
->signalClientAuth
);
2826 memcpy(buffer
->data
+ offset
, &ctx
->breakOnClientHello
, sizeof(ctx
->breakOnClientHello
));
2827 offset
+= sizeof(ctx
->breakOnClientHello
);
2829 memcpy(buffer
->data
+ offset
, &ctx
->allowServerIdentityChange
, sizeof(ctx
->allowServerIdentityChange
));
2830 offset
+= sizeof(ctx
->allowServerIdentityChange
);
2832 memcpy(buffer
->data
+ offset
, &ctx
->allowRenegotiation
, sizeof(ctx
->allowRenegotiation
));
2833 offset
+= sizeof(ctx
->allowRenegotiation
);
2835 memcpy(buffer
->data
+ offset
, &ctx
->enableSessionTickets
, sizeof(ctx
->enableSessionTickets
));
2836 offset
+= sizeof(ctx
->enableSessionTickets
);
2838 // Sanity check on the length
2839 if (offset
!= buffer
->length
) {
2841 return errSecInternal
;
2844 // Save the configuration buffer for later use
2845 ctx
->contextConfigurationBuffer
.length
= buffer
->length
;
2846 ctx
->contextConfigurationBuffer
.data
= (uint8_t *) malloc(buffer
->length
);
2847 memcpy(ctx
->contextConfigurationBuffer
.data
, buffer
->data
, buffer
->length
);
2849 return errSecSuccess
;