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 ctx
->dheEnabled
= true;
320 ctx
->dheEnabled
= 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 sslFree(ctx
->validCipherSuites
);
409 ctx
->validCipherSuites
= NULL
;
410 ctx
->numValidCipherSuites
= 0;
412 CFReleaseSafe(ctx
->acceptableCAs
);
413 CFReleaseSafe(ctx
->trustedLeafCerts
);
414 CFReleaseSafe(ctx
->localCertArray
);
415 CFReleaseSafe(ctx
->encryptCertArray
);
416 CFReleaseSafe(ctx
->peerCert
);
417 CFReleaseSafe(ctx
->trustedCerts
);
418 CFReleaseSafe(ctx
->peerSecTrust
);
420 sslFreePrivKey(&ctx
->signingPrivKeyRef
);
422 sslFreeLocalCert(ctx
);
425 SSLFreeBuffer(&ctx
->ownVerifyData
);
426 SSLFreeBuffer(&ctx
->peerVerifyData
);
428 SSLFreeBuffer(&ctx
->pskIdentity
);
429 SSLFreeBuffer(&ctx
->pskSharedSecret
);
431 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
433 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
439 * Determine the state of an SSL session.
442 SSLGetSessionState (SSLContextRef context
,
443 SSLSessionState
*state
) /* RETURNED */
445 SSLSessionState rtnState
= kSSLIdle
;
447 if(context
== NULL
) {
451 switch(context
->state
) {
452 case SSL_HdskStateUninit
:
455 case SSL_HdskStateGracefulClose
:
456 rtnState
= kSSLClosed
;
458 case SSL_HdskStateErrorClose
:
459 case SSL_HdskStateNoNotifyClose
:
460 rtnState
= kSSLAborted
;
462 case SSL_HdskStateReady
:
463 rtnState
= kSSLConnected
;
465 case SSL_HdskStatePending
:
466 rtnState
= kSSLHandshake
;
470 return errSecSuccess
;
474 * Set options for an SSL session.
477 SSLSetSessionOption (SSLContextRef context
,
478 SSLSessionOption option
,
481 if(context
== NULL
) {
484 if(sslIsSessionActive(context
)) {
485 /* can't do this with an active session */
489 case kSSLSessionOptionBreakOnServerAuth
:
490 context
->breakOnServerAuth
= value
;
491 context
->enableCertVerify
= !value
;
493 case kSSLSessionOptionBreakOnCertRequested
:
494 context
->breakOnCertRequest
= value
;
496 case kSSLSessionOptionBreakOnClientAuth
:
497 context
->breakOnClientAuth
= value
;
498 context
->enableCertVerify
= !value
;
500 case kSSLSessionOptionSendOneByteRecord
:
501 /* Only call the record layer function if the value changed */
502 if(value
!= context
->oneByteRecordEnable
)
503 context
->recFuncs
->setOption(context
->recCtx
, kSSLRecordOptionSendOneByteRecord
, value
);
504 context
->oneByteRecordEnable
= value
;
506 case kSSLSessionOptionFalseStart
:
507 context
->falseStartEnabled
= value
;
509 case kSSLSessionOptionFallback
:
510 tls_handshake_set_fallback(context
->hdsk
, value
);
511 context
->fallbackEnabled
= value
;
513 case kSSLSessionOptionBreakOnClientHello
:
514 context
->breakOnClientHello
= value
;
516 case kSSLSessionOptionAllowServerIdentityChange
:
517 tls_handshake_set_server_identity_change(context
->hdsk
, value
);
523 return errSecSuccess
;
527 * Determine current value for the specified option in an SSL session.
530 SSLGetSessionOption (SSLContextRef context
,
531 SSLSessionOption option
,
534 if(context
== NULL
|| value
== NULL
) {
538 case kSSLSessionOptionBreakOnServerAuth
:
539 *value
= context
->breakOnServerAuth
;
541 case kSSLSessionOptionBreakOnCertRequested
:
542 *value
= context
->breakOnCertRequest
;
544 case kSSLSessionOptionBreakOnClientAuth
:
545 *value
= context
->breakOnClientAuth
;
547 case kSSLSessionOptionSendOneByteRecord
:
548 *value
= context
->oneByteRecordEnable
;
550 case kSSLSessionOptionFalseStart
:
551 *value
= context
->falseStartEnabled
;
553 case kSSLSessionOptionBreakOnClientHello
:
554 *value
= context
->breakOnClientHello
;
556 case kSSLSessionOptionAllowServerIdentityChange
:
557 tls_handshake_get_server_identity_change(context
->hdsk
, (bool *)value
);
563 return errSecSuccess
;
567 SSLSetRecordContext (SSLContextRef ctx
,
568 SSLRecordContextRef recCtx
)
573 if(sslIsSessionActive(ctx
)) {
574 /* can't do this with an active session */
577 ctx
->recCtx
= recCtx
;
578 return errSecSuccess
;
582 SSLSetIOFuncs (SSLContextRef ctx
,
583 SSLReadFunc readFunc
,
584 SSLWriteFunc writeFunc
)
589 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
590 /* Can Only do this with the internal record layer */
594 if(sslIsSessionActive(ctx
)) {
595 /* can't do this with an active session */
599 ctx
->ioCtx
.read
=readFunc
;
600 ctx
->ioCtx
.write
=writeFunc
;
606 SSLSetNPNFunc(SSLContextRef context
,
610 if (context
== NULL
) {
613 if (sslIsSessionActive(context
)) {
616 context
->npnFunc
= npnFunc
;
617 context
->npnFuncInfo
= info
;
618 if(context
->protocolSide
==kSSLClientSide
) {
619 tls_handshake_set_npn_enable(context
->hdsk
, npnFunc
!=NULL
);
624 SSLSetNPNData(SSLContextRef context
,
628 if (context
== NULL
|| data
== NULL
|| length
== 0) {
638 npn_data
.data
= (uint8_t *)data
;
639 npn_data
.length
= length
;
641 return tls_handshake_set_npn_data(context
->hdsk
, npn_data
);
645 SSLGetNPNData(SSLContextRef context
,
648 if (context
== NULL
|| length
== NULL
)
651 const tls_buffer
*npn_data
;
653 npn_data
= tls_handshake_get_peer_npn_data(context
->hdsk
);
656 *length
= npn_data
->length
;
657 return npn_data
->data
;
666 SSLSetALPNFunc(SSLContextRef context
,
667 SSLALPNFunc alpnFunc
,
670 if (context
== NULL
) {
673 if (sslIsSessionActive(context
)) {
676 context
->alpnFunc
= alpnFunc
;
677 context
->alpnFuncInfo
= info
;
678 if(context
->protocolSide
==kSSLServerSide
) {
684 SSLSetALPNData(SSLContextRef context
,
688 if (context
== NULL
|| data
== NULL
|| length
== 0) {
696 tls_buffer alpn_data
;
698 alpn_data
.data
= (uint8_t *)data
;
699 alpn_data
.length
= length
;
701 return tls_handshake_set_alpn_data(context
->hdsk
, alpn_data
);
705 SSLGetALPNData(SSLContextRef context
,
708 if (context
== NULL
|| length
== NULL
)
711 const tls_buffer
*alpn_data
;
713 alpn_data
= tls_handshake_get_peer_alpn_data(context
->hdsk
);
716 *length
= alpn_data
->length
;
717 return alpn_data
->data
;
726 SSLSetConnection (SSLContextRef ctx
,
727 SSLConnectionRef connection
)
732 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
733 /* Can Only do this with the internal record layer */
737 if(sslIsSessionActive(ctx
)) {
738 /* can't do this with an active session */
742 /* Need to keep a copy of it this layer for the Get function */
743 ctx
->ioCtx
.ioRef
= connection
;
749 SSLGetConnection (SSLContextRef ctx
,
750 SSLConnectionRef
*connection
)
752 if((ctx
== NULL
) || (connection
== NULL
)) {
755 *connection
= ctx
->ioCtx
.ioRef
;
756 return errSecSuccess
;
760 SSLSetPeerDomainName (SSLContextRef ctx
,
761 const char *peerName
,
767 if(sslIsSessionActive(ctx
)) {
768 /* can't do this with an active session */
772 if(ctx
->protocolSide
== kSSLClientSide
) {
773 return tls_handshake_set_peer_hostname(ctx
->hdsk
, peerName
, peerNameLen
);
775 return 0; // This should probably return an error, but historically didnt.
780 * Determine the buffer size needed for SSLGetPeerDomainName().
783 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
784 size_t *peerNameLen
) // RETURNED
789 const char *hostname
;
791 return tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, peerNameLen
);
795 SSLGetPeerDomainName (SSLContextRef ctx
,
796 char *peerName
, // returned here
797 size_t *peerNameLen
) // IN/OUT
799 const char *hostname
;
808 err
=tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
812 } else if(*peerNameLen
<len
) {
813 return errSSLBufferOverflow
;
815 memcpy(peerName
, hostname
, len
);
822 SSLCopyRequestedPeerNameLength (SSLContextRef ctx
,
823 size_t *peerNameLen
) // RETURNED
825 const tls_buffer
*hostname
;
829 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
833 *peerNameLen
= hostname
->length
;
839 SSLCopyRequestedPeerName (SSLContextRef ctx
,
840 char *peerName
, // returned here
841 size_t *peerNameLen
) // IN/OUT
843 const tls_buffer
*hostname
;
849 hostname
= tls_handshake_get_sni_hostname(ctx
->hdsk
);
853 } else if(*peerNameLen
< hostname
->length
) {
854 return errSSLBufferOverflow
;
856 memcpy(peerName
, hostname
->data
, hostname
->length
);
857 *peerNameLen
= hostname
->length
;
864 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
874 if(!ctx
->isDTLS
) return errSecParam
;
876 if((ctx
== NULL
) || (cookieLen
>32)) {
879 if(sslIsSessionActive(ctx
)) {
880 /* can't do this with an active session */
884 /* free possible existing cookie */
885 if(ctx
->dtlsCookie
.data
) {
886 SSLFreeBuffer(&ctx
->dtlsCookie
);
890 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
)))
893 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
894 return errSecSuccess
;
898 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
902 if(ctx
== NULL
) return errSecParam
;
903 if(!ctx
->isDTLS
) return errSecParam
;
905 tls_handshake_set_mtu(ctx
->hdsk
, maxSize
);
907 return errSecSuccess
;
911 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
914 if(ctx
== NULL
) return errSecParam
;
915 if(!ctx
->isDTLS
) return errSecParam
;
919 return errSecSuccess
;
924 Keys to to math below:
926 A DTLS record looks like this: | header (13 bytes) | fragment |
928 For Null cipher, fragment is clear text as follows:
931 For block cipher, fragment size must be a multiple of the cipher block size, and is the
932 encryption of the following plaintext :
933 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
935 The maximum content length in that case is achieved for 0 padding bytes.
940 SSLGetDatagramWriteSize (SSLContextRef ctx
,
943 if(ctx
== NULL
) return errSecParam
;
944 if(!ctx
->isDTLS
) return errSecParam
;
945 if(bufSize
== NULL
) return errSecParam
;
947 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
950 SSLCipherSpecParams
*currCipher
= &ctx
->selectedCipherSpecParams
;
952 size_t blockSize
= currCipher
->blockSize
;
953 size_t macSize
= currCipher
->macSize
;
955 size_t blockSize
= 16;
960 /* max_fragment_size must be a multiple of blocksize */
961 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
962 max_fragment_size
-= blockSize
; /* 1 block for IV */
963 max_fragment_size
-= 1; /* 1 byte for pad length */
966 /* less the mac size */
967 max_fragment_size
-= macSize
;
969 /* Thats just a sanity check */
970 assert(max_fragment_size
<ctx
->mtu
);
972 *bufSize
= max_fragment_size
;
974 return errSecSuccess
;
978 All the complexity around protocol version is to support legacy APIs.
979 Eventually that should go away:
980 <rdar://problem/20842025> Remove deprecated SecureTransport function related to protocol version selection.
983 static tls_protocol_version
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
985 case kSSLProtocol2
: return SSL_Version_2_0
;
986 case kSSLProtocol3
: return tls_protocol_version_SSL_3
;
987 case kTLSProtocol1
: return tls_protocol_version_TLS_1_0
;
988 case kTLSProtocol11
: return tls_protocol_version_TLS_1_1
;
989 case kTLSProtocol12
: return tls_protocol_version_TLS_1_2
;
990 case kDTLSProtocol1
: return tls_protocol_version_DTLS_1_0
;
991 default: return tls_protocol_version_Undertermined
;
995 /* concert between private SSLProtocolVersion and public SSLProtocol */
996 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
999 case tls_protocol_version_SSL_3
: return kSSLProtocol3
;
1000 case tls_protocol_version_TLS_1_0
: return kTLSProtocol1
;
1001 case tls_protocol_version_TLS_1_1
: return kTLSProtocol11
;
1002 case tls_protocol_version_TLS_1_2
: return kTLSProtocol12
;
1003 case tls_protocol_version_DTLS_1_0
: return kDTLSProtocol1
;
1005 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
1008 case tls_protocol_version_Undertermined
: return kSSLProtocolUnknown
;
1013 SSLSetProtocolVersionMin (SSLContextRef ctx
,
1014 SSLProtocol minVersion
)
1016 if(ctx
== NULL
) return errSecParam
;
1018 tls_protocol_version version
= SSLProtocolToProtocolVersion(minVersion
);
1020 if (version
> MINIMUM_DATAGRAM_VERSION
||
1021 version
< MAXIMUM_DATAGRAM_VERSION
)
1022 return errSSLIllegalParam
;
1023 if (version
< ctx
->maxProtocolVersion
)
1024 ctx
->maxProtocolVersion
= version
;
1026 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1027 return errSSLIllegalParam
;
1028 if (version
> ctx
->maxProtocolVersion
)
1029 ctx
->maxProtocolVersion
= version
;
1031 ctx
->minProtocolVersion
= version
;
1033 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1034 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1036 return errSecSuccess
;
1040 SSLGetProtocolVersionMin (SSLContextRef ctx
,
1041 SSLProtocol
*minVersion
)
1043 if(ctx
== NULL
) return errSecParam
;
1045 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
1046 return errSecSuccess
;
1050 SSLSetProtocolVersionMax (SSLContextRef ctx
,
1051 SSLProtocol maxVersion
)
1053 if(ctx
== NULL
) return errSecParam
;
1055 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
1057 if (version
> MINIMUM_DATAGRAM_VERSION
||
1058 version
< MAXIMUM_DATAGRAM_VERSION
)
1059 return errSSLIllegalParam
;
1060 if (version
> ctx
->minProtocolVersion
)
1061 ctx
->minProtocolVersion
= version
;
1063 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
1064 return errSSLIllegalParam
;
1065 if (version
< ctx
->minProtocolVersion
)
1066 ctx
->minProtocolVersion
= version
;
1068 ctx
->maxProtocolVersion
= version
;
1070 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1071 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1073 return errSecSuccess
;
1077 SSLGetProtocolVersionMax (SSLContextRef ctx
,
1078 SSLProtocol
*maxVersion
)
1080 if(ctx
== NULL
) return errSecParam
;
1082 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
1083 return errSecSuccess
;
1086 #define max(x,y) ((x)<(y)?(y):(x))
1089 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
1090 SSLProtocol protocol
,
1096 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1097 /* Can't do this with an active session, nor with a DTLS session */
1098 return errSecBadReq
;
1100 if (protocol
== kSSLProtocolAll
) {
1102 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1103 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1105 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1106 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1109 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1111 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
1114 if (version
> ctx
->maxProtocolVersion
) {
1115 ctx
->maxProtocolVersion
= version
;
1116 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
1117 ctx
->minProtocolVersion
= version
;
1119 if (version
< ctx
->minProtocolVersion
) {
1120 ctx
->minProtocolVersion
= version
;
1123 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
1126 /* Disabling a protocol version now resets the minimum acceptable
1127 * version to the next higher version. This means it's no longer
1128 * possible to enable a discontiguous set of protocol versions.
1130 SSLProtocolVersion nextVersion
;
1132 case SSL_Version_2_0
:
1133 nextVersion
= SSL_Version_3_0
;
1135 case SSL_Version_3_0
:
1136 nextVersion
= TLS_Version_1_0
;
1138 case TLS_Version_1_0
:
1139 nextVersion
= TLS_Version_1_1
;
1141 case TLS_Version_1_1
:
1142 nextVersion
= TLS_Version_1_2
;
1144 case TLS_Version_1_2
:
1146 nextVersion
= SSL_Version_Undetermined
;
1149 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
1150 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1151 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1152 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1157 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1158 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1160 return errSecSuccess
;
1164 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1165 SSLProtocol protocol
,
1166 Boolean
*enable
) /* RETURNED */
1172 /* Can't do this with a DTLS session */
1173 return errSecBadReq
;
1179 case kTLSProtocol11
:
1180 case kTLSProtocol12
:
1182 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1183 *enable
= (ctx
->minProtocolVersion
<= version
1184 && ctx
->maxProtocolVersion
>= version
);
1187 case kSSLProtocolAll
:
1188 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1189 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1194 return errSecSuccess
;
1199 SSLSetProtocolVersion (SSLContextRef ctx
,
1200 SSLProtocol version
)
1205 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1206 /* Can't do this with an active session, nor with a DTLS session */
1207 return errSecBadReq
;
1212 /* this tells us to do our best, up to 3.0 */
1213 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1214 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1216 case kSSLProtocol3Only
:
1217 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1218 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1221 /* this tells us to do our best, up to TLS, but allows 3.0 */
1222 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1223 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1225 case kTLSProtocol1Only
:
1226 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1227 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1229 case kTLSProtocol11
:
1230 /* This tells us to do our best, up to TLS 1.1, currently also
1231 allows 3.0 or TLS 1.0 */
1232 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1233 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1235 case kTLSProtocol12
:
1236 case kSSLProtocolAll
:
1237 case kSSLProtocolUnknown
:
1238 /* This tells us to do our best, up to TLS 1.2, currently also
1239 allows 3.0 or TLS 1.0 or TLS 1.1 */
1240 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1241 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1247 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1248 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1250 return errSecSuccess
;
1255 SSLGetProtocolVersion (SSLContextRef ctx
,
1256 SSLProtocol
*protocol
) /* RETURNED */
1261 /* translate array of booleans to public value; not all combinations
1262 * are legal (i.e., meaningful) for this call */
1263 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1264 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1265 /* traditional 'all enabled' */
1266 *protocol
= kSSLProtocolAll
;
1267 return errSecSuccess
;
1269 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1270 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1271 /* traditional 'all enabled' */
1272 *protocol
= kTLSProtocol11
;
1273 return errSecSuccess
;
1275 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1276 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1277 /* TLS1.1 and below enabled */
1278 *protocol
= kTLSProtocol1
;
1279 return errSecSuccess
;
1280 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1281 *protocol
= kTLSProtocol1Only
;
1283 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1284 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1285 /* Could also return kSSLProtocol3Only since
1286 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1287 *protocol
= kSSLProtocol3
;
1288 return errSecSuccess
;
1296 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1297 SSLProtocol
*protocol
) /* RETURNED */
1302 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1303 return errSecSuccess
;
1307 SSLSetEnableCertVerify (SSLContextRef ctx
,
1308 Boolean enableVerify
)
1313 sslCertDebug("SSLSetEnableCertVerify %s",
1314 enableVerify
? "true" : "false");
1315 if(sslIsSessionActive(ctx
)) {
1316 /* can't do this with an active session */
1317 return errSecBadReq
;
1319 ctx
->enableCertVerify
= enableVerify
;
1320 return errSecSuccess
;
1324 SSLGetEnableCertVerify (SSLContextRef ctx
,
1325 Boolean
*enableVerify
)
1330 *enableVerify
= ctx
->enableCertVerify
;
1331 return errSecSuccess
;
1335 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1336 Boolean allowExpired
)
1341 sslCertDebug("SSLSetAllowsExpiredCerts %s",
1342 allowExpired
? "true" : "false");
1343 if(sslIsSessionActive(ctx
)) {
1344 /* can't do this with an active session */
1345 return errSecBadReq
;
1347 ctx
->allowExpiredCerts
= allowExpired
;
1348 return errSecSuccess
;
1352 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1353 Boolean
*allowExpired
)
1358 *allowExpired
= ctx
->allowExpiredCerts
;
1359 return errSecSuccess
;
1363 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1364 Boolean allowExpired
)
1369 sslCertDebug("SSLSetAllowsExpiredRoots %s",
1370 allowExpired
? "true" : "false");
1371 if(sslIsSessionActive(ctx
)) {
1372 /* can't do this with an active session */
1373 return errSecBadReq
;
1375 ctx
->allowExpiredRoots
= allowExpired
;
1376 return errSecSuccess
;
1380 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1381 Boolean
*allowExpired
)
1386 *allowExpired
= ctx
->allowExpiredRoots
;
1387 return errSecSuccess
;
1390 OSStatus
SSLSetAllowsAnyRoot(
1397 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1398 ctx
->allowAnyRoot
= anyRoot
;
1399 return errSecSuccess
;
1403 SSLGetAllowsAnyRoot(
1410 *anyRoot
= ctx
->allowAnyRoot
;
1411 return errSecSuccess
;
1414 #if !TARGET_OS_IPHONE
1415 /* obtain the system roots sets for this app, policy SSL */
1416 static OSStatus
sslDefaultSystemRoots(
1418 CFArrayRef
*systemRoots
) // created and RETURNED
1421 const char *hostname
;
1424 tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
1426 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1429 (ctx
->protocolSide
== kSSLServerSide
) ?
1430 /* server verifies, client encrypts */
1431 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1434 #endif /* OS X only */
1437 SSLSetTrustedRoots (SSLContextRef ctx
,
1438 CFArrayRef trustedRoots
,
1439 Boolean replaceExisting
)
1441 if (sslIsSessionActive(ctx
)) {
1442 /* can't do this with an active session */
1443 return errSecBadReq
;
1445 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1446 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1448 if (replaceExisting
) {
1449 ctx
->trustedCertsOnly
= true;
1450 CFReleaseNull(ctx
->trustedCerts
);
1453 if (ctx
->trustedCerts
) {
1454 CFIndex count
= CFArrayGetCount(trustedRoots
);
1455 CFRange range
= { 0, count
};
1456 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1458 require(ctx
->trustedCerts
=
1459 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1463 return errSecSuccess
;
1466 return errSecAllocate
;
1470 SSLCopyTrustedRoots (SSLContextRef ctx
,
1471 CFArrayRef
*trustedRoots
) /* RETURNED */
1473 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1476 if(ctx
->trustedCerts
!= NULL
) {
1477 *trustedRoots
= ctx
->trustedCerts
;
1478 CFRetain(ctx
->trustedCerts
);
1479 return errSecSuccess
;
1481 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1482 /* use default system roots */
1483 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1485 *trustedRoots
= NULL
;
1486 return errSecSuccess
;
1491 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1492 CFArrayRef trustedCerts
)
1497 if(sslIsSessionActive(ctx
)) {
1498 /* can't do this with an active session */
1499 return errSecBadReq
;
1502 if(ctx
->trustedLeafCerts
) {
1503 CFRelease(ctx
->trustedLeafCerts
);
1505 ctx
->trustedLeafCerts
= trustedCerts
;
1506 CFRetain(trustedCerts
);
1507 return errSecSuccess
;
1511 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1512 CFArrayRef
*trustedCerts
) /* RETURNED */
1517 if(ctx
->trustedLeafCerts
!= NULL
) {
1518 *trustedCerts
= ctx
->trustedLeafCerts
;
1519 CFRetain(ctx
->trustedCerts
);
1520 return errSecSuccess
;
1522 *trustedCerts
= NULL
;
1523 return errSecSuccess
;
1527 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1528 SSLAuthenticate auth
)
1533 if(sslIsSessionActive(ctx
)) {
1534 /* can't do this with an active session */
1535 return errSecBadReq
;
1537 ctx
->clientAuth
= auth
;
1539 case kNeverAuthenticate
:
1540 tls_handshake_set_client_auth(ctx
->hdsk
, false);
1542 case kAlwaysAuthenticate
:
1543 case kTryAuthenticate
:
1544 tls_handshake_set_client_auth(ctx
->hdsk
, true);
1547 return errSecSuccess
;
1551 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1552 SSLAuthenticate
*auth
) /* RETURNED */
1554 if(ctx
== NULL
|| auth
== NULL
) {
1557 *auth
= ctx
->clientAuth
;
1558 return errSecSuccess
;
1562 SSLGetClientCertificateState (SSLContextRef ctx
,
1563 SSLClientCertificateState
*clientState
)
1568 if(ctx
->protocolSide
== kSSLClientSide
) {
1570 switch(ctx
->clientCertState
) {
1571 case kSSLClientCertNone
:
1572 *clientState
= kSSLClientCertNone
;
1574 case kSSLClientCertRequested
:
1575 if(ctx
->localCert
) {
1576 *clientState
= kSSLClientCertSent
;
1578 *clientState
= kSSLClientCertRequested
;
1582 /* Anything else is an internal error */
1583 sslErrorLog("TLS client has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1584 return errSSLInternal
;
1588 switch(ctx
->clientCertState
) {
1589 case kSSLClientCertNone
:
1590 case kSSLClientCertRejected
:
1591 *clientState
= ctx
->clientCertState
;
1593 case kSSLClientCertRequested
:
1595 *clientState
= kSSLClientCertSent
;
1597 *clientState
= kSSLClientCertRequested
;
1601 /* Anything else is an internal error */
1602 sslErrorLog("TLS server has invalid internal clientCertState (%d)\n", ctx
->clientCertState
);
1603 return errSSLInternal
;
1606 return errSecSuccess
;
1610 SSLSetCertificate (SSLContextRef ctx
,
1611 CFArrayRef certRefs
)
1614 * -- free localCerts if we have any
1615 * -- Get raw cert data, convert to ctx->localCert
1616 * -- get pub, priv keys from certRef[0]
1617 * -- validate cert chain
1623 CFReleaseNull(ctx
->localCertArray
);
1624 /* changing the client cert invalidates negotiated auth type */
1625 ctx
->negAuthType
= SSLClientAuthNone
;
1626 if(certRefs
== NULL
) {
1627 return errSecSuccess
; // we have cleared the cert, as requested
1629 sslFreeLocalCert(ctx
);
1630 OSStatus ortn
= parseIncomingCerts(ctx
,
1633 &ctx
->signingPrivKeyRef
);
1634 if(ortn
== errSecSuccess
) {
1635 ctx
->localCertArray
= certRefs
;
1637 if(ctx
->protocolSide
==kSSLClientSide
)
1638 SSLUpdateNegotiatedClientAuthType(ctx
);
1639 tls_handshake_set_identity(ctx
->hdsk
, ctx
->localCert
, ctx
->signingPrivKeyRef
);
1645 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1646 CFArrayRef certRefs
)
1651 if(sslIsSessionActive(ctx
)) {
1652 /* can't do this with an active session */
1653 return errSecBadReq
;
1655 CFReleaseNull(ctx
->encryptCertArray
);
1656 ctx
->encryptCertArray
= certRefs
;
1658 return errSecSuccess
;
1661 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1662 CFArrayRef
*certRefs
)
1667 *certRefs
= ctx
->localCertArray
;
1668 return errSecSuccess
;
1671 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1672 CFArrayRef
*certRefs
)
1677 *certRefs
= ctx
->encryptCertArray
;
1678 return errSecSuccess
;
1682 SSLSetPeerID (SSLContext
*ctx
,
1688 /* copy peerId to context->peerId */
1694 if(sslIsSessionActive(ctx
) &&
1695 /* kSSLClientCertRequested implies client side */
1696 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1698 return errSecBadReq
;
1700 SSLFreeBuffer(&ctx
->peerID
);
1701 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1705 tls_handshake_set_resumption(ctx
->hdsk
, true);
1706 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1707 return errSecSuccess
;
1711 SSLGetPeerID (SSLContextRef ctx
,
1712 const void **peerID
,
1715 *peerID
= ctx
->peerID
.data
; // may be NULL
1716 *peerIDLen
= ctx
->peerID
.length
;
1717 return errSecSuccess
;
1721 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1722 SSLCipherSuite
*cipherSuite
)
1728 if(!sslIsSessionActive(ctx
)) {
1729 return errSecBadReq
;
1732 *cipherSuite
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
1734 return errSecSuccess
;
1738 * Add an acceptable distinguished name (client authentication only).
1741 SSLAddDistinguishedName(
1752 if(sslIsSessionActive(ctx
)) {
1753 return errSecBadReq
;
1756 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1758 return errSecAllocate
;
1760 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1765 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1766 dn
->next
= ctx
->acceptableDNList
;
1767 ctx
->acceptableDNList
= dn
;
1769 tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
);
1771 return errSecSuccess
;
1774 /* single-cert version of SSLSetCertificateAuthorities() */
1776 sslAddCA(SSLContextRef ctx
,
1777 SecCertificateRef cert
)
1779 OSStatus ortn
= errSecParam
;
1781 /* Get subject from certificate. */
1782 #if TARGET_OS_IPHONE
1783 CFDataRef subjectName
= NULL
;
1784 subjectName
= SecCertificateCopySubjectSequence(cert
);
1785 require(subjectName
, errOut
);
1787 CSSM_DATA_PTR subjectName
= NULL
;
1788 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1789 require_noerr(ortn
, errOut
);
1792 /* add to acceptableCAs as cert, creating array if necessary */
1793 if(ctx
->acceptableCAs
== NULL
) {
1794 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1795 &kCFTypeArrayCallBacks
), errOut
);
1796 if(ctx
->acceptableCAs
== NULL
) {
1797 return errSecAllocate
;
1800 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1802 /* then add this cert's subject name to acceptableDNList */
1803 #if TARGET_OS_IPHONE
1804 ortn
= SSLAddDistinguishedName(ctx
,
1805 CFDataGetBytePtr(subjectName
),
1806 CFDataGetLength(subjectName
));
1808 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1812 #if TARGET_OS_IPHONE
1813 CFReleaseSafe(subjectName
);
1819 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1820 * of acceptable Certificate Authorities (CAs) to present to the client
1821 * when client authentication is performed.
1824 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1825 CFTypeRef certificateOrArray
,
1826 Boolean replaceExisting
)
1829 OSStatus ortn
= errSecSuccess
;
1831 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1832 (ctx
->protocolSide
!= kSSLServerSide
)) {
1835 if(replaceExisting
) {
1837 if(ctx
->acceptableCAs
) {
1838 CFRelease(ctx
->acceptableCAs
);
1839 ctx
->acceptableCAs
= NULL
;
1842 /* else appending */
1844 itemType
= CFGetTypeID(certificateOrArray
);
1845 if(itemType
== SecCertificateGetTypeID()) {
1847 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
1849 else if(itemType
== CFArrayGetTypeID()) {
1850 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
1851 CFIndex numCerts
= CFArrayGetCount(cfa
);
1854 /* array of certs */
1855 for(dex
=0; dex
<numCerts
; dex
++) {
1856 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
1857 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
1860 ortn
= sslAddCA(ctx
, cert
);
1874 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1875 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1877 * Caller must CFRelease the returned array.
1880 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
1881 CFArrayRef
*certificates
) /* RETURNED */
1883 if((ctx
== NULL
) || (certificates
== NULL
)) {
1886 if(ctx
->acceptableCAs
== NULL
) {
1887 *certificates
= NULL
;
1888 return errSecSuccess
;
1890 *certificates
= ctx
->acceptableCAs
;
1891 CFRetain(ctx
->acceptableCAs
);
1892 return errSecSuccess
;
1897 * Obtain the list of acceptable distinguished names as provided by
1898 * a server (if the SSLCotextRef is configured as a client), or as
1899 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1900 * is configured as a server).
1903 SSLCopyDistinguishedNames (SSLContextRef ctx
,
1906 CFMutableArrayRef outArray
= NULL
;
1907 const DNListElem
*dn
;
1909 if((ctx
== NULL
) || (names
== NULL
)) {
1912 if(ctx
->protocolSide
==kSSLServerSide
) {
1913 dn
= ctx
->acceptableDNList
;
1915 dn
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList;
1920 return errSecSuccess
;
1922 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1925 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
1926 CFArrayAppendValue(outArray
, cfDn
);
1931 return errSecSuccess
;
1936 * Request peer certificates. Valid anytime, subsequent to
1937 * a handshake attempt.
1938 * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
1939 * TODO: the 'legacy' argument is not used anymore.
1942 sslCopyPeerCertificates (SSLContextRef ctx
,
1950 if (!ctx
->peerCert
) {
1952 return errSecBadReq
;
1955 CFArrayRef ca
= CFArrayCreateCopy(kCFAllocatorDefault
, ctx
->peerCert
);
1958 return errSecAllocate
;
1962 CFIndex ix
, count
= CFArrayGetCount(ca
);
1963 for (ix
= 0; ix
< count
; ++ix
) {
1964 CFRetain(CFArrayGetValueAtIndex(ca
, ix
));
1968 return errSecSuccess
;
1972 SSLCopyPeerCertificates (SSLContextRef ctx
,
1975 return sslCopyPeerCertificates(ctx
, certs
, false);
1978 #if !TARGET_OS_IPHONE
1979 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
1980 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
1982 SSLGetPeerCertificates (SSLContextRef ctx
,
1985 SSLGetPeerCertificates (SSLContextRef ctx
,
1988 return sslCopyPeerCertificates(ctx
, certs
, true);
1993 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1994 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1995 * been called, a set of process-wide parameters will be calculated. However
1996 * that can take a long time (30 seconds).
1998 OSStatus
SSLSetDiffieHellmanParams(
2000 const void *dhParams
,
2007 if(sslIsSessionActive(ctx
)) {
2008 return errSecBadReq
;
2010 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
2013 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
2014 &ctx
->dhParamsEncoded
);
2019 return tls_handshake_set_dh_parameters(ctx
->hdsk
, &ctx
->dhParamsEncoded
);
2022 #endif /* APPLE_DH */
2026 * Return parameter block specified in SSLSetDiffieHellmanParams.
2027 * Returned data is not copied and belongs to the SSLContextRef.
2029 OSStatus
SSLGetDiffieHellmanParams(
2031 const void **dhParams
,
2032 size_t *dhParamsLen
)
2038 *dhParams
= ctx
->dhParamsEncoded
.data
;
2039 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
2040 return errSecSuccess
;
2042 return errSecUnimplemented
;
2043 #endif /* APPLE_DH */
2046 OSStatus
SSLSetDHEEnabled(SSLContextRef ctx
, bool enabled
)
2048 ctx
->dheEnabled
= enabled
;
2052 OSStatus
SSLGetDHEEnabled(SSLContextRef ctx
, bool *enabled
)
2054 *enabled
= ctx
->dheEnabled
;
2058 OSStatus
SSLSetMinimumDHGroupSize(SSLContextRef ctx
, unsigned nbits
)
2060 return tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
2063 OSStatus
SSLGetMinimumDHGroupSize(SSLContextRef ctx
, unsigned *nbits
)
2065 return tls_handshake_get_min_dh_group_size(ctx
->hdsk
, nbits
);
2068 OSStatus
SSLSetRsaBlinding(
2075 ctx
->rsaBlindingEnable
= blinding
;
2076 return errSecSuccess
;
2079 OSStatus
SSLGetRsaBlinding(
2086 *blinding
= ctx
->rsaBlindingEnable
;
2087 return errSecSuccess
;
2093 SecTrustRef
*trust
) /* RETURNED */
2095 OSStatus status
= errSecSuccess
;
2096 if (ctx
== NULL
|| trust
== NULL
)
2099 /* Create a SecTrustRef if this was a resumed session and we
2100 didn't have one yet. */
2101 if (!ctx
->peerCert
) {
2102 ctx
->peerCert
= tls_get_peer_certs(tls_handshake_get_peer_certificates(ctx
->hdsk
));
2104 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2105 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
,
2106 &ctx
->peerSecTrust
);
2109 *trust
= ctx
->peerSecTrust
;
2110 if (ctx
->peerSecTrust
)
2111 CFRetain(ctx
->peerSecTrust
);
2116 OSStatus
SSLGetPeerSecTrust(
2118 SecTrustRef
*trust
) /* RETURNED */
2120 OSStatus status
= errSecSuccess
;
2121 if (ctx
== NULL
|| trust
== NULL
)
2124 /* Create a SecTrustRef if this was a resumed session and we
2125 didn't have one yet. */
2126 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2127 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
,
2128 &ctx
->peerSecTrust
);
2131 *trust
= ctx
->peerSecTrust
;
2135 OSStatus
SSLInternalMasterSecret(
2137 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
2138 size_t *secretSize
) // in/out
2140 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
2143 return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
);
2146 OSStatus
SSLInternalServerRandom(
2148 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2149 size_t *randSize
) // in/out
2151 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2154 return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
);
2157 OSStatus
SSLInternalClientRandom(
2159 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2160 size_t *randSize
) // in/out
2162 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2165 return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
);
2168 /* This is used by EAP 802.1x */
2169 OSStatus
SSLGetCipherSizes(
2172 size_t *symmetricKeySize
,
2175 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2176 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2180 SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
2182 *digestSize
= sslCipherSuiteGetMacSize(cipher
);
2183 *symmetricKeySize
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
);
2184 *ivSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
);
2185 return errSecSuccess
;
2189 SSLGetResumableSessionInfo(
2191 Boolean
*sessionWasResumed
, // RETURNED
2192 void *sessionID
, // RETURNED, mallocd by caller
2193 size_t *sessionIDLength
) // IN/OUT
2195 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2196 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2197 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2201 SSLBuffer localSessionID
;
2202 bool sessionMatch
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
);
2205 *sessionWasResumed
= true;
2206 if(localSessionID
.length
> *sessionIDLength
) {
2207 /* really should never happen - means ID > 32 */
2210 if(localSessionID
.length
) {
2212 * Note PAC-based session resumption can result in sessionMatch
2215 memmove(sessionID
, localSessionID
.data
, localSessionID
.length
);
2217 *sessionIDLength
= localSessionID
.length
;
2220 *sessionWasResumed
= false;
2221 *sessionIDLength
= 0;
2223 return errSecSuccess
;
2227 * Get/set enable of anonymous ciphers. This is deprecated and now a no-op.
2230 SSLSetAllowAnonymousCiphers(
2234 return errSecSuccess
;
2238 SSLGetAllowAnonymousCiphers(
2242 return errSecSuccess
;
2246 * Override the default session cache timeout for a cache entry created for
2247 * the current session.
2250 SSLSetSessionCacheTimeout(
2252 uint32_t timeoutInSeconds
)
2257 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2258 return errSecSuccess
;
2263 void tls_handshake_master_secret_function(const void *arg
, /* opaque to coreTLS; app-specific */
2264 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2265 size_t *secretLength
)
2267 SSLContextRef ctx
= (SSLContextRef
) arg
;
2268 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
);
2273 * Register a callback for obtaining the master_secret when performing
2274 * PAC-based session resumption.
2277 SSLInternalSetMasterSecretFunction(
2279 SSLInternalMasterSecretFunction mFunc
,
2280 const void *arg
) /* opaque to SecureTransport; app-specific */
2286 ctx
->masterSecretArg
= arg
;
2287 ctx
->masterSecretCallback
= mFunc
;
2289 return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
);
2293 * Provide an opaque SessionTicket for use in PAC-based session
2294 * resumption. Client side only. The provided ticket is sent in
2295 * the ClientHello message as a SessionTicket extension.
2297 * We won't reject this on the server side, but server-side support
2298 * for PAC-based session resumption is currently enabled for
2299 * Development builds only. To fully support this for server side,
2300 * besides the rudimentary support that's here for Development builds,
2301 * we'd need a getter for the session ticket, so the app code can
2302 * access the SessionTicket when its SSLInternalMasterSecretFunction
2303 * callback is called.
2305 OSStatus
SSLInternalSetSessionTicket(
2308 size_t ticketLength
)
2313 if(sslIsSessionActive(ctx
)) {
2314 /* can't do this with an active session */
2315 return errSecBadReq
;
2317 return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
);
2322 * ECDSA curve accessors.
2326 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2327 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2329 OSStatus
SSLGetNegotiatedCurve(
2331 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2333 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2336 unsigned int curve
= tls_handshake_get_negotiated_curve(ctx
->hdsk
);
2337 if(curve
== SSL_Curve_None
) {
2340 *namedCurve
= curve
;
2341 return errSecSuccess
;
2345 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2347 OSStatus
SSLGetNumberOfECDSACurves(
2349 unsigned *numCurves
) /* RETURNED */
2351 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2354 *numCurves
= ctx
->ecdhNumCurves
;
2355 return errSecSuccess
;
2359 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2361 OSStatus
SSLGetECDSACurves(
2363 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2364 unsigned *numCurves
) /* IN/OUT */
2366 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2369 if(*numCurves
< ctx
->ecdhNumCurves
) {
2372 memmove(namedCurves
, ctx
->ecdhCurves
,
2373 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2374 *numCurves
= ctx
->ecdhNumCurves
;
2375 return errSecSuccess
;
2379 * Specify ordered list of allowable named curves.
2381 OSStatus
SSLSetECDSACurves(
2383 const SSL_ECDSA_NamedCurve
*namedCurves
,
2386 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2389 if(sslIsSessionActive(ctx
)) {
2390 /* can't do this with an active session */
2391 return errSecBadReq
;
2394 size_t size
= numCurves
* sizeof(uint16_t);
2395 ctx
->ecdhCurves
= (uint16_t *)sslMalloc(size
);
2396 if(ctx
->ecdhCurves
== NULL
) {
2397 ctx
->ecdhNumCurves
= 0;
2398 return errSecAllocate
;
2401 for (unsigned i
=0; i
<numCurves
; i
++) {
2402 ctx
->ecdhCurves
[i
] = namedCurves
[i
];
2405 ctx
->ecdhNumCurves
= numCurves
;
2407 tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
);
2408 return errSecSuccess
;
2412 * Obtain the number of client authentication mechanisms specified by
2413 * the server in its Certificate Request message.
2414 * Returns errSecParam if server hasn't sent a Certificate Request message
2415 * (i.e., client certificate state is kSSLClientCertNone).
2417 OSStatus
SSLGetNumberOfClientAuthTypes(
2421 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2424 *numTypes
= ctx
->numAuthTypes
;
2425 return errSecSuccess
;
2429 * Obtain the client authentication mechanisms specified by
2430 * the server in its Certificate Request message.
2431 * Caller allocates returned array and specifies its size (in
2432 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2433 * is the actual size of the returned array on successful return.
2435 OSStatus
SSLGetClientAuthTypes(
2437 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2438 unsigned *numTypes
) /* IN/OUT */
2440 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2443 memmove(authTypes
, ctx
->clientAuthTypes
,
2444 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2445 *numTypes
= ctx
->numAuthTypes
;
2446 return errSecSuccess
;
2450 * Obtain the SSLClientAuthenticationType actually performed.
2451 * Only valid if client certificate state is kSSLClientCertSent
2452 * or kSSLClientCertRejected; returns errSecParam otherwise.
2454 OSStatus
SSLGetNegotiatedClientAuthType(
2456 SSLClientAuthenticationType
*authType
) /* RETURNED */
2462 *authType
= ctx
->negAuthType
;
2464 return errSecSuccess
;
2468 * Update the negotiated client authentication type.
2469 * This function may be called at any time; however, note that
2470 * the negotiated authentication type will be SSLClientAuthNone
2471 * until both of the following have taken place (in either order):
2472 * - a CertificateRequest message from the server has been processed
2473 * - a client certificate has been specified
2474 * As such, this function (only) needs to be called from (both)
2475 * SSLProcessCertificateRequest and SSLSetCertificate.
2477 OSStatus
SSLUpdateNegotiatedClientAuthType(
2483 assert(ctx
->protocolSide
==kSSLClientSide
);
2485 * See if we have a signing cert that matches one of the
2486 * allowed auth types. The x509Requested flag indicates "we
2487 * have a cert that we think the server will accept".
2489 ctx
->x509Requested
= 0;
2490 ctx
->negAuthType
= SSLClientAuthNone
;
2491 if(ctx
->signingPrivKeyRef
!= NULL
) {
2492 CFIndex ourKeyAlg
= sslPrivKeyGetAlgorithmID((SecKeyRef
)tls_private_key_get_context(ctx
->signingPrivKeyRef
));
2495 for(i
=0; i
<ctx
->numAuthTypes
; i
++) {
2496 switch(ctx
->clientAuthTypes
[i
]) {
2497 case SSLClientAuth_RSASign
:
2498 if(ourKeyAlg
== kSecRSAAlgorithmID
) {
2499 ctx
->x509Requested
= 1;
2500 ctx
->negAuthType
= SSLClientAuth_RSASign
;
2503 case SSLClientAuth_ECDSASign
:
2504 #if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
2505 case SSLClientAuth_ECDSAFixedECDH
:
2507 if(ourKeyAlg
== kSecECDSAAlgorithmID
) {
2508 ctx
->x509Requested
= 1;
2509 ctx
->negAuthType
= ctx
->clientAuthTypes
[i
];
2512 #if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
2513 case SSLClientAuth_RSAFixedECDH
:
2514 /* Odd case, we differ from our signer */
2515 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2516 (ctx
->ourSignerAlg
== kSecRSAAlgorithmID
)) {
2517 ctx
->x509Requested
= 1;
2518 ctx
->negAuthType
= SSLClientAuth_RSAFixedECDH
;
2523 /* None others supported */
2526 if(ctx
->x509Requested
) {
2527 sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx
->negAuthType
);
2530 } /* parsing authTypes */
2531 } /* we have a signing key */
2533 tls_handshake_set_client_auth_type(ctx
->hdsk
, ctx
->negAuthType
);
2535 return errSecSuccess
;
2538 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2540 unsigned *numSigAlgs
)
2546 tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
);
2547 return errSecSuccess
;
2550 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
),
2551 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2553 OSStatus
SSLGetSignatureAlgorithms(
2555 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2556 unsigned *numSigAlgs
) /* IN/OUT */
2562 unsigned numPeerSigAlgs
;
2563 const tls_signature_and_hash_algorithm
*peerAlgs
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
);
2565 memmove(sigAlgs
, peerAlgs
,
2566 numPeerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2567 *numSigAlgs
= numPeerSigAlgs
;
2568 return errSecSuccess
;
2572 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2576 if(ctx
== NULL
) return errSecParam
;
2578 if(ctx
->pskSharedSecret
.data
)
2579 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2581 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2582 return errSecAllocate
;
2584 tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
);
2586 return errSecSuccess
;
2589 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2590 const void *pskIdentity
,
2591 size_t pskIdentityLen
)
2593 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2595 if(ctx
->pskIdentity
.data
)
2596 SSLFreeBuffer(&ctx
->pskIdentity
);
2598 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2599 return errSecAllocate
;
2601 tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
);
2603 return errSecSuccess
;
2607 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2608 const void **pskIdentity
,
2609 size_t *pskIdentityLen
)
2611 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2613 *pskIdentity
=ctx
->pskIdentity
.data
;
2614 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2616 return errSecSuccess
;
2619 OSStatus
SSLInternal_PRF(
2621 const void *vsecret
,
2623 const void *label
, // optional, NULL implies that seed contains
2628 void *vout
, // mallocd by caller, length >= outLen
2631 return tls_handshake_internal_prf(ctx
->hdsk
,
2638 /* To be implemented */
2640 SSLSetSessionStrengthPolicy(SSLContextRef context
,
2641 SSLSessionStrengthPolicy policyStrength
)
2643 return errSecSuccess
;