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
;
121 CFIndex kMinDhGroupSizeDefaultValue
;
125 * Instead of using CFPropertyListReadFromFile we use a
126 * CFPropertyListCreateWithStream directly
127 * here. CFPropertyListReadFromFile() uses
128 * CFURLCopyResourcePropertyForKey() andCF pulls in CoreServices for
129 * CFURLCopyResourcePropertyForKey() and that doesn't work in install
132 static CFPropertyListRef
133 CopyPlistFromFile(CFURLRef url
)
135 CFDictionaryRef d
= NULL
;
136 CFReadStreamRef s
= CFReadStreamCreateWithFile(kCFAllocatorDefault
, url
);
137 if (s
&& CFReadStreamOpen(s
)) {
138 d
= (CFDictionaryRef
)CFPropertyListCreateWithStream(kCFAllocatorDefault
, s
, 0, kCFPropertyListImmutable
, NULL
, NULL
);
146 static void _SSLContextReadDefault()
148 /* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
149 /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
150 const int defaultSplitDefaultValue
= 2;
152 CFTypeRef value
= (CFTypeRef
)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
153 CFSTR("com.apple.security"),
154 kCFPreferencesAnyUser
,
155 kCFPreferencesCurrentHost
);
157 if (CFGetTypeID(value
) == CFBooleanGetTypeID())
158 kSplitDefaultValue
= CFBooleanGetValue((CFBooleanRef
)value
) ? 1 : 0;
159 else if (CFGetTypeID(value
) == CFNumberGetTypeID()) {
160 if (!CFNumberGetValue((CFNumberRef
)value
, kCFNumberIntType
, &kSplitDefaultValue
))
161 kSplitDefaultValue
= defaultSplitDefaultValue
;
163 if (kSplitDefaultValue
< 0 || kSplitDefaultValue
> 2) {
164 kSplitDefaultValue
= defaultSplitDefaultValue
;
169 kSplitDefaultValue
= defaultSplitDefaultValue
;
172 /* Min DH Group Size */
173 kMinDhGroupSizeDefaultValue
= CFPreferencesGetAppIntegerValue(CFSTR("SSLMinDhGroupSize"), kCFPreferencesCurrentApplication
, NULL
);
176 /* on iOS, if the above returned nothing, we manually look into mobile's Managed Preferences */
177 /* Note that if the process is running as mobile, the above call will already have read the Managed Preference plist.
178 As a result, if you have some preferences set manually with defaults, which preference applies may be different for mobile vs not-mobile. */
179 if(kMinDhGroupSizeDefaultValue
== 0) {
180 CFURLRef prefURL
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, CFSTR("/Library/Managed Preferences/mobile/.GlobalPreferences.plist"), kCFURLPOSIXPathStyle
, false);
182 CFPropertyListRef plist
= CopyPlistFromFile(prefURL
);
184 value
= CFDictionaryGetValue(plist
, CFSTR("SSLMinDhGroupSize"));
185 if (isNumber(value
)) {
186 CFNumberGetValue(value
, kCFNumberCFIndexType
, &kMinDhGroupSizeDefaultValue
);
189 CFReleaseSafe(plist
);
191 CFReleaseSafe(prefURL
);
196 CFGiblisWithHashFor(SSLContext
)
199 SSLNewContext (Boolean isServer
,
200 SSLContextRef
*contextPtr
) /* RETURNED */
202 if(contextPtr
== NULL
) {
206 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
208 if (*contextPtr
== NULL
)
209 return errSecAllocate
;
211 return errSecSuccess
;
214 SSLContextRef
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
)
217 SSLRecordContextRef recCtx
;
219 ctx
= SSLCreateContextWithRecordFuncs(alloc
, protocolSide
, connectionType
, &SSLRecordLayerInternal
);
224 recCtx
= SSLCreateInternalRecordLayer(connectionType
);
230 SSLSetRecordContext(ctx
, recCtx
);
235 SSLContextRef
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
, const struct SSLRecordFuncs
*recFuncs
)
237 OSStatus serr
= errSecSuccess
;
238 SSLContext
*ctx
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
);
244 /* subsequent errors to errOut: */
245 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
248 ctx
->hdsk
= tls_handshake_create(connectionType
==kSSLDatagramType
, protocolSide
==kSSLServerSide
);
251 tls_handshake_set_callbacks(ctx
->hdsk
,
252 &tls_handshake_callbacks
,
255 ctx
->isDTLS
= (connectionType
==kSSLDatagramType
);
257 ctx
->state
= SSL_HdskStateUninit
;
258 ctx
->timeout_duration
= DEFAULT_DTLS_TIMEOUT
;
259 ctx
->mtu
= DEFAULT_DTLS_MTU
;
262 ctx
->minProtocolVersion
= MINIMUM_DATAGRAM_VERSION
;
263 ctx
->maxProtocolVersion
= MAXIMUM_DATAGRAM_VERSION
;
265 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
266 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
268 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
269 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
271 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
272 ctx
->protocolSide
= protocolSide
;
273 ctx
->recFuncs
= recFuncs
;
275 /* Initial cert verify state: verify with default system roots */
276 ctx
->enableCertVerify
= true;
278 /* Default for RSA blinding is ENABLED */
279 ctx
->rsaBlindingEnable
= true;
281 /* Default for sending one-byte app data record is DISABLED */
282 ctx
->oneByteRecordEnable
= false;
284 /* Dont enable fallback behavior by default */
285 ctx
->fallbackEnabled
= false;
287 /* Consult global system preference for default behavior:
288 * 0 = disabled, 1 = split every write, 2 = split second and subsequent writes
289 * (caller can override by setting kSSLSessionOptionSendOneByteRecord)
291 static pthread_once_t sReadDefault
= PTHREAD_ONCE_INIT
;
292 pthread_once(&sReadDefault
, _SSLContextReadDefault
);
293 if (kSplitDefaultValue
> 0) {
294 ctx
->oneByteRecordEnable
= true;
297 if(kMinDhGroupSizeDefaultValue
) {
298 tls_handshake_set_min_dh_group_size(ctx
->hdsk
, (unsigned)kMinDhGroupSizeDefaultValue
);
301 /* default for anonymous ciphers is DISABLED */
302 ctx
->anonCipherEnable
= false;
304 ctx
->breakOnServerAuth
= false;
305 ctx
->breakOnCertRequest
= false;
306 ctx
->breakOnClientAuth
= false;
307 ctx
->signalServerAuth
= false;
308 ctx
->signalCertRequest
= false;
309 ctx
->signalClientAuth
= false;
311 ctx
->negAuthType
= SSLClientAuthNone
; /* ditto */
313 if (serr
!= errSecSuccess
) {
321 SSLNewDatagramContext (Boolean isServer
,
322 SSLContextRef
*contextPtr
) /* RETURNED */
324 if (contextPtr
== NULL
)
326 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
);
327 if (*contextPtr
== NULL
)
328 return errSecAllocate
;
329 return errSecSuccess
;
333 * Dispose of an SSLContext. (private)
334 * This function is invoked after our dispatch queue is safely released,
335 * or directly from SSLDisposeContext if there is no dispatch queue.
338 SSLDisposeContext (SSLContextRef context
)
340 if(context
== NULL
) {
344 return errSecSuccess
;
347 CFStringRef
SSLContextCopyFormatDescription(CFTypeRef arg
, CFDictionaryRef formatOptions
)
349 SSLContext
* ctx
= (SSLContext
*) arg
;
354 CFStringRef result
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
);
359 Boolean
SSLContextCompare(CFTypeRef a
, CFTypeRef b
)
364 CFHashCode
SSLContextHash(CFTypeRef arg
)
366 return (CFHashCode
) arg
;
369 void SSLContextDestroy(CFTypeRef arg
)
371 SSLContext
* ctx
= (SSLContext
*) arg
;
373 /* destroy the coreTLS handshake object */
374 tls_handshake_destroy(ctx
->hdsk
);
376 /* Only destroy if we were using the internal record layer */
377 if(ctx
->recFuncs
==&SSLRecordLayerInternal
)
378 SSLDestroyInternalRecordLayer(ctx
->recCtx
);
380 SSLFreeBuffer(&ctx
->sessionTicket
);
381 SSLFreeBuffer(&ctx
->sessionID
);
382 SSLFreeBuffer(&ctx
->peerID
);
383 SSLFreeBuffer(&ctx
->resumableSession
);
384 SSLFreeBuffer(&ctx
->receivedDataBuffer
);
386 sslFree(ctx
->validCipherSuites
);
387 ctx
->validCipherSuites
= NULL
;
388 ctx
->numValidCipherSuites
= 0;
390 CFReleaseSafe(ctx
->acceptableCAs
);
391 CFReleaseSafe(ctx
->trustedLeafCerts
);
392 CFReleaseSafe(ctx
->localCertArray
);
393 CFReleaseSafe(ctx
->encryptCertArray
);
394 CFReleaseSafe(ctx
->encryptCertArray
);
395 CFReleaseSafe(ctx
->peerCert
);
396 CFReleaseSafe(ctx
->trustedCerts
);
397 CFReleaseSafe(ctx
->peerSecTrust
);
399 sslFreePrivKey(&ctx
->signingPrivKeyRef
);
400 sslFreePrivKey(&ctx
->encryptPrivKeyRef
);
402 sslFree(ctx
->localCert
);
403 sslFree(ctx
->encryptCert
);
408 SSLFreeBuffer(&ctx
->ownVerifyData
);
409 SSLFreeBuffer(&ctx
->peerVerifyData
);
411 SSLFreeBuffer(&ctx
->pskIdentity
);
412 SSLFreeBuffer(&ctx
->pskSharedSecret
);
414 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
416 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
422 * Determine the state of an SSL session.
425 SSLGetSessionState (SSLContextRef context
,
426 SSLSessionState
*state
) /* RETURNED */
428 SSLSessionState rtnState
= kSSLIdle
;
430 if(context
== NULL
) {
434 switch(context
->state
) {
435 case SSL_HdskStateUninit
:
438 case SSL_HdskStateGracefulClose
:
439 rtnState
= kSSLClosed
;
441 case SSL_HdskStateErrorClose
:
442 case SSL_HdskStateNoNotifyClose
:
443 rtnState
= kSSLAborted
;
445 case SSL_HdskStateReady
:
446 rtnState
= kSSLConnected
;
448 case SSL_HdskStatePending
:
449 rtnState
= kSSLHandshake
;
453 return errSecSuccess
;
457 * Set options for an SSL session.
460 SSLSetSessionOption (SSLContextRef context
,
461 SSLSessionOption option
,
464 if(context
== NULL
) {
467 if(sslIsSessionActive(context
)) {
468 /* can't do this with an active session */
472 case kSSLSessionOptionBreakOnServerAuth
:
473 context
->breakOnServerAuth
= value
;
474 context
->enableCertVerify
= !value
;
476 case kSSLSessionOptionBreakOnCertRequested
:
477 context
->breakOnCertRequest
= value
;
479 case kSSLSessionOptionBreakOnClientAuth
:
480 context
->breakOnClientAuth
= value
;
481 context
->enableCertVerify
= !value
;
483 case kSSLSessionOptionSendOneByteRecord
:
484 /* Only call the record layer function if the value changed */
485 if(value
!= context
->oneByteRecordEnable
)
486 context
->recFuncs
->setOption(context
->recCtx
, kSSLRecordOptionSendOneByteRecord
, value
);
487 context
->oneByteRecordEnable
= value
;
489 case kSSLSessionOptionFalseStart
:
490 context
->falseStartEnabled
= value
;
492 case kSSLSessionOptionFallback
:
493 tls_handshake_set_fallback(context
->hdsk
, value
);
494 context
->fallbackEnabled
= value
;
500 return errSecSuccess
;
504 * Determine current value for the specified option in an SSL session.
507 SSLGetSessionOption (SSLContextRef context
,
508 SSLSessionOption option
,
511 if(context
== NULL
|| value
== NULL
) {
515 case kSSLSessionOptionBreakOnServerAuth
:
516 *value
= context
->breakOnServerAuth
;
518 case kSSLSessionOptionBreakOnCertRequested
:
519 *value
= context
->breakOnCertRequest
;
521 case kSSLSessionOptionBreakOnClientAuth
:
522 *value
= context
->breakOnClientAuth
;
524 case kSSLSessionOptionSendOneByteRecord
:
525 *value
= context
->oneByteRecordEnable
;
527 case kSSLSessionOptionFalseStart
:
528 *value
= context
->falseStartEnabled
;
534 return errSecSuccess
;
538 SSLSetRecordContext (SSLContextRef ctx
,
539 SSLRecordContextRef recCtx
)
544 if(sslIsSessionActive(ctx
)) {
545 /* can't do this with an active session */
548 ctx
->recCtx
= recCtx
;
549 return errSecSuccess
;
552 /* Those two trampolines are used to make the connetion between
553 the record layer IO callbacks and the user provided IO callbacks.
554 Those are currently necessary because the record layer read/write callbacks
555 have different prototypes that the user callbacks advertised in the API.
556 They have different prototypes because the record layer callback have to build in kernelland.
558 This situation is not desirable. So we should figure out a way to get rid of them.
560 static int IORead(SSLIOConnectionRef connection
,
565 SSLContextRef ctx
= connection
;
568 rc
= ctx
->ioCtx
.read(ctx
->ioCtx
.ioRef
, data
, dataLength
);
570 /* We may need to translate error codes at this layer */
571 if(rc
==errSSLWouldBlock
) {
572 rc
=errSSLRecordWouldBlock
;
578 static int IOWrite(SSLIOConnectionRef connection
,
583 SSLContextRef ctx
= connection
;
585 rc
= ctx
->ioCtx
.write(ctx
->ioCtx
.ioRef
, data
, dataLength
);
587 /* We may need to translate error codes at this layer */
588 if(rc
==errSSLWouldBlock
) {
589 rc
=errSSLRecordWouldBlock
;
596 SSLSetIOFuncs (SSLContextRef ctx
,
597 SSLReadFunc readFunc
,
598 SSLWriteFunc writeFunc
)
603 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
604 /* Can Only do this with the internal record layer */
608 if(sslIsSessionActive(ctx
)) {
609 /* can't do this with an active session */
613 ctx
->ioCtx
.read
=readFunc
;
614 ctx
->ioCtx
.write
=writeFunc
;
616 return SSLSetInternalRecordLayerIOFuncs(ctx
->recCtx
, IORead
, IOWrite
);
620 SSLSetNPNFunc(SSLContextRef context
,
624 if (context
== NULL
) {
627 if (sslIsSessionActive(context
)) {
630 context
->npnFunc
= npnFunc
;
631 context
->npnFuncInfo
= info
;
632 if(context
->protocolSide
==kSSLClientSide
) {
633 tls_handshake_set_npn_enable(context
->hdsk
, npnFunc
!=NULL
);
638 SSLSetNPNData(SSLContextRef context
,
642 if (context
== NULL
|| data
== NULL
|| length
== 0) {
652 npn_data
.data
= (uint8_t *)data
;
653 npn_data
.length
= length
;
655 return tls_handshake_set_npn_data(context
->hdsk
, npn_data
);
659 SSLGetNPNData(SSLContextRef context
,
662 if (context
== NULL
|| length
== NULL
)
665 const tls_buffer
*npn_data
;
667 npn_data
= tls_handshake_get_peer_npn_data(context
->hdsk
);
670 *length
= npn_data
->length
;
671 return npn_data
->data
;
678 SSLSetConnection (SSLContextRef ctx
,
679 SSLConnectionRef connection
)
684 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
685 /* Can Only do this with the internal record layer */
689 if(sslIsSessionActive(ctx
)) {
690 /* can't do this with an active session */
694 /* Need to keep a copy of it this layer for the Get function */
695 ctx
->ioCtx
.ioRef
= connection
;
697 return SSLSetInternalRecordLayerConnection(ctx
->recCtx
, ctx
);
701 SSLGetConnection (SSLContextRef ctx
,
702 SSLConnectionRef
*connection
)
704 if((ctx
== NULL
) || (connection
== NULL
)) {
707 *connection
= ctx
->ioCtx
.ioRef
;
708 return errSecSuccess
;
712 SSLSetPeerDomainName (SSLContextRef ctx
,
713 const char *peerName
,
719 if(sslIsSessionActive(ctx
)) {
720 /* can't do this with an active session */
724 if(ctx
->protocolSide
== kSSLClientSide
) {
725 return tls_handshake_set_peer_hostname(ctx
->hdsk
, peerName
, peerNameLen
);
727 return 0; // This should probably return an error, but historically didnt.
732 * Determine the buffer size needed for SSLGetPeerDomainName().
735 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
736 size_t *peerNameLen
) // RETURNED
741 const char *hostname
;
743 return tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, peerNameLen
);
747 SSLGetPeerDomainName (SSLContextRef ctx
,
748 char *peerName
, // returned here
749 size_t *peerNameLen
) // IN/OUT
751 const char *hostname
;
760 err
=tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
764 } else if(*peerNameLen
<len
) {
765 return errSSLBufferOverflow
;
767 memcpy(peerName
, hostname
, len
);
774 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
784 if(!ctx
->isDTLS
) return errSecParam
;
786 if((ctx
== NULL
) || (cookieLen
>32)) {
789 if(sslIsSessionActive(ctx
)) {
790 /* can't do this with an active session */
794 /* free possible existing cookie */
795 if(ctx
->dtlsCookie
.data
) {
796 SSLFreeBuffer(&ctx
->dtlsCookie
);
800 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
)))
803 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
804 return errSecSuccess
;
808 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
812 if(ctx
== NULL
) return errSecParam
;
813 if(!ctx
->isDTLS
) return errSecParam
;
815 tls_handshake_set_mtu(ctx
->hdsk
, maxSize
);
817 return errSecSuccess
;
821 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
824 if(ctx
== NULL
) return errSecParam
;
825 if(!ctx
->isDTLS
) return errSecParam
;
829 return errSecSuccess
;
834 Keys to to math below:
836 A DTLS record looks like this: | header (13 bytes) | fragment |
838 For Null cipher, fragment is clear text as follows:
841 For block cipher, fragment size must be a multiple of the cipher block size, and is the
842 encryption of the following plaintext :
843 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
845 The maximum content length in that case is achieved for 0 padding bytes.
850 SSLGetDatagramWriteSize (SSLContextRef ctx
,
853 if(ctx
== NULL
) return errSecParam
;
854 if(!ctx
->isDTLS
) return errSecParam
;
855 if(bufSize
== NULL
) return errSecParam
;
857 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
859 #warning <rdar://problem/16060896> SecureTransport: SSLGetDatagramWriteSize is wrong, need hookup with coreTLS
861 SSLCipherSpecParams
*currCipher
= &ctx
->selectedCipherSpecParams
;
863 size_t blockSize
= currCipher
->blockSize
;
864 size_t macSize
= currCipher
->macSize
;
866 size_t blockSize
= 16;
871 /* max_fragment_size must be a multiple of blocksize */
872 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
873 max_fragment_size
-= blockSize
; /* 1 block for IV */
874 max_fragment_size
-= 1; /* 1 byte for pad length */
877 /* less the mac size */
878 max_fragment_size
-= macSize
;
880 /* Thats just a sanity check */
881 assert(max_fragment_size
<ctx
->mtu
);
883 *bufSize
= max_fragment_size
;
885 return errSecSuccess
;
888 static SSLProtocolVersion
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
890 case kSSLProtocol2
: return SSL_Version_2_0
;
891 case kSSLProtocol3
: return SSL_Version_3_0
;
892 case kTLSProtocol1
: return TLS_Version_1_0
;
893 case kTLSProtocol11
: return TLS_Version_1_1
;
894 case kTLSProtocol12
: return TLS_Version_1_2
;
895 case kDTLSProtocol1
: return DTLS_Version_1_0
;
896 default: return SSL_Version_Undetermined
;
900 /* concert between private SSLProtocolVersion and public SSLProtocol */
901 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
904 case SSL_Version_2_0
: return kSSLProtocol2
;
905 case SSL_Version_3_0
: return kSSLProtocol3
;
906 case TLS_Version_1_0
: return kTLSProtocol1
;
907 case TLS_Version_1_1
: return kTLSProtocol11
;
908 case TLS_Version_1_2
: return kTLSProtocol12
;
909 case DTLS_Version_1_0
: return kDTLSProtocol1
;
911 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
914 case SSL_Version_Undetermined
: return kSSLProtocolUnknown
;
919 SSLSetProtocolVersionMin (SSLContextRef ctx
,
920 SSLProtocol minVersion
)
922 if(ctx
== NULL
) return errSecParam
;
924 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(minVersion
);
926 if (version
> MINIMUM_DATAGRAM_VERSION
||
927 version
< MAXIMUM_DATAGRAM_VERSION
)
928 return errSSLIllegalParam
;
929 if (version
< ctx
->maxProtocolVersion
)
930 ctx
->maxProtocolVersion
= version
;
932 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
933 return errSSLIllegalParam
;
934 if (version
> ctx
->maxProtocolVersion
)
935 ctx
->maxProtocolVersion
= version
;
937 ctx
->minProtocolVersion
= version
;
939 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
940 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
942 return errSecSuccess
;
946 SSLGetProtocolVersionMin (SSLContextRef ctx
,
947 SSLProtocol
*minVersion
)
949 if(ctx
== NULL
) return errSecParam
;
951 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
952 return errSecSuccess
;
956 SSLSetProtocolVersionMax (SSLContextRef ctx
,
957 SSLProtocol maxVersion
)
959 if(ctx
== NULL
) return errSecParam
;
961 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
963 if (version
> MINIMUM_DATAGRAM_VERSION
||
964 version
< MAXIMUM_DATAGRAM_VERSION
)
965 return errSSLIllegalParam
;
966 if (version
> ctx
->minProtocolVersion
)
967 ctx
->minProtocolVersion
= version
;
969 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
970 return errSSLIllegalParam
;
971 if (version
< ctx
->minProtocolVersion
)
972 ctx
->minProtocolVersion
= version
;
974 ctx
->maxProtocolVersion
= version
;
976 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
977 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
979 return errSecSuccess
;
983 SSLGetProtocolVersionMax (SSLContextRef ctx
,
984 SSLProtocol
*maxVersion
)
986 if(ctx
== NULL
) return errSecParam
;
988 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
989 return errSecSuccess
;
992 #define max(x,y) ((x)<(y)?(y):(x))
995 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
996 SSLProtocol protocol
,
1002 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1003 /* Can't do this with an active session, nor with a DTLS session */
1004 return errSecBadReq
;
1006 if (protocol
== kSSLProtocolAll
) {
1008 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1009 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1011 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1012 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1015 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1017 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
1020 if (version
> ctx
->maxProtocolVersion
) {
1021 ctx
->maxProtocolVersion
= version
;
1022 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
1023 ctx
->minProtocolVersion
= version
;
1025 if (version
< ctx
->minProtocolVersion
) {
1026 ctx
->minProtocolVersion
= version
;
1029 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
1032 /* Disabling a protocol version now resets the minimum acceptable
1033 * version to the next higher version. This means it's no longer
1034 * possible to enable a discontiguous set of protocol versions.
1036 SSLProtocolVersion nextVersion
;
1038 case SSL_Version_2_0
:
1039 nextVersion
= SSL_Version_3_0
;
1041 case SSL_Version_3_0
:
1042 nextVersion
= TLS_Version_1_0
;
1044 case TLS_Version_1_0
:
1045 nextVersion
= TLS_Version_1_1
;
1047 case TLS_Version_1_1
:
1048 nextVersion
= TLS_Version_1_2
;
1050 case TLS_Version_1_2
:
1052 nextVersion
= SSL_Version_Undetermined
;
1055 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
1056 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1057 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1058 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1063 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1064 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1066 return errSecSuccess
;
1070 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1071 SSLProtocol protocol
,
1072 Boolean
*enable
) /* RETURNED */
1078 /* Can't do this with a DTLS session */
1079 return errSecBadReq
;
1085 case kTLSProtocol11
:
1086 case kTLSProtocol12
:
1088 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1089 *enable
= (ctx
->minProtocolVersion
<= version
1090 && ctx
->maxProtocolVersion
>= version
);
1093 case kSSLProtocolAll
:
1094 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1095 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1100 return errSecSuccess
;
1105 SSLSetProtocolVersion (SSLContextRef ctx
,
1106 SSLProtocol version
)
1111 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1112 /* Can't do this with an active session, nor with a DTLS session */
1113 return errSecBadReq
;
1118 /* this tells us to do our best, up to 3.0 */
1119 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1120 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1122 case kSSLProtocol3Only
:
1123 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1124 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1127 /* this tells us to do our best, up to TLS, but allows 3.0 */
1128 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1129 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1131 case kTLSProtocol1Only
:
1132 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1133 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1135 case kTLSProtocol11
:
1136 /* This tells us to do our best, up to TLS 1.1, currently also
1137 allows 3.0 or TLS 1.0 */
1138 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1139 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1141 case kTLSProtocol12
:
1142 case kSSLProtocolAll
:
1143 case kSSLProtocolUnknown
:
1144 /* This tells us to do our best, up to TLS 1.2, currently also
1145 allows 3.0 or TLS 1.0 or TLS 1.1 */
1146 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1147 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1153 tls_handshake_set_min_protocol_version(ctx
->hdsk
, ctx
->minProtocolVersion
);
1154 tls_handshake_set_max_protocol_version(ctx
->hdsk
, ctx
->maxProtocolVersion
);
1156 return errSecSuccess
;
1161 SSLGetProtocolVersion (SSLContextRef ctx
,
1162 SSLProtocol
*protocol
) /* RETURNED */
1167 /* translate array of booleans to public value; not all combinations
1168 * are legal (i.e., meaningful) for this call */
1169 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1170 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1171 /* traditional 'all enabled' */
1172 *protocol
= kSSLProtocolAll
;
1173 return errSecSuccess
;
1175 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1176 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1177 /* traditional 'all enabled' */
1178 *protocol
= kTLSProtocol11
;
1179 return errSecSuccess
;
1181 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1182 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1183 /* TLS1.1 and below enabled */
1184 *protocol
= kTLSProtocol1
;
1185 return errSecSuccess
;
1186 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1187 *protocol
= kTLSProtocol1Only
;
1189 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1190 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1191 /* Could also return kSSLProtocol3Only since
1192 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1193 *protocol
= kSSLProtocol3
;
1194 return errSecSuccess
;
1202 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1203 SSLProtocol
*protocol
) /* RETURNED */
1208 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1209 return errSecSuccess
;
1213 SSLSetEnableCertVerify (SSLContextRef ctx
,
1214 Boolean enableVerify
)
1219 sslCertDebug("SSLSetEnableCertVerify %s",
1220 enableVerify
? "true" : "false");
1221 if(sslIsSessionActive(ctx
)) {
1222 /* can't do this with an active session */
1223 return errSecBadReq
;
1225 ctx
->enableCertVerify
= enableVerify
;
1226 return errSecSuccess
;
1230 SSLGetEnableCertVerify (SSLContextRef ctx
,
1231 Boolean
*enableVerify
)
1236 *enableVerify
= ctx
->enableCertVerify
;
1237 return errSecSuccess
;
1241 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1242 Boolean allowExpired
)
1247 sslCertDebug("SSLSetAllowsExpiredCerts %s",
1248 allowExpired
? "true" : "false");
1249 if(sslIsSessionActive(ctx
)) {
1250 /* can't do this with an active session */
1251 return errSecBadReq
;
1253 ctx
->allowExpiredCerts
= allowExpired
;
1254 return errSecSuccess
;
1258 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1259 Boolean
*allowExpired
)
1264 *allowExpired
= ctx
->allowExpiredCerts
;
1265 return errSecSuccess
;
1269 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1270 Boolean allowExpired
)
1275 sslCertDebug("SSLSetAllowsExpiredRoots %s",
1276 allowExpired
? "true" : "false");
1277 if(sslIsSessionActive(ctx
)) {
1278 /* can't do this with an active session */
1279 return errSecBadReq
;
1281 ctx
->allowExpiredRoots
= allowExpired
;
1282 return errSecSuccess
;
1286 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1287 Boolean
*allowExpired
)
1292 *allowExpired
= ctx
->allowExpiredRoots
;
1293 return errSecSuccess
;
1296 OSStatus
SSLSetAllowsAnyRoot(
1303 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1304 ctx
->allowAnyRoot
= anyRoot
;
1305 return errSecSuccess
;
1309 SSLGetAllowsAnyRoot(
1316 *anyRoot
= ctx
->allowAnyRoot
;
1317 return errSecSuccess
;
1320 #if !TARGET_OS_IPHONE
1321 /* obtain the system roots sets for this app, policy SSL */
1322 static OSStatus
sslDefaultSystemRoots(
1324 CFArrayRef
*systemRoots
) // created and RETURNED
1327 const char *hostname
;
1330 tls_handshake_get_peer_hostname(ctx
->hdsk
, &hostname
, &len
);
1332 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1335 (ctx
->protocolSide
== kSSLServerSide
) ?
1336 /* server verifies, client encrypts */
1337 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1340 #endif /* OS X only */
1343 SSLSetTrustedRoots (SSLContextRef ctx
,
1344 CFArrayRef trustedRoots
,
1345 Boolean replaceExisting
)
1347 #ifdef USE_CDSA_CRYPTO
1351 if(sslIsSessionActive(ctx
)) {
1352 /* can't do this with an active session */
1353 return errSecBadReq
;
1356 if(replaceExisting
) {
1357 /* trivial case - retain the new, throw out the old. */
1359 CFRetain(trustedRoots
);
1360 CFReleaseSafe(ctx
->trustedCerts
);
1361 ctx
->trustedCerts
= trustedRoots
;
1362 return errSecSuccess
;
1365 /* adding new trusted roots - to either our existing set, or the system set */
1366 CFArrayRef existingRoots
= NULL
;
1368 if(ctx
->trustedCerts
!= NULL
) {
1369 /* we'll release these as we exit */
1370 existingRoots
= ctx
->trustedCerts
;
1373 /* get system set for this app, policy SSL */
1374 ortn
= sslDefaultSystemRoots(ctx
, &existingRoots
);
1376 CFReleaseSafe(existingRoots
);
1381 /* Create a new root array with caller's roots first */
1382 CFMutableArrayRef newRoots
= CFArrayCreateMutableCopy(NULL
, 0, trustedRoots
);
1383 CFRange existRange
= { 0, CFArrayGetCount(existingRoots
) };
1384 CFArrayAppendArray(newRoots
, existingRoots
, existRange
);
1385 CFRelease(existingRoots
);
1386 ctx
->trustedCerts
= newRoots
;
1387 return errSecSuccess
;
1390 if (sslIsSessionActive(ctx
)) {
1391 /* can't do this with an active session */
1392 return errSecBadReq
;
1394 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1395 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1397 if (replaceExisting
) {
1398 ctx
->trustedCertsOnly
= true;
1399 CFReleaseNull(ctx
->trustedCerts
);
1402 if (ctx
->trustedCerts
) {
1403 CFIndex count
= CFArrayGetCount(trustedRoots
);
1404 CFRange range
= { 0, count
};
1405 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1407 require(ctx
->trustedCerts
=
1408 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1412 return errSecSuccess
;
1415 return errSecAllocate
;
1416 #endif /* !USE_CDSA_CRYPTO */
1420 SSLCopyTrustedRoots (SSLContextRef ctx
,
1421 CFArrayRef
*trustedRoots
) /* RETURNED */
1423 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1426 if(ctx
->trustedCerts
!= NULL
) {
1427 *trustedRoots
= ctx
->trustedCerts
;
1428 CFRetain(ctx
->trustedCerts
);
1429 return errSecSuccess
;
1431 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1432 /* use default system roots */
1433 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1435 *trustedRoots
= NULL
;
1436 return errSecSuccess
;
1441 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1442 CFArrayRef trustedCerts
)
1447 if(sslIsSessionActive(ctx
)) {
1448 /* can't do this with an active session */
1449 return errSecBadReq
;
1452 if(ctx
->trustedLeafCerts
) {
1453 CFRelease(ctx
->trustedLeafCerts
);
1455 ctx
->trustedLeafCerts
= trustedCerts
;
1456 CFRetain(trustedCerts
);
1457 return errSecSuccess
;
1461 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1462 CFArrayRef
*trustedCerts
) /* RETURNED */
1467 if(ctx
->trustedLeafCerts
!= NULL
) {
1468 *trustedCerts
= ctx
->trustedLeafCerts
;
1469 CFRetain(ctx
->trustedCerts
);
1470 return errSecSuccess
;
1472 *trustedCerts
= NULL
;
1473 return errSecSuccess
;
1477 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1478 SSLAuthenticate auth
)
1483 if(sslIsSessionActive(ctx
)) {
1484 /* can't do this with an active session */
1485 return errSecBadReq
;
1487 ctx
->clientAuth
= auth
;
1489 case kNeverAuthenticate
:
1490 tls_handshake_set_client_auth(ctx
->hdsk
, false);
1492 case kAlwaysAuthenticate
:
1493 case kTryAuthenticate
:
1494 tls_handshake_set_client_auth(ctx
->hdsk
, true);
1497 return errSecSuccess
;
1501 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1502 SSLAuthenticate
*auth
) /* RETURNED */
1504 if(ctx
== NULL
|| auth
== NULL
) {
1507 *auth
= ctx
->clientAuth
;
1508 return errSecSuccess
;
1512 SSLGetClientCertificateState (SSLContextRef ctx
,
1513 SSLClientCertificateState
*clientState
)
1518 *clientState
= ctx
->clientCertState
;
1519 return errSecSuccess
;
1523 SSLSetCertificate (SSLContextRef ctx
,
1524 CFArrayRef certRefs
)
1527 * -- free localCerts if we have any
1528 * -- Get raw cert data, convert to ctx->localCert
1529 * -- get pub, priv keys from certRef[0]
1530 * -- validate cert chain
1536 /* can't do this with an active session */
1537 if(sslIsSessionActive(ctx
) &&
1538 /* kSSLClientCertRequested implies client side */
1539 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1541 return errSecBadReq
;
1544 CFReleaseNull(ctx
->localCertArray
);
1545 /* changing the client cert invalidates negotiated auth type */
1546 ctx
->negAuthType
= SSLClientAuthNone
;
1547 if(certRefs
== NULL
) {
1548 return errSecSuccess
; // we have cleared the cert, as requested
1550 OSStatus ortn
= parseIncomingCerts(ctx
,
1553 &ctx
->signingPrivKeyRef
);
1554 if(ortn
== errSecSuccess
) {
1555 ctx
->localCertArray
= certRefs
;
1557 if(ctx
->protocolSide
==kSSLClientSide
)
1558 SSLUpdateNegotiatedClientAuthType(ctx
);
1559 tls_handshake_set_identity(ctx
->hdsk
, ctx
->localCert
, ctx
->signingPrivKeyRef
);
1565 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1566 CFArrayRef certRefs
)
1569 * -- free encryptCert if we have any
1570 * -- Get raw cert data, convert to ctx->encryptCert
1571 * -- get pub, priv keys from certRef[0]
1572 * -- validate cert chain
1577 if(sslIsSessionActive(ctx
)) {
1578 /* can't do this with an active session */
1579 return errSecBadReq
;
1581 CFReleaseNull(ctx
->encryptCertArray
);
1582 OSStatus ortn
= parseIncomingCerts(ctx
,
1585 &ctx
->encryptPrivKeyRef
);
1586 if(ortn
== errSecSuccess
) {
1587 ctx
->encryptCertArray
= certRefs
;
1593 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1594 CFArrayRef
*certRefs
)
1599 *certRefs
= ctx
->localCertArray
;
1600 return errSecSuccess
;
1603 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1604 CFArrayRef
*certRefs
)
1609 *certRefs
= ctx
->encryptCertArray
;
1610 return errSecSuccess
;
1614 SSLSetPeerID (SSLContext
*ctx
,
1620 /* copy peerId to context->peerId */
1626 if(sslIsSessionActive(ctx
) &&
1627 /* kSSLClientCertRequested implies client side */
1628 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1630 return errSecBadReq
;
1632 SSLFreeBuffer(&ctx
->peerID
);
1633 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1637 tls_handshake_set_resumption(ctx
->hdsk
, true);
1638 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1639 return errSecSuccess
;
1643 SSLGetPeerID (SSLContextRef ctx
,
1644 const void **peerID
,
1647 *peerID
= ctx
->peerID
.data
; // may be NULL
1648 *peerIDLen
= ctx
->peerID
.length
;
1649 return errSecSuccess
;
1653 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1654 SSLCipherSuite
*cipherSuite
)
1660 if(!sslIsSessionActive(ctx
)) {
1661 return errSecBadReq
;
1664 *cipherSuite
= (SSLCipherSuite
)tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
1666 return errSecSuccess
;
1670 * Add an acceptable distinguished name (client authentication only).
1673 SSLAddDistinguishedName(
1684 if(sslIsSessionActive(ctx
)) {
1685 return errSecBadReq
;
1688 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1690 return errSecAllocate
;
1692 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1694 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1695 dn
->next
= ctx
->acceptableDNList
;
1696 ctx
->acceptableDNList
= dn
;
1698 tls_handshake_set_acceptable_dn_list(ctx
->hdsk
, dn
);
1700 return errSecSuccess
;
1703 /* single-cert version of SSLSetCertificateAuthorities() */
1705 sslAddCA(SSLContextRef ctx
,
1706 SecCertificateRef cert
)
1708 OSStatus ortn
= errSecParam
;
1710 /* Get subject from certificate. */
1711 #if TARGET_OS_IPHONE
1712 CFDataRef subjectName
= NULL
;
1713 subjectName
= SecCertificateCopySubjectSequence(cert
);
1714 require(subjectName
, errOut
);
1716 CSSM_DATA_PTR subjectName
= NULL
;
1717 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1718 require_noerr(ortn
, errOut
);
1721 /* add to acceptableCAs as cert, creating array if necessary */
1722 if(ctx
->acceptableCAs
== NULL
) {
1723 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1724 &kCFTypeArrayCallBacks
), errOut
);
1725 if(ctx
->acceptableCAs
== NULL
) {
1726 return errSecAllocate
;
1729 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1731 /* then add this cert's subject name to acceptableDNList */
1732 #if TARGET_OS_IPHONE
1733 ortn
= SSLAddDistinguishedName(ctx
,
1734 CFDataGetBytePtr(subjectName
),
1735 CFDataGetLength(subjectName
));
1737 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1741 #if TARGET_OS_IPHONE
1742 CFReleaseSafe(subjectName
);
1748 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1749 * of acceptable Certificate Authorities (CAs) to present to the client
1750 * when client authentication is performed.
1753 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1754 CFTypeRef certificateOrArray
,
1755 Boolean replaceExisting
)
1758 OSStatus ortn
= errSecSuccess
;
1760 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1761 (ctx
->protocolSide
!= kSSLServerSide
)) {
1764 if(replaceExisting
) {
1766 if(ctx
->acceptableCAs
) {
1767 CFRelease(ctx
->acceptableCAs
);
1768 ctx
->acceptableCAs
= NULL
;
1771 /* else appending */
1773 itemType
= CFGetTypeID(certificateOrArray
);
1774 if(itemType
== SecCertificateGetTypeID()) {
1776 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
1778 else if(itemType
== CFArrayGetTypeID()) {
1779 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
1780 CFIndex numCerts
= CFArrayGetCount(cfa
);
1783 /* array of certs */
1784 for(dex
=0; dex
<numCerts
; dex
++) {
1785 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
1786 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
1789 ortn
= sslAddCA(ctx
, cert
);
1803 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1804 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1806 * Caller must CFRelease the returned array.
1809 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
1810 CFArrayRef
*certificates
) /* RETURNED */
1812 if((ctx
== NULL
) || (certificates
== NULL
)) {
1815 if(ctx
->acceptableCAs
== NULL
) {
1816 *certificates
= NULL
;
1817 return errSecSuccess
;
1819 *certificates
= ctx
->acceptableCAs
;
1820 CFRetain(ctx
->acceptableCAs
);
1821 return errSecSuccess
;
1826 * Obtain the list of acceptable distinguished names as provided by
1827 * a server (if the SSLCotextRef is configured as a client), or as
1828 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1829 * is configured as a server).
1832 SSLCopyDistinguishedNames (SSLContextRef ctx
,
1835 CFMutableArrayRef outArray
= NULL
;
1836 const DNListElem
*dn
;
1838 if((ctx
== NULL
) || (names
== NULL
)) {
1841 if(ctx
->protocolSide
==kSSLServerSide
) {
1842 dn
= ctx
->acceptableDNList
;
1844 dn
= tls_handshake_get_peer_acceptable_dn_list(ctx
->hdsk
); // ctx->acceptableDNList;
1849 return errSecSuccess
;
1851 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1854 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
1855 CFArrayAppendValue(outArray
, cfDn
);
1860 return errSecSuccess
;
1865 * Request peer certificates. Valid anytime, subsequent to
1866 * a handshake attempt.
1867 * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
1868 * TODO: the 'legacy' argument is not used anymore.
1871 sslCopyPeerCertificates (SSLContextRef ctx
,
1879 if (!ctx
->peerCert
) {
1881 return errSecBadReq
;
1884 CFArrayRef ca
= CFArrayCreateCopy(kCFAllocatorDefault
, ctx
->peerCert
);
1887 return errSecAllocate
;
1891 CFIndex ix
, count
= CFArrayGetCount(ca
);
1892 for (ix
= 0; ix
< count
; ++ix
) {
1893 CFRetain(CFArrayGetValueAtIndex(ca
, ix
));
1897 return errSecSuccess
;
1901 SSLCopyPeerCertificates (SSLContextRef ctx
,
1904 return sslCopyPeerCertificates(ctx
, certs
, false);
1907 #if !TARGET_OS_IPHONE
1908 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
1909 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
1911 SSLGetPeerCertificates (SSLContextRef ctx
,
1914 SSLGetPeerCertificates (SSLContextRef ctx
,
1917 return sslCopyPeerCertificates(ctx
, certs
, true);
1922 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1923 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1924 * been called, a set of process-wide parameters will be calculated. However
1925 * that can take a long time (30 seconds).
1927 OSStatus
SSLSetDiffieHellmanParams(
1929 const void *dhParams
,
1936 if(sslIsSessionActive(ctx
)) {
1937 return errSecBadReq
;
1939 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
1942 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
1943 &ctx
->dhParamsEncoded
);
1947 #endif /* APPLE_DH */
1951 * Return parameter block specified in SSLSetDiffieHellmanParams.
1952 * Returned data is not copied and belongs to the SSLContextRef.
1954 OSStatus
SSLGetDiffieHellmanParams(
1956 const void **dhParams
,
1957 size_t *dhParamsLen
)
1963 *dhParams
= ctx
->dhParamsEncoded
.data
;
1964 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
1965 return errSecSuccess
;
1967 return errSecUnimplemented
;
1968 #endif /* APPLE_DH */
1971 OSStatus
SSLSetMinimumDHGroupSize(SSLContextRef ctx
, unsigned nbits
)
1973 return tls_handshake_set_min_dh_group_size(ctx
->hdsk
, nbits
);
1976 OSStatus
SSLGetMinimumDHGroupSize(SSLContextRef ctx
, unsigned *nbits
)
1978 return tls_handshake_get_min_dh_group_size(ctx
->hdsk
, nbits
);
1981 OSStatus
SSLSetRsaBlinding(
1988 ctx
->rsaBlindingEnable
= blinding
;
1989 return errSecSuccess
;
1992 OSStatus
SSLGetRsaBlinding(
1999 *blinding
= ctx
->rsaBlindingEnable
;
2000 return errSecSuccess
;
2006 SecTrustRef
*trust
) /* RETURNED */
2008 OSStatus status
= errSecSuccess
;
2009 if (ctx
== NULL
|| trust
== NULL
)
2012 /* Create a SecTrustRef if this was a resumed session and we
2013 didn't have one yet. */
2014 if (!ctx
->peerCert
) {
2015 ctx
->peerCert
= tls_get_peer_certs(tls_handshake_get_peer_certificates(ctx
->hdsk
));
2017 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2018 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
2019 &ctx
->peerSecTrust
);
2022 *trust
= ctx
->peerSecTrust
;
2023 if (ctx
->peerSecTrust
)
2024 CFRetain(ctx
->peerSecTrust
);
2029 OSStatus
SSLGetPeerSecTrust(
2031 SecTrustRef
*trust
) /* RETURNED */
2033 OSStatus status
= errSecSuccess
;
2034 if (ctx
== NULL
|| trust
== NULL
)
2037 /* Create a SecTrustRef if this was a resumed session and we
2038 didn't have one yet. */
2039 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2040 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
2041 &ctx
->peerSecTrust
);
2044 *trust
= ctx
->peerSecTrust
;
2048 OSStatus
SSLInternalMasterSecret(
2050 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
2051 size_t *secretSize
) // in/out
2053 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
2056 return tls_handshake_internal_master_secret(ctx
->hdsk
, secret
, secretSize
);
2059 OSStatus
SSLInternalServerRandom(
2061 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2062 size_t *randSize
) // in/out
2064 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2067 return tls_handshake_internal_server_random(ctx
->hdsk
, randBuf
, randSize
);
2070 OSStatus
SSLInternalClientRandom(
2072 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2073 size_t *randSize
) // in/out
2075 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2078 return tls_handshake_internal_client_random(ctx
->hdsk
, randBuf
, randSize
);
2081 /* This is used by EAP 802.1x */
2082 OSStatus
SSLGetCipherSizes(
2085 size_t *symmetricKeySize
,
2088 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2089 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2093 SSLCipherSuite cipher
=tls_handshake_get_negotiated_cipherspec(ctx
->hdsk
);
2095 *digestSize
= sslCipherSuiteGetMacSize(cipher
);
2096 *symmetricKeySize
= sslCipherSuiteGetSymmetricCipherKeySize(cipher
);
2097 *ivSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher
);
2098 return errSecSuccess
;
2102 SSLGetResumableSessionInfo(
2104 Boolean
*sessionWasResumed
, // RETURNED
2105 void *sessionID
, // RETURNED, mallocd by caller
2106 size_t *sessionIDLength
) // IN/OUT
2108 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2109 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2110 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2114 SSLBuffer localSessionID
;
2115 bool sessionMatch
= tls_handshake_get_session_match(ctx
->hdsk
, &localSessionID
);
2118 *sessionWasResumed
= true;
2119 if(localSessionID
.length
> *sessionIDLength
) {
2120 /* really should never happen - means ID > 32 */
2123 if(localSessionID
.length
) {
2125 * Note PAC-based session resumption can result in sessionMatch
2128 memmove(sessionID
, localSessionID
.data
, localSessionID
.length
);
2130 *sessionIDLength
= localSessionID
.length
;
2133 *sessionWasResumed
= false;
2134 *sessionIDLength
= 0;
2136 return errSecSuccess
;
2140 * Get/set enable of anonymous ciphers. Default is enabled.
2143 SSLSetAllowAnonymousCiphers(
2150 if(sslIsSessionActive(ctx
)) {
2151 return errSecBadReq
;
2153 if(ctx
->validCipherSuites
!= NULL
) {
2154 /* SSLSetEnabledCiphers() has already been called */
2155 return errSecBadReq
;
2157 ctx
->anonCipherEnable
= enable
;
2158 return errSecSuccess
;
2162 SSLGetAllowAnonymousCiphers(
2166 if((ctx
== NULL
) || (enable
== NULL
)) {
2169 if(sslIsSessionActive(ctx
)) {
2170 return errSecBadReq
;
2172 *enable
= ctx
->anonCipherEnable
;
2173 return errSecSuccess
;
2177 * Override the default session cache timeout for a cache entry created for
2178 * the current session.
2181 SSLSetSessionCacheTimeout(
2183 uint32_t timeoutInSeconds
)
2188 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2189 return errSecSuccess
;
2194 void tls_handshake_master_secret_function(const void *arg
, /* opaque to coreTLS; app-specific */
2195 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2196 size_t *secretLength
)
2198 SSLContextRef ctx
= (SSLContextRef
) arg
;
2199 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
, secret
, secretLength
);
2204 * Register a callback for obtaining the master_secret when performing
2205 * PAC-based session resumption.
2208 SSLInternalSetMasterSecretFunction(
2210 SSLInternalMasterSecretFunction mFunc
,
2211 const void *arg
) /* opaque to SecureTransport; app-specific */
2217 ctx
->masterSecretArg
= arg
;
2218 ctx
->masterSecretCallback
= mFunc
;
2220 return tls_handshake_internal_set_master_secret_function(ctx
->hdsk
, &tls_handshake_master_secret_function
, ctx
);
2224 * Provide an opaque SessionTicket for use in PAC-based session
2225 * resumption. Client side only. The provided ticket is sent in
2226 * the ClientHello message as a SessionTicket extension.
2228 * We won't reject this on the server side, but server-side support
2229 * for PAC-based session resumption is currently enabled for
2230 * Development builds only. To fully support this for server side,
2231 * besides the rudimentary support that's here for Development builds,
2232 * we'd need a getter for the session ticket, so the app code can
2233 * access the SessionTicket when its SSLInternalMasterSecretFunction
2234 * callback is called.
2236 OSStatus
SSLInternalSetSessionTicket(
2239 size_t ticketLength
)
2244 if(sslIsSessionActive(ctx
)) {
2245 /* can't do this with an active session */
2246 return errSecBadReq
;
2248 return tls_handshake_internal_set_session_ticket(ctx
->hdsk
, ticket
, ticketLength
);
2253 * ECDSA curve accessors.
2257 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2258 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2260 OSStatus
SSLGetNegotiatedCurve(
2262 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2264 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2267 unsigned int curve
= tls_handshake_get_negotiated_curve(ctx
->hdsk
);
2268 if(curve
== SSL_Curve_None
) {
2271 *namedCurve
= curve
;
2272 return errSecSuccess
;
2276 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2278 OSStatus
SSLGetNumberOfECDSACurves(
2280 unsigned *numCurves
) /* RETURNED */
2282 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2285 *numCurves
= ctx
->ecdhNumCurves
;
2286 return errSecSuccess
;
2290 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2292 OSStatus
SSLGetECDSACurves(
2294 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2295 unsigned *numCurves
) /* IN/OUT */
2297 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2300 if(*numCurves
< ctx
->ecdhNumCurves
) {
2303 memmove(namedCurves
, ctx
->ecdhCurves
,
2304 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2305 *numCurves
= ctx
->ecdhNumCurves
;
2306 return errSecSuccess
;
2310 * Specify ordered list of allowable named curves.
2312 OSStatus
SSLSetECDSACurves(
2314 const SSL_ECDSA_NamedCurve
*namedCurves
,
2317 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2320 if(sslIsSessionActive(ctx
)) {
2321 /* can't do this with an active session */
2322 return errSecBadReq
;
2325 size_t size
= numCurves
* sizeof(uint16_t);
2326 ctx
->ecdhCurves
= (uint16_t *)sslMalloc(size
);
2327 if(ctx
->ecdhCurves
== NULL
) {
2328 ctx
->ecdhNumCurves
= 0;
2329 return errSecAllocate
;
2332 for (unsigned i
=0; i
<numCurves
; i
++) {
2333 ctx
->ecdhCurves
[i
] = namedCurves
[i
];
2336 ctx
->ecdhNumCurves
= numCurves
;
2338 tls_handshake_set_curves(ctx
->hdsk
, ctx
->ecdhCurves
, ctx
->ecdhNumCurves
);
2339 return errSecSuccess
;
2343 * Obtain the number of client authentication mechanisms specified by
2344 * the server in its Certificate Request message.
2345 * Returns errSecParam if server hasn't sent a Certificate Request message
2346 * (i.e., client certificate state is kSSLClientCertNone).
2348 OSStatus
SSLGetNumberOfClientAuthTypes(
2352 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2355 *numTypes
= ctx
->numAuthTypes
;
2356 return errSecSuccess
;
2360 * Obtain the client authentication mechanisms specified by
2361 * the server in its Certificate Request message.
2362 * Caller allocates returned array and specifies its size (in
2363 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2364 * is the actual size of the returned array on successful return.
2366 OSStatus
SSLGetClientAuthTypes(
2368 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2369 unsigned *numTypes
) /* IN/OUT */
2371 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2374 memmove(authTypes
, ctx
->clientAuthTypes
,
2375 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2376 *numTypes
= ctx
->numAuthTypes
;
2377 return errSecSuccess
;
2381 * Obtain the SSLClientAuthenticationType actually performed.
2382 * Only valid if client certificate state is kSSLClientCertSent
2383 * or kSSLClientCertRejected; returns errSecParam otherwise.
2385 OSStatus
SSLGetNegotiatedClientAuthType(
2387 SSLClientAuthenticationType
*authType
) /* RETURNED */
2393 *authType
= ctx
->negAuthType
;
2395 return errSecSuccess
;
2399 * Update the negotiated client authentication type.
2400 * This function may be called at any time; however, note that
2401 * the negotiated authentication type will be SSLClientAuthNone
2402 * until both of the following have taken place (in either order):
2403 * - a CertificateRequest message from the server has been processed
2404 * - a client certificate has been specified
2405 * As such, this function (only) needs to be called from (both)
2406 * SSLProcessCertificateRequest and SSLSetCertificate.
2408 OSStatus
SSLUpdateNegotiatedClientAuthType(
2414 assert(ctx
->protocolSide
==kSSLClientSide
);
2416 * See if we have a signing cert that matches one of the
2417 * allowed auth types. The x509Requested flag indicates "we
2418 * have a cert that we think the server will accept".
2420 ctx
->x509Requested
= 0;
2421 ctx
->negAuthType
= SSLClientAuthNone
;
2422 if(ctx
->signingPrivKeyRef
!= NULL
) {
2423 CFIndex ourKeyAlg
= sslPrivKeyGetAlgorithmID((SecKeyRef
)tls_private_key_get_context(ctx
->signingPrivKeyRef
));
2424 assert(ourKeyAlg
==kSecRSAAlgorithmID
); /* We don't suport anything else */
2427 for(i
=0; i
<ctx
->numAuthTypes
; i
++) {
2428 switch(ctx
->clientAuthTypes
[i
]) {
2429 case SSLClientAuth_RSASign
:
2430 if(ourKeyAlg
== kSecRSAAlgorithmID
) {
2431 ctx
->x509Requested
= 1;
2432 ctx
->negAuthType
= SSLClientAuth_RSASign
;
2436 // The code below is hopelessly broken: ctx->ourSignerAlg is never set
2437 #if SSL_ENABLE_ECDSA_SIGN_AUTH
2438 case SSLClientAuth_ECDSASign
:
2440 #if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
2441 case SSLClientAuth_ECDSAFixedECDH
:
2443 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2444 (ctx
->ourSignerAlg
== kSecECDSAAlgorithmID
)) {
2445 ctx
->x509Requested
= 1;
2446 ctx
->negAuthType
= ctx
->clientAuthTypes
[i
];
2449 #if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
2450 case SSLClientAuth_RSAFixedECDH
:
2451 /* Odd case, we differ from our signer */
2452 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2453 (ctx
->ourSignerAlg
== kSecRSAAlgorithmID
)) {
2454 ctx
->x509Requested
= 1;
2455 ctx
->negAuthType
= SSLClientAuth_RSAFixedECDH
;
2461 /* None others supported */
2464 if(ctx
->x509Requested
) {
2465 sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx
->negAuthType
);
2468 } /* parsing authTypes */
2469 } /* we have a signing key */
2471 tls_handshake_set_client_auth_type(ctx
->hdsk
, ctx
->negAuthType
);
2473 return errSecSuccess
;
2476 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2478 unsigned *numSigAlgs
)
2484 tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, numSigAlgs
);
2485 return errSecSuccess
;
2488 _Static_assert(sizeof(SSLSignatureAndHashAlgorithm
)==sizeof(tls_signature_and_hash_algorithm
),
2489 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2491 OSStatus
SSLGetSignatureAlgorithms(
2493 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2494 unsigned *numSigAlgs
) /* IN/OUT */
2500 unsigned numPeerSigAlgs
;
2501 const tls_signature_and_hash_algorithm
*peerAlgs
= tls_handshake_get_peer_signature_algorithms(ctx
->hdsk
, &numPeerSigAlgs
);
2503 memmove(sigAlgs
, peerAlgs
,
2504 numPeerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2505 *numSigAlgs
= numPeerSigAlgs
;
2506 return errSecSuccess
;
2510 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2514 if(ctx
== NULL
) return errSecParam
;
2516 if(ctx
->pskSharedSecret
.data
)
2517 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2519 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2520 return errSecAllocate
;
2522 tls_handshake_set_psk_secret(ctx
->hdsk
, &ctx
->pskSharedSecret
);
2524 return errSecSuccess
;
2527 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2528 const void *pskIdentity
,
2529 size_t pskIdentityLen
)
2531 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2533 if(ctx
->pskIdentity
.data
)
2534 SSLFreeBuffer(&ctx
->pskIdentity
);
2536 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2537 return errSecAllocate
;
2539 tls_handshake_set_psk_identity(ctx
->hdsk
, &ctx
->pskIdentity
);
2541 return errSecSuccess
;
2545 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2546 const void **pskIdentity
,
2547 size_t *pskIdentityLen
)
2549 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2551 *pskIdentity
=ctx
->pskIdentity
.data
;
2552 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2554 return errSecSuccess
;
2557 OSStatus
SSLInternal_PRF(
2559 const void *vsecret
,
2561 const void *label
, // optional, NULL implies that seed contains
2566 void *vout
, // mallocd by caller, length >= outLen
2569 return tls_handshake_internal_prf(ctx
->hdsk
,