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