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