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