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