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 "sslDigests.h"
39 #include "sslKeychain.h"
40 #include "sslMemory.h"
43 #include "tlsCallbacks.h"
45 #include <AssertMacros.h>
46 #include <CoreFoundation/CFData.h>
47 #include <CoreFoundation/CFPreferences.h>
48 #include <Security/SecCertificate.h>
49 #include <Security/SecCertificatePriv.h>
50 #include <Security/SecTrust.h>
51 #include <Security/SecTrustSettingsPriv.h>
52 #include <Security/oidsalg.h>
53 #include "utilities/SecCFRelease.h"
54 #include "utilities/SecCFWrappers.h"
59 #include <Security/SecCertificateInternal.h>
61 #include <Security/oidsalg.h>
62 #include <Security/oidscert.h>
63 #include <Security/SecTrustSettingsPriv.h>
67 static void sslFreeDnList(
70 DNListElem
*dn
, *nextDN
;
72 dn
= ctx
->acceptableDNList
;
75 SSLFreeBuffer(&dn
->derDN
);
80 ctx
->acceptableDNList
= NULL
;
84 Boolean
sslIsSessionActive(const SSLContext
*ctx
)
90 case SSL_HdskStateUninit
:
91 case SSL_HdskStateGracefulClose
:
92 case SSL_HdskStateErrorClose
:
101 * Minimum and maximum supported versions
103 //#define MINIMUM_STREAM_VERSION SSL_Version_2_0 /* Disabled */
104 #define MINIMUM_STREAM_VERSION SSL_Version_3_0
105 #define MAXIMUM_STREAM_VERSION TLS_Version_1_2
106 #define MINIMUM_DATAGRAM_VERSION DTLS_Version_1_0
108 /* This should be changed when we start supporting DTLS_Version_1_x */
109 #define MAXIMUM_DATAGRAM_VERSION DTLS_Version_1_0
111 #define SSL_ENABLE_ECDSA_SIGN_AUTH 0
112 #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH 0
113 #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH 0
115 #define DEFAULT_DTLS_TIMEOUT 1
116 #define DEFAULT_DTLS_MTU 1400
117 #define MIN_ALLOWED_DTLS_MTU 64 /* this ensure than there will be no integer
118 underflow when calculating max write size */
120 int kSplitDefaultValue
;
122 static void _SSLContextReadDefault()
124 /* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
125 /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
126 const int defaultSplitDefaultValue
= 2;
128 CFTypeRef value
= (CFTypeRef
)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
129 CFSTR("com.apple.security"),
130 kCFPreferencesAnyUser
,
131 kCFPreferencesCurrentHost
);
133 if (CFGetTypeID(value
) == CFBooleanGetTypeID())
134 kSplitDefaultValue
= CFBooleanGetValue((CFBooleanRef
)value
) ? 1 : 0;
135 else if (CFGetTypeID(value
) == CFNumberGetTypeID()) {
136 if (!CFNumberGetValue((CFNumberRef
)value
, kCFNumberIntType
, &kSplitDefaultValue
))
137 kSplitDefaultValue
= defaultSplitDefaultValue
;
139 if (kSplitDefaultValue
< 0 || kSplitDefaultValue
> 2) {
140 kSplitDefaultValue
= defaultSplitDefaultValue
;
145 kSplitDefaultValue
= defaultSplitDefaultValue
;
149 CFGiblisWithHashFor(SSLContext
)
152 SSLNewContext (Boolean isServer
,
153 SSLContextRef
*contextPtr
) /* RETURNED */
155 if(contextPtr
== NULL
) {
159 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
161 if (*contextPtr
== NULL
)
162 return errSecAllocate
;
164 return errSecSuccess
;
167 SSLContextRef
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
)
170 SSLRecordContextRef recCtx
;
172 ctx
= SSLCreateContextWithRecordFuncs(alloc
, protocolSide
, connectionType
, &SSLRecordLayerInternal
);
177 recCtx
= SSLCreateInternalRecordLayer(connectionType
);
183 SSLSetRecordContext(ctx
, recCtx
);
188 SSLContextRef
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
, const struct SSLRecordFuncs
*recFuncs
)
190 OSStatus serr
= errSecSuccess
;
191 SSLContext
*ctx
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
);
197 /* subsequent errors to errOut: */
198 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
201 ctx
->hdsk
= tls_handshake_create(connectionType
==kSSLDatagramType
, protocolSide
==kSSLServerSide
);
204 tls_handshake_set_callbacks(ctx
->hdsk
,
205 &tls_handshake_callbacks
,
208 ctx
->isDTLS
= (connectionType
==kSSLDatagramType
);
210 ctx
->state
= SSL_HdskStateUninit
;
211 ctx
->timeout_duration
= DEFAULT_DTLS_TIMEOUT
;
212 ctx
->mtu
= DEFAULT_DTLS_MTU
;
215 ctx
->minProtocolVersion
= MINIMUM_DATAGRAM_VERSION
;
216 ctx
->maxProtocolVersion
= MAXIMUM_DATAGRAM_VERSION
;
218 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
219 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
221 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
222 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
224 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
225 ctx
->protocolSide
= protocolSide
;
226 ctx
->recFuncs
= recFuncs
;
228 /* Initial cert verify state: verify with default system roots */
229 ctx
->enableCertVerify
= true;
231 /* Default for RSA blinding is ENABLED */
232 ctx
->rsaBlindingEnable
= true;
234 /* Default for sending one-byte app data record is DISABLED */
235 ctx
->oneByteRecordEnable
= false;
237 /* Dont enable fallback behavior by default */
238 ctx
->fallbackEnabled
= false;
240 /* Consult global system preference for default behavior:
241 * 0 = disabled, 1 = split every write, 2 = split second and subsequent writes
242 * (caller can override by setting kSSLSessionOptionSendOneByteRecord)
244 static pthread_once_t sReadDefault
= PTHREAD_ONCE_INIT
;
245 pthread_once(&sReadDefault
, _SSLContextReadDefault
);
246 if (kSplitDefaultValue
> 0)
247 ctx
->oneByteRecordEnable
= true;
249 /* default for anonymous ciphers is DISABLED */
250 ctx
->anonCipherEnable
= false;
252 ctx
->breakOnServerAuth
= false;
253 ctx
->breakOnCertRequest
= false;
254 ctx
->breakOnClientAuth
= false;
255 ctx
->signalServerAuth
= false;
256 ctx
->signalCertRequest
= false;
257 ctx
->signalClientAuth
= false;
259 ctx
->negAuthType
= SSLClientAuthNone
; /* ditto */
261 if (serr
!= errSecSuccess
) {
269 SSLNewDatagramContext (Boolean isServer
,
270 SSLContextRef
*contextPtr
) /* RETURNED */
272 if (contextPtr
== NULL
)
274 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
);
275 if (*contextPtr
== NULL
)
276 return errSecAllocate
;
277 return errSecSuccess
;
281 * Dispose of an SSLContext. (private)
282 * This function is invoked after our dispatch queue is safely released,
283 * or directly from SSLDisposeContext if there is no dispatch queue.
286 SSLDisposeContext (SSLContextRef context
)
288 if(context
== NULL
) {
292 return errSecSuccess
;
295 CFStringRef
SSLContextCopyDescription(CFTypeRef arg
)
297 SSLContext
* ctx
= (SSLContext
*) arg
;
302 CFStringRef result
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
);
307 Boolean
SSLContextCompare(CFTypeRef a
, CFTypeRef b
)
312 CFHashCode
SSLContextHash(CFTypeRef arg
)
314 return (CFHashCode
) arg
;
317 void SSLContextDestroy(CFTypeRef arg
)
319 SSLContext
* ctx
= (SSLContext
*) arg
;
321 /* destroy the coreTLS handshake object */
322 tls_handshake_destroy(ctx
->hdsk
);
324 /* Only destroy if we were using the internal record layer */
325 if(ctx
->recFuncs
==&SSLRecordLayerInternal
)
326 SSLDestroyInternalRecordLayer(ctx
->recCtx
);
328 SSLFreeBuffer(&ctx
->sessionTicket
);
329 SSLFreeBuffer(&ctx
->sessionID
);
330 SSLFreeBuffer(&ctx
->peerID
);
331 SSLFreeBuffer(&ctx
->resumableSession
);
332 SSLFreeBuffer(&ctx
->receivedDataBuffer
);
334 sslFree(ctx
->validCipherSuites
);
335 ctx
->validCipherSuites
= NULL
;
336 ctx
->numValidCipherSuites
= 0;
338 CFReleaseSafe(ctx
->acceptableCAs
);
339 CFReleaseSafe(ctx
->trustedLeafCerts
);
340 CFReleaseSafe(ctx
->localCertArray
);
341 CFReleaseSafe(ctx
->encryptCertArray
);
342 CFReleaseSafe(ctx
->encryptCertArray
);
343 CFReleaseSafe(ctx
->peerCert
);
344 CFReleaseSafe(ctx
->trustedCerts
);
345 CFReleaseSafe(ctx
->peerSecTrust
);
347 sslFreePrivKey(&ctx
->signingPrivKeyRef
);
348 sslFreePrivKey(&ctx
->encryptPrivKeyRef
);
350 sslFree(ctx
->localCert
);
351 sslFree(ctx
->encryptCert
);
356 SSLFreeBuffer(&ctx
->ownVerifyData
);
357 SSLFreeBuffer(&ctx
->peerVerifyData
);
359 SSLFreeBuffer(&ctx
->pskIdentity
);
360 SSLFreeBuffer(&ctx
->pskSharedSecret
);
362 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
364 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
370 * Determine the state of an SSL session.
373 SSLGetSessionState (SSLContextRef context
,
374 SSLSessionState
*state
) /* RETURNED */
376 SSLSessionState rtnState
= kSSLIdle
;
378 if(context
== NULL
) {
382 switch(context
->state
) {
383 case SSL_HdskStateUninit
:
386 case SSL_HdskStateGracefulClose
:
387 rtnState
= kSSLClosed
;
389 case SSL_HdskStateErrorClose
:
390 case SSL_HdskStateNoNotifyClose
:
391 rtnState
= kSSLAborted
;
393 case SSL_HdskStateReady
:
394 rtnState
= kSSLConnected
;
396 case SSL_HdskStatePending
:
397 rtnState
= kSSLHandshake
;
401 return errSecSuccess
;
405 * Set options for an SSL session.
408 SSLSetSessionOption (SSLContextRef context
,
409 SSLSessionOption option
,
412 if(context
== NULL
) {
415 if(sslIsSessionActive(context
)) {
416 /* can't do this with an active session */
420 case kSSLSessionOptionBreakOnServerAuth
:
421 context
->breakOnServerAuth
= value
;
422 context
->enableCertVerify
= !value
;
424 case kSSLSessionOptionBreakOnCertRequested
:
425 context
->breakOnCertRequest
= value
;
427 case kSSLSessionOptionBreakOnClientAuth
:
428 context
->breakOnClientAuth
= value
;
429 context
->enableCertVerify
= !value
;
431 case kSSLSessionOptionSendOneByteRecord
:
432 /* Only call the record layer function if the value changed */
433 if(value
!= context
->oneByteRecordEnable
)
434 context
->recFuncs
->setOption(context
->recCtx
, kSSLRecordOptionSendOneByteRecord
, value
);
435 context
->oneByteRecordEnable
= value
;
437 case kSSLSessionOptionFalseStart
:
438 context
->falseStartEnabled
= value
;
440 case kSSLSessionOptionFallback
:
441 tls_handshake_set_fallback(context
->hdsk
, value
);
442 context
->fallbackEnabled
= value
;
448 return errSecSuccess
;
452 * Determine current value for the specified option in an SSL session.
455 SSLGetSessionOption (SSLContextRef context
,
456 SSLSessionOption option
,
459 if(context
== NULL
|| value
== NULL
) {
463 case kSSLSessionOptionBreakOnServerAuth
:
464 *value
= context
->breakOnServerAuth
;
466 case kSSLSessionOptionBreakOnCertRequested
:
467 *value
= context
->breakOnCertRequest
;
469 case kSSLSessionOptionBreakOnClientAuth
:
470 *value
= context
->breakOnClientAuth
;
472 case kSSLSessionOptionSendOneByteRecord
:
473 *value
= context
->oneByteRecordEnable
;
475 case kSSLSessionOptionFalseStart
:
476 *value
= context
->falseStartEnabled
;
482 return errSecSuccess
;
486 SSLSetRecordContext (SSLContextRef ctx
,
487 SSLRecordContextRef recCtx
)
492 if(sslIsSessionActive(ctx
)) {
493 /* can't do this with an active session */
496 ctx
->recCtx
= recCtx
;
497 return errSecSuccess
;
500 /* Those two trampolines are used to make the connetion between
501 the record layer IO callbacks and the user provided IO callbacks.
502 Those are currently necessary because the record layer read/write callbacks
503 have different prototypes that the user callbacks advertised in the API.
504 They have different prototypes because the record layer callback have to build in kernelland.
506 This situation is not desirable. So we should figure out a way to get rid of them.
508 static int IORead(SSLIOConnectionRef connection
,
513 SSLContextRef ctx
= connection
;
516 rc
= ctx
->ioCtx
.read(ctx
->ioCtx
.ioRef
, data
, dataLength
);
518 /* We may need to translate error codes at this layer */
519 if(rc
==errSSLWouldBlock
) {
520 rc
=errSSLRecordWouldBlock
;
526 static int IOWrite(SSLIOConnectionRef connection
,
531 SSLContextRef ctx
= connection
;
533 rc
= ctx
->ioCtx
.write(ctx
->ioCtx
.ioRef
, data
, dataLength
);
535 /* We may need to translate error codes at this layer */
536 if(rc
==errSSLWouldBlock
) {
537 rc
=errSSLRecordWouldBlock
;
544 SSLSetIOFuncs (SSLContextRef ctx
,
545 SSLReadFunc readFunc
,
546 SSLWriteFunc writeFunc
)
551 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
552 /* Can Only do this with the internal record layer */
556 if(sslIsSessionActive(ctx
)) {
557 /* can't do this with an active session */
561 ctx
->ioCtx
.read
=readFunc
;
562 ctx
->ioCtx
.write
=writeFunc
;
564 return SSLSetInternalRecordLayerIOFuncs(ctx
->recCtx
, IORead
, IOWrite
);
568 SSLSetNPNFunc(SSLContextRef context
,
572 if (context
== NULL
) {
575 if (sslIsSessionActive(context
)) {
578 context
->npnFunc
= npnFunc
;
579 context
->npnFuncInfo
= info
;
580 if(context
->protocolSide
==kSSLClientSide
) {
581 tls_handshake_set_npn_enable(context
->hdsk
, npnFunc
!=NULL
);
586 SSLSetNPNData(SSLContextRef context
,
590 if (context
== NULL
|| data
== NULL
|| length
== 0) {
600 npn_data
.data
= (uint8_t *)data
;
601 npn_data
.length
= length
;
603 return tls_handshake_set_npn_data(context
->hdsk
, npn_data
);
607 SSLGetNPNData(SSLContextRef context
,
610 if (context
== NULL
|| length
== NULL
)
613 const tls_buffer
*npn_data
;
615 npn_data
= tls_handshake_get_peer_npn_data(context
->hdsk
);
618 *length
= npn_data
->length
;
619 return npn_data
->data
;
626 SSLSetConnection (SSLContextRef ctx
,
627 SSLConnectionRef connection
)
632 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
633 /* Can Only do this with the internal record layer */
637 if(sslIsSessionActive(ctx
)) {
638 /* can't do this with an active session */
642 /* Need to keep a copy of it this layer for the Get function */
643 ctx
->ioCtx
.ioRef
= connection
;
645 return SSLSetInternalRecordLayerConnection(ctx
->recCtx
, ctx
);
649 SSLGetConnection (SSLContextRef ctx
,
650 SSLConnectionRef
*connection
)
652 if((ctx
== NULL
) || (connection
== NULL
)) {
655 *connection
= ctx
->ioCtx
.ioRef
;
656 return errSecSuccess
;
660 SSLSetPeerDomainName (SSLContextRef ctx
,
661 const char *peerName
,
667 if(sslIsSessionActive(ctx
)) {
668 /* can't do this with an active session */
672 if(ctx
->protocolSide
== kSSLClientSide
) {
673 return tls_handshake_set_peer_hostname(ctx
->hdsk
, peerName
, peerNameLen
);
675 return 0; // This should probably return an error, but historically didnt.
680 * Determine the buffer size needed for SSLGetPeerDomainName().
683 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
684 size_t *peerNameLen
) // RETURNED
689 const char *hostname
;
691 return tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, peerNameLen
);
695 SSLGetPeerDomainName (SSLContextRef ctx
,
696 char *peerName
, // returned here
697 size_t *peerNameLen
) // IN/OUT
699 const char *hostname
;
708 err
=tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
712 } else if(*peerNameLen
<len
) {
713 return errSSLBufferOverflow
;
715 memcpy(peerName
, hostname
, len
);
722 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
732 if(!ctx
->isDTLS
) return errSecParam
;
734 if((ctx
== NULL
) || (cookieLen
>32)) {
737 if(sslIsSessionActive(ctx
)) {
738 /* can't do this with an active session */
742 /* free possible existing cookie */
743 if(ctx
->dtlsCookie
.data
) {
744 SSLFreeBuffer(&ctx
->dtlsCookie
);
748 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
)))
751 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
752 return errSecSuccess
;
756 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
760 if(ctx
== NULL
) return errSecParam
;
761 if(!ctx
->isDTLS
) return errSecParam
;
763 tls_handshake_set_mtu(ctx
->hdsk
, maxSize
);
765 return errSecSuccess
;
769 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
772 if(ctx
== NULL
) return errSecParam
;
773 if(!ctx
->isDTLS
) return errSecParam
;
777 return errSecSuccess
;
782 Keys to to math below:
784 A DTLS record looks like this: | header (13 bytes) | fragment |
786 For Null cipher, fragment is clear text as follows:
789 For block cipher, fragment size must be a multiple of the cipher block size, and is the
790 encryption of the following plaintext :
791 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
793 The maximum content length in that case is achieved for 0 padding bytes.
798 SSLGetDatagramWriteSize (SSLContextRef ctx
,
801 if(ctx
== NULL
) return errSecParam
;
802 if(!ctx
->isDTLS
) return errSecParam
;
803 if(bufSize
== NULL
) return errSecParam
;
805 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
807 #warning <rdar://problem/16060896> SecureTransport: SSLGetDatagramWriteSize is wrong, need hookup with coreTLS
809 SSLCipherSpecParams
*currCipher
= &ctx
->selectedCipherSpecParams
;
811 size_t blockSize
= currCipher
->blockSize
;
812 size_t macSize
= currCipher
->macSize
;
814 size_t blockSize
= 16;
819 /* max_fragment_size must be a multiple of blocksize */
820 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
821 max_fragment_size
-= blockSize
; /* 1 block for IV */
822 max_fragment_size
-= 1; /* 1 byte for pad length */
825 /* less the mac size */
826 max_fragment_size
-= macSize
;
828 /* Thats just a sanity check */
829 assert(max_fragment_size
<ctx
->mtu
);
831 *bufSize
= max_fragment_size
;
833 return errSecSuccess
;
836 static SSLProtocolVersion
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
838 case kSSLProtocol2
: return SSL_Version_2_0
;
839 case kSSLProtocol3
: return SSL_Version_3_0
;
840 case kTLSProtocol1
: return TLS_Version_1_0
;
841 case kTLSProtocol11
: return TLS_Version_1_1
;
842 case kTLSProtocol12
: return TLS_Version_1_2
;
843 case kDTLSProtocol1
: return DTLS_Version_1_0
;
844 default: return SSL_Version_Undetermined
;
848 /* concert between private SSLProtocolVersion and public SSLProtocol */
849 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
852 case SSL_Version_2_0
: return kSSLProtocol2
;
853 case SSL_Version_3_0
: return kSSLProtocol3
;
854 case TLS_Version_1_0
: return kTLSProtocol1
;
855 case TLS_Version_1_1
: return kTLSProtocol11
;
856 case TLS_Version_1_2
: return kTLSProtocol12
;
857 case DTLS_Version_1_0
: return kDTLSProtocol1
;
859 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
862 case SSL_Version_Undetermined
: return kSSLProtocolUnknown
;
867 SSLSetProtocolVersionMin (SSLContextRef ctx
,
868 SSLProtocol minVersion
)
870 if(ctx
== NULL
) return errSecParam
;
872 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(minVersion
);
874 if (version
> MINIMUM_DATAGRAM_VERSION
||
875 version
< MAXIMUM_DATAGRAM_VERSION
)
876 return errSSLIllegalParam
;
877 if (version
< ctx
->maxProtocolVersion
)
878 ctx
->maxProtocolVersion
= version
;
880 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
881 return errSSLIllegalParam
;
882 if (version
> ctx
->maxProtocolVersion
)
883 ctx
->maxProtocolVersion
= version
;
885 ctx
->minProtocolVersion
= version
;
887 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
888 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
890 return errSecSuccess
;
894 SSLGetProtocolVersionMin (SSLContextRef ctx
,
895 SSLProtocol
*minVersion
)
897 if(ctx
== NULL
) return errSecParam
;
899 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
900 return errSecSuccess
;
904 SSLSetProtocolVersionMax (SSLContextRef ctx
,
905 SSLProtocol maxVersion
)
907 if(ctx
== NULL
) return errSecParam
;
909 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
911 if (version
> MINIMUM_DATAGRAM_VERSION
||
912 version
< MAXIMUM_DATAGRAM_VERSION
)
913 return errSSLIllegalParam
;
914 if (version
> ctx
->minProtocolVersion
)
915 ctx
->minProtocolVersion
= version
;
917 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
918 return errSSLIllegalParam
;
919 if (version
< ctx
->minProtocolVersion
)
920 ctx
->minProtocolVersion
= version
;
922 ctx
->maxProtocolVersion
= version
;
924 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
925 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
927 return errSecSuccess
;
931 SSLGetProtocolVersionMax (SSLContextRef ctx
,
932 SSLProtocol
*maxVersion
)
934 if(ctx
== NULL
) return errSecParam
;
936 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
937 return errSecSuccess
;
940 #define max(x,y) ((x)<(y)?(y):(x))
943 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
944 SSLProtocol protocol
,
950 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
951 /* Can't do this with an active session, nor with a DTLS session */
954 if (protocol
== kSSLProtocolAll
) {
956 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
957 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
959 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
960 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
963 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
965 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
968 if (version
> ctx
->maxProtocolVersion
) {
969 ctx
->maxProtocolVersion
= version
;
970 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
971 ctx
->minProtocolVersion
= version
;
973 if (version
< ctx
->minProtocolVersion
) {
974 ctx
->minProtocolVersion
= version
;
977 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
980 /* Disabling a protocol version now resets the minimum acceptable
981 * version to the next higher version. This means it's no longer
982 * possible to enable a discontiguous set of protocol versions.
984 SSLProtocolVersion nextVersion
;
986 case SSL_Version_2_0
:
987 nextVersion
= SSL_Version_3_0
;
989 case SSL_Version_3_0
:
990 nextVersion
= TLS_Version_1_0
;
992 case TLS_Version_1_0
:
993 nextVersion
= TLS_Version_1_1
;
995 case TLS_Version_1_1
:
996 nextVersion
= TLS_Version_1_2
;
998 case TLS_Version_1_2
:
1000 nextVersion
= SSL_Version_Undetermined
;
1003 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
1004 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1005 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1006 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1011 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1012 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1014 return errSecSuccess
;
1018 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1019 SSLProtocol protocol
,
1020 Boolean
*enable
) /* RETURNED */
1026 /* Can't do this with a DTLS session */
1027 return errSecBadReq
;
1033 case kTLSProtocol11
:
1034 case kTLSProtocol12
:
1036 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1037 *enable
= (ctx
->minProtocolVersion
<= version
1038 && ctx
->maxProtocolVersion
>= version
);
1041 case kSSLProtocolAll
:
1042 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1043 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1048 return errSecSuccess
;
1053 SSLSetProtocolVersion (SSLContextRef ctx
,
1054 SSLProtocol version
)
1059 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1060 /* Can't do this with an active session, nor with a DTLS session */
1061 return errSecBadReq
;
1066 /* this tells us to do our best, up to 3.0 */
1067 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1068 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1070 case kSSLProtocol3Only
:
1071 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1072 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1075 /* this tells us to do our best, up to TLS, but allows 3.0 */
1076 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1077 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1079 case kTLSProtocol1Only
:
1080 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1081 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1083 case kTLSProtocol11
:
1084 /* This tells us to do our best, up to TLS 1.1, currently also
1085 allows 3.0 or TLS 1.0 */
1086 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1087 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1089 case kTLSProtocol12
:
1090 case kSSLProtocolAll
:
1091 case kSSLProtocolUnknown
:
1092 /* This tells us to do our best, up to TLS 1.2, currently also
1093 allows 3.0 or TLS 1.0 or TLS 1.1 */
1094 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1095 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1101 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1102 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1104 return errSecSuccess
;
1109 SSLGetProtocolVersion (SSLContextRef ctx
,
1110 SSLProtocol
*protocol
) /* RETURNED */
1115 /* translate array of booleans to public value; not all combinations
1116 * are legal (i.e., meaningful) for this call */
1117 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1118 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1119 /* traditional 'all enabled' */
1120 *protocol
= kSSLProtocolAll
;
1121 return errSecSuccess
;
1123 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1124 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1125 /* traditional 'all enabled' */
1126 *protocol
= kTLSProtocol11
;
1127 return errSecSuccess
;
1129 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1130 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1131 /* TLS1.1 and below enabled */
1132 *protocol
= kTLSProtocol1
;
1133 return errSecSuccess
;
1134 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1135 *protocol
= kTLSProtocol1Only
;
1137 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1138 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1139 /* Could also return kSSLProtocol3Only since
1140 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1141 *protocol
= kSSLProtocol3
;
1142 return errSecSuccess
;
1150 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1151 SSLProtocol
*protocol
) /* RETURNED */
1156 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1157 return errSecSuccess
;
1161 SSLSetEnableCertVerify (SSLContextRef ctx
,
1162 Boolean enableVerify
)
1167 sslCertDebug("SSLSetEnableCertVerify %s",
1168 enableVerify
? "true" : "false");
1169 if(sslIsSessionActive(ctx
)) {
1170 /* can't do this with an active session */
1171 return errSecBadReq
;
1173 ctx
->enableCertVerify
= enableVerify
;
1174 return errSecSuccess
;
1178 SSLGetEnableCertVerify (SSLContextRef ctx
,
1179 Boolean
*enableVerify
)
1184 *enableVerify
= ctx
->enableCertVerify
;
1185 return errSecSuccess
;
1189 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1190 Boolean allowExpired
)
1195 sslCertDebug("SSLSetAllowsExpiredCerts %s",
1196 allowExpired
? "true" : "false");
1197 if(sslIsSessionActive(ctx
)) {
1198 /* can't do this with an active session */
1199 return errSecBadReq
;
1201 ctx
->allowExpiredCerts
= allowExpired
;
1202 return errSecSuccess
;
1206 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1207 Boolean
*allowExpired
)
1212 *allowExpired
= ctx
->allowExpiredCerts
;
1213 return errSecSuccess
;
1217 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1218 Boolean allowExpired
)
1223 sslCertDebug("SSLSetAllowsExpiredRoots %s",
1224 allowExpired
? "true" : "false");
1225 if(sslIsSessionActive(ctx
)) {
1226 /* can't do this with an active session */
1227 return errSecBadReq
;
1229 ctx
->allowExpiredRoots
= allowExpired
;
1230 return errSecSuccess
;
1234 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1235 Boolean
*allowExpired
)
1240 *allowExpired
= ctx
->allowExpiredRoots
;
1241 return errSecSuccess
;
1244 OSStatus
SSLSetAllowsAnyRoot(
1251 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1252 ctx
->allowAnyRoot
= anyRoot
;
1253 return errSecSuccess
;
1257 SSLGetAllowsAnyRoot(
1264 *anyRoot
= ctx
->allowAnyRoot
;
1265 return errSecSuccess
;
1268 #if !TARGET_OS_IPHONE
1269 /* obtain the system roots sets for this app, policy SSL */
1270 static OSStatus
sslDefaultSystemRoots(
1272 CFArrayRef
*systemRoots
) // created and RETURNED
1275 const char *hostname
;
1278 tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
1280 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1283 (ctx
->protocolSide
== kSSLServerSide
) ?
1284 /* server verifies, client encrypts */
1285 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1288 #endif /* OS X only */
1291 SSLSetTrustedRoots (SSLContextRef ctx
,
1292 CFArrayRef trustedRoots
,
1293 Boolean replaceExisting
)
1295 #ifdef USE_CDSA_CRYPTO
1299 if(sslIsSessionActive(ctx
)) {
1300 /* can't do this with an active session */
1301 return errSecBadReq
;
1304 if(replaceExisting
) {
1305 /* trivial case - retain the new, throw out the old. */
1307 CFRetain(trustedRoots
);
1308 CFReleaseSafe(ctx
->trustedCerts
);
1309 ctx
->trustedCerts
= trustedRoots
;
1310 return errSecSuccess
;
1313 /* adding new trusted roots - to either our existing set, or the system set */
1314 CFArrayRef existingRoots
= NULL
;
1316 if(ctx
->trustedCerts
!= NULL
) {
1317 /* we'll release these as we exit */
1318 existingRoots
= ctx
->trustedCerts
;
1321 /* get system set for this app, policy SSL */
1322 ortn
= sslDefaultSystemRoots(ctx
, &existingRoots
);
1324 CFReleaseSafe(existingRoots
);
1329 /* Create a new root array with caller's roots first */
1330 CFMutableArrayRef newRoots
= CFArrayCreateMutableCopy(NULL
, 0, trustedRoots
);
1331 CFRange existRange
= { 0, CFArrayGetCount(existingRoots
) };
1332 CFArrayAppendArray(newRoots
, existingRoots
, existRange
);
1333 CFRelease(existingRoots
);
1334 ctx
->trustedCerts
= newRoots
;
1335 return errSecSuccess
;
1338 if (sslIsSessionActive(ctx
)) {
1339 /* can't do this with an active session */
1340 return errSecBadReq
;
1342 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1343 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1345 if (replaceExisting
) {
1346 ctx
->trustedCertsOnly
= true;
1347 CFReleaseNull(ctx
->trustedCerts
);
1350 if (ctx
->trustedCerts
) {
1351 CFIndex count
= CFArrayGetCount(trustedRoots
);
1352 CFRange range
= { 0, count
};
1353 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1355 require(ctx
->trustedCerts
=
1356 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1360 return errSecSuccess
;
1363 return errSecAllocate
;
1364 #endif /* !USE_CDSA_CRYPTO */
1368 SSLCopyTrustedRoots (SSLContextRef ctx
,
1369 CFArrayRef
*trustedRoots
) /* RETURNED */
1371 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1374 if(ctx
->trustedCerts
!= NULL
) {
1375 *trustedRoots
= ctx
->trustedCerts
;
1376 CFRetain(ctx
->trustedCerts
);
1377 return errSecSuccess
;
1379 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1380 /* use default system roots */
1381 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1383 *trustedRoots
= NULL
;
1384 return errSecSuccess
;
1389 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1390 CFArrayRef trustedCerts
)
1395 if(sslIsSessionActive(ctx
)) {
1396 /* can't do this with an active session */
1397 return errSecBadReq
;
1400 if(ctx
->trustedLeafCerts
) {
1401 CFRelease(ctx
->trustedLeafCerts
);
1403 ctx
->trustedLeafCerts
= trustedCerts
;
1404 CFRetain(trustedCerts
);
1405 return errSecSuccess
;
1409 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1410 CFArrayRef
*trustedCerts
) /* RETURNED */
1415 if(ctx
->trustedLeafCerts
!= NULL
) {
1416 *trustedCerts
= ctx
->trustedLeafCerts
;
1417 CFRetain(ctx
->trustedCerts
);
1418 return errSecSuccess
;
1420 *trustedCerts
= NULL
;
1421 return errSecSuccess
;
1425 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1426 SSLAuthenticate auth
)
1431 if(sslIsSessionActive(ctx
)) {
1432 /* can't do this with an active session */
1433 return errSecBadReq
;
1435 ctx
->clientAuth
= auth
;
1437 case kNeverAuthenticate
:
1438 tls_handshake_set_client_auth(ctx
->hdsk
, false);
1440 case kAlwaysAuthenticate
:
1441 case kTryAuthenticate
:
1442 tls_handshake_set_client_auth(ctx
->hdsk
, true);
1445 return errSecSuccess
;
1449 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1450 SSLAuthenticate
*auth
) /* RETURNED */
1452 if(ctx
== NULL
|| auth
== NULL
) {
1455 *auth
= ctx
->clientAuth
;
1456 return errSecSuccess
;
1460 SSLGetClientCertificateState (SSLContextRef ctx
,
1461 SSLClientCertificateState
*clientState
)
1466 *clientState
= ctx
->clientCertState
;
1467 return errSecSuccess
;
1471 SSLSetCertificate (SSLContextRef ctx
,
1472 CFArrayRef certRefs
)
1475 * -- free localCerts if we have any
1476 * -- Get raw cert data, convert to ctx->localCert
1477 * -- get pub, priv keys from certRef[0]
1478 * -- validate cert chain
1484 /* can't do this with an active session */
1485 if(sslIsSessionActive(ctx
) &&
1486 /* kSSLClientCertRequested implies client side */
1487 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1489 return errSecBadReq
;
1492 CFReleaseNull(ctx
->localCertArray
);
1493 /* changing the client cert invalidates negotiated auth type */
1494 ctx
->negAuthType
= SSLClientAuthNone
;
1495 if(certRefs
== NULL
) {
1496 return errSecSuccess
; // we have cleared the cert, as requested
1498 OSStatus ortn
= parseIncomingCerts(ctx
,
1501 &ctx
->signingPrivKeyRef
);
1502 if(ortn
== errSecSuccess
) {
1503 ctx
->localCertArray
= certRefs
;
1505 if(ctx
->protocolSide
==kSSLClientSide
)
1506 SSLUpdateNegotiatedClientAuthType(ctx
);
1507 tls_handshake_set_identity(ctx
->hdsk
, ctx
->localCert
, ctx
->signingPrivKeyRef
);
1513 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1514 CFArrayRef certRefs
)
1517 * -- free encryptCert if we have any
1518 * -- Get raw cert data, convert to ctx->encryptCert
1519 * -- get pub, priv keys from certRef[0]
1520 * -- validate cert chain
1525 if(sslIsSessionActive(ctx
)) {
1526 /* can't do this with an active session */
1527 return errSecBadReq
;
1529 CFReleaseNull(ctx
->encryptCertArray
);
1530 OSStatus ortn
= parseIncomingCerts(ctx
,
1533 &ctx
->encryptPrivKeyRef
);
1534 if(ortn
== errSecSuccess
) {
1535 ctx
->encryptCertArray
= certRefs
;
1541 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1542 CFArrayRef
*certRefs
)
1547 *certRefs
= ctx
->localCertArray
;
1548 return errSecSuccess
;
1551 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1552 CFArrayRef
*certRefs
)
1557 *certRefs
= ctx
->encryptCertArray
;
1558 return errSecSuccess
;
1562 SSLSetPeerID (SSLContext
*ctx
,
1568 /* copy peerId to context->peerId */
1574 if(sslIsSessionActive(ctx
) &&
1575 /* kSSLClientCertRequested implies client side */
1576 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1578 return errSecBadReq
;
1580 SSLFreeBuffer(&ctx
->peerID
);
1581 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1585 tls_handshake_set_resumption(ctx
->hdsk
, true);
1586 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1587 return errSecSuccess
;
1591 SSLGetPeerID (SSLContextRef ctx
,
1592 const void **peerID
,
1595 *peerID
= ctx
->peerID
.data
; // may be NULL
1596 *peerIDLen
= ctx
->peerID
.length
;
1597 return errSecSuccess
;
1601 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1602 SSLCipherSuite
*cipherSuite
)
1608 if(!sslIsSessionActive(ctx
)) {
1609 return errSecBadReq
;
1612 *cipherSuite
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
1614 return errSecSuccess
;
1618 * Add an acceptable distinguished name (client authentication only).
1621 SSLAddDistinguishedName(
1632 if(sslIsSessionActive(ctx
)) {
1633 return errSecBadReq
;
1636 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1638 return errSecAllocate
;
1640 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1642 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1643 dn
->next
= ctx
->acceptableDNList
;
1644 ctx
->acceptableDNList
= dn
;
1646 tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
);
1648 return errSecSuccess
;
1651 /* single-cert version of SSLSetCertificateAuthorities() */
1653 sslAddCA(SSLContextRef ctx
,
1654 SecCertificateRef cert
)
1656 OSStatus ortn
= errSecParam
;
1658 /* Get subject from certificate. */
1659 #if TARGET_OS_IPHONE
1660 CFDataRef subjectName
= NULL
;
1661 subjectName
= SecCertificateCopySubjectSequence(cert
);
1662 require(subjectName
, errOut
);
1664 CSSM_DATA_PTR subjectName
= NULL
;
1665 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1666 require_noerr(ortn
, errOut
);
1669 /* add to acceptableCAs as cert, creating array if necessary */
1670 if(ctx
->acceptableCAs
== NULL
) {
1671 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1672 &kCFTypeArrayCallBacks
), errOut
);
1673 if(ctx
->acceptableCAs
== NULL
) {
1674 return errSecAllocate
;
1677 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1679 /* then add this cert's subject name to acceptableDNList */
1680 #if TARGET_OS_IPHONE
1681 ortn
= SSLAddDistinguishedName(ctx
,
1682 CFDataGetBytePtr(subjectName
),
1683 CFDataGetLength(subjectName
));
1685 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1689 #if TARGET_OS_IPHONE
1690 CFReleaseSafe(subjectName
);
1696 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1697 * of acceptable Certificate Authorities (CAs) to present to the client
1698 * when client authentication is performed.
1701 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1702 CFTypeRef certificateOrArray
,
1703 Boolean replaceExisting
)
1706 OSStatus ortn
= errSecSuccess
;
1708 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1709 (ctx
->protocolSide
!= kSSLServerSide
)) {
1712 if(replaceExisting
) {
1714 if(ctx
->acceptableCAs
) {
1715 CFRelease(ctx
->acceptableCAs
);
1716 ctx
->acceptableCAs
= NULL
;
1719 /* else appending */
1721 itemType
= CFGetTypeID(certificateOrArray
);
1722 if(itemType
== SecCertificateGetTypeID()) {
1724 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
1726 else if(itemType
== CFArrayGetTypeID()) {
1727 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
1728 CFIndex numCerts
= CFArrayGetCount(cfa
);
1731 /* array of certs */
1732 for(dex
=0; dex
<numCerts
; dex
++) {
1733 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
1734 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
1737 ortn
= sslAddCA(ctx
, cert
);
1751 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1752 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1754 * Caller must CFRelease the returned array.
1757 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
1758 CFArrayRef
*certificates
) /* RETURNED */
1760 if((ctx
== NULL
) || (certificates
== NULL
)) {
1763 if(ctx
->acceptableCAs
== NULL
) {
1764 *certificates
= NULL
;
1765 return errSecSuccess
;
1767 *certificates
= ctx
->acceptableCAs
;
1768 CFRetain(ctx
->acceptableCAs
);
1769 return errSecSuccess
;
1774 * Obtain the list of acceptable distinguished names as provided by
1775 * a server (if the SSLCotextRef is configured as a client), or as
1776 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1777 * is configured as a server).
1780 SSLCopyDistinguishedNames (SSLContextRef ctx
,
1783 CFMutableArrayRef outArray
= NULL
;
1784 const DNListElem
*dn
;
1786 if((ctx
== NULL
) || (names
== NULL
)) {
1789 if(ctx
->protocolSide
==kSSLServerSide
) {
1790 dn
= ctx
->acceptableDNList
;
1792 dn
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList;
1797 return errSecSuccess
;
1799 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1802 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
1803 CFArrayAppendValue(outArray
, cfDn
);
1808 return errSecSuccess
;
1813 * Request peer certificates. Valid anytime, subsequent to
1814 * a handshake attempt.
1815 * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
1816 * TODO: the 'legacy' argument is not used anymore.
1819 sslCopyPeerCertificates (SSLContextRef ctx
,
1827 if (!ctx
->peerCert
) {
1829 return errSecBadReq
;
1832 CFArrayRef ca
= CFArrayCreateCopy(kCFAllocatorDefault
, ctx
->peerCert
);
1835 return errSecAllocate
;
1839 CFIndex ix
, count
= CFArrayGetCount(ca
);
1840 for (ix
= 0; ix
< count
; ++ix
) {
1841 CFRetain(CFArrayGetValueAtIndex(ca
, ix
));
1845 return errSecSuccess
;
1849 SSLCopyPeerCertificates (SSLContextRef ctx
,
1852 return sslCopyPeerCertificates(ctx
, certs
, false);
1855 #if !TARGET_OS_IPHONE
1856 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
1857 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
1859 SSLGetPeerCertificates (SSLContextRef ctx
,
1862 SSLGetPeerCertificates (SSLContextRef ctx
,
1865 return sslCopyPeerCertificates(ctx
, certs
, true);
1870 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1871 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1872 * been called, a set of process-wide parameters will be calculated. However
1873 * that can take a long time (30 seconds).
1875 OSStatus
SSLSetDiffieHellmanParams(
1877 const void *dhParams
,
1884 if(sslIsSessionActive(ctx
)) {
1885 return errSecBadReq
;
1887 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
1890 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
1891 &ctx
->dhParamsEncoded
);
1895 #endif /* APPLE_DH */
1899 * Return parameter block specified in SSLSetDiffieHellmanParams.
1900 * Returned data is not copied and belongs to the SSLContextRef.
1902 OSStatus
SSLGetDiffieHellmanParams(
1904 const void **dhParams
,
1905 size_t *dhParamsLen
)
1911 *dhParams
= ctx
->dhParamsEncoded
.data
;
1912 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
1913 return errSecSuccess
;
1915 return errSecUnimplemented
;
1916 #endif /* APPLE_DH */
1919 OSStatus
SSLSetRsaBlinding(
1926 ctx
->rsaBlindingEnable
= blinding
;
1927 return errSecSuccess
;
1930 OSStatus
SSLGetRsaBlinding(
1937 *blinding
= ctx
->rsaBlindingEnable
;
1938 return errSecSuccess
;
1944 SecTrustRef
*trust
) /* RETURNED */
1946 OSStatus status
= errSecSuccess
;
1947 if (ctx
== NULL
|| trust
== NULL
)
1950 /* Create a SecTrustRef if this was a resumed session and we
1951 didn't have one yet. */
1952 if (!ctx
->peerCert
) {
1953 ctx
->peerCert
= tls_get_peer_certs(tls_handshake_get_peer_certificates(ctx
->hdsk
));
1955 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
1956 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
1957 &ctx
->peerSecTrust
);
1960 *trust
= ctx
->peerSecTrust
;
1961 if (ctx
->peerSecTrust
)
1962 CFRetain(ctx
->peerSecTrust
);
1967 OSStatus
SSLGetPeerSecTrust(
1969 SecTrustRef
*trust
) /* RETURNED */
1971 OSStatus status
= errSecSuccess
;
1972 if (ctx
== NULL
|| trust
== NULL
)
1975 /* Create a SecTrustRef if this was a resumed session and we
1976 didn't have one yet. */
1977 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
1978 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
1979 &ctx
->peerSecTrust
);
1982 *trust
= ctx
->peerSecTrust
;
1986 OSStatus
SSLInternalMasterSecret(
1988 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
1989 size_t *secretSize
) // in/out
1991 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
1994 return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
);
1997 OSStatus
SSLInternalServerRandom(
1999 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2000 size_t *randSize
) // in/out
2002 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2005 return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
);
2008 OSStatus
SSLInternalClientRandom(
2010 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2011 size_t *randSize
) // in/out
2013 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2016 return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
);
2019 /* This is used by EAP 802.1x */
2020 OSStatus
SSLGetCipherSizes(
2023 size_t *symmetricKeySize
,
2026 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2027 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2031 SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
2033 *digestSize
= sslCipherSuiteGetMacSize(cipher
);
2034 *symmetricKeySize
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
);
2035 *ivSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
);
2036 return errSecSuccess
;
2040 SSLGetResumableSessionInfo(
2042 Boolean
*sessionWasResumed
, // RETURNED
2043 void *sessionID
, // RETURNED, mallocd by caller
2044 size_t *sessionIDLength
) // IN/OUT
2046 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2047 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2048 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2052 SSLBuffer localSessionID
;
2053 bool sessionMatch
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
);
2056 *sessionWasResumed
= true;
2057 if(localSessionID
.length
> *sessionIDLength
) {
2058 /* really should never happen - means ID > 32 */
2061 if(localSessionID
.length
) {
2063 * Note PAC-based session resumption can result in sessionMatch
2066 memmove(sessionID
, localSessionID
.data
, localSessionID
.length
);
2068 *sessionIDLength
= localSessionID
.length
;
2071 *sessionWasResumed
= false;
2072 *sessionIDLength
= 0;
2074 return errSecSuccess
;
2078 * Get/set enable of anonymous ciphers. Default is enabled.
2081 SSLSetAllowAnonymousCiphers(
2088 if(sslIsSessionActive(ctx
)) {
2089 return errSecBadReq
;
2091 if(ctx
->validCipherSuites
!= NULL
) {
2092 /* SSLSetEnabledCiphers() has already been called */
2093 return errSecBadReq
;
2095 ctx
->anonCipherEnable
= enable
;
2096 return errSecSuccess
;
2100 SSLGetAllowAnonymousCiphers(
2104 if((ctx
== NULL
) || (enable
== NULL
)) {
2107 if(sslIsSessionActive(ctx
)) {
2108 return errSecBadReq
;
2110 *enable
= ctx
->anonCipherEnable
;
2111 return errSecSuccess
;
2115 * Override the default session cache timeout for a cache entry created for
2116 * the current session.
2119 SSLSetSessionCacheTimeout(
2121 uint32_t timeoutInSeconds
)
2126 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2127 return errSecSuccess
;
2132 void tls_handshake_master_secret_function(const void *arg
, /* opaque to coreTLS; app-specific */
2133 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2134 size_t *secretLength
)
2136 SSLContextRef ctx
= (SSLContextRef
) arg
;
2137 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
);
2142 * Register a callback for obtaining the master_secret when performing
2143 * PAC-based session resumption.
2146 SSLInternalSetMasterSecretFunction(
2148 SSLInternalMasterSecretFunction mFunc
,
2149 const void *arg
) /* opaque to SecureTransport; app-specific */
2155 ctx
->masterSecretArg
= arg
;
2156 ctx
->masterSecretCallback
= mFunc
;
2158 return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
);
2162 * Provide an opaque SessionTicket for use in PAC-based session
2163 * resumption. Client side only. The provided ticket is sent in
2164 * the ClientHello message as a SessionTicket extension.
2166 * We won't reject this on the server side, but server-side support
2167 * for PAC-based session resumption is currently enabled for
2168 * Development builds only. To fully support this for server side,
2169 * besides the rudimentary support that's here for Development builds,
2170 * we'd need a getter for the session ticket, so the app code can
2171 * access the SessionTicket when its SSLInternalMasterSecretFunction
2172 * callback is called.
2174 OSStatus
SSLInternalSetSessionTicket(
2177 size_t ticketLength
)
2182 if(sslIsSessionActive(ctx
)) {
2183 /* can't do this with an active session */
2184 return errSecBadReq
;
2186 return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
);
2191 * ECDSA curve accessors.
2195 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2196 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2198 OSStatus
SSLGetNegotiatedCurve(
2200 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2202 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2205 unsigned int curve
= tls_handshake_get_negotiated_curve(ctx
->hdsk
);
2206 if(curve
== SSL_Curve_None
) {
2209 *namedCurve
= curve
;
2210 return errSecSuccess
;
2214 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2216 OSStatus
SSLGetNumberOfECDSACurves(
2218 unsigned *numCurves
) /* RETURNED */
2220 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2223 *numCurves
= ctx
->ecdhNumCurves
;
2224 return errSecSuccess
;
2228 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2230 OSStatus
SSLGetECDSACurves(
2232 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2233 unsigned *numCurves
) /* IN/OUT */
2235 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2238 if(*numCurves
< ctx
->ecdhNumCurves
) {
2241 memmove(namedCurves
, ctx
->ecdhCurves
,
2242 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2243 *numCurves
= ctx
->ecdhNumCurves
;
2244 return errSecSuccess
;
2248 * Specify ordered list of allowable named curves.
2250 OSStatus
SSLSetECDSACurves(
2252 const SSL_ECDSA_NamedCurve
*namedCurves
,
2255 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2258 if(sslIsSessionActive(ctx
)) {
2259 /* can't do this with an active session */
2260 return errSecBadReq
;
2263 size_t size
= numCurves
* sizeof(uint16_t);
2264 ctx
->ecdhCurves
= (uint16_t *)sslMalloc(size
);
2265 if(ctx
->ecdhCurves
== NULL
) {
2266 ctx
->ecdhNumCurves
= 0;
2267 return errSecAllocate
;
2270 for (unsigned i
=0; i
<numCurves
; i
++) {
2271 ctx
->ecdhCurves
[i
] = namedCurves
[i
];
2274 ctx
->ecdhNumCurves
= numCurves
;
2276 tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
);
2277 return errSecSuccess
;
2281 * Obtain the number of client authentication mechanisms specified by
2282 * the server in its Certificate Request message.
2283 * Returns errSecParam if server hasn't sent a Certificate Request message
2284 * (i.e., client certificate state is kSSLClientCertNone).
2286 OSStatus
SSLGetNumberOfClientAuthTypes(
2290 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2293 *numTypes
= ctx
->numAuthTypes
;
2294 return errSecSuccess
;
2298 * Obtain the client authentication mechanisms specified by
2299 * the server in its Certificate Request message.
2300 * Caller allocates returned array and specifies its size (in
2301 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2302 * is the actual size of the returned array on successful return.
2304 OSStatus
SSLGetClientAuthTypes(
2306 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2307 unsigned *numTypes
) /* IN/OUT */
2309 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2312 memmove(authTypes
, ctx
->clientAuthTypes
,
2313 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2314 *numTypes
= ctx
->numAuthTypes
;
2315 return errSecSuccess
;
2319 * Obtain the SSLClientAuthenticationType actually performed.
2320 * Only valid if client certificate state is kSSLClientCertSent
2321 * or kSSLClientCertRejected; returns errSecParam otherwise.
2323 OSStatus
SSLGetNegotiatedClientAuthType(
2325 SSLClientAuthenticationType
*authType
) /* RETURNED */
2331 *authType
= ctx
->negAuthType
;
2333 return errSecSuccess
;
2337 * Update the negotiated client authentication type.
2338 * This function may be called at any time; however, note that
2339 * the negotiated authentication type will be SSLClientAuthNone
2340 * until both of the following have taken place (in either order):
2341 * - a CertificateRequest message from the server has been processed
2342 * - a client certificate has been specified
2343 * As such, this function (only) needs to be called from (both)
2344 * SSLProcessCertificateRequest and SSLSetCertificate.
2346 OSStatus
SSLUpdateNegotiatedClientAuthType(
2352 assert(ctx
->protocolSide
==kSSLClientSide
);
2354 * See if we have a signing cert that matches one of the
2355 * allowed auth types. The x509Requested flag indicates "we
2356 * have a cert that we think the server will accept".
2358 ctx
->x509Requested
= 0;
2359 ctx
->negAuthType
= SSLClientAuthNone
;
2360 if(ctx
->signingPrivKeyRef
!= NULL
) {
2361 CFIndex ourKeyAlg
= sslPrivKeyGetAlgorithmID((SecKeyRef
)tls_private_key_get_context(ctx
->signingPrivKeyRef
));
2362 assert(ourKeyAlg
==kSecRSAAlgorithmID
); /* We don't suport anything else */
2365 for(i
=0; i
<ctx
->numAuthTypes
; i
++) {
2366 switch(ctx
->clientAuthTypes
[i
]) {
2367 case SSLClientAuth_RSASign
:
2368 if(ourKeyAlg
== kSecRSAAlgorithmID
) {
2369 ctx
->x509Requested
= 1;
2370 ctx
->negAuthType
= SSLClientAuth_RSASign
;
2374 // The code below is hopelessly broken: ctx->ourSignerAlg is never set
2375 #if SSL_ENABLE_ECDSA_SIGN_AUTH
2376 case SSLClientAuth_ECDSASign
:
2378 #if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
2379 case SSLClientAuth_ECDSAFixedECDH
:
2381 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2382 (ctx
->ourSignerAlg
== kSecECDSAAlgorithmID
)) {
2383 ctx
->x509Requested
= 1;
2384 ctx
->negAuthType
= ctx
->clientAuthTypes
[i
];
2387 #if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
2388 case SSLClientAuth_RSAFixedECDH
:
2389 /* Odd case, we differ from our signer */
2390 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2391 (ctx
->ourSignerAlg
== kSecRSAAlgorithmID
)) {
2392 ctx
->x509Requested
= 1;
2393 ctx
->negAuthType
= SSLClientAuth_RSAFixedECDH
;
2399 /* None others supported */
2402 if(ctx
->x509Requested
) {
2403 sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx
->negAuthType
);
2406 } /* parsing authTypes */
2407 } /* we have a signing key */
2409 tls_handshake_set_client_auth_type(ctx
->hdsk
, ctx
->negAuthType
);
2411 return errSecSuccess
;
2414 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2416 unsigned *numSigAlgs
)
2422 tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
);
2423 return errSecSuccess
;
2426 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
),
2427 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2429 OSStatus
SSLGetSignatureAlgorithms(
2431 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2432 unsigned *numSigAlgs
) /* IN/OUT */
2438 unsigned numPeerSigAlgs
;
2439 const tls_signature_and_hash_algorithm
*peerAlgs
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
);
2441 memmove(sigAlgs
, peerAlgs
,
2442 numPeerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2443 *numSigAlgs
= numPeerSigAlgs
;
2444 return errSecSuccess
;
2448 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2452 if(ctx
== NULL
) return errSecParam
;
2454 if(ctx
->pskSharedSecret
.data
)
2455 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2457 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2458 return errSecAllocate
;
2460 tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
);
2462 return errSecSuccess
;
2465 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2466 const void *pskIdentity
,
2467 size_t pskIdentityLen
)
2469 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2471 if(ctx
->pskIdentity
.data
)
2472 SSLFreeBuffer(&ctx
->pskIdentity
);
2474 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2475 return errSecAllocate
;
2477 tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
);
2479 return errSecSuccess
;
2483 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2484 const void **pskIdentity
,
2485 size_t *pskIdentityLen
)
2487 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2489 *pskIdentity
=ctx
->pskIdentity
.data
;
2490 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2492 return errSecSuccess
;
2495 OSStatus
SSLInternal_PRF(
2497 const void *vsecret
,
2499 const void *label
, // optional, NULL implies that seed contains
2504 void *vout
, // mallocd by caller, length >= outLen
2507 return tls_handshake_internal_prf(ctx
->hdsk
,