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"
32 #include "appleSession.h"
34 #include "sslCipherSpecs.h"
35 #include "sslContext.h"
36 #include "sslCrypto.h"
38 #include "sslKeychain.h"
39 #include "sslMemory.h"
42 #include "tlsCallbacks.h"
44 #include <AssertMacros.h>
45 #include <CoreFoundation/CFData.h>
46 #include <CoreFoundation/CFPreferences.h>
47 #include <Security/SecCertificate.h>
48 #include <Security/SecCertificatePriv.h>
49 #include <Security/SecTrust.h>
50 #include <Security/SecTrustSettingsPriv.h>
51 #include <Security/oidsalg.h>
52 #include "utilities/SecCFRelease.h"
53 #include "utilities/SecCFWrappers.h"
58 #include <Security/SecCertificateInternal.h>
60 #include <Security/oidsalg.h>
61 #include <Security/oidscert.h>
62 #include <Security/SecTrustSettingsPriv.h>
66 static void sslFreeDnList(SSLContext
*ctx
)
68 DNListElem
*dn
, *nextDN
;
70 dn
= ctx
->acceptableDNList
;
73 SSLFreeBuffer(&dn
->derDN
);
78 ctx
->acceptableDNList
= NULL
;
82 This frees ctx->localCert, which is allocated in parseIncomingCert.
83 This is structured as a list, but all the SSLCertificates structs are
84 allocated as a single array, so there is only on sslFree(localCert).
86 static void sslFreeLocalCert(SSLContext
*ctx
)
90 cert
= ctx
->localCert
;
93 SSLFreeBuffer(&cert
->derCert
);
96 sslFree(ctx
->localCert
);
97 ctx
->localCert
= NULL
;
101 Boolean
sslIsSessionActive(const SSLContext
*ctx
)
107 case SSL_HdskStateUninit
:
108 case SSL_HdskStateGracefulClose
:
109 case SSL_HdskStateErrorClose
:
118 * Minimum and maximum supported versions
120 //#define MINIMUM_STREAM_VERSION SSL_Version_2_0 /* Disabled */
121 #define MINIMUM_STREAM_VERSION SSL_Version_3_0
122 #define MAXIMUM_STREAM_VERSION TLS_Version_1_2
123 #define MINIMUM_DATAGRAM_VERSION DTLS_Version_1_0
125 /* This should be changed when we start supporting DTLS_Version_1_x */
126 #define MAXIMUM_DATAGRAM_VERSION DTLS_Version_1_0
128 #define SSL_ENABLE_ECDSA_SIGN_AUTH 1
129 #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH 0
130 #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH 0
132 #define DEFAULT_DTLS_TIMEOUT 1
133 #define DEFAULT_DTLS_MTU 1400
134 #define MIN_ALLOWED_DTLS_MTU 64 /* this ensure than there will be no integer
135 underflow when calculating max write size */
137 int kSplitDefaultValue
;
138 CFIndex kMinDhGroupSizeDefaultValue
;
142 * Instead of using CFPropertyListReadFromFile we use a
143 * CFPropertyListCreateWithStream directly
144 * here. CFPropertyListReadFromFile() uses
145 * CFURLCopyResourcePropertyForKey() andCF pulls in CoreServices for
146 * CFURLCopyResourcePropertyForKey() and that doesn't work in install
149 static CFPropertyListRef
150 CopyPlistFromFile(CFURLRef url
)
152 CFDictionaryRef d
= NULL
;
153 CFReadStreamRef s
= CFReadStreamCreateWithFile(kCFAllocatorDefault
, url
);
154 if (s
&& CFReadStreamOpen(s
)) {
155 d
= (CFDictionaryRef
)CFPropertyListCreateWithStream(kCFAllocatorDefault
, s
, 0, kCFPropertyListImmutable
, NULL
, NULL
);
164 static void _SSLContextReadDefault()
166 /* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
167 /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
168 const int defaultSplitDefaultValue
= 2;
170 CFTypeRef value
= (CFTypeRef
)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
171 CFSTR("com.apple.security"),
172 kCFPreferencesAnyUser
,
173 kCFPreferencesCurrentHost
);
175 if (CFGetTypeID(value
) == CFBooleanGetTypeID())
176 kSplitDefaultValue
= CFBooleanGetValue((CFBooleanRef
)value
) ? 1 : 0;
177 else if (CFGetTypeID(value
) == CFNumberGetTypeID()) {
178 if (!CFNumberGetValue((CFNumberRef
)value
, kCFNumberIntType
, &kSplitDefaultValue
))
179 kSplitDefaultValue
= defaultSplitDefaultValue
;
181 if (kSplitDefaultValue
< 0 || kSplitDefaultValue
> 2) {
182 kSplitDefaultValue
= defaultSplitDefaultValue
;
187 kSplitDefaultValue
= defaultSplitDefaultValue
;
190 /* Min DH Group Size */
191 kMinDhGroupSizeDefaultValue
= CFPreferencesGetAppIntegerValue(CFSTR("SSLMinDhGroupSize"), kCFPreferencesCurrentApplication
, NULL
);
194 /* on iOS, if the above returned nothing, we manually look into mobile's Managed Preferences */
195 /* Note that if the process is running as mobile, the above call will already have read the Managed Preference plist.
196 As a result, if you have some preferences set manually with defaults, which preference applies may be different for mobile vs not-mobile. */
197 if(kMinDhGroupSizeDefaultValue
== 0) {
198 CFURLRef prefURL
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, CFSTR("/Library/Managed Preferences/mobile/.GlobalPreferences.plist"), kCFURLPOSIXPathStyle
, false);
200 CFPropertyListRef plist
= CopyPlistFromFile(prefURL
);
202 value
= CFDictionaryGetValue(plist
, CFSTR("SSLMinDhGroupSize"));
203 if (isNumber(value
)) {
204 CFNumberGetValue(value
, kCFNumberCFIndexType
, &kMinDhGroupSizeDefaultValue
);
207 CFReleaseSafe(plist
);
209 CFReleaseSafe(prefURL
);
215 CFGiblisWithHashFor(SSLContext
)
218 SSLNewContext (Boolean isServer
,
219 SSLContextRef
*contextPtr
) /* RETURNED */
221 if(contextPtr
== NULL
) {
225 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
227 if (*contextPtr
== NULL
)
228 return errSecAllocate
;
230 return errSecSuccess
;
233 SSLContextRef
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
)
236 SSLRecordContextRef recCtx
;
238 ctx
= SSLCreateContextWithRecordFuncs(alloc
, protocolSide
, connectionType
, &SSLRecordLayerInternal
);
243 recCtx
= SSLCreateInternalRecordLayer(ctx
);
249 SSLSetRecordContext(ctx
, recCtx
);
254 SSLContextRef
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
, const struct SSLRecordFuncs
*recFuncs
)
256 SSLContext
*ctx
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
);
262 /* subsequent errors to errOut: */
263 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
266 ctx
->hdsk
= tls_handshake_create(connectionType
==kSSLDatagramType
, protocolSide
==kSSLServerSide
);
267 if(ctx
->hdsk
== NULL
) {
272 tls_handshake_set_callbacks(ctx
->hdsk
,
273 &tls_handshake_callbacks
,
276 ctx
->isDTLS
= (connectionType
==kSSLDatagramType
);
278 ctx
->state
= SSL_HdskStateUninit
;
279 ctx
->timeout_duration
= DEFAULT_DTLS_TIMEOUT
;
280 ctx
->mtu
= DEFAULT_DTLS_MTU
;
282 tls_handshake_get_min_protocol_version(ctx
->hdsk
, &ctx
->minProtocolVersion
);
283 tls_handshake_get_max_protocol_version(ctx
->hdsk
, &ctx
->maxProtocolVersion
);
285 if(protocolSide
== kSSLClientSide
) {
286 tls_handshake_set_sct_enable(ctx
->hdsk
, true);
287 tls_handshake_set_ocsp_enable(ctx
->hdsk
, true);
290 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
291 ctx
->protocolSide
= protocolSide
;
292 ctx
->recFuncs
= recFuncs
;
294 /* Initial cert verify state: verify with default system roots */
295 ctx
->enableCertVerify
= true;
297 /* Default for RSA blinding is ENABLED */
298 ctx
->rsaBlindingEnable
= true;
300 /* Default for sending one-byte app data record is DISABLED */
301 ctx
->oneByteRecordEnable
= false;
303 /* Dont enable fallback behavior by default */
304 ctx
->fallbackEnabled
= false;
306 /* Consult global system preference for default behavior:
307 * 0 = disabled, 1 = split every write, 2 = split second and subsequent writes
308 * (caller can override by setting kSSLSessionOptionSendOneByteRecord)
310 static pthread_once_t sReadDefault
= PTHREAD_ONCE_INIT
;
311 pthread_once(&sReadDefault
, _SSLContextReadDefault
);
312 if (kSplitDefaultValue
> 0) {
313 ctx
->oneByteRecordEnable
= true;
316 /* Default for server is DHE enabled, default for client is disabled */
317 if(ctx
->protocolSide
== kSSLServerSide
) {
318 SSLSetDHEEnabled(ctx
, true);
320 SSLSetDHEEnabled(ctx
, false);
323 if(kMinDhGroupSizeDefaultValue
) {
324 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, (unsigned)kMinDhGroupSizeDefaultValue
);
327 /* default for anonymous ciphers is DISABLED */
328 ctx
->anonCipherEnable
= false;
330 ctx
->breakOnServerAuth
= false;
331 ctx
->breakOnCertRequest
= false;
332 ctx
->breakOnClientAuth
= false;
333 ctx
->signalServerAuth
= false;
334 ctx
->signalCertRequest
= false;
335 ctx
->signalClientAuth
= false;
337 ctx
->negAuthType
= SSLClientAuthNone
; /* ditto */
343 SSLNewDatagramContext (Boolean isServer
,
344 SSLContextRef
*contextPtr
) /* RETURNED */
346 if (contextPtr
== NULL
)
348 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
);
349 if (*contextPtr
== NULL
)
350 return errSecAllocate
;
351 return errSecSuccess
;
355 * Dispose of an SSLContext. (private)
356 * This function is invoked after our dispatch queue is safely released,
357 * or directly from SSLDisposeContext if there is no dispatch queue.
360 SSLDisposeContext (SSLContextRef context
)
362 if(context
== NULL
) {
366 return errSecSuccess
;
369 CFStringRef
SSLContextCopyFormatDescription(CFTypeRef arg
, CFDictionaryRef formatOptions
)
371 SSLContext
* ctx
= (SSLContext
*) arg
;
376 CFStringRef result
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
);
381 Boolean
SSLContextCompare(CFTypeRef a
, CFTypeRef b
)
386 CFHashCode
SSLContextHash(CFTypeRef arg
)
388 return (CFHashCode
) arg
;
391 void SSLContextDestroy(CFTypeRef arg
)
393 SSLContext
* ctx
= (SSLContext
*) arg
;
395 /* destroy the coreTLS handshake object */
396 tls_handshake_destroy(ctx
->hdsk
);
398 /* Only destroy if we were using the internal record layer */
399 if(ctx
->recFuncs
==&SSLRecordLayerInternal
)
400 SSLDestroyInternalRecordLayer(ctx
->recCtx
);
402 SSLFreeBuffer(&ctx
->sessionTicket
);
403 SSLFreeBuffer(&ctx
->sessionID
);
404 SSLFreeBuffer(&ctx
->peerID
);
405 SSLFreeBuffer(&ctx
->resumableSession
);
406 SSLFreeBuffer(&ctx
->receivedDataBuffer
);
408 CFReleaseSafe(ctx
->acceptableCAs
);
409 CFReleaseSafe(ctx
->trustedLeafCerts
);
410 CFReleaseSafe(ctx
->localCertArray
);
411 CFReleaseSafe(ctx
->encryptCertArray
);
412 CFReleaseSafe(ctx
->peerCert
);
413 CFReleaseSafe(ctx
->trustedCerts
);
414 CFReleaseSafe(ctx
->peerSecTrust
);
416 sslFreePrivKey(&ctx
->signingPrivKeyRef
);
418 sslFreeLocalCert(ctx
);
421 SSLFreeBuffer(&ctx
->ownVerifyData
);
422 SSLFreeBuffer(&ctx
->peerVerifyData
);
424 SSLFreeBuffer(&ctx
->pskIdentity
);
425 SSLFreeBuffer(&ctx
->pskSharedSecret
);
427 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
429 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
435 * Determine the state of an SSL session.
438 SSLGetSessionState (SSLContextRef context
,
439 SSLSessionState
*state
) /* RETURNED */
441 SSLSessionState rtnState
= kSSLIdle
;
443 if(context
== NULL
) {
447 switch(context
->state
) {
448 case SSL_HdskStateUninit
:
451 case SSL_HdskStateGracefulClose
:
452 rtnState
= kSSLClosed
;
454 case SSL_HdskStateErrorClose
:
455 case SSL_HdskStateNoNotifyClose
:
456 rtnState
= kSSLAborted
;
458 case SSL_HdskStateReady
:
459 rtnState
= kSSLConnected
;
461 case SSL_HdskStatePending
:
462 rtnState
= kSSLHandshake
;
466 return errSecSuccess
;
470 * Set options for an SSL session.
473 SSLSetSessionOption (SSLContextRef context
,
474 SSLSessionOption option
,
477 if(context
== NULL
) {
480 if(sslIsSessionActive(context
)) {
481 /* can't do this with an active session */
485 case kSSLSessionOptionBreakOnServerAuth
:
486 context
->breakOnServerAuth
= value
;
487 context
->enableCertVerify
= !value
;
489 case kSSLSessionOptionBreakOnCertRequested
:
490 context
->breakOnCertRequest
= value
;
492 case kSSLSessionOptionBreakOnClientAuth
:
493 context
->breakOnClientAuth
= value
;
494 context
->enableCertVerify
= !value
;
496 case kSSLSessionOptionSendOneByteRecord
:
497 /* Only call the record layer function if the value changed */
498 if(value
!= context
->oneByteRecordEnable
)
499 context
->recFuncs
->setOption(context
->recCtx
, kSSLRecordOptionSendOneByteRecord
, value
);
500 context
->oneByteRecordEnable
= value
;
502 case kSSLSessionOptionFalseStart
:
503 context
->falseStartEnabled
= value
;
505 case kSSLSessionOptionFallback
:
506 tls_handshake_set_fallback(context
->hdsk
, value
);
507 context
->fallbackEnabled
= value
;
509 case kSSLSessionOptionBreakOnClientHello
:
510 context
->breakOnClientHello
= value
;
512 case kSSLSessionOptionAllowServerIdentityChange
:
513 tls_handshake_set_server_identity_change(context
->hdsk
, value
);
519 return errSecSuccess
;
523 * Determine current value for the specified option in an SSL session.
526 SSLGetSessionOption (SSLContextRef context
,
527 SSLSessionOption option
,
530 if(context
== NULL
|| value
== NULL
) {
534 case kSSLSessionOptionBreakOnServerAuth
:
535 *value
= context
->breakOnServerAuth
;
537 case kSSLSessionOptionBreakOnCertRequested
:
538 *value
= context
->breakOnCertRequest
;
540 case kSSLSessionOptionBreakOnClientAuth
:
541 *value
= context
->breakOnClientAuth
;
543 case kSSLSessionOptionSendOneByteRecord
:
544 *value
= context
->oneByteRecordEnable
;
546 case kSSLSessionOptionFalseStart
:
547 *value
= context
->falseStartEnabled
;
549 case kSSLSessionOptionBreakOnClientHello
:
550 *value
= context
->breakOnClientHello
;
552 case kSSLSessionOptionAllowServerIdentityChange
:
553 tls_handshake_get_server_identity_change(context
->hdsk
, (bool *)value
);
559 return errSecSuccess
;
563 SSLSetRecordContext (SSLContextRef ctx
,
564 SSLRecordContextRef recCtx
)
569 if(sslIsSessionActive(ctx
)) {
570 /* can't do this with an active session */
573 ctx
->recCtx
= recCtx
;
574 return errSecSuccess
;
578 SSLSetIOFuncs (SSLContextRef ctx
,
579 SSLReadFunc readFunc
,
580 SSLWriteFunc writeFunc
)
585 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
586 /* Can Only do this with the internal record layer */
590 if(sslIsSessionActive(ctx
)) {
591 /* can't do this with an active session */
595 ctx
->ioCtx
.read
=readFunc
;
596 ctx
->ioCtx
.write
=writeFunc
;
602 SSLSetNPNFunc(SSLContextRef context
,
606 if (context
== NULL
) {
609 if (sslIsSessionActive(context
)) {
612 context
->npnFunc
= npnFunc
;
613 context
->npnFuncInfo
= info
;
614 if(context
->protocolSide
==kSSLClientSide
) {
615 tls_handshake_set_npn_enable(context
->hdsk
, npnFunc
!=NULL
);
620 SSLSetNPNData(SSLContextRef context
,
624 if (context
== NULL
|| data
== NULL
|| length
== 0) {
634 npn_data
.data
= (uint8_t *)data
;
635 npn_data
.length
= length
;
637 return tls_handshake_set_npn_data(context
->hdsk
, npn_data
);
641 SSLGetNPNData(SSLContextRef context
,
644 if (context
== NULL
|| length
== NULL
)
647 const tls_buffer
*npn_data
;
649 npn_data
= tls_handshake_get_peer_npn_data(context
->hdsk
);
652 *length
= npn_data
->length
;
653 return npn_data
->data
;
662 SSLSetALPNFunc(SSLContextRef context
,
663 SSLALPNFunc alpnFunc
,
666 if (context
== NULL
) {
669 if (sslIsSessionActive(context
)) {
672 context
->alpnFunc
= alpnFunc
;
673 context
->alpnFuncInfo
= info
;
674 if(context
->protocolSide
==kSSLServerSide
) {
680 SSLSetALPNData(SSLContextRef context
,
684 if (context
== NULL
|| data
== NULL
|| length
== 0) {
692 tls_buffer alpn_data
;
694 alpn_data
.data
= (uint8_t *)data
;
695 alpn_data
.length
= length
;
697 return tls_handshake_set_alpn_data(context
->hdsk
, alpn_data
);
701 SSLGetALPNData(SSLContextRef context
,
704 if (context
== NULL
|| length
== NULL
)
707 const tls_buffer
*alpn_data
;
709 alpn_data
= tls_handshake_get_peer_alpn_data(context
->hdsk
);
712 *length
= alpn_data
->length
;
713 return alpn_data
->data
;
722 SSLSetConnection (SSLContextRef ctx
,
723 SSLConnectionRef connection
)
728 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
729 /* Can Only do this with the internal record layer */
733 if(sslIsSessionActive(ctx
)) {
734 /* can't do this with an active session */
738 /* Need to keep a copy of it this layer for the Get function */
739 ctx
->ioCtx
.ioRef
= connection
;
745 SSLGetConnection (SSLContextRef ctx
,
746 SSLConnectionRef
*connection
)
748 if((ctx
== NULL
) || (connection
== NULL
)) {
751 *connection
= ctx
->ioCtx
.ioRef
;
752 return errSecSuccess
;
756 SSLSetPeerDomainName (SSLContextRef ctx
,
757 const char *peerName
,
763 if(sslIsSessionActive(ctx
)) {
764 /* can't do this with an active session */
768 if(ctx
->protocolSide
== kSSLClientSide
) {
769 return tls_handshake_set_peer_hostname(ctx
->hdsk
, peerName
, peerNameLen
);
771 return 0; // This should probably return an error, but historically didnt.
776 * Determine the buffer size needed for SSLGetPeerDomainName().
779 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
780 size_t *peerNameLen
) // RETURNED
785 const char *hostname
;
787 return tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, peerNameLen
);
791 SSLGetPeerDomainName (SSLContextRef ctx
,
792 char *peerName
, // returned here
793 size_t *peerNameLen
) // IN/OUT
795 const char *hostname
;
804 err
=tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
808 } else if(*peerNameLen
<len
) {
809 return errSSLBufferOverflow
;
811 memcpy(peerName
, hostname
, len
);
818 SSLCopyRequestedPeerNameLength (SSLContextRef ctx
,
819 size_t *peerNameLen
) // RETURNED
821 const tls_buffer
*hostname
;
825 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
829 *peerNameLen
= hostname
->length
;
835 SSLCopyRequestedPeerName (SSLContextRef ctx
,
836 char *peerName
, // returned here
837 size_t *peerNameLen
) // IN/OUT
839 const tls_buffer
*hostname
;
845 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
849 } else if(*peerNameLen
< hostname
->length
) {
850 return errSSLBufferOverflow
;
852 memcpy(peerName
, hostname
->data
, hostname
->length
);
853 *peerNameLen
= hostname
->length
;
860 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
870 if(!ctx
->isDTLS
) return errSecParam
;
872 if((ctx
== NULL
) || (cookieLen
>32)) {
875 if(sslIsSessionActive(ctx
)) {
876 /* can't do this with an active session */
880 /* free possible existing cookie */
881 if(ctx
->dtlsCookie
.data
) {
882 SSLFreeBuffer(&ctx
->dtlsCookie
);
886 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
)))
889 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
890 return errSecSuccess
;
894 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
898 if(ctx
== NULL
) return errSecParam
;
899 if(!ctx
->isDTLS
) return errSecParam
;
901 tls_handshake_set_mtu(ctx
->hdsk
, maxSize
);
903 return errSecSuccess
;
907 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
910 if(ctx
== NULL
) return errSecParam
;
911 if(!ctx
->isDTLS
) return errSecParam
;
915 return errSecSuccess
;
920 Keys to to math below:
922 A DTLS record looks like this: | header (13 bytes) | fragment |
924 For Null cipher, fragment is clear text as follows:
927 For block cipher, fragment size must be a multiple of the cipher block size, and is the
928 encryption of the following plaintext :
929 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
931 The maximum content length in that case is achieved for 0 padding bytes.
936 SSLGetDatagramWriteSize (SSLContextRef ctx
,
939 if(ctx
== NULL
) return errSecParam
;
940 if(!ctx
->isDTLS
) return errSecParam
;
941 if(bufSize
== NULL
) return errSecParam
;
943 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
946 SSLCipherSpecParams
*currCipher
= &ctx
->selectedCipherSpecParams
;
948 size_t blockSize
= currCipher
->blockSize
;
949 size_t macSize
= currCipher
->macSize
;
951 size_t blockSize
= 16;
956 /* max_fragment_size must be a multiple of blocksize */
957 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
958 max_fragment_size
-= blockSize
; /* 1 block for IV */
959 max_fragment_size
-= 1; /* 1 byte for pad length */
962 /* less the mac size */
963 max_fragment_size
-= macSize
;
965 /* Thats just a sanity check */
966 assert(max_fragment_size
<ctx
->mtu
);
968 *bufSize
= max_fragment_size
;
970 return errSecSuccess
;
974 All the complexity around protocol version is to support legacy APIs.
975 Eventually that should go away:
976 <rdar://problem/20842025> Remove deprecated SecureTransport function related to protocol version selection.
979 static tls_protocol_version
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
981 case kSSLProtocol2
: return SSL_Version_2_0
;
982 case kSSLProtocol3
: return tls_protocol_version_SSL_3
;
983 case kTLSProtocol1
: return tls_protocol_version_TLS_1_0
;
984 case kTLSProtocol11
: return tls_protocol_version_TLS_1_1
;
985 case kTLSProtocol12
: return tls_protocol_version_TLS_1_2
;
986 case kDTLSProtocol1
: return tls_protocol_version_DTLS_1_0
;
987 default: return tls_protocol_version_Undertermined
;
991 /* concert between private SSLProtocolVersion and public SSLProtocol */
992 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
995 case tls_protocol_version_SSL_3
: return kSSLProtocol3
;
996 case tls_protocol_version_TLS_1_0
: return kTLSProtocol1
;
997 case tls_protocol_version_TLS_1_1
: return kTLSProtocol11
;
998 case tls_protocol_version_TLS_1_2
: return kTLSProtocol12
;
999 case tls_protocol_version_DTLS_1_0
: return kDTLSProtocol1
;
1001 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
1004 case tls_protocol_version_Undertermined
: return kSSLProtocolUnknown
;
1009 SSLSetProtocolVersionMin (SSLContextRef ctx
,
1010 SSLProtocol minVersion
)
1012 if(ctx
== NULL
) return errSecParam
;
1014 tls_protocol_version version
= SSLProtocolToProtocolVersion(minVersion
);
1016 if (version
> MINIMUM_DATAGRAM_VERSION
||
1017 version
< MAXIMUM_DATAGRAM_VERSION
)
1018 return errSSLIllegalParam
;
1019 if (version
< ctx
->maxProtocolVersion
)
1020 ctx
->maxProtocolVersion
= version
;
1022 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1023 return errSSLIllegalParam
;
1024 if (version
> ctx
->maxProtocolVersion
)
1025 ctx
->maxProtocolVersion
= version
;
1027 ctx
->minProtocolVersion
= version
;
1029 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1030 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1032 return errSecSuccess
;
1036 SSLGetProtocolVersionMin (SSLContextRef ctx
,
1037 SSLProtocol
*minVersion
)
1039 if(ctx
== NULL
) return errSecParam
;
1041 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
1042 return errSecSuccess
;
1046 SSLSetProtocolVersionMax (SSLContextRef ctx
,
1047 SSLProtocol maxVersion
)
1049 if(ctx
== NULL
) return errSecParam
;
1051 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
1053 if (version
> MINIMUM_DATAGRAM_VERSION
||
1054 version
< MAXIMUM_DATAGRAM_VERSION
)
1055 return errSSLIllegalParam
;
1056 if (version
> ctx
->minProtocolVersion
)
1057 ctx
->minProtocolVersion
= version
;
1059 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1060 return errSSLIllegalParam
;
1061 if (version
< ctx
->minProtocolVersion
)
1062 ctx
->minProtocolVersion
= version
;
1064 ctx
->maxProtocolVersion
= version
;
1066 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1067 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1069 return errSecSuccess
;
1073 SSLGetProtocolVersionMax (SSLContextRef ctx
,
1074 SSLProtocol
*maxVersion
)
1076 if(ctx
== NULL
) return errSecParam
;
1078 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
1079 return errSecSuccess
;
1082 #define max(x,y) ((x)<(y)?(y):(x))
1085 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
1086 SSLProtocol protocol
,
1092 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1093 /* Can't do this with an active session, nor with a DTLS session */
1094 return errSecBadReq
;
1096 if (protocol
== kSSLProtocolAll
) {
1098 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1099 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1101 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1102 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1105 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1107 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
1110 if (version
> ctx
->maxProtocolVersion
) {
1111 ctx
->maxProtocolVersion
= version
;
1112 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
1113 ctx
->minProtocolVersion
= version
;
1115 if (version
< ctx
->minProtocolVersion
) {
1116 ctx
->minProtocolVersion
= version
;
1119 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
1122 /* Disabling a protocol version now resets the minimum acceptable
1123 * version to the next higher version. This means it's no longer
1124 * possible to enable a discontiguous set of protocol versions.
1126 SSLProtocolVersion nextVersion
;
1128 case SSL_Version_2_0
:
1129 nextVersion
= SSL_Version_3_0
;
1131 case SSL_Version_3_0
:
1132 nextVersion
= TLS_Version_1_0
;
1134 case TLS_Version_1_0
:
1135 nextVersion
= TLS_Version_1_1
;
1137 case TLS_Version_1_1
:
1138 nextVersion
= TLS_Version_1_2
;
1140 case TLS_Version_1_2
:
1142 nextVersion
= SSL_Version_Undetermined
;
1145 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
1146 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1147 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1148 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1153 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1154 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1156 return errSecSuccess
;
1160 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1161 SSLProtocol protocol
,
1162 Boolean
*enable
) /* RETURNED */
1168 /* Can't do this with a DTLS session */
1169 return errSecBadReq
;
1175 case kTLSProtocol11
:
1176 case kTLSProtocol12
:
1178 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1179 *enable
= (ctx
->minProtocolVersion
<= version
1180 && ctx
->maxProtocolVersion
>= version
);
1183 case kSSLProtocolAll
:
1184 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1185 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1190 return errSecSuccess
;
1195 SSLSetProtocolVersion (SSLContextRef ctx
,
1196 SSLProtocol version
)
1201 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1202 /* Can't do this with an active session, nor with a DTLS session */
1203 return errSecBadReq
;
1208 /* this tells us to do our best, up to 3.0 */
1209 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1210 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1212 case kSSLProtocol3Only
:
1213 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1214 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1217 /* this tells us to do our best, up to TLS, but allows 3.0 */
1218 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1219 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1221 case kTLSProtocol1Only
:
1222 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1223 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1225 case kTLSProtocol11
:
1226 /* This tells us to do our best, up to TLS 1.1, currently also
1227 allows 3.0 or TLS 1.0 */
1228 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1229 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1231 case kTLSProtocol12
:
1232 case kSSLProtocolAll
:
1233 case kSSLProtocolUnknown
:
1234 /* This tells us to do our best, up to TLS 1.2, currently also
1235 allows 3.0 or TLS 1.0 or TLS 1.1 */
1236 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1237 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1243 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1244 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1246 return errSecSuccess
;
1251 SSLGetProtocolVersion (SSLContextRef ctx
,
1252 SSLProtocol
*protocol
) /* RETURNED */
1257 /* translate array of booleans to public value; not all combinations
1258 * are legal (i.e., meaningful) for this call */
1259 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1260 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1261 /* traditional 'all enabled' */
1262 *protocol
= kSSLProtocolAll
;
1263 return errSecSuccess
;
1265 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1266 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1267 /* traditional 'all enabled' */
1268 *protocol
= kTLSProtocol11
;
1269 return errSecSuccess
;
1271 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1272 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1273 /* TLS1.1 and below enabled */
1274 *protocol
= kTLSProtocol1
;
1275 return errSecSuccess
;
1276 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1277 *protocol
= kTLSProtocol1Only
;
1279 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1280 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1281 /* Could also return kSSLProtocol3Only since
1282 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1283 *protocol
= kSSLProtocol3
;
1284 return errSecSuccess
;
1292 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1293 SSLProtocol
*protocol
) /* RETURNED */
1298 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1299 return errSecSuccess
;
1303 SSLSetEnableCertVerify (SSLContextRef ctx
,
1304 Boolean enableVerify
)
1309 sslCertDebug("SSLSetEnableCertVerify %s",
1310 enableVerify
? "true" : "false");
1311 if(sslIsSessionActive(ctx
)) {
1312 /* can't do this with an active session */
1313 return errSecBadReq
;
1315 ctx
->enableCertVerify
= enableVerify
;
1316 return errSecSuccess
;
1320 SSLGetEnableCertVerify (SSLContextRef ctx
,
1321 Boolean
*enableVerify
)
1326 *enableVerify
= ctx
->enableCertVerify
;
1327 return errSecSuccess
;
1331 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1332 Boolean allowExpired
)
1337 sslCertDebug("SSLSetAllowsExpiredCerts %s",
1338 allowExpired
? "true" : "false");
1339 if(sslIsSessionActive(ctx
)) {
1340 /* can't do this with an active session */
1341 return errSecBadReq
;
1343 ctx
->allowExpiredCerts
= allowExpired
;
1344 return errSecSuccess
;
1348 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1349 Boolean
*allowExpired
)
1354 *allowExpired
= ctx
->allowExpiredCerts
;
1355 return errSecSuccess
;
1359 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1360 Boolean allowExpired
)
1365 sslCertDebug("SSLSetAllowsExpiredRoots %s",
1366 allowExpired
? "true" : "false");
1367 if(sslIsSessionActive(ctx
)) {
1368 /* can't do this with an active session */
1369 return errSecBadReq
;
1371 ctx
->allowExpiredRoots
= allowExpired
;
1372 return errSecSuccess
;
1376 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1377 Boolean
*allowExpired
)
1382 *allowExpired
= ctx
->allowExpiredRoots
;
1383 return errSecSuccess
;
1386 OSStatus
SSLSetAllowsAnyRoot(
1393 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1394 ctx
->allowAnyRoot
= anyRoot
;
1395 return errSecSuccess
;
1399 SSLGetAllowsAnyRoot(
1406 *anyRoot
= ctx
->allowAnyRoot
;
1407 return errSecSuccess
;
1410 #if !TARGET_OS_IPHONE
1411 /* obtain the system roots sets for this app, policy SSL */
1412 static OSStatus
sslDefaultSystemRoots(
1414 CFArrayRef
*systemRoots
) // created and RETURNED
1417 const char *hostname
;
1420 tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
1422 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1425 (ctx
->protocolSide
== kSSLServerSide
) ?
1426 /* server verifies, client encrypts */
1427 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1430 #endif /* OS X only */
1433 SSLSetTrustedRoots (SSLContextRef ctx
,
1434 CFArrayRef trustedRoots
,
1435 Boolean replaceExisting
)
1437 if (sslIsSessionActive(ctx
)) {
1438 /* can't do this with an active session */
1439 return errSecBadReq
;
1441 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1442 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1444 if (replaceExisting
) {
1445 ctx
->trustedCertsOnly
= true;
1446 CFReleaseNull(ctx
->trustedCerts
);
1449 if (ctx
->trustedCerts
) {
1450 CFIndex count
= CFArrayGetCount(trustedRoots
);
1451 CFRange range
= { 0, count
};
1452 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1454 require(ctx
->trustedCerts
=
1455 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1459 return errSecSuccess
;
1462 return errSecAllocate
;
1466 SSLCopyTrustedRoots (SSLContextRef ctx
,
1467 CFArrayRef
*trustedRoots
) /* RETURNED */
1469 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1472 if(ctx
->trustedCerts
!= NULL
) {
1473 *trustedRoots
= ctx
->trustedCerts
;
1474 CFRetain(ctx
->trustedCerts
);
1475 return errSecSuccess
;
1477 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1478 /* use default system roots */
1479 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1481 *trustedRoots
= NULL
;
1482 return errSecSuccess
;
1487 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1488 CFArrayRef trustedCerts
)
1493 if(sslIsSessionActive(ctx
)) {
1494 /* can't do this with an active session */
1495 return errSecBadReq
;
1498 if(ctx
->trustedLeafCerts
) {
1499 CFRelease(ctx
->trustedLeafCerts
);
1501 ctx
->trustedLeafCerts
= trustedCerts
;
1502 CFRetain(trustedCerts
);
1503 return errSecSuccess
;
1507 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1508 CFArrayRef
*trustedCerts
) /* RETURNED */
1513 if(ctx
->trustedLeafCerts
!= NULL
) {
1514 *trustedCerts
= ctx
->trustedLeafCerts
;
1515 CFRetain(ctx
->trustedCerts
);
1516 return errSecSuccess
;
1518 *trustedCerts
= NULL
;
1519 return errSecSuccess
;
1523 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1524 SSLAuthenticate auth
)
1529 if(sslIsSessionActive(ctx
)) {
1530 /* can't do this with an active session */
1531 return errSecBadReq
;
1533 ctx
->clientAuth
= auth
;
1535 case kNeverAuthenticate
:
1536 tls_handshake_set_client_auth(ctx
->hdsk
, false);
1538 case kAlwaysAuthenticate
:
1539 case kTryAuthenticate
:
1540 tls_handshake_set_client_auth(ctx
->hdsk
, true);
1543 return errSecSuccess
;
1547 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1548 SSLAuthenticate
*auth
) /* RETURNED */
1550 if(ctx
== NULL
|| auth
== NULL
) {
1553 *auth
= ctx
->clientAuth
;
1554 return errSecSuccess
;
1558 SSLGetClientCertificateState (SSLContextRef ctx
,
1559 SSLClientCertificateState
*clientState
)
1564 if(ctx
->protocolSide
== kSSLClientSide
) {
1566 switch(ctx
->clientCertState
) {
1567 case kSSLClientCertNone
:
1568 *clientState
= kSSLClientCertNone
;
1570 case kSSLClientCertRequested
:
1571 if(ctx
->localCert
) {
1572 *clientState
= kSSLClientCertSent
;
1574 *clientState
= kSSLClientCertRequested
;
1578 /* Anything else is an internal error */
1579 sslErrorLog("TLS client has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1580 return errSSLInternal
;
1584 switch(ctx
->clientCertState
) {
1585 case kSSLClientCertNone
:
1586 case kSSLClientCertRejected
:
1587 *clientState
= ctx
->clientCertState
;
1589 case kSSLClientCertRequested
:
1591 *clientState
= kSSLClientCertSent
;
1593 *clientState
= kSSLClientCertRequested
;
1597 /* Anything else is an internal error */
1598 sslErrorLog("TLS server has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1599 return errSSLInternal
;
1602 return errSecSuccess
;
1606 SSLSetCertificate (SSLContextRef ctx
,
1607 CFArrayRef certRefs
)
1610 * -- free localCerts if we have any
1611 * -- Get raw cert data, convert to ctx->localCert
1612 * -- get pub, priv keys from certRef[0]
1613 * -- validate cert chain
1619 CFReleaseNull(ctx
->localCertArray
);
1620 /* changing the client cert invalidates negotiated auth type */
1621 ctx
->negAuthType
= SSLClientAuthNone
;
1622 if(certRefs
== NULL
) {
1623 return errSecSuccess
; // we have cleared the cert, as requested
1625 sslFreeLocalCert(ctx
);
1626 OSStatus ortn
= parseIncomingCerts(ctx
,
1629 &ctx
->signingPrivKeyRef
);
1630 if(ortn
== errSecSuccess
) {
1631 ctx
->localCertArray
= certRefs
;
1633 if(ctx
->protocolSide
==kSSLClientSide
)
1634 SSLUpdateNegotiatedClientAuthType(ctx
);
1635 tls_handshake_set_identity(ctx
->hdsk
, ctx
->localCert
, ctx
->signingPrivKeyRef
);
1641 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1642 CFArrayRef certRefs
)
1647 if(sslIsSessionActive(ctx
)) {
1648 /* can't do this with an active session */
1649 return errSecBadReq
;
1651 CFReleaseNull(ctx
->encryptCertArray
);
1652 ctx
->encryptCertArray
= certRefs
;
1654 return errSecSuccess
;
1657 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1658 CFArrayRef
*certRefs
)
1663 *certRefs
= ctx
->localCertArray
;
1664 return errSecSuccess
;
1667 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1668 CFArrayRef
*certRefs
)
1673 *certRefs
= ctx
->encryptCertArray
;
1674 return errSecSuccess
;
1678 SSLSetPeerID (SSLContext
*ctx
,
1684 /* copy peerId to context->peerId */
1690 if(sslIsSessionActive(ctx
) &&
1691 /* kSSLClientCertRequested implies client side */
1692 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1694 return errSecBadReq
;
1696 SSLFreeBuffer(&ctx
->peerID
);
1697 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1701 tls_handshake_set_resumption(ctx
->hdsk
, true);
1702 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1703 return errSecSuccess
;
1707 SSLGetPeerID (SSLContextRef ctx
,
1708 const void **peerID
,
1711 *peerID
= ctx
->peerID
.data
; // may be NULL
1712 *peerIDLen
= ctx
->peerID
.length
;
1713 return errSecSuccess
;
1717 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1718 SSLCipherSuite
*cipherSuite
)
1724 if(!sslIsSessionActive(ctx
)) {
1725 return errSecBadReq
;
1728 *cipherSuite
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
1730 return errSecSuccess
;
1734 * Add an acceptable distinguished name (client authentication only).
1737 SSLAddDistinguishedName(
1748 if(sslIsSessionActive(ctx
)) {
1749 return errSecBadReq
;
1752 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1754 return errSecAllocate
;
1756 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1761 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1762 dn
->next
= ctx
->acceptableDNList
;
1763 ctx
->acceptableDNList
= dn
;
1765 tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
);
1767 return errSecSuccess
;
1770 /* single-cert version of SSLSetCertificateAuthorities() */
1772 sslAddCA(SSLContextRef ctx
,
1773 SecCertificateRef cert
)
1775 OSStatus ortn
= errSecParam
;
1777 /* Get subject from certificate. */
1778 #if TARGET_OS_IPHONE
1779 CFDataRef subjectName
= NULL
;
1780 subjectName
= SecCertificateCopySubjectSequence(cert
);
1781 require(subjectName
, errOut
);
1783 CSSM_DATA_PTR subjectName
= NULL
;
1784 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1785 require_noerr(ortn
, errOut
);
1788 /* add to acceptableCAs as cert, creating array if necessary */
1789 if(ctx
->acceptableCAs
== NULL
) {
1790 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1791 &kCFTypeArrayCallBacks
), errOut
);
1792 if(ctx
->acceptableCAs
== NULL
) {
1793 return errSecAllocate
;
1796 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1798 /* then add this cert's subject name to acceptableDNList */
1799 #if TARGET_OS_IPHONE
1800 ortn
= SSLAddDistinguishedName(ctx
,
1801 CFDataGetBytePtr(subjectName
),
1802 CFDataGetLength(subjectName
));
1804 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1808 #if TARGET_OS_IPHONE
1809 CFReleaseSafe(subjectName
);
1815 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1816 * of acceptable Certificate Authorities (CAs) to present to the client
1817 * when client authentication is performed.
1820 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1821 CFTypeRef certificateOrArray
,
1822 Boolean replaceExisting
)
1825 OSStatus ortn
= errSecSuccess
;
1827 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1828 (ctx
->protocolSide
!= kSSLServerSide
)) {
1831 if(replaceExisting
) {
1833 if(ctx
->acceptableCAs
) {
1834 CFRelease(ctx
->acceptableCAs
);
1835 ctx
->acceptableCAs
= NULL
;
1838 /* else appending */
1840 itemType
= CFGetTypeID(certificateOrArray
);
1841 if(itemType
== SecCertificateGetTypeID()) {
1843 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
1845 else if(itemType
== CFArrayGetTypeID()) {
1846 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
1847 CFIndex numCerts
= CFArrayGetCount(cfa
);
1850 /* array of certs */
1851 for(dex
=0; dex
<numCerts
; dex
++) {
1852 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
1853 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
1856 ortn
= sslAddCA(ctx
, cert
);
1870 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1871 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1873 * Caller must CFRelease the returned array.
1876 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
1877 CFArrayRef
*certificates
) /* RETURNED */
1879 if((ctx
== NULL
) || (certificates
== NULL
)) {
1882 if(ctx
->acceptableCAs
== NULL
) {
1883 *certificates
= NULL
;
1884 return errSecSuccess
;
1886 *certificates
= ctx
->acceptableCAs
;
1887 CFRetain(ctx
->acceptableCAs
);
1888 return errSecSuccess
;
1893 * Obtain the list of acceptable distinguished names as provided by
1894 * a server (if the SSLCotextRef is configured as a client), or as
1895 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1896 * is configured as a server).
1899 SSLCopyDistinguishedNames (SSLContextRef ctx
,
1902 CFMutableArrayRef outArray
= NULL
;
1903 const DNListElem
*dn
;
1905 if((ctx
== NULL
) || (names
== NULL
)) {
1908 if(ctx
->protocolSide
==kSSLServerSide
) {
1909 dn
= ctx
->acceptableDNList
;
1911 dn
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList;
1916 return errSecSuccess
;
1918 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1921 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
1922 CFArrayAppendValue(outArray
, cfDn
);
1927 return errSecSuccess
;
1932 * Request peer certificates. Valid anytime, subsequent to
1933 * a handshake attempt.
1934 * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
1935 * TODO: the 'legacy' argument is not used anymore.
1938 sslCopyPeerCertificates (SSLContextRef ctx
,
1946 if (!ctx
->peerCert
) {
1948 return errSecBadReq
;
1951 CFArrayRef ca
= CFArrayCreateCopy(kCFAllocatorDefault
, ctx
->peerCert
);
1954 return errSecAllocate
;
1958 CFIndex ix
, count
= CFArrayGetCount(ca
);
1959 for (ix
= 0; ix
< count
; ++ix
) {
1960 CFRetain(CFArrayGetValueAtIndex(ca
, ix
));
1964 return errSecSuccess
;
1968 SSLCopyPeerCertificates (SSLContextRef ctx
,
1971 return sslCopyPeerCertificates(ctx
, certs
, false);
1974 #if !TARGET_OS_IPHONE
1975 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
1976 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
1978 SSLGetPeerCertificates (SSLContextRef ctx
,
1981 SSLGetPeerCertificates (SSLContextRef ctx
,
1984 return sslCopyPeerCertificates(ctx
, certs
, true);
1989 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1990 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1991 * been called, a set of process-wide parameters will be calculated. However
1992 * that can take a long time (30 seconds).
1994 OSStatus
SSLSetDiffieHellmanParams(
1996 const void *dhParams
,
2003 if(sslIsSessionActive(ctx
)) {
2004 return errSecBadReq
;
2006 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
2009 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
2010 &ctx
->dhParamsEncoded
);
2015 return tls_handshake_set_dh_parameters(ctx
->hdsk
, &ctx
->dhParamsEncoded
);
2018 #endif /* APPLE_DH */
2022 * Return parameter block specified in SSLSetDiffieHellmanParams.
2023 * Returned data is not copied and belongs to the SSLContextRef.
2025 OSStatus
SSLGetDiffieHellmanParams(
2027 const void **dhParams
,
2028 size_t *dhParamsLen
)
2034 *dhParams
= ctx
->dhParamsEncoded
.data
;
2035 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
2036 return errSecSuccess
;
2038 return errSecUnimplemented
;
2039 #endif /* APPLE_DH */
2042 OSStatus
SSLSetDHEEnabled(SSLContextRef ctx
, bool enabled
)
2044 ctx
->dheEnabled
= enabled
;
2045 /* Hack a little so that only the ciphersuites change */
2046 tls_protocol_version min
, max
;
2048 tls_handshake_get_min_protocol_version(ctx
->hdsk
, &min
);
2049 tls_handshake_get_max_protocol_version(ctx
->hdsk
, &max
);
2050 tls_handshake_get_min_dh_group_size(ctx
->hdsk
, &nbits
);
2051 tls_handshake_set_config(ctx
->hdsk
, enabled
?tls_handshake_config_legacy_DHE
:tls_handshake_config_legacy
);
2052 tls_handshake_set_min_protocol_version(ctx
->hdsk
, min
);
2053 tls_handshake_set_max_protocol_version(ctx
->hdsk
, max
);
2054 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2059 OSStatus
SSLGetDHEEnabled(SSLContextRef ctx
, bool *enabled
)
2061 *enabled
= ctx
->dheEnabled
;
2065 OSStatus
SSLSetMinimumDHGroupSize(SSLContextRef ctx
, unsigned nbits
)
2067 return tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2070 OSStatus
SSLGetMinimumDHGroupSize(SSLContextRef ctx
, unsigned *nbits
)
2072 return tls_handshake_get_min_dh_group_size(ctx
->hdsk
, nbits
);
2075 OSStatus
SSLSetRsaBlinding(
2082 ctx
->rsaBlindingEnable
= blinding
;
2083 return errSecSuccess
;
2086 OSStatus
SSLGetRsaBlinding(
2093 *blinding
= ctx
->rsaBlindingEnable
;
2094 return errSecSuccess
;
2100 SecTrustRef
*trust
) /* RETURNED */
2102 OSStatus status
= errSecSuccess
;
2103 if (ctx
== NULL
|| trust
== NULL
)
2106 /* Create a SecTrustRef if this was a resumed session and we
2107 didn't have one yet. */
2108 if (!ctx
->peerCert
) {
2109 ctx
->peerCert
= tls_get_peer_certs(tls_handshake_get_peer_certificates(ctx
->hdsk
));
2111 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2112 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
,
2113 &ctx
->peerSecTrust
);
2116 *trust
= ctx
->peerSecTrust
;
2117 if (ctx
->peerSecTrust
)
2118 CFRetain(ctx
->peerSecTrust
);
2123 OSStatus
SSLGetPeerSecTrust(
2125 SecTrustRef
*trust
) /* RETURNED */
2127 OSStatus status
= errSecSuccess
;
2128 if (ctx
== NULL
|| trust
== NULL
)
2131 /* Create a SecTrustRef if this was a resumed session and we
2132 didn't have one yet. */
2133 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2134 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
,
2135 &ctx
->peerSecTrust
);
2138 *trust
= ctx
->peerSecTrust
;
2142 OSStatus
SSLInternalMasterSecret(
2144 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
2145 size_t *secretSize
) // in/out
2147 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
2150 return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
);
2153 OSStatus
SSLInternalServerRandom(
2155 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2156 size_t *randSize
) // in/out
2158 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2161 return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
);
2164 OSStatus
SSLInternalClientRandom(
2166 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2167 size_t *randSize
) // in/out
2169 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2172 return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
);
2175 /* This is used by EAP 802.1x */
2176 OSStatus
SSLGetCipherSizes(
2179 size_t *symmetricKeySize
,
2182 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2183 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2187 SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
2189 *digestSize
= sslCipherSuiteGetMacSize(cipher
);
2190 *symmetricKeySize
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
);
2191 *ivSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
);
2192 return errSecSuccess
;
2196 SSLGetResumableSessionInfo(
2198 Boolean
*sessionWasResumed
, // RETURNED
2199 void *sessionID
, // RETURNED, mallocd by caller
2200 size_t *sessionIDLength
) // IN/OUT
2202 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2203 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2204 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2208 SSLBuffer localSessionID
;
2209 bool sessionMatch
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
);
2212 *sessionWasResumed
= true;
2213 if(localSessionID
.length
> *sessionIDLength
) {
2214 /* really should never happen - means ID > 32 */
2217 if(localSessionID
.length
) {
2219 * Note PAC-based session resumption can result in sessionMatch
2222 memmove(sessionID
, localSessionID
.data
, localSessionID
.length
);
2224 *sessionIDLength
= localSessionID
.length
;
2227 *sessionWasResumed
= false;
2228 *sessionIDLength
= 0;
2230 return errSecSuccess
;
2234 * Get/set enable of anonymous ciphers. This is deprecated and now a no-op.
2237 SSLSetAllowAnonymousCiphers(
2241 return errSecSuccess
;
2245 SSLGetAllowAnonymousCiphers(
2249 return errSecSuccess
;
2253 * Override the default session cache timeout for a cache entry created for
2254 * the current session.
2257 SSLSetSessionCacheTimeout(
2259 uint32_t timeoutInSeconds
)
2264 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2265 return errSecSuccess
;
2270 void tls_handshake_master_secret_function(const void *arg
, /* opaque to coreTLS; app-specific */
2271 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2272 size_t *secretLength
)
2274 SSLContextRef ctx
= (SSLContextRef
) arg
;
2275 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
);
2280 * Register a callback for obtaining the master_secret when performing
2281 * PAC-based session resumption.
2284 SSLInternalSetMasterSecretFunction(
2286 SSLInternalMasterSecretFunction mFunc
,
2287 const void *arg
) /* opaque to SecureTransport; app-specific */
2293 ctx
->masterSecretArg
= arg
;
2294 ctx
->masterSecretCallback
= mFunc
;
2296 return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
);
2300 * Provide an opaque SessionTicket for use in PAC-based session
2301 * resumption. Client side only. The provided ticket is sent in
2302 * the ClientHello message as a SessionTicket extension.
2304 * We won't reject this on the server side, but server-side support
2305 * for PAC-based session resumption is currently enabled for
2306 * Development builds only. To fully support this for server side,
2307 * besides the rudimentary support that's here for Development builds,
2308 * we'd need a getter for the session ticket, so the app code can
2309 * access the SessionTicket when its SSLInternalMasterSecretFunction
2310 * callback is called.
2312 OSStatus
SSLInternalSetSessionTicket(
2315 size_t ticketLength
)
2320 if(sslIsSessionActive(ctx
)) {
2321 /* can't do this with an active session */
2322 return errSecBadReq
;
2324 return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
);
2329 * ECDSA curve accessors.
2333 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2334 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2336 OSStatus
SSLGetNegotiatedCurve(
2338 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2340 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2343 unsigned int curve
= tls_handshake_get_negotiated_curve(ctx
->hdsk
);
2344 if(curve
== SSL_Curve_None
) {
2347 *namedCurve
= curve
;
2348 return errSecSuccess
;
2352 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2354 OSStatus
SSLGetNumberOfECDSACurves(
2356 unsigned *numCurves
) /* RETURNED */
2358 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2361 *numCurves
= ctx
->ecdhNumCurves
;
2362 return errSecSuccess
;
2366 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2368 OSStatus
SSLGetECDSACurves(
2370 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2371 unsigned *numCurves
) /* IN/OUT */
2373 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2376 if(*numCurves
< ctx
->ecdhNumCurves
) {
2379 memmove(namedCurves
, ctx
->ecdhCurves
,
2380 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2381 *numCurves
= ctx
->ecdhNumCurves
;
2382 return errSecSuccess
;
2386 * Specify ordered list of allowable named curves.
2388 OSStatus
SSLSetECDSACurves(
2390 const SSL_ECDSA_NamedCurve
*namedCurves
,
2393 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2396 if(sslIsSessionActive(ctx
)) {
2397 /* can't do this with an active session */
2398 return errSecBadReq
;
2401 size_t size
= numCurves
* sizeof(uint16_t);
2402 ctx
->ecdhCurves
= (uint16_t *)sslMalloc(size
);
2403 if(ctx
->ecdhCurves
== NULL
) {
2404 ctx
->ecdhNumCurves
= 0;
2405 return errSecAllocate
;
2408 for (unsigned i
=0; i
<numCurves
; i
++) {
2409 ctx
->ecdhCurves
[i
] = namedCurves
[i
];
2412 ctx
->ecdhNumCurves
= numCurves
;
2414 tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
);
2415 return errSecSuccess
;
2419 * Obtain the number of client authentication mechanisms specified by
2420 * the server in its Certificate Request message.
2421 * Returns errSecParam if server hasn't sent a Certificate Request message
2422 * (i.e., client certificate state is kSSLClientCertNone).
2424 OSStatus
SSLGetNumberOfClientAuthTypes(
2428 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2431 *numTypes
= ctx
->numAuthTypes
;
2432 return errSecSuccess
;
2436 * Obtain the client authentication mechanisms specified by
2437 * the server in its Certificate Request message.
2438 * Caller allocates returned array and specifies its size (in
2439 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2440 * is the actual size of the returned array on successful return.
2442 OSStatus
SSLGetClientAuthTypes(
2444 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2445 unsigned *numTypes
) /* IN/OUT */
2447 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2450 memmove(authTypes
, ctx
->clientAuthTypes
,
2451 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2452 *numTypes
= ctx
->numAuthTypes
;
2453 return errSecSuccess
;
2457 * Obtain the SSLClientAuthenticationType actually performed.
2458 * Only valid if client certificate state is kSSLClientCertSent
2459 * or kSSLClientCertRejected; returns errSecParam otherwise.
2461 OSStatus
SSLGetNegotiatedClientAuthType(
2463 SSLClientAuthenticationType
*authType
) /* RETURNED */
2469 *authType
= ctx
->negAuthType
;
2471 return errSecSuccess
;
2475 * Update the negotiated client authentication type.
2476 * This function may be called at any time; however, note that
2477 * the negotiated authentication type will be SSLClientAuthNone
2478 * until both of the following have taken place (in either order):
2479 * - a CertificateRequest message from the server has been processed
2480 * - a client certificate has been specified
2481 * As such, this function (only) needs to be called from (both)
2482 * SSLProcessCertificateRequest and SSLSetCertificate.
2484 OSStatus
SSLUpdateNegotiatedClientAuthType(
2490 assert(ctx
->protocolSide
==kSSLClientSide
);
2492 * See if we have a signing cert that matches one of the
2493 * allowed auth types. The x509Requested flag indicates "we
2494 * have a cert that we think the server will accept".
2496 ctx
->x509Requested
= 0;
2497 ctx
->negAuthType
= SSLClientAuthNone
;
2498 if(ctx
->signingPrivKeyRef
!= NULL
) {
2499 CFIndex ourKeyAlg
= sslPrivKeyGetAlgorithmID((SecKeyRef
)tls_private_key_get_context(ctx
->signingPrivKeyRef
));
2502 for(i
=0; i
<ctx
->numAuthTypes
; i
++) {
2503 switch(ctx
->clientAuthTypes
[i
]) {
2504 case SSLClientAuth_RSASign
:
2505 if(ourKeyAlg
== kSecRSAAlgorithmID
) {
2506 ctx
->x509Requested
= 1;
2507 ctx
->negAuthType
= SSLClientAuth_RSASign
;
2510 case SSLClientAuth_ECDSASign
:
2511 #if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
2512 case SSLClientAuth_ECDSAFixedECDH
:
2514 if(ourKeyAlg
== kSecECDSAAlgorithmID
) {
2515 ctx
->x509Requested
= 1;
2516 ctx
->negAuthType
= ctx
->clientAuthTypes
[i
];
2519 #if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
2520 case SSLClientAuth_RSAFixedECDH
:
2521 /* Odd case, we differ from our signer */
2522 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2523 (ctx
->ourSignerAlg
== kSecRSAAlgorithmID
)) {
2524 ctx
->x509Requested
= 1;
2525 ctx
->negAuthType
= SSLClientAuth_RSAFixedECDH
;
2530 /* None others supported */
2533 if(ctx
->x509Requested
) {
2534 sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx
->negAuthType
);
2537 } /* parsing authTypes */
2538 } /* we have a signing key */
2540 tls_handshake_set_client_auth_type(ctx
->hdsk
, ctx
->negAuthType
);
2542 return errSecSuccess
;
2545 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2547 unsigned *numSigAlgs
)
2553 tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
);
2554 return errSecSuccess
;
2557 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
),
2558 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2560 OSStatus
SSLGetSignatureAlgorithms(
2562 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2563 unsigned *numSigAlgs
) /* IN/OUT */
2569 unsigned numPeerSigAlgs
;
2570 const tls_signature_and_hash_algorithm
*peerAlgs
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
);
2572 memmove(sigAlgs
, peerAlgs
,
2573 numPeerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2574 *numSigAlgs
= numPeerSigAlgs
;
2575 return errSecSuccess
;
2579 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2583 if(ctx
== NULL
) return errSecParam
;
2585 if(ctx
->pskSharedSecret
.data
)
2586 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2588 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2589 return errSecAllocate
;
2591 tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
);
2593 return errSecSuccess
;
2596 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2597 const void *pskIdentity
,
2598 size_t pskIdentityLen
)
2600 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2602 if(ctx
->pskIdentity
.data
)
2603 SSLFreeBuffer(&ctx
->pskIdentity
);
2605 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2606 return errSecAllocate
;
2608 tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
);
2610 return errSecSuccess
;
2614 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2615 const void **pskIdentity
,
2616 size_t *pskIdentityLen
)
2618 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2620 *pskIdentity
=ctx
->pskIdentity
.data
;
2621 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2623 return errSecSuccess
;
2626 OSStatus
SSLInternal_PRF(
2628 const void *vsecret
,
2630 const void *label
, // optional, NULL implies that seed contains
2635 void *vout
, // mallocd by caller, length >= outLen
2638 return tls_handshake_internal_prf(ctx
->hdsk
,
2645 /* To be implemented */
2647 SSLSetSessionStrengthPolicy(SSLContextRef context
,
2648 SSLSessionStrengthPolicy policyStrength
)
2650 return errSecSuccess
;
2653 const CFStringRef kSSLSessionConfig_default
= CFSTR("default");
2654 const CFStringRef kSSLSessionConfig_ATSv1
= CFSTR("ATSv1");
2655 const CFStringRef kSSLSessionConfig_ATSv1_noPFS
= CFSTR("ATSv1_noPFS");
2656 const CFStringRef kSSLSessionConfig_legacy
= CFSTR("legacy");
2657 const CFStringRef kSSLSessionConfig_standard
= CFSTR("standard");
2658 const CFStringRef kSSLSessionConfig_RC4_fallback
= CFSTR("RC4_fallback");
2659 const CFStringRef kSSLSessionConfig_TLSv1_fallback
= CFSTR("TLSv1_fallback");
2660 const CFStringRef kSSLSessionConfig_TLSv1_RC4_fallback
= CFSTR("TLSv1_RC4_fallback");
2661 const CFStringRef kSSLSessionConfig_legacy_DHE
= CFSTR("legacy_DHE");
2664 tls_handshake_config_t
SSLSessionConfig_to_tls_handshake_config(CFStringRef config
)
2666 if(CFEqual(config
, kSSLSessionConfig_ATSv1
)){
2667 return tls_handshake_config_ATSv1
;
2668 } else if(CFEqual(config
, kSSLSessionConfig_ATSv1_noPFS
)){
2669 return tls_handshake_config_ATSv1_noPFS
;
2670 } else if(CFEqual(config
, kSSLSessionConfig_standard
)){
2671 return tls_handshake_config_standard
;
2672 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_fallback
)){
2673 return tls_handshake_config_TLSv1_fallback
;
2674 } else if(CFEqual(config
, kSSLSessionConfig_TLSv1_RC4_fallback
)){
2675 return tls_handshake_config_TLSv1_RC4_fallback
;
2676 } else if(CFEqual(config
, kSSLSessionConfig_RC4_fallback
)){
2677 return tls_handshake_config_RC4_fallback
;
2678 } else if(CFEqual(config
, kSSLSessionConfig_legacy
)){
2679 return tls_handshake_config_legacy
;
2680 } else if(CFEqual(config
, kSSLSessionConfig_legacy_DHE
)){
2681 return tls_handshake_config_legacy_DHE
;
2682 } else if(CFEqual(config
, kSSLSessionConfig_default
)){
2683 return tls_handshake_config_default
;
2685 return tls_handshake_config_none
;
2690 const CFStringRef
tls_handshake_config_to_SSLSessionConfig(tls_handshake_config_t config
)
2693 case tls_handshake_config_ATSv1
:
2694 return kSSLSessionConfig_ATSv1
;
2695 case tls_handshake_config_ATSv1_noPFS
:
2696 return kSSLSessionConfig_ATSv1_noPFS
;
2697 case tls_handshake_config_standard
:
2698 return kSSLSessionConfig_standard
;
2699 case tls_handshake_config_RC4_fallback
:
2700 return kSSLSessionConfig_RC4_fallback
;
2701 case tls_handshake_config_TLSv1_fallback
:
2702 return kSSLSessionConfig_TLSv1_fallback
;
2703 case tls_handshake_config_TLSv1_RC4_fallback
:
2704 return kSSLSessionConfig_TLSv1_RC4_fallback
;
2705 case tls_handshake_config_legacy
:
2706 return kSSLSessionConfig_legacy
;
2707 case tls_handshake_config_legacy_DHE
:
2708 return kSSLSessionConfig_legacy_DHE
;
2709 case tls_handshake_config_default
:
2710 return kSSLSessionConfig_default
;
2711 case tls_handshake_config_none
:
2717 /* Set Predefined TLS Configuration */
2719 SSLSetSessionConfig(SSLContextRef context
,
2722 tls_handshake_config_t cfg
= SSLSessionConfig_to_tls_handshake_config(config
);
2724 return tls_handshake_set_config(context
->hdsk
, cfg
);
2731 SSLGetSessionConfig(SSLContextRef context
,
2732 CFStringRef
*config
)
2734 tls_handshake_config_t cfg
;
2735 OSStatus err
= tls_handshake_get_config(context
->hdsk
, &cfg
);
2740 *config
= tls_handshake_config_to_SSLSessionConfig(cfg
);