1/*
2 * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * sslContext.c - SSLContext accessors
26 */
27
28#include "SecureTransport.h"
29
30#include "SSLRecordInternal.h"
31#include "SecureTransportPriv.h"
32#include "appleSession.h"
33#include "ssl.h"
34#include "sslCipherSpecs.h"
35#include "sslContext.h"
36#include "sslCrypto.h"
37#include "sslDebug.h"
38#include "sslDigests.h"
39#include "sslKeychain.h"
40#include "sslMemory.h"
41#include "sslUtils.h"
42
43#include <AssertMacros.h>
44#include <CoreFoundation/CFData.h>
45#include <CoreFoundation/CFPreferences.h>
46#include <Security/SecCertificate.h>
47#include <Security/SecCertificatePriv.h>
48#include <Security/SecTrust.h>
49#include <Security/SecTrustSettingsPriv.h>
50#include <Security/oidsalg.h>
51#include "utilities/SecCFRelease.h"
52#include <pthread.h>
53#include <string.h>
54
55#if TARGET_OS_IPHONE
56#include <Security/SecCertificateInternal.h>
57#else
58#include <Security/oidsalg.h>
59#include <Security/oidscert.h>
60#include <Security/SecTrustSettingsPriv.h>
61#endif
62
63
64static void sslFreeDnList(
65	SSLContext *ctx)
66{
67    DNListElem      *dn, *nextDN;
68
69    dn = ctx->acceptableDNList;
70    while (dn)
71    {
72	SSLFreeBuffer(&dn->derDN);
73        nextDN = dn->next;
74        sslFree(dn);
75        dn = nextDN;
76    }
77    ctx->acceptableDNList = NULL;
78}
79
80
81Boolean sslIsSessionActive(const SSLContext *ctx)
82{
83	assert(ctx != NULL);
84	switch(ctx->state) {
85		case SSL_HdskStateUninit:
86		case SSL_HdskStateServerUninit:
87		case SSL_HdskStateClientUninit:
88		case SSL_HdskStateGracefulClose:
89		case SSL_HdskStateErrorClose:
90			return false;
91		default:
92			return true;
93	}
94}
95
96/*
97 * Minimum and maximum supported versions
98 */
99//#define MINIMUM_STREAM_VERSION  SSL_Version_2_0 /* Disabled */
100#define MINIMUM_STREAM_VERSION  SSL_Version_3_0
101#define MAXIMUM_STREAM_VERSION  TLS_Version_1_2
102#define MINIMUM_DATAGRAM_VERSION  DTLS_Version_1_0
103
104/* This should be changed when we start supporting DTLS_Version_1_x */
105#define MAXIMUM_DATAGRAM_VERSION  DTLS_Version_1_0
106
107#define SSL_ENABLE_ECDSA_SIGN_AUTH			0
108#define SSL_ENABLE_RSA_FIXED_ECDH_AUTH		0
109#define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH	0
110
111#define DEFAULT_DTLS_TIMEOUT    1
112#define DEFAULT_DTLS_MTU        1400
113#define MIN_ALLOWED_DTLS_MTU    64      /* this ensure than there will be no integer
114                                            underflow when calculating max write size */
115
116static CFTypeID kSSLContextTypeID;
117int kSplitDefaultValue;
118bool kAllowServerIdentityChangeDefaultValue;
119
120static void _sslContextDestroy(CFTypeRef arg);
121static Boolean _sslContextEqual(CFTypeRef a, CFTypeRef b);
122static CFHashCode _sslContextHash(CFTypeRef arg);
123static CFStringRef _sslContextDescribe(CFTypeRef arg);
124
125static void _SSLContextReadDefault()
126{
127	/* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
128    /* Enabled by default, this make cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
129    const int defaultSplitDefaultValue = 2;
130    //To change:
131    //sudo defaults write /Library/Preferences/com.apple.security SSLWriteSplit -int 0
132	CFTypeRef value = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
133							CFSTR("com.apple.security"),
134							kCFPreferencesAnyUser,
135							kCFPreferencesCurrentHost);
136	if (value) {
137		if (CFGetTypeID(value) == CFBooleanGetTypeID())
138			kSplitDefaultValue = CFBooleanGetValue((CFBooleanRef)value) ? 1 : 0;
139		else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
140			if (!CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &kSplitDefaultValue))
141				kSplitDefaultValue = defaultSplitDefaultValue;
142		}
143		if (kSplitDefaultValue < 0 || kSplitDefaultValue > 2) {
144			kSplitDefaultValue = defaultSplitDefaultValue;
145		}
146		CFRelease(value);
147	}
148	else {
149		kSplitDefaultValue = defaultSplitDefaultValue;
150	}
151
152
153    /* 0 = disallowed, 1 = allowed */
154    /* Disallowed by default */
155    const bool defaultValue = false;
156    //To change:
157    //sudo defaults write /Library/Preferences/com.apple.security SSLAllowServerIdentityChange -bool YES
158	value = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SSLAllowServerIdentityChange"),
159                                              CFSTR("com.apple.security"),
160                                              kCFPreferencesAnyUser,
161                                              kCFPreferencesCurrentHost);
162	if (value) {
163		if (CFGetTypeID(value) == CFBooleanGetTypeID())
164			kAllowServerIdentityChangeDefaultValue = CFBooleanGetValue((CFBooleanRef)value);
165		else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
166            int localValue;
167			if (!CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &localValue)) {
168				kAllowServerIdentityChangeDefaultValue = defaultValue;
169            } else {
170                kAllowServerIdentityChangeDefaultValue = localValue;
171            }
172		}
173		CFRelease(value);
174	}
175	else {
176		kAllowServerIdentityChangeDefaultValue = defaultValue;
177	}
178}
179
180static void _SSLContextRegisterClass()
181{
182	static const CFRuntimeClass kSSLContextRegisterClass = {
183		0,												/* version */
184        "SSLContext",					     			/* class name */
185		NULL,											/* init */
186		NULL,											/* copy */
187		_sslContextDestroy,     	                    /* dealloc */
188		_sslContextEqual,							    /* equal */
189		_sslContextHash,								/* hash */
190		NULL,											/* copyFormattingDesc */
191		_sslContextDescribe		                        /* copyDebugDesc */
192	};
193
194    kSSLContextTypeID = _CFRuntimeRegisterClass(&kSSLContextRegisterClass);
195}
196
197CFTypeID
198SSLContextGetTypeID(void)
199{
200	static pthread_once_t sOnce = PTHREAD_ONCE_INIT;
201	pthread_once(&sOnce, _SSLContextRegisterClass);
202	return kSSLContextTypeID;
203}
204
205
206OSStatus
207SSLNewContext				(Boolean 			isServer,
208							 SSLContextRef 		*contextPtr)	/* RETURNED */
209{
210	if(contextPtr == NULL) {
211		return errSecParam;
212	}
213
214	*contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLStreamType);
215
216	if (*contextPtr == NULL)
217		return errSecAllocate;
218
219	return errSecSuccess;
220}
221
222SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
223{
224    SSLContextRef ctx;
225
226    ctx = SSLCreateContextWithRecordFuncs(alloc, protocolSide, connectionType, &SSLRecordLayerInternal);
227
228    if(ctx==NULL)
229        return NULL;
230
231    ctx->recCtx = SSLCreateInternalRecordLayer(connectionType);
232    if(ctx->recCtx==NULL) {
233    	CFRelease(ctx);
234		return NULL;
235    }
236
237    return ctx;
238}
239
240SSLContextRef SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType, const struct SSLRecordFuncs *recFuncs)
241{
242	OSStatus	serr = errSecSuccess;
243	SSLContext *ctx = (SSLContext*) _CFRuntimeCreateInstance(alloc, SSLContextGetTypeID(), sizeof(SSLContext) - sizeof(CFRuntimeBase), NULL);
244
245	if(ctx == NULL) {
246		return NULL;
247	}
248
249	/* subsequent errors to errOut: */
250    memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
251
252    ctx->state = SSL_HdskStateUninit;
253    ctx->timeout_duration = DEFAULT_DTLS_TIMEOUT;
254    ctx->clientCertState = kSSLClientCertNone;
255
256    ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
257    ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
258
259    ctx->isDTLS = false;
260    ctx->dtlsCookie.data = NULL;
261    ctx->dtlsCookie.length = 0;
262    ctx->hdskMessageSeq = 0;
263    ctx->hdskMessageSeqNext = 0;
264    ctx->mtu = DEFAULT_DTLS_MTU;
265
266	ctx->negProtocolVersion = SSL_Version_Undetermined;
267
268
269    ctx->protocolSide = protocolSide;
270	/* Default value so we can send and receive hello msgs */
271	ctx->sslTslCalls = &Ssl3Callouts;
272
273    ctx->recFuncs = recFuncs;
274
275    /* Initialize the cipher state to NULL_WITH_NULL_NULL */
276    ctx->selectedCipher        = TLS_NULL_WITH_NULL_NULL;
277    InitCipherSpecParams(ctx);
278
279    /* this gets init'd on first call to SSLHandshake() */
280    ctx->validCipherSuites = NULL;
281    ctx->numValidCipherSuites = 0;
282#if ENABLE_SSLV2
283    ctx->numValidNonSSLv2Suites = 0;
284#endif
285
286	ctx->peerDomainName = NULL;
287	ctx->peerDomainNameLen = 0;
288
289#ifdef USE_CDSA_CRYPTO
290	/* attach to CSP, CL, TP */
291	serr = attachToAll(ctx);
292	if(serr) {
293		goto errOut;
294	}
295#endif /* USE_CDSA_CRYPTO */
296
297	/* Initial cert verify state: verify with default system roots */
298	ctx->enableCertVerify = true;
299
300	/* Default for RSA blinding is ENABLED */
301	ctx->rsaBlindingEnable = true;
302
303	/* Default for sending one-byte app data record is DISABLED */
304	ctx->oneByteRecordEnable = false;
305
306    /* Default for allowing server identity change on renegotiation is FALSE */
307    ctx->allowServerIdentityChange = false;
308
309	/* Consult global system preference for default behavior:
310	 * 0 = disabled, 1 = split every write, 2 = split second and subsequent writes
311	 * (caller can override by setting kSSLSessionOptionSendOneByteRecord)
312	 */
313	static pthread_once_t sReadDefault = PTHREAD_ONCE_INIT;
314	pthread_once(&sReadDefault, _SSLContextReadDefault);
315	if (kSplitDefaultValue > 0)
316		ctx->oneByteRecordEnable = true;
317    if (kAllowServerIdentityChangeDefaultValue>0)
318        ctx->allowServerIdentityChange = true;
319
320	/* default for anonymous ciphers is DISABLED */
321	ctx->anonCipherEnable = false;
322
323    ctx->breakOnServerAuth = false;
324    ctx->breakOnCertRequest = false;
325    ctx->breakOnClientAuth = false;
326    ctx->signalServerAuth = false;
327    ctx->signalCertRequest = false;
328    ctx->signalClientAuth = false;
329
330	/*
331	 * Initial/default set of ECDH curves
332	 */
333	ctx->ecdhNumCurves = SSL_ECDSA_NUM_CURVES;
334	ctx->ecdhCurves[0] = SSL_Curve_secp256r1;
335	ctx->ecdhCurves[1] = SSL_Curve_secp384r1;
336	ctx->ecdhCurves[2] = SSL_Curve_secp521r1;
337
338	ctx->ecdhPeerCurve = SSL_Curve_None;		/* until we negotiate one */
339	ctx->negAuthType = SSLClientAuthNone;		/* ditto */
340
341    ctx->messageWriteQueue = NULL;
342
343    if(connectionType==kSSLDatagramType) {
344        ctx->minProtocolVersion = MINIMUM_DATAGRAM_VERSION;
345        ctx->maxProtocolVersion = MAXIMUM_DATAGRAM_VERSION;
346        ctx->isDTLS = true;
347	}
348
349    ctx->secure_renegotiation = false;
350
351	if (serr != errSecSuccess) {
352		CFRelease(ctx);
353		ctx = NULL;
354    }
355	return ctx;
356}
357
358OSStatus
359SSLNewDatagramContext       (Boolean 			isServer,
360							 SSLContextRef 		*contextPtr)	/* RETURNED */
361{
362	if (contextPtr == NULL)
363		return errSecParam;
364	*contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLDatagramType);
365	if (*contextPtr == NULL)
366		return errSecAllocate;
367    return errSecSuccess;
368}
369
370/*
371 * Dispose of an SSLContext. (private)
372 * This function is invoked after our dispatch queue is safely released,
373 * or directly from SSLDisposeContext if there is no dispatch queue.
374 */
375OSStatus
376SSLDisposeContext				(SSLContextRef context)
377{
378    if(context == NULL) {
379        return errSecParam;
380    }
381	CFRelease(context);
382	return errSecSuccess;
383}
384
385CF_RETURNS_RETAINED CFStringRef _sslContextDescribe(CFTypeRef arg)
386{
387    SSLContext* ctx = (SSLContext*) arg;
388
389    if (ctx == NULL) {
390        return NULL;
391    } else {
392		CFStringRef result = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SSLContext(%p) { ... }>"), ctx);
393		return result;
394    }
395}
396
397Boolean _sslContextEqual(CFTypeRef a, CFTypeRef b)
398{
399	return a == b;
400}
401
402CFHashCode _sslContextHash(CFTypeRef arg)
403{
404	return (CFHashCode) arg;
405}
406
407void _sslContextDestroy(CFTypeRef arg)
408{
409	SSLContext* ctx = (SSLContext*) arg;
410
411#if USE_SSLCERTIFICATE
412	sslDeleteCertificateChain(ctx->localCert, ctx);
413    sslDeleteCertificateChain(ctx->encryptCert, ctx);
414    sslDeleteCertificateChain(ctx->peerCert, ctx);
415    ctx->localCert = ctx->encryptCert = ctx->peerCert = NULL;
416#else
417	CFReleaseNull(ctx->localCert);
418	CFReleaseNull(ctx->encryptCert);
419	CFReleaseNull(ctx->peerCert);
420	CFReleaseNull(ctx->trustedCerts);
421#endif
422
423    /* Free the last handshake message flight */
424    SSLResetFlight(ctx);
425
426    if(ctx->peerSecTrust) {
427		CFRelease(ctx->peerSecTrust);
428		ctx->peerSecTrust = NULL;
429	}
430    SSLFreeBuffer(&ctx->sessionTicket);
431
432	#if APPLE_DH
433    SSLFreeBuffer(&ctx->dhParamsEncoded);
434#ifdef USE_CDSA_CRYPTO
435	sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
436#else
437    if (ctx->secDHContext)
438        SecDHDestroy(ctx->secDHContext);
439#endif /* !USE_CDSA_CRYPTO */
440    SSLFreeBuffer(&ctx->dhPeerPublic);
441    SSLFreeBuffer(&ctx->dhExchangePublic);
442    #endif	/* APPLE_DH */
443
444    SSLFreeBuffer(&ctx->ecdhPeerPublic);
445    SSLFreeBuffer(&ctx->ecdhExchangePublic);
446#if USE_CDSA_CRYPTO
447	if(ctx->ecdhPrivCspHand == ctx->cspHand) {
448		sslFreeKey(ctx->ecdhPrivCspHand, &ctx->ecdhPrivate, NULL);
449	}
450	/* else we got this key from a SecKeyRef, no free needed */
451#endif
452
453    /* Only destroy if we were using the internal record layer */
454    if(ctx->recFuncs==&SSLRecordLayerInternal)
455        SSLDestroyInternalRecordLayer(ctx->recCtx);
456
457	CloseHash(&SSLHashSHA1, &ctx->shaState);
458	CloseHash(&SSLHashMD5,  &ctx->md5State);
459	CloseHash(&SSLHashSHA256,  &ctx->sha256State);
460	CloseHash(&SSLHashSHA384,  &ctx->sha512State);
461
462    SSLFreeBuffer(&ctx->sessionID);
463    SSLFreeBuffer(&ctx->peerID);
464    SSLFreeBuffer(&ctx->resumableSession);
465    SSLFreeBuffer(&ctx->preMasterSecret);
466    SSLFreeBuffer(&ctx->fragmentedMessageCache);
467    SSLFreeBuffer(&ctx->receivedDataBuffer);
468
469	if(ctx->peerDomainName) {
470		sslFree(ctx->peerDomainName);
471		ctx->peerDomainName = NULL;
472		ctx->peerDomainNameLen = 0;
473	}
474
475	sslFree(ctx->validCipherSuites);
476	ctx->validCipherSuites = NULL;
477	ctx->numValidCipherSuites = 0;
478
479#if USE_CDSA_CRYPTO
480	/*
481	 * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
482	 * We really don't know what CSP the CL used to generate a public key (in fact,
483	 * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
484	 * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
485	 * signingPubKey is not tecnically accurate. However, our public keys
486	 * are all raw keys, and all Apple CSPs dispose of raw keys in the same
487	 * way.
488	 */
489	sslFreeKey(ctx->cspHand, &ctx->signingPubKey, NULL);
490	sslFreeKey(ctx->cspHand, &ctx->encryptPubKey, NULL);
491	sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
492
493	if(ctx->signingPrivKeyRef) {
494		CFRelease(ctx->signingPrivKeyRef);
495	}
496	if(ctx->encryptPrivKeyRef) {
497		CFRelease(ctx->encryptPrivKeyRef);
498	}
499	if(ctx->trustedCerts) {
500		CFRelease(ctx->trustedCerts);
501	}
502	detachFromAll(ctx);
503#else
504	sslFreePubKey(&ctx->signingPubKey);
505	sslFreePubKey(&ctx->encryptPubKey);
506	sslFreePubKey(&ctx->peerPubKey);
507	sslFreePrivKey(&ctx->signingPrivKeyRef);
508	sslFreePrivKey(&ctx->encryptPrivKeyRef);
509#endif /* USE_CDSA_CRYPTO */
510    CFReleaseSafe(ctx->acceptableCAs);
511    CFReleaseSafe(ctx->trustedLeafCerts);
512	CFReleaseSafe(ctx->localCertArray);
513	CFReleaseSafe(ctx->encryptCertArray);
514    CFReleaseSafe(ctx->encryptCertArray);
515	if(ctx->clientAuthTypes) {
516		sslFree(ctx->clientAuthTypes);
517	}
518    if(ctx->serverSigAlgs != NULL) {
519        sslFree(ctx->serverSigAlgs);
520    }
521    if(ctx->clientSigAlgs != NULL) {
522        sslFree(ctx->clientSigAlgs);
523    }
524	sslFreeDnList(ctx);
525
526    SSLFreeBuffer(&ctx->ownVerifyData);
527    SSLFreeBuffer(&ctx->peerVerifyData);
528
529    SSLFreeBuffer(&ctx->pskIdentity);
530    SSLFreeBuffer(&ctx->pskSharedSecret);
531
532    memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
533
534	sslCleanupSession();
535}
536
537/*
538 * Determine the state of an SSL session.
539 */
540OSStatus
541SSLGetSessionState			(SSLContextRef		context,
542							 SSLSessionState	*state)		/* RETURNED */
543{
544	SSLSessionState rtnState = kSSLIdle;
545
546	if(context == NULL) {
547		return errSecParam;
548	}
549	*state = rtnState;
550	switch(context->state) {
551		case SSL_HdskStateUninit:
552		case SSL_HdskStateServerUninit:
553		case SSL_HdskStateClientUninit:
554			rtnState = kSSLIdle;
555			break;
556		case SSL_HdskStateGracefulClose:
557			rtnState = kSSLClosed;
558			break;
559		case SSL_HdskStateErrorClose:
560		case SSL_HdskStateNoNotifyClose:
561			rtnState = kSSLAborted;
562			break;
563		case SSL_HdskStateServerReady:
564		case SSL_HdskStateClientReady:
565			rtnState = kSSLConnected;
566			break;
567		default:
568			assert((context->state >= SSL_HdskStateServerHello) &&
569			        (context->state <= SSL_HdskStateFinished));
570			rtnState = kSSLHandshake;
571			break;
572
573	}
574	*state = rtnState;
575	return errSecSuccess;
576}
577
578/*
579 * Set options for an SSL session.
580 */
581OSStatus
582SSLSetSessionOption			(SSLContextRef		context,
583							 SSLSessionOption	option,
584							 Boolean			value)
585{
586    if(context == NULL) {
587	return errSecParam;
588    }
589    if(sslIsSessionActive(context)) {
590	/* can't do this with an active session */
591	return errSecBadReq;
592    }
593    switch(option) {
594        case kSSLSessionOptionBreakOnServerAuth:
595            context->breakOnServerAuth = value;
596            context->enableCertVerify = !value;
597            break;
598        case kSSLSessionOptionBreakOnCertRequested:
599            context->breakOnCertRequest = value;
600            break;
601        case kSSLSessionOptionBreakOnClientAuth:
602            context->breakOnClientAuth = value;
603            context->enableCertVerify = !value;
604            break;
605        case kSSLSessionOptionSendOneByteRecord:
606            context->oneByteRecordEnable = value;
607            break;
608        case kSSLSessionOptionFalseStart:
609            context->falseStartEnabled = value;
610            break;
611        case kSSLSessionOptionAllowServerIdentityChange:
612            context->allowServerIdentityChange = value;
613            break;
614        default:
615            return errSecParam;
616    }
617
618    return errSecSuccess;
619}
620
621/*
622 * Determine current value for the specified option in an SSL session.
623 */
624OSStatus
625SSLGetSessionOption			(SSLContextRef		context,
626							 SSLSessionOption	option,
627							 Boolean			*value)
628{
629    if(context == NULL || value == NULL) {
630        return errSecParam;
631    }
632    switch(option) {
633        case kSSLSessionOptionBreakOnServerAuth:
634            *value = context->breakOnServerAuth;
635            break;
636        case kSSLSessionOptionBreakOnCertRequested:
637            *value = context->breakOnCertRequest;
638            break;
639        case kSSLSessionOptionBreakOnClientAuth:
640            *value = context->breakOnClientAuth;
641            break;
642        case kSSLSessionOptionSendOneByteRecord:
643            *value = context->oneByteRecordEnable;
644            break;
645        case kSSLSessionOptionFalseStart:
646            *value = context->falseStartEnabled;
647            break;
648        default:
649            return errSecParam;
650    }
651
652    return errSecSuccess;
653}
654
655OSStatus
656SSLSetRecordContext         (SSLContextRef          ctx,
657                             SSLRecordContextRef    recCtx)
658{
659	if(ctx == NULL) {
660		return errSecParam;
661	}
662	if(sslIsSessionActive(ctx)) {
663		/* can't do this with an active session */
664		return errSecBadReq;
665	}
666    ctx->recCtx = recCtx;
667    return errSecSuccess;
668}
669
670/* Those two trampolines are used to make the connetion between
671   the record layer IO callbacks and the user provided IO callbacks.
672   Those are currently necessary because the record layer read/write callbacks
673   have different prototypes that the user callbacks advertised in the API.
674   They have different prototypes because the record layer callback have to build in kernelland.
675
676   This situation is not desirable. So we should figure out a way to get rid of them.
677 */
678static int IORead(SSLIOConnectionRef 	connection,
679                  void 				*data,
680                  size_t 			*dataLength)
681{
682    OSStatus rc;
683    SSLContextRef ctx = connection;
684
685
686    rc = ctx->ioCtx.read(ctx->ioCtx.ioRef, data, dataLength);
687
688    /* We may need to translate error codes at this layer */
689    if(rc==errSSLWouldBlock) {
690        rc=errSSLRecordWouldBlock;
691    }
692
693    return rc;
694}
695
696static int IOWrite(SSLIOConnectionRef 	connection,
697                   const void 		*data,
698                   size_t 			*dataLength)
699{
700    OSStatus rc;
701    SSLContextRef ctx = connection;
702
703    rc = ctx->ioCtx.write(ctx->ioCtx.ioRef, data, dataLength);
704
705    /* We may need to translate error codes at this layer */
706    if(rc==errSSLWouldBlock) {
707        rc=errSSLRecordWouldBlock;
708    }
709    return rc;
710}
711
712
713OSStatus
714SSLSetIOFuncs				(SSLContextRef		ctx,
715							 SSLReadFunc 		readFunc,
716							 SSLWriteFunc		writeFunc)
717{
718	if(ctx == NULL) {
719		return errSecParam;
720	}
721    if(ctx->recFuncs!=&SSLRecordLayerInternal) {
722        /* Can Only do this with the internal record layer */
723        check(0);
724        return errSecBadReq;
725    }
726	if(sslIsSessionActive(ctx)) {
727		/* can't do this with an active session */
728		return errSecBadReq;
729	}
730
731    ctx->ioCtx.read=readFunc;
732    ctx->ioCtx.write=writeFunc;
733
734    return SSLSetInternalRecordLayerIOFuncs(ctx->recCtx, IORead, IOWrite);
735}
736
737OSStatus
738SSLSetConnection			(SSLContextRef		ctx,
739							 SSLConnectionRef	connection)
740{
741	if(ctx == NULL) {
742		return errSecParam;
743	}
744    if(ctx->recFuncs!=&SSLRecordLayerInternal) {
745        /* Can Only do this with the internal record layer */
746        check(0);
747        return errSecBadReq;
748    }
749	if(sslIsSessionActive(ctx)) {
750		/* can't do this with an active session */
751		return errSecBadReq;
752	}
753
754    /* Need to keep a copy of it this layer for the Get function */
755    ctx->ioCtx.ioRef = connection;
756
757    return SSLSetInternalRecordLayerConnection(ctx->recCtx, ctx);
758}
759
760OSStatus
761SSLGetConnection			(SSLContextRef		ctx,
762							 SSLConnectionRef	*connection)
763{
764	if((ctx == NULL) || (connection == NULL)) {
765		return errSecParam;
766	}
767	*connection = ctx->ioCtx.ioRef;
768	return errSecSuccess;
769}
770
771OSStatus
772SSLSetPeerDomainName		(SSLContextRef		ctx,
773							 const char			*peerName,
774							 size_t				peerNameLen)
775{
776	if(ctx == NULL) {
777		return errSecParam;
778	}
779	if(sslIsSessionActive(ctx)) {
780		/* can't do this with an active session */
781		return errSecBadReq;
782	}
783
784	/* free possible existing name */
785	if(ctx->peerDomainName) {
786		sslFree(ctx->peerDomainName);
787	}
788
789	/* copy in */
790	ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
791	if(ctx->peerDomainName == NULL) {
792		return errSecAllocate;
793	}
794	memmove(ctx->peerDomainName, peerName, peerNameLen);
795	ctx->peerDomainNameLen = peerNameLen;
796	return errSecSuccess;
797}
798
799/*
800 * Determine the buffer size needed for SSLGetPeerDomainName().
801 */
802OSStatus
803SSLGetPeerDomainNameLength	(SSLContextRef		ctx,
804							 size_t				*peerNameLen)	// RETURNED
805{
806	if(ctx == NULL) {
807		return errSecParam;
808	}
809	*peerNameLen = ctx->peerDomainNameLen;
810	return errSecSuccess;
811}
812
813OSStatus
814SSLGetPeerDomainName		(SSLContextRef		ctx,
815							 char				*peerName,		// returned here
816							 size_t				*peerNameLen)	// IN/OUT
817{
818	if(ctx == NULL) {
819		return errSecParam;
820	}
821	if(*peerNameLen < ctx->peerDomainNameLen) {
822		return errSSLBufferOverflow;
823	}
824	memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
825	*peerNameLen = ctx->peerDomainNameLen;
826	return errSecSuccess;
827}
828
829OSStatus
830SSLSetDatagramHelloCookie   (SSLContextRef	ctx,
831                             const void         *cookie,
832                             size_t             cookieLen)
833{
834    OSStatus err;
835
836    if(ctx == NULL) {
837		return errSecParam;
838	}
839
840    if(!ctx->isDTLS) return errSecParam;
841
842	if((ctx == NULL) || (cookieLen>32)) {
843		return errSecParam;
844	}
845	if(sslIsSessionActive(ctx)) {
846		/* can't do this with an active session */
847		return errSecBadReq;
848	}
849
850	/* free possible existing cookie */
851	if(ctx->dtlsCookie.data) {
852        SSLFreeBuffer(&ctx->dtlsCookie);
853	}
854
855	/* copy in */
856    if((err=SSLAllocBuffer(&ctx->dtlsCookie, cookieLen)))
857       return err;
858
859	memmove(ctx->dtlsCookie.data, cookie, cookieLen);
860    return errSecSuccess;
861}
862
863OSStatus
864SSLSetMaxDatagramRecordSize (SSLContextRef		ctx,
865                             size_t             maxSize)
866{
867
868    if(ctx == NULL) return errSecParam;
869    if(!ctx->isDTLS) return errSecParam;
870    if(maxSize < MIN_ALLOWED_DTLS_MTU) return errSecParam;
871
872    ctx->mtu = maxSize;
873
874    return errSecSuccess;
875}
876
877OSStatus
878SSLGetMaxDatagramRecordSize (SSLContextRef		ctx,
879                             size_t             *maxSize)
880{
881    if(ctx == NULL) return errSecParam;
882    if(!ctx->isDTLS) return errSecParam;
883
884    *maxSize = ctx->mtu;
885
886    return errSecSuccess;
887}
888
889/*
890
891 Keys to to math below:
892
893 A DTLS record looks like this: | header (13 bytes) | fragment |
894
895 For Null cipher, fragment is clear text as follows:
896 | Contents | Mac |
897
898 For block cipher, fragment size must be a multiple of the cipher block size, and is the
899 encryption of the following plaintext :
900 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
901
902 The maximum content length in that case is achieved for 0 padding bytes.
903
904*/
905
906OSStatus
907SSLGetDatagramWriteSize		(SSLContextRef ctx,
908							 size_t *bufSize)
909{
910    if(ctx == NULL) return errSecParam;
911    if(!ctx->isDTLS) return errSecParam;
912    if(bufSize == NULL) return errSecParam;
913
914    size_t max_fragment_size = ctx->mtu-13; /* 13 = dtls record header */
915
916    SSLCipherSpecParams *currCipher = &ctx->selectedCipherSpecParams;
917
918    size_t blockSize = currCipher->blockSize;
919    size_t macSize = currCipher->macSize;
920
921    if (blockSize > 0) {
922        /* max_fragment_size must be a multiple of blocksize */
923        max_fragment_size = max_fragment_size & ~(blockSize-1);
924        max_fragment_size -= blockSize; /* 1 block for IV */
925        max_fragment_size -= 1; /* 1 byte for pad length */
926    }
927
928    /* less the mac size */
929    max_fragment_size -= macSize;
930
931    /* Thats just a sanity check */
932    assert(max_fragment_size<ctx->mtu);
933
934    *bufSize = max_fragment_size;
935
936    return errSecSuccess;
937}
938
939static SSLProtocolVersion SSLProtocolToProtocolVersion(SSLProtocol protocol) {
940    switch (protocol) {
941        case kSSLProtocol2:             return SSL_Version_2_0;
942        case kSSLProtocol3:             return SSL_Version_3_0;
943        case kTLSProtocol1:             return TLS_Version_1_0;
944        case kTLSProtocol11:            return TLS_Version_1_1;
945        case kTLSProtocol12:            return TLS_Version_1_2;
946        case kDTLSProtocol1:            return DTLS_Version_1_0;
947        default:                        return SSL_Version_Undetermined;
948    }
949}
950
951/* concert between private SSLProtocolVersion and public SSLProtocol */
952static SSLProtocol SSLProtocolVersionToProtocol(SSLProtocolVersion version)
953{
954	switch(version) {
955		case SSL_Version_2_0:           return kSSLProtocol2;
956		case SSL_Version_3_0:           return kSSLProtocol3;
957		case TLS_Version_1_0:           return kTLSProtocol1;
958		case TLS_Version_1_1:           return kTLSProtocol11;
959		case TLS_Version_1_2:           return kTLSProtocol12;
960		case DTLS_Version_1_0:          return kDTLSProtocol1;
961		default:
962			sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
963                        version);
964            /* DROPTHROUGH */
965		case SSL_Version_Undetermined:  return kSSLProtocolUnknown;
966	}
967}
968
969OSStatus
970SSLSetProtocolVersionMin  (SSLContextRef      ctx,
971                           SSLProtocol        minVersion)
972{
973    if(ctx == NULL) return errSecParam;
974
975    SSLProtocolVersion version = SSLProtocolToProtocolVersion(minVersion);
976    if (ctx->isDTLS) {
977        if (version > MINIMUM_DATAGRAM_VERSION ||
978            version < MAXIMUM_DATAGRAM_VERSION)
979            return errSSLIllegalParam;
980        if (version < ctx->maxProtocolVersion)
981            ctx->maxProtocolVersion = version;
982    } else {
983        if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
984            return errSSLIllegalParam;
985        if (version > ctx->maxProtocolVersion)
986            ctx->maxProtocolVersion = version;
987    }
988    ctx->minProtocolVersion = version;
989
990    return errSecSuccess;
991}
992
993OSStatus
994SSLGetProtocolVersionMin  (SSLContextRef      ctx,
995                           SSLProtocol        *minVersion)
996{
997    if(ctx == NULL) return errSecParam;
998
999    *minVersion = SSLProtocolVersionToProtocol(ctx->minProtocolVersion);
1000    return errSecSuccess;
1001}
1002
1003OSStatus
1004SSLSetProtocolVersionMax  (SSLContextRef      ctx,
1005                           SSLProtocol        maxVersion)
1006{
1007    if(ctx == NULL) return errSecParam;
1008
1009    SSLProtocolVersion version = SSLProtocolToProtocolVersion(maxVersion);
1010    if (ctx->isDTLS) {
1011        if (version > MINIMUM_DATAGRAM_VERSION ||
1012            version < MAXIMUM_DATAGRAM_VERSION)
1013            return errSSLIllegalParam;
1014        if (version > ctx->minProtocolVersion)
1015            ctx->minProtocolVersion = version;
1016    } else {
1017        if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
1018            return errSSLIllegalParam;
1019        if (version < ctx->minProtocolVersion)
1020            ctx->minProtocolVersion = version;
1021    }
1022    ctx->maxProtocolVersion = version;
1023
1024    return errSecSuccess;
1025}
1026
1027OSStatus
1028SSLGetProtocolVersionMax  (SSLContextRef      ctx,
1029                           SSLProtocol        *maxVersion)
1030{
1031    if(ctx == NULL) return errSecParam;
1032
1033    *maxVersion = SSLProtocolVersionToProtocol(ctx->maxProtocolVersion);
1034    return errSecSuccess;
1035}
1036
1037#define max(x,y) ((x)<(y)?(y):(x))
1038
1039OSStatus
1040SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
1041							 SSLProtocol		protocol,
1042							 Boolean			enable)
1043{
1044	if(ctx == NULL) {
1045		return errSecParam;
1046	}
1047	if(sslIsSessionActive(ctx) || ctx->isDTLS) {
1048		/* Can't do this with an active session, nor with a DTLS session */
1049		return errSecBadReq;
1050	}
1051    if (protocol == kSSLProtocolAll) {
1052        if (enable) {
1053            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1054            ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
1055        } else {
1056            ctx->minProtocolVersion = SSL_Version_Undetermined;
1057            ctx->maxProtocolVersion = SSL_Version_Undetermined;
1058        }
1059	} else {
1060		SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
1061        if (enable) {
1062			if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) {
1063				return errSecParam;
1064			}
1065            if (version > ctx->maxProtocolVersion) {
1066                ctx->maxProtocolVersion = version;
1067                if (ctx->minProtocolVersion == SSL_Version_Undetermined)
1068                    ctx->minProtocolVersion = version;
1069            }
1070            if (version < ctx->minProtocolVersion) {
1071                ctx->minProtocolVersion = version;
1072            }
1073        } else {
1074			if (version < SSL_Version_2_0 || version > MAXIMUM_STREAM_VERSION) {
1075				return errSecParam;
1076			}
1077			/* Disabling a protocol version now resets the minimum acceptable
1078			 * version to the next higher version. This means it's no longer
1079			 * possible to enable a discontiguous set of protocol versions.
1080			 */
1081			SSLProtocolVersion nextVersion;
1082			switch (version) {
1083				case SSL_Version_2_0:
1084					nextVersion = SSL_Version_3_0;
1085					break;
1086				case SSL_Version_3_0:
1087					nextVersion = TLS_Version_1_0;
1088					break;
1089				case TLS_Version_1_0:
1090					nextVersion = TLS_Version_1_1;
1091					break;
1092				case TLS_Version_1_1:
1093					nextVersion = TLS_Version_1_2;
1094					break;
1095				case TLS_Version_1_2:
1096				default:
1097					nextVersion = SSL_Version_Undetermined;
1098					break;
1099			}
1100			ctx->minProtocolVersion = max(ctx->minProtocolVersion, nextVersion);
1101			if (ctx->minProtocolVersion > ctx->maxProtocolVersion) {
1102				ctx->minProtocolVersion = SSL_Version_Undetermined;
1103				ctx->maxProtocolVersion = SSL_Version_Undetermined;
1104			}
1105        }
1106    }
1107
1108	return errSecSuccess;
1109}
1110
1111OSStatus
1112SSLGetProtocolVersionEnabled(SSLContextRef 		ctx,
1113							 SSLProtocol		protocol,
1114							 Boolean			*enable)		/* RETURNED */
1115{
1116	if(ctx == NULL) {
1117		return errSecParam;
1118	}
1119	if(ctx->isDTLS) {
1120		/* Can't do this with a DTLS session */
1121		return errSecBadReq;
1122	}
1123	switch(protocol) {
1124		case kSSLProtocol2:
1125		case kSSLProtocol3:
1126		case kTLSProtocol1:
1127        case kTLSProtocol11:
1128        case kTLSProtocol12:
1129        {
1130            SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
1131			*enable = (ctx->minProtocolVersion <= version
1132                       && ctx->maxProtocolVersion >= version);
1133			break;
1134        }
1135		case kSSLProtocolAll:
1136            *enable = (ctx->minProtocolVersion <= MINIMUM_STREAM_VERSION
1137                       && ctx->maxProtocolVersion >= MAXIMUM_STREAM_VERSION);
1138			break;
1139		default:
1140			return errSecParam;
1141	}
1142	return errSecSuccess;
1143}
1144
1145/* deprecated */
1146OSStatus
1147SSLSetProtocolVersion		(SSLContextRef 		ctx,
1148							 SSLProtocol		version)
1149{
1150	if(ctx == NULL) {
1151		return errSecParam;
1152	}
1153	if(sslIsSessionActive(ctx) || ctx->isDTLS) {
1154		/* Can't do this with an active session, nor with a DTLS session */
1155		return errSecBadReq;
1156	}
1157
1158	switch(version) {
1159		case kSSLProtocol3:
1160			/* this tells us to do our best, up to 3.0 */
1161            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1162            ctx->maxProtocolVersion = SSL_Version_3_0;
1163			break;
1164		case kSSLProtocol3Only:
1165            ctx->minProtocolVersion = SSL_Version_3_0;
1166            ctx->maxProtocolVersion = SSL_Version_3_0;
1167			break;
1168		case kTLSProtocol1:
1169			/* this tells us to do our best, up to TLS, but allows 3.0 */
1170            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1171            ctx->maxProtocolVersion = TLS_Version_1_0;
1172            break;
1173        case kTLSProtocol1Only:
1174            ctx->minProtocolVersion = TLS_Version_1_0;
1175            ctx->maxProtocolVersion = TLS_Version_1_0;
1176			break;
1177        case kTLSProtocol11:
1178			/* This tells us to do our best, up to TLS 1.1, currently also
1179               allows 3.0 or TLS 1.0 */
1180            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1181            ctx->maxProtocolVersion = TLS_Version_1_1;
1182			break;
1183        case kTLSProtocol12:
1184        case kSSLProtocolAll:
1185		case kSSLProtocolUnknown:
1186			/* This tells us to do our best, up to TLS 1.2, currently also
1187               allows 3.0 or TLS 1.0 or TLS 1.1 */
1188            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1189            ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
1190			break;
1191		default:
1192			return errSecParam;
1193	}
1194
1195    return errSecSuccess;
1196}
1197
1198/* deprecated */
1199OSStatus
1200SSLGetProtocolVersion		(SSLContextRef		ctx,
1201							 SSLProtocol		*protocol)		/* RETURNED */
1202{
1203	if(ctx == NULL) {
1204		return errSecParam;
1205	}
1206	/* translate array of booleans to public value; not all combinations
1207	 * are legal (i.e., meaningful) for this call */
1208    if (ctx->maxProtocolVersion == MAXIMUM_STREAM_VERSION) {
1209        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1210            /* traditional 'all enabled' */
1211            *protocol = kSSLProtocolAll;
1212            return errSecSuccess;
1213		}
1214	} else if (ctx->maxProtocolVersion == TLS_Version_1_1) {
1215        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1216            /* traditional 'all enabled' */
1217            *protocol = kTLSProtocol11;
1218            return errSecSuccess;
1219        }
1220	} else if (ctx->maxProtocolVersion == TLS_Version_1_0) {
1221        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1222            /* TLS1.1 and below enabled */
1223            *protocol = kTLSProtocol1;
1224            return errSecSuccess;
1225        } else if(ctx->minProtocolVersion == TLS_Version_1_0) {
1226        	*protocol = kTLSProtocol1Only;
1227		}
1228	} else if(ctx->maxProtocolVersion == SSL_Version_3_0) {
1229        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1230            /* Could also return kSSLProtocol3Only since
1231               MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1232            *protocol = kSSLProtocol3;
1233			return errSecSuccess;
1234		}
1235	}
1236
1237    return errSecParam;
1238}
1239
1240OSStatus
1241SSLGetNegotiatedProtocolVersion		(SSLContextRef		ctx,
1242									 SSLProtocol		*protocol) /* RETURNED */
1243{
1244	if(ctx == NULL) {
1245		return errSecParam;
1246	}
1247	*protocol = SSLProtocolVersionToProtocol(ctx->negProtocolVersion);
1248	return errSecSuccess;
1249}
1250
1251OSStatus
1252SSLSetEnableCertVerify		(SSLContextRef		ctx,
1253							 Boolean			enableVerify)
1254{
1255	if(ctx == NULL) {
1256		return errSecParam;
1257	}
1258	sslCertDebug("SSLSetEnableCertVerify %s",
1259		enableVerify ? "true" : "false");
1260	if(sslIsSessionActive(ctx)) {
1261		/* can't do this with an active session */
1262		return errSecBadReq;
1263	}
1264	ctx->enableCertVerify = enableVerify;
1265	return errSecSuccess;
1266}
1267
1268OSStatus
1269SSLGetEnableCertVerify		(SSLContextRef		ctx,
1270							Boolean				*enableVerify)
1271{
1272	if(ctx == NULL) {
1273		return errSecParam;
1274	}
1275	*enableVerify = ctx->enableCertVerify;
1276	return errSecSuccess;
1277}
1278
1279OSStatus
1280SSLSetAllowsExpiredCerts(SSLContextRef		ctx,
1281						 Boolean			allowExpired)
1282{
1283	if(ctx == NULL) {
1284		return errSecParam;
1285	}
1286	sslCertDebug("SSLSetAllowsExpiredCerts %s",
1287		allowExpired ? "true" : "false");
1288	if(sslIsSessionActive(ctx)) {
1289		/* can't do this with an active session */
1290		return errSecBadReq;
1291	}
1292	ctx->allowExpiredCerts = allowExpired;
1293	return errSecSuccess;
1294}
1295
1296OSStatus
1297SSLGetAllowsExpiredCerts	(SSLContextRef		ctx,
1298							 Boolean			*allowExpired)
1299{
1300	if(ctx == NULL) {
1301		return errSecParam;
1302	}
1303	*allowExpired = ctx->allowExpiredCerts;
1304	return errSecSuccess;
1305}
1306
1307OSStatus
1308SSLSetAllowsExpiredRoots(SSLContextRef		ctx,
1309						 Boolean			allowExpired)
1310{
1311	if(ctx == NULL) {
1312		return errSecParam;
1313	}
1314	sslCertDebug("SSLSetAllowsExpiredRoots %s",
1315		allowExpired ? "true" : "false");
1316	if(sslIsSessionActive(ctx)) {
1317		/* can't do this with an active session */
1318		return errSecBadReq;
1319	}
1320	ctx->allowExpiredRoots = allowExpired;
1321	return errSecSuccess;
1322}
1323
1324OSStatus
1325SSLGetAllowsExpiredRoots	(SSLContextRef		ctx,
1326							 Boolean			*allowExpired)
1327{
1328	if(ctx == NULL) {
1329		return errSecParam;
1330	}
1331	*allowExpired = ctx->allowExpiredRoots;
1332	return errSecSuccess;
1333}
1334
1335OSStatus SSLSetAllowsAnyRoot(
1336	SSLContextRef	ctx,
1337	Boolean			anyRoot)
1338{
1339	if(ctx == NULL) {
1340		return errSecParam;
1341	}
1342	sslCertDebug("SSLSetAllowsAnyRoot %s",	anyRoot ? "true" : "false");
1343	ctx->allowAnyRoot = anyRoot;
1344	return errSecSuccess;
1345}
1346
1347OSStatus
1348SSLGetAllowsAnyRoot(
1349	SSLContextRef	ctx,
1350	Boolean			*anyRoot)
1351{
1352	if(ctx == NULL) {
1353		return errSecParam;
1354	}
1355	*anyRoot = ctx->allowAnyRoot;
1356	return errSecSuccess;
1357}
1358
1359#if !TARGET_OS_IPHONE
1360/* obtain the system roots sets for this app, policy SSL */
1361static OSStatus sslDefaultSystemRoots(
1362	SSLContextRef ctx,
1363	CFArrayRef *systemRoots)				// created and RETURNED
1364
1365{
1366	return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL,
1367		ctx->peerDomainName,
1368		(uint32_t)ctx->peerDomainNameLen,
1369		(ctx->protocolSide == kSSLServerSide) ?
1370			/* server verifies, client encrypts */
1371			CSSM_KEYUSE_VERIFY : CSSM_KEYUSE_ENCRYPT,
1372		systemRoots);
1373}
1374#endif /* OS X only */
1375
1376OSStatus
1377SSLSetTrustedRoots			(SSLContextRef 		ctx,
1378							 CFArrayRef 		trustedRoots,
1379							 Boolean 			replaceExisting)
1380{
1381#ifdef USE_CDSA_CRYPTO
1382	if(ctx == NULL) {
1383		return errSecParam;
1384	}
1385	if(sslIsSessionActive(ctx)) {
1386		/* can't do this with an active session */
1387		return errSecBadReq;
1388	}
1389
1390	if(replaceExisting) {
1391		/* trivial case - retain the new, throw out the old.  */
1392		if (trustedRoots)
1393            CFRetain(trustedRoots);
1394        CFReleaseSafe(ctx->trustedCerts);
1395		ctx->trustedCerts = trustedRoots;
1396		return errSecSuccess;
1397	}
1398
1399	/* adding new trusted roots - to either our existing set, or the system set */
1400	CFArrayRef existingRoots = NULL;
1401	OSStatus ortn;
1402	if(ctx->trustedCerts != NULL) {
1403		/* we'll release these as we exit */
1404		existingRoots = ctx->trustedCerts;
1405	}
1406	else {
1407		/* get system set for this app, policy SSL */
1408		ortn = sslDefaultSystemRoots(ctx, &existingRoots);
1409		if(ortn) {
1410            CFReleaseSafe(existingRoots);
1411			return ortn;
1412		}
1413	}
1414
1415	/* Create a new root array with caller's roots first */
1416	CFMutableArrayRef newRoots = CFArrayCreateMutableCopy(NULL, 0, trustedRoots);
1417	CFRange existRange = { 0, CFArrayGetCount(existingRoots) };
1418	CFArrayAppendArray(newRoots, existingRoots, existRange);
1419	CFRelease(existingRoots);
1420	ctx->trustedCerts = newRoots;
1421	return errSecSuccess;
1422
1423#else
1424	if (sslIsSessionActive(ctx)) {
1425		/* can't do this with an active session */
1426		return errSecBadReq;
1427	}
1428	sslCertDebug("SSLSetTrustedRoot  numCerts %d  replaceExist %s",
1429		(int)CFArrayGetCount(trustedRoots), replaceExisting ? "true" : "false");
1430
1431    if (replaceExisting) {
1432        ctx->trustedCertsOnly = true;
1433        CFReleaseNull(ctx->trustedCerts);
1434    }
1435
1436    if (ctx->trustedCerts) {
1437        CFIndex count = CFArrayGetCount(trustedRoots);
1438        CFRange range = { 0, count };
1439        CFArrayAppendArray(ctx->trustedCerts, trustedRoots, range);
1440    } else {
1441        require(ctx->trustedCerts =
1442            CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, trustedRoots),
1443            errOut);
1444    }
1445
1446    return errSecSuccess;
1447
1448errOut:
1449    return errSecAllocate;
1450#endif /* !USE_CDSA_CRYPTO */
1451}
1452
1453OSStatus
1454SSLCopyTrustedRoots			(SSLContextRef 		ctx,
1455							 CFArrayRef 		*trustedRoots)	/* RETURNED */
1456{
1457	if(ctx == NULL || trustedRoots == NULL) {
1458		return errSecParam;
1459	}
1460	if(ctx->trustedCerts != NULL) {
1461		*trustedRoots = ctx->trustedCerts;
1462		CFRetain(ctx->trustedCerts);
1463		return errSecSuccess;
1464	}
1465#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1466	/* use default system roots */
1467    return sslDefaultSystemRoots(ctx, trustedRoots);
1468#else
1469    *trustedRoots = NULL;
1470    return errSecSuccess;
1471#endif
1472}
1473
1474OSStatus
1475SSLSetTrustedLeafCertificates	(SSLContextRef 		ctx,
1476								 CFArrayRef 		trustedCerts)
1477{
1478	if(ctx == NULL) {
1479		return errSecParam;
1480	}
1481	if(sslIsSessionActive(ctx)) {
1482		/* can't do this with an active session */
1483		return errSecBadReq;
1484	}
1485
1486	if(ctx->trustedLeafCerts) {
1487		CFRelease(ctx->trustedLeafCerts);
1488	}
1489	ctx->trustedLeafCerts = trustedCerts;
1490	CFRetain(trustedCerts);
1491	return errSecSuccess;
1492}
1493
1494OSStatus
1495SSLCopyTrustedLeafCertificates	(SSLContextRef 		ctx,
1496								 CFArrayRef 		*trustedCerts)	/* RETURNED */
1497{
1498	if(ctx == NULL) {
1499		return errSecParam;
1500	}
1501	if(ctx->trustedLeafCerts != NULL) {
1502		*trustedCerts = ctx->trustedLeafCerts;
1503		CFRetain(ctx->trustedCerts);
1504		return errSecSuccess;
1505	}
1506	*trustedCerts = NULL;
1507	return errSecSuccess;
1508}
1509
1510OSStatus
1511SSLSetClientSideAuthenticate 	(SSLContext			*ctx,
1512								 SSLAuthenticate	auth)
1513{
1514	if(ctx == NULL) {
1515		return errSecParam;
1516	}
1517	if(sslIsSessionActive(ctx)) {
1518		/* can't do this with an active session */
1519		return errSecBadReq;
1520	}
1521	ctx->clientAuth = auth;
1522	switch(auth) {
1523		case kNeverAuthenticate:
1524			ctx->tryClientAuth = false;
1525			break;
1526		case kAlwaysAuthenticate:
1527		case kTryAuthenticate:
1528			ctx->tryClientAuth = true;
1529			break;
1530	}
1531	return errSecSuccess;
1532}
1533
1534OSStatus
1535SSLGetClientSideAuthenticate 	(SSLContext			*ctx,
1536								 SSLAuthenticate	*auth)	/* RETURNED */
1537{
1538	if(ctx == NULL || auth == NULL) {
1539		return errSecParam;
1540	}
1541	*auth = ctx->clientAuth;
1542	return errSecSuccess;
1543}
1544
1545OSStatus
1546SSLGetClientCertificateState	(SSLContextRef				ctx,
1547								 SSLClientCertificateState	*clientState)
1548{
1549	if(ctx == NULL) {
1550		return errSecParam;
1551	}
1552	*clientState = ctx->clientCertState;
1553	return errSecSuccess;
1554}
1555
1556OSStatus
1557SSLSetCertificate			(SSLContextRef		ctx,
1558							 CFArrayRef			certRefs)
1559{
1560	/*
1561	 * -- free localCerts if we have any
1562	 * -- Get raw cert data, convert to ctx->localCert
1563	 * -- get pub, priv keys from certRef[0]
1564	 * -- validate cert chain
1565	 */
1566	if(ctx == NULL) {
1567		return errSecParam;
1568	}
1569
1570	/* can't do this with an active session */
1571	if(sslIsSessionActive(ctx) &&
1572	   /* kSSLClientCertRequested implies client side */
1573	   (ctx->clientCertState != kSSLClientCertRequested))
1574	{
1575			return errSecBadReq;
1576	}
1577    CFReleaseNull(ctx->localCertArray);
1578	/* changing the client cert invalidates negotiated auth type */
1579	ctx->negAuthType = SSLClientAuthNone;
1580	if(certRefs == NULL) {
1581		return errSecSuccess; // we have cleared the cert, as requested
1582	}
1583	OSStatus ortn = parseIncomingCerts(ctx,
1584		certRefs,
1585		&ctx->localCert,
1586		&ctx->signingPubKey,
1587		&ctx->signingPrivKeyRef,
1588		&ctx->ourSignerAlg);
1589	if(ortn == errSecSuccess) {
1590		ctx->localCertArray = certRefs;
1591		CFRetain(certRefs);
1592		/* client cert was changed, must update auth type */
1593		ortn = SSLUpdateNegotiatedClientAuthType(ctx);
1594	}
1595	return ortn;
1596}
1597
1598OSStatus
1599SSLSetEncryptionCertificate	(SSLContextRef		ctx,
1600							 CFArrayRef			certRefs)
1601{
1602	/*
1603	 * -- free encryptCert if we have any
1604	 * -- Get raw cert data, convert to ctx->encryptCert
1605	 * -- get pub, priv keys from certRef[0]
1606	 * -- validate cert chain
1607	 */
1608	if(ctx == NULL) {
1609		return errSecParam;
1610	}
1611	if(sslIsSessionActive(ctx)) {
1612		/* can't do this with an active session */
1613		return errSecBadReq;
1614	}
1615    CFReleaseNull(ctx->encryptCertArray);
1616	OSStatus ortn = parseIncomingCerts(ctx,
1617		certRefs,
1618		&ctx->encryptCert,
1619		&ctx->encryptPubKey,
1620		&ctx->encryptPrivKeyRef,
1621		NULL);			/* Signer alg */
1622	if(ortn == errSecSuccess) {
1623		ctx->encryptCertArray = certRefs;
1624		CFRetain(certRefs);
1625	}
1626	return ortn;
1627}
1628
1629OSStatus SSLGetCertificate(SSLContextRef		ctx,
1630						   CFArrayRef			*certRefs)
1631{
1632	if(ctx == NULL) {
1633		return errSecParam;
1634	}
1635	*certRefs = ctx->localCertArray;
1636	return errSecSuccess;
1637}
1638
1639OSStatus SSLGetEncryptionCertificate(SSLContextRef		ctx,
1640								     CFArrayRef			*certRefs)
1641{
1642	if(ctx == NULL) {
1643		return errSecParam;
1644	}
1645	*certRefs = ctx->encryptCertArray;
1646	return errSecSuccess;
1647}
1648
1649OSStatus
1650SSLSetPeerID				(SSLContext 		*ctx,
1651							 const void 		*peerID,
1652							 size_t				peerIDLen)
1653{
1654	OSStatus serr;
1655
1656	/* copy peerId to context->peerId */
1657	if((ctx == NULL) ||
1658	   (peerID == NULL) ||
1659	   (peerIDLen == 0)) {
1660		return errSecParam;
1661	}
1662	if(sslIsSessionActive(ctx) &&
1663        /* kSSLClientCertRequested implies client side */
1664        (ctx->clientCertState != kSSLClientCertRequested))
1665    {
1666		return errSecBadReq;
1667	}
1668	SSLFreeBuffer(&ctx->peerID);
1669	serr = SSLAllocBuffer(&ctx->peerID, peerIDLen);
1670	if(serr) {
1671		return serr;
1672	}
1673	memmove(ctx->peerID.data, peerID, peerIDLen);
1674	return errSecSuccess;
1675}
1676
1677OSStatus
1678SSLGetPeerID				(SSLContextRef 		ctx,
1679							 const void 		**peerID,
1680							 size_t				*peerIDLen)
1681{
1682	*peerID = ctx->peerID.data;			// may be NULL
1683	*peerIDLen = ctx->peerID.length;
1684	return errSecSuccess;
1685}
1686
1687OSStatus
1688SSLGetNegotiatedCipher		(SSLContextRef 		ctx,
1689							 SSLCipherSuite 	*cipherSuite)
1690{
1691	if(ctx == NULL) {
1692		return errSecParam;
1693	}
1694	if(!sslIsSessionActive(ctx)) {
1695		return errSecBadReq;
1696	}
1697	*cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
1698	return errSecSuccess;
1699}
1700
1701/*
1702 * Add an acceptable distinguished name (client authentication only).
1703 */
1704OSStatus
1705SSLAddDistinguishedName(
1706	SSLContextRef ctx,
1707	const void *derDN,
1708	size_t derDNLen)
1709{
1710    DNListElem      *dn;
1711    OSStatus        err;
1712
1713	if(ctx == NULL) {
1714		return errSecParam;
1715	}
1716	if(sslIsSessionActive(ctx)) {
1717		return errSecBadReq;
1718	}
1719
1720	dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
1721	if(dn == NULL) {
1722		return errSecAllocate;
1723	}
1724    if ((err = SSLAllocBuffer(&dn->derDN, derDNLen)))
1725        return err;
1726    memcpy(dn->derDN.data, derDN, derDNLen);
1727    dn->next = ctx->acceptableDNList;
1728    ctx->acceptableDNList = dn;
1729    return errSecSuccess;
1730}
1731
1732/* single-cert version of SSLSetCertificateAuthorities() */
1733static OSStatus
1734sslAddCA(SSLContextRef		ctx,
1735		 SecCertificateRef	cert)
1736{
1737	OSStatus ortn = errSecParam;
1738
1739    /* Get subject from certificate. */
1740#if TARGET_OS_IPHONE
1741    CFDataRef subjectName = NULL;
1742    subjectName = SecCertificateCopySubjectSequence(cert);
1743    require(subjectName, errOut);
1744#else
1745    CSSM_DATA_PTR subjectName = NULL;
1746    ortn = SecCertificateCopyFirstFieldValue(cert, &CSSMOID_X509V1SubjectNameStd, &subjectName);
1747    require_noerr(ortn, errOut);
1748#endif
1749
1750	/* add to acceptableCAs as cert, creating array if necessary */
1751	if(ctx->acceptableCAs == NULL) {
1752		require(ctx->acceptableCAs = CFArrayCreateMutable(NULL, 0,
1753            &kCFTypeArrayCallBacks), errOut);
1754		if(ctx->acceptableCAs == NULL) {
1755			return errSecAllocate;
1756		}
1757	}
1758	CFArrayAppendValue(ctx->acceptableCAs, cert);
1759
1760	/* then add this cert's subject name to acceptableDNList */
1761#if TARGET_OS_IPHONE
1762	ortn = SSLAddDistinguishedName(ctx,
1763                                   CFDataGetBytePtr(subjectName),
1764                                   CFDataGetLength(subjectName));
1765#else
1766    ortn = SSLAddDistinguishedName(ctx, subjectName->Data, subjectName->Length);
1767#endif
1768
1769errOut:
1770#if TARGET_OS_IPHONE
1771    CFReleaseSafe(subjectName);
1772#endif
1773	return ortn;
1774}
1775
1776/*
1777 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1778 * of acceptable Certificate Authorities (CAs) to present to the client
1779 * when client authentication is performed.
1780 */
1781OSStatus
1782SSLSetCertificateAuthorities(SSLContextRef		ctx,
1783							 CFTypeRef			certificateOrArray,
1784							 Boolean 			replaceExisting)
1785{
1786	CFTypeID itemType;
1787	OSStatus ortn = errSecSuccess;
1788
1789	if((ctx == NULL) || sslIsSessionActive(ctx) ||
1790	   (ctx->protocolSide != kSSLServerSide)) {
1791		return errSecParam;
1792	}
1793	if(replaceExisting) {
1794		sslFreeDnList(ctx);
1795		if(ctx->acceptableCAs) {
1796			CFRelease(ctx->acceptableCAs);
1797			ctx->acceptableCAs = NULL;
1798		}
1799	}
1800	/* else appending */
1801
1802	itemType = CFGetTypeID(certificateOrArray);
1803	if(itemType == SecCertificateGetTypeID()) {
1804		/* one cert */
1805		ortn = sslAddCA(ctx, (SecCertificateRef)certificateOrArray);
1806	}
1807	else if(itemType == CFArrayGetTypeID()) {
1808		CFArrayRef cfa = (CFArrayRef)certificateOrArray;
1809		CFIndex numCerts = CFArrayGetCount(cfa);
1810		CFIndex dex;
1811
1812		/* array of certs */
1813		for(dex=0; dex<numCerts; dex++) {
1814			SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(cfa, dex);
1815			if(CFGetTypeID(cert) != SecCertificateGetTypeID()) {
1816				return errSecParam;
1817			}
1818			ortn = sslAddCA(ctx, cert);
1819			if(ortn) {
1820				break;
1821			}
1822		}
1823	}
1824	else {
1825		ortn = errSecParam;
1826	}
1827	return ortn;
1828}
1829
1830
1831/*
1832 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1833 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1834 * been called.
1835 * Caller must CFRelease the returned array.
1836 */
1837OSStatus
1838SSLCopyCertificateAuthorities(SSLContextRef		ctx,
1839							  CFArrayRef		*certificates)	/* RETURNED */
1840{
1841	if((ctx == NULL) || (certificates == NULL)) {
1842		return errSecParam;
1843	}
1844	if(ctx->acceptableCAs == NULL) {
1845		*certificates = NULL;
1846		return errSecSuccess;
1847	}
1848	*certificates = ctx->acceptableCAs;
1849	CFRetain(ctx->acceptableCAs);
1850	return errSecSuccess;
1851}
1852
1853
1854/*
1855 * Obtain the list of acceptable distinguished names as provided by
1856 * a server (if the SSLCotextRef is configured as a client), or as
1857 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1858 * is configured as a server).
1859  */
1860OSStatus
1861SSLCopyDistinguishedNames	(SSLContextRef		ctx,
1862							 CFArrayRef			*names)
1863{
1864	CFMutableArrayRef outArray = NULL;
1865	DNListElem *dn;
1866
1867	if((ctx == NULL) || (names == NULL)) {
1868		return errSecParam;
1869	}
1870	if(ctx->acceptableDNList == NULL) {
1871		*names = NULL;
1872		return errSecSuccess;
1873	}
1874	outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1875	dn = ctx->acceptableDNList;
1876	while (dn) {
1877		CFDataRef cfDn = CFDataCreate(NULL, dn->derDN.data, dn->derDN.length);
1878		CFArrayAppendValue(outArray, cfDn);
1879		CFRelease(cfDn);
1880		dn = dn->next;
1881	}
1882	*names = outArray;
1883	return errSecSuccess;
1884}
1885
1886
1887/*
1888 * Request peer certificates. Valid anytime, subsequent to
1889 * a handshake attempt.
1890 * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
1891 * TODO: the 'legacy' argument is not used anymore.
1892 */
1893static OSStatus
1894sslCopyPeerCertificates		(SSLContextRef 		ctx,
1895							 CFArrayRef			*certs,
1896							 Boolean			legacy)
1897{
1898	if(ctx == NULL) {
1899		return errSecParam;
1900	}
1901
1902#ifdef USE_SSLCERTIFICATE
1903	uint32 				numCerts;
1904	CFMutableArrayRef	ca;
1905	CFIndex				i;
1906	SecCertificateRef	cfd;
1907	OSStatus			ortn;
1908	CSSM_DATA			certData;
1909	SSLCertificate		*scert;
1910
1911	*certs = NULL;
1912
1913	/*
1914	 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
1915	 * CFDataRefs, each of which is one DER-encoded cert.
1916	 */
1917	numCerts = SSLGetCertificateChainLength(ctx->peerCert);
1918	if(numCerts == 0) {
1919		return errSecSuccess;
1920	}
1921	ca = CFArrayCreateMutable(kCFAllocatorDefault,
1922		(CFIndex)numCerts, &kCFTypeArrayCallBacks);
1923	if(ca == NULL) {
1924		return errSecAllocate;
1925	}
1926
1927	/*
1928	 * Caller gets leaf cert first, the opposite of the way we store them.
1929	 */
1930	scert = ctx->peerCert;
1931	for(i=0; (unsigned)i<numCerts; i++) {
1932		assert(scert != NULL);		/* else SSLGetCertificateChainLength
1933									 * broken */
1934		SSLBUF_TO_CSSM(&scert->derCert, &certData);
1935		ortn = SecCertificateCreateFromData(&certData,
1936			CSSM_CERT_X_509v3,
1937			CSSM_CERT_ENCODING_DER,
1938			&cfd);
1939		if(ortn) {
1940			CFRelease(ca);
1941			return ortn;
1942		}
1943		/* insert at head of array */
1944		CFArrayInsertValueAtIndex(ca, 0, cfd);
1945		if(!legacy) {
1946			/* skip for legacy SSLGetPeerCertificates() */
1947			CFRelease(cfd);
1948		}
1949		scert = scert->next;
1950	}
1951	*certs = ca;
1952
1953#else
1954	if (!ctx->peerCert) {
1955		*certs = NULL;
1956		return errSecBadReq;
1957	}
1958
1959    CFArrayRef ca = CFArrayCreateCopy(kCFAllocatorDefault, ctx->peerCert);
1960    *certs = ca;
1961    if (ca == NULL) {
1962        return errSecAllocate;
1963    }
1964
1965	if (legacy) {
1966		CFIndex ix, count = CFArrayGetCount(ca);
1967		for (ix = 0; ix < count; ++ix) {
1968			CFRetain(CFArrayGetValueAtIndex(ca, ix));
1969		}
1970	}
1971#endif
1972
1973	return errSecSuccess;
1974}
1975
1976OSStatus
1977SSLCopyPeerCertificates		(SSLContextRef 		ctx,
1978							 CFArrayRef			*certs)
1979{
1980	return sslCopyPeerCertificates(ctx, certs, false);
1981}
1982
1983#if !TARGET_OS_IPHONE
1984// Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
1985// <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
1986OSStatus
1987SSLGetPeerCertificates (SSLContextRef ctx,
1988                        CFArrayRef *certs);
1989OSStatus
1990SSLGetPeerCertificates (SSLContextRef ctx,
1991                        CFArrayRef *certs)
1992{
1993    return sslCopyPeerCertificates(ctx, certs, true);
1994}
1995#endif
1996
1997/*
1998 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1999 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
2000 * been called, a set of process-wide parameters will be calculated. However
2001 * that can take a long time (30 seconds).
2002 */
2003OSStatus SSLSetDiffieHellmanParams(
2004	SSLContextRef	ctx,
2005	const void 		*dhParams,
2006	size_t			dhParamsLen)
2007{
2008#if APPLE_DH
2009	if(ctx == NULL) {
2010		return errSecParam;
2011	}
2012	if(sslIsSessionActive(ctx)) {
2013		return errSecBadReq;
2014	}
2015	SSLFreeBuffer(&ctx->dhParamsEncoded);
2016#if !USE_CDSA_CRYPTO
2017    if (ctx->secDHContext)
2018        SecDHDestroy(ctx->secDHContext);
2019#endif
2020
2021	OSStatus ortn;
2022	ortn = SSLCopyBufferFromData(dhParams, dhParamsLen,
2023		&ctx->dhParamsEncoded);
2024
2025    return ortn;
2026
2027#endif /* APPLE_DH */
2028}
2029
2030/*
2031 * Return parameter block specified in SSLSetDiffieHellmanParams.
2032 * Returned data is not copied and belongs to the SSLContextRef.
2033 */
2034OSStatus SSLGetDiffieHellmanParams(
2035	SSLContextRef	ctx,
2036	const void 		**dhParams,
2037	size_t			*dhParamsLen)
2038{
2039#if APPLE_DH
2040	if(ctx == NULL) {
2041		return errSecParam;
2042	}
2043	*dhParams = ctx->dhParamsEncoded.data;
2044	*dhParamsLen = ctx->dhParamsEncoded.length;
2045	return errSecSuccess;
2046#else
2047    return errSecUnimplemented;
2048#endif /* APPLE_DH */
2049}
2050
2051OSStatus SSLSetRsaBlinding(
2052	SSLContextRef	ctx,
2053	Boolean			blinding)
2054{
2055	if(ctx == NULL) {
2056		return errSecParam;
2057	}
2058	ctx->rsaBlindingEnable = blinding;
2059	return errSecSuccess;
2060}
2061
2062OSStatus SSLGetRsaBlinding(
2063	SSLContextRef	ctx,
2064	Boolean			*blinding)
2065{
2066	if(ctx == NULL) {
2067		return errSecParam;
2068	}
2069	*blinding = ctx->rsaBlindingEnable;
2070	return errSecSuccess;
2071}
2072
2073OSStatus
2074SSLCopyPeerTrust(
2075    SSLContextRef 		ctx,
2076    SecTrustRef        *trust)	/* RETURNED */
2077{
2078	OSStatus status = errSecSuccess;
2079	if (ctx == NULL || trust == NULL)
2080		return errSecParam;
2081
2082	/* Create a SecTrustRef if this was a resumed session and we
2083	   didn't have one yet. */
2084	if (!ctx->peerSecTrust && ctx->peerCert) {
2085		status = sslCreateSecTrust(ctx, ctx->peerCert, true,
2086			&ctx->peerSecTrust);
2087    }
2088
2089	*trust = ctx->peerSecTrust;
2090    if (ctx->peerSecTrust)
2091        CFRetain(ctx->peerSecTrust);
2092
2093	return status;
2094}
2095
2096OSStatus SSLGetPeerSecTrust(
2097	SSLContextRef	ctx,
2098	SecTrustRef		*trust)	/* RETURNED */
2099{
2100    OSStatus status = errSecSuccess;
2101	if (ctx == NULL || trust == NULL)
2102		return errSecParam;
2103
2104	/* Create a SecTrustRef if this was a resumed session and we
2105	   didn't have one yet. */
2106	if (!ctx->peerSecTrust && ctx->peerCert) {
2107		status = sslCreateSecTrust(ctx, ctx->peerCert, true,
2108			&ctx->peerSecTrust);
2109    }
2110
2111	*trust = ctx->peerSecTrust;
2112	return status;
2113}
2114
2115OSStatus SSLInternalMasterSecret(
2116   SSLContextRef ctx,
2117   void *secret,        // mallocd by caller, SSL_MASTER_SECRET_SIZE
2118   size_t *secretSize)  // in/out
2119{
2120	if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
2121		return errSecParam;
2122	}
2123	if(*secretSize < SSL_MASTER_SECRET_SIZE) {
2124		return errSecParam;
2125	}
2126	memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
2127	*secretSize = SSL_MASTER_SECRET_SIZE;
2128	return errSecSuccess;
2129}
2130
2131OSStatus SSLInternalServerRandom(
2132   SSLContextRef ctx,
2133   void *randBuf, 			// mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2134   size_t *randSize)	// in/out
2135{
2136	if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
2137		return errSecParam;
2138	}
2139	if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
2140		return errSecParam;
2141	}
2142	memmove(randBuf, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
2143	*randSize = SSL_CLIENT_SRVR_RAND_SIZE;
2144	return errSecSuccess;
2145}
2146
2147OSStatus SSLInternalClientRandom(
2148   SSLContextRef ctx,
2149   void *randBuf,  		// mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2150   size_t *randSize)	// in/out
2151{
2152	if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
2153		return errSecParam;
2154	}
2155	if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
2156		return errSecParam;
2157	}
2158	memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
2159	*randSize = SSL_CLIENT_SRVR_RAND_SIZE;
2160	return errSecSuccess;
2161}
2162
2163/* This is used by EAP 802.1x */
2164OSStatus SSLGetCipherSizes(
2165	SSLContextRef ctx,
2166	size_t *digestSize,
2167	size_t *symmetricKeySize,
2168	size_t *ivSize)
2169{
2170	const SSLCipherSpecParams *currCipher;
2171
2172	if((ctx == NULL) || (digestSize == NULL) ||
2173	   (symmetricKeySize == NULL) || (ivSize == NULL)) {
2174		return errSecParam;
2175	}
2176	currCipher = &ctx->selectedCipherSpecParams;
2177	*digestSize = currCipher->macSize;
2178	*symmetricKeySize = currCipher->keySize;
2179	*ivSize = currCipher->ivSize;
2180	return errSecSuccess;
2181}
2182
2183OSStatus
2184SSLGetResumableSessionInfo(
2185	SSLContextRef	ctx,
2186	Boolean			*sessionWasResumed,		// RETURNED
2187	void			*sessionID,				// RETURNED, mallocd by caller
2188	size_t			*sessionIDLength)		// IN/OUT
2189{
2190	if((ctx == NULL) || (sessionWasResumed == NULL) ||
2191	   (sessionID == NULL) || (sessionIDLength == NULL) ||
2192	   (*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
2193		return errSecParam;
2194	}
2195	if(ctx->sessionMatch) {
2196		*sessionWasResumed = true;
2197		if(ctx->sessionID.length > *sessionIDLength) {
2198			/* really should never happen - means ID > 32 */
2199			return errSecParam;
2200		}
2201		if(ctx->sessionID.length) {
2202			/*
2203 			 * Note PAC-based session resumption can result in sessionMatch
2204			 * with no sessionID
2205			 */
2206			memmove(sessionID, ctx->sessionID.data, ctx->sessionID.length);
2207		}
2208		*sessionIDLength = ctx->sessionID.length;
2209	}
2210	else {
2211		*sessionWasResumed = false;
2212		*sessionIDLength = 0;
2213	}
2214	return errSecSuccess;
2215}
2216
2217/*
2218 * Get/set enable of anonymous ciphers. Default is enabled.
2219 */
2220OSStatus
2221SSLSetAllowAnonymousCiphers(
2222	SSLContextRef	ctx,
2223	Boolean			enable)
2224{
2225	if(ctx == NULL) {
2226		return errSecParam;
2227	}
2228	if(sslIsSessionActive(ctx)) {
2229		return errSecBadReq;
2230	}
2231	if(ctx->validCipherSuites != NULL) {
2232		/* SSLSetEnabledCiphers() has already been called */
2233		return errSecBadReq;
2234	}
2235	ctx->anonCipherEnable = enable;
2236	return errSecSuccess;
2237}
2238
2239OSStatus
2240SSLGetAllowAnonymousCiphers(
2241	SSLContextRef	ctx,
2242	Boolean			*enable)
2243{
2244	if((ctx == NULL) || (enable == NULL)) {
2245		return errSecParam;
2246	}
2247	if(sslIsSessionActive(ctx)) {
2248		return errSecBadReq;
2249	}
2250	*enable = ctx->anonCipherEnable;
2251	return errSecSuccess;
2252}
2253
2254/*
2255 * Override the default session cache timeout for a cache entry created for
2256 * the current session.
2257 */
2258OSStatus
2259SSLSetSessionCacheTimeout(
2260	SSLContextRef ctx,
2261	uint32_t timeoutInSeconds)
2262{
2263	if(ctx == NULL) {
2264		return errSecParam;
2265	}
2266	ctx->sessionCacheTimeout = timeoutInSeconds;
2267	return errSecSuccess;
2268}
2269
2270/*
2271 * Register a callback for obtaining the master_secret when performing
2272 * PAC-based session resumption.
2273 */
2274OSStatus
2275SSLInternalSetMasterSecretFunction(
2276	SSLContextRef ctx,
2277	SSLInternalMasterSecretFunction mFunc,
2278	const void *arg)		/* opaque to SecureTransport; app-specific */
2279{
2280	if(ctx == NULL) {
2281		return errSecParam;
2282	}
2283	ctx->masterSecretCallback = mFunc;
2284	ctx->masterSecretArg = arg;
2285	return errSecSuccess;
2286}
2287
2288/*
2289 * Provide an opaque SessionTicket for use in PAC-based session
2290 * resumption. Client side only. The provided ticket is sent in
2291 * the ClientHello message as a SessionTicket extension.
2292 *
2293 * We won't reject this on the server side, but server-side support
2294 * for PAC-based session resumption is currently enabled for
2295 * Development builds only. To fully support this for server side,
2296 * besides the rudimentary support that's here for Development builds,
2297 * we'd need a getter for the session ticket, so the app code can
2298 * access the SessionTicket when its SSLInternalMasterSecretFunction
2299 * callback is called.
2300 */
2301OSStatus SSLInternalSetSessionTicket(
2302   SSLContextRef ctx,
2303   const void *ticket,
2304   size_t ticketLength)
2305{
2306	if(ctx == NULL) {
2307		return errSecParam;
2308	}
2309	if(sslIsSessionActive(ctx)) {
2310		/* can't do this with an active session */
2311		return errSecBadReq;
2312	}
2313	if(ticketLength > 0xffff) {
2314		/* extension data encoded with a 2-byte length! */
2315		return errSecParam;
2316	}
2317	SSLFreeBuffer(&ctx->sessionTicket);
2318	return SSLCopyBufferFromData(ticket, ticketLength, &ctx->sessionTicket);
2319}
2320
2321/*
2322 * ECDSA curve accessors.
2323 */
2324
2325/*
2326 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2327 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2328 */
2329OSStatus SSLGetNegotiatedCurve(
2330   SSLContextRef ctx,
2331   SSL_ECDSA_NamedCurve *namedCurve)    /* RETURNED */
2332{
2333	if((ctx == NULL) || (namedCurve == NULL)) {
2334		return errSecParam;
2335	}
2336	if(ctx->ecdhPeerCurve == SSL_Curve_None) {
2337		return errSecParam;
2338	}
2339	*namedCurve = ctx->ecdhPeerCurve;
2340	return errSecSuccess;
2341}
2342
2343/*
2344 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2345 */
2346OSStatus SSLGetNumberOfECDSACurves(
2347   SSLContextRef ctx,
2348   unsigned *numCurves)	/* RETURNED */
2349{
2350	if((ctx == NULL) || (numCurves == NULL)) {
2351		return errSecParam;
2352	}
2353	*numCurves = ctx->ecdhNumCurves;
2354	return errSecSuccess;
2355}
2356
2357/*
2358 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2359 */
2360OSStatus SSLGetECDSACurves(
2361   SSLContextRef ctx,
2362   SSL_ECDSA_NamedCurve *namedCurves,		/* RETURNED */
2363   unsigned *numCurves)						/* IN/OUT */
2364{
2365	if((ctx == NULL) || (namedCurves == NULL) || (numCurves == NULL)) {
2366		return errSecParam;
2367	}
2368	if(*numCurves < ctx->ecdhNumCurves) {
2369		return errSecParam;
2370	}
2371	memmove(namedCurves, ctx->ecdhCurves,
2372		(ctx->ecdhNumCurves * sizeof(SSL_ECDSA_NamedCurve)));
2373	*numCurves = ctx->ecdhNumCurves;
2374	return errSecSuccess;
2375}
2376
2377/*
2378 * Specify ordered list of allowable named curves.
2379 */
2380OSStatus SSLSetECDSACurves(
2381   SSLContextRef ctx,
2382   const SSL_ECDSA_NamedCurve *namedCurves,
2383   unsigned numCurves)
2384{
2385	if((ctx == NULL) || (namedCurves == NULL) || (numCurves == 0)) {
2386		return errSecParam;
2387	}
2388	if(numCurves > SSL_ECDSA_NUM_CURVES) {
2389		return errSecParam;
2390	}
2391	if(sslIsSessionActive(ctx)) {
2392		/* can't do this with an active session */
2393		return errSecBadReq;
2394	}
2395	memmove(ctx->ecdhCurves, namedCurves, (numCurves * sizeof(SSL_ECDSA_NamedCurve)));
2396	ctx->ecdhNumCurves = numCurves;
2397	return errSecSuccess;
2398}
2399
2400/*
2401 * Obtain the number of client authentication mechanisms specified by
2402 * the server in its Certificate Request message.
2403 * Returns errSecParam if server hasn't sent a Certificate Request message
2404 * (i.e., client certificate state is kSSLClientCertNone).
2405 */
2406OSStatus SSLGetNumberOfClientAuthTypes(
2407	SSLContextRef ctx,
2408	unsigned *numTypes)
2409{
2410	if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
2411		return errSecParam;
2412	}
2413	*numTypes = ctx->numAuthTypes;
2414	return errSecSuccess;
2415}
2416
2417/*
2418 * Obtain the client authentication mechanisms specified by
2419 * the server in its Certificate Request message.
2420 * Caller allocates returned array and specifies its size (in
2421 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2422 * is the actual size of the returned array on successful return.
2423 */
2424OSStatus SSLGetClientAuthTypes(
2425   SSLContextRef ctx,
2426   SSLClientAuthenticationType *authTypes,		/* RETURNED */
2427   unsigned *numTypes)							/* IN/OUT */
2428{
2429	if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
2430		return errSecParam;
2431	}
2432	memmove(authTypes, ctx->clientAuthTypes,
2433		ctx->numAuthTypes * sizeof(SSLClientAuthenticationType));
2434	*numTypes = ctx->numAuthTypes;
2435	return errSecSuccess;
2436}
2437
2438/*
2439 * Obtain the SSLClientAuthenticationType actually performed.
2440 * Only valid if client certificate state is kSSLClientCertSent
2441 * or kSSLClientCertRejected; returns errSecParam otherwise.
2442 */
2443OSStatus SSLGetNegotiatedClientAuthType(
2444   SSLContextRef ctx,
2445   SSLClientAuthenticationType *authType)		/* RETURNED */
2446{
2447	if(ctx == NULL) {
2448		return errSecParam;
2449	}
2450	*authType = ctx->negAuthType;
2451	return errSecSuccess;
2452}
2453
2454/*
2455 * Update the negotiated client authentication type.
2456 * This function may be called at any time; however, note that
2457 * the negotiated authentication type will be SSLClientAuthNone
2458 * until both of the following have taken place (in either order):
2459 *   - a CertificateRequest message from the server has been processed
2460 *   - a client certificate has been specified
2461 * As such, this function (only) needs to be called from (both)
2462 * SSLProcessCertificateRequest and SSLSetCertificate.
2463 */
2464OSStatus SSLUpdateNegotiatedClientAuthType(
2465	SSLContextRef ctx)
2466{
2467	if(ctx == NULL) {
2468		return errSecParam;
2469	}
2470	/*
2471	 * See if we have a signing cert that matches one of the
2472	 * allowed auth types. The x509Requested flag indicates "we
2473	 * have a cert that we think the server will accept".
2474	 */
2475	ctx->x509Requested = 0;
2476	ctx->negAuthType = SSLClientAuthNone;
2477	if(ctx->signingPrivKeyRef != NULL) {
2478        CFIndex ourKeyAlg = sslPubKeyGetAlgorithmID(ctx->signingPubKey);
2479		unsigned i;
2480		for(i=0; i<ctx->numAuthTypes; i++) {
2481			switch(ctx->clientAuthTypes[i]) {
2482				case SSLClientAuth_RSASign:
2483					if(ourKeyAlg == kSecRSAAlgorithmID) {
2484						ctx->x509Requested = 1;
2485						ctx->negAuthType = SSLClientAuth_RSASign;
2486					}
2487					break;
2488			#if SSL_ENABLE_ECDSA_SIGN_AUTH
2489				case SSLClientAuth_ECDSASign:
2490			#endif
2491			#if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
2492				case SSLClientAuth_ECDSAFixedECDH:
2493			#endif
2494					if((ourKeyAlg == kSecECDSAAlgorithmID) &&
2495					   (ctx->ourSignerAlg == kSecECDSAAlgorithmID)) {
2496						ctx->x509Requested = 1;
2497						ctx->negAuthType = ctx->clientAuthTypes[i];
2498					}
2499					break;
2500			#if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
2501				case SSLClientAuth_RSAFixedECDH:
2502					/* Odd case, we differ from our signer */
2503					if((ourKeyAlg == kSecECDSAAlgorithmID) &&
2504					   (ctx->ourSignerAlg == kSecRSAAlgorithmID)) {
2505						ctx->x509Requested = 1;
2506						ctx->negAuthType = SSLClientAuth_RSAFixedECDH;
2507					}
2508					break;
2509			#endif
2510				default:
2511					/* None others supported */
2512					break;
2513			}
2514			if(ctx->x509Requested) {
2515				sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx->negAuthType);
2516				break;
2517			}
2518		}	/* parsing authTypes */
2519	}	/* we have a signing key */
2520
2521	return errSecSuccess;
2522}
2523
2524OSStatus SSLGetNumberOfSignatureAlgorithms(
2525    SSLContextRef ctx,
2526    unsigned *numSigAlgs)
2527{
2528	if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
2529		return errSecParam;
2530	}
2531	*numSigAlgs = ctx->numServerSigAlgs;
2532	return errSecSuccess;
2533}
2534
2535OSStatus SSLGetSignatureAlgorithms(
2536    SSLContextRef ctx,
2537    SSLSignatureAndHashAlgorithm *sigAlgs,		/* RETURNED */
2538    unsigned *numSigAlgs)							/* IN/OUT */
2539{
2540	if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
2541		return errSecParam;
2542	}
2543	memmove(sigAlgs, ctx->serverSigAlgs,
2544            ctx->numServerSigAlgs * sizeof(SSLSignatureAndHashAlgorithm));
2545	*numSigAlgs = ctx->numServerSigAlgs;
2546	return errSecSuccess;
2547}
2548
2549/* PSK SPIs */
2550OSStatus SSLSetPSKSharedSecret(SSLContextRef ctx,
2551                               const void *secret,
2552                               size_t secretLen)
2553{
2554    if(ctx == NULL) return errSecParam;
2555
2556    if(ctx->pskSharedSecret.data)
2557        SSLFreeBuffer(&ctx->pskSharedSecret);
2558
2559    if(SSLCopyBufferFromData(secret, secretLen, &ctx->pskSharedSecret))
2560        return errSecAllocate;
2561
2562    return errSecSuccess;
2563}
2564
2565OSStatus SSLSetPSKIdentity(SSLContextRef ctx,
2566                           const void *pskIdentity,
2567                           size_t pskIdentityLen)
2568{
2569    if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == 0)) return errSecParam;
2570
2571    if(ctx->pskIdentity.data)
2572        SSLFreeBuffer(&ctx->pskIdentity);
2573
2574    if(SSLCopyBufferFromData(pskIdentity, pskIdentityLen, &ctx->pskIdentity))
2575        return errSecAllocate;
2576
2577    return errSecSuccess;
2578
2579}
2580
2581OSStatus SSLGetPSKIdentity(SSLContextRef ctx,
2582                           const void **pskIdentity,
2583                           size_t *pskIdentityLen)
2584{
2585    if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == NULL)) return errSecParam;
2586
2587    *pskIdentity=ctx->pskIdentity.data;
2588    *pskIdentityLen=ctx->pskIdentity.length;
2589    return errSecSuccess;
2590}
2591
2592
2593#ifdef USE_SSLCERTIFICATE
2594
2595size_t
2596SSLGetCertificateChainLength(const SSLCertificate *c)
2597{
2598	size_t rtn = 0;
2599
2600    while (c)
2601    {
2602	rtn++;
2603        c = c->next;
2604    }
2605    return rtn;
2606}
2607
2608OSStatus sslDeleteCertificateChain(
2609                                   SSLCertificate		*certs,
2610                                   SSLContext 			*ctx)
2611{
2612	SSLCertificate		*cert;
2613	SSLCertificate		*nextCert;
2614
2615	assert(ctx != NULL);
2616	cert=certs;
2617	while(cert != NULL) {
2618		nextCert = cert->next;
2619		SSLFreeBuffer(&cert->derCert);
2620		sslFree(cert);
2621		cert = nextCert;
2622	}
2623	return errSecSuccess;
2624}
2625#endif /* USE_SSLCERTIFICATE */
2626