]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslContext.cpp
Security-164.1.tar.gz
[apple/security.git] / SecureTransport / sslContext.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 File: sslContext.cpp
21
22 Contains: SSLContext accessors
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "ssl.h"
31 #include "sslContext.h"
32 #include "sslMemory.h"
33 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
34 #include "sslDigests.h"
35 #include "sslDebug.h"
36 #include "appleCdsa.h"
37 #include "sslKeychain.h"
38 #include "sslUtils.h"
39 #include "cipherSpecs.h"
40 #include "appleSession.h"
41 #include "sslBER.h"
42 #include <string.h>
43 #include <Security/SecCertificate.h>
44 #include <Security/SecTrust.h>
45
46 static void sslFreeDnList(
47 SSLContext *ctx)
48 {
49 DNListElem *dn, *nextDN;
50
51 dn = ctx->acceptableDNList;
52 while (dn)
53 {
54 SSLFreeBuffer(dn->derDN, ctx);
55 nextDN = dn->next;
56 sslFree(dn);
57 dn = nextDN;
58 }
59 ctx->acceptableDNList = NULL;
60 }
61
62 static OSStatus sslFreeTrustedRoots(
63 SSLContext *ctx)
64 {
65 unsigned i;
66
67 assert(ctx != NULL);
68 if((ctx->numTrustedCerts == 0) || (ctx->trustedCerts == NULL)) {
69 /* they really should both be zero, right? */
70 assert((ctx->numTrustedCerts == 0) && (ctx->trustedCerts == NULL));
71 }
72 else {
73 for(i=0; i<ctx->numTrustedCerts; i++) {
74 stFreeCssmData(&ctx->trustedCerts[i], CSSM_FALSE);
75 }
76 sslFree(ctx->trustedCerts);
77 }
78 ctx->numTrustedCerts = 0;
79 ctx->trustedCerts = NULL;
80 sslFreeDnList(ctx);
81 return noErr;
82 }
83
84 /*
85 * Default version enables.
86 */
87 #define DEFAULT_SSL2_ENABLE true
88 #define DEFAULT_SSL3_ENABLE true
89 #define DEFAULT_TLS1_ENABLE true
90
91 OSStatus
92 SSLNewContext (Boolean isServer,
93 SSLContextRef *contextPtr) /* RETURNED */
94 {
95 SSLContext *ctx;
96 OSStatus serr;
97
98 if(contextPtr == NULL) {
99 return paramErr;
100 }
101 *contextPtr = NULL;
102 ctx = (SSLContext *)sslMalloc(sizeof(SSLContext));
103 if(ctx == NULL) {
104 return memFullErr;
105 }
106 /* subsequent errors to errOut: */
107
108 memset(ctx, 0, sizeof(SSLContext));
109 ctx->state = SSL_HdskStateUninit;
110 ctx->clientCertState = kSSLClientCertNone;
111
112 ctx->versionSsl2Enable = DEFAULT_SSL2_ENABLE;
113 ctx->versionSsl3Enable = DEFAULT_SSL3_ENABLE;
114 ctx->versionTls1Enable = DEFAULT_TLS1_ENABLE;
115 ctx->negProtocolVersion = SSL_Version_Undetermined;
116
117 if(isServer) {
118 ctx->protocolSide = SSL_ServerSide;
119 }
120 else {
121 ctx->protocolSide = SSL_ClientSide;
122 }
123
124 /* Default value so we can send and receive hello msgs */
125 ctx->sslTslCalls = &Ssl3Callouts;
126
127 /* Initialize the cipher state to NULL_WITH_NULL_NULL */
128 ctx->selectedCipherSpec = &SSL_NULL_WITH_NULL_NULL_CipherSpec;
129 ctx->selectedCipher = ctx->selectedCipherSpec->cipherSpec;
130 ctx->writeCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
131 ctx->readCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
132 ctx->readCipher.symCipher = ctx->selectedCipherSpec->cipher;
133 ctx->writeCipher.symCipher = ctx->selectedCipherSpec->cipher;
134
135 /* these two are invariant */
136 ctx->writeCipher.encrypting = 1;
137 ctx->writePending.encrypting = 1;
138
139 /* this gets init'd on first call to SSLHandshake() */
140 ctx->validCipherSpecs = NULL;
141 ctx->numValidCipherSpecs = 0;
142
143 ctx->peerDomainName = NULL;
144 ctx->peerDomainNameLen = 0;
145
146 /* attach to CSP, CL, TP */
147 serr = attachToAll(ctx);
148 if(serr) {
149 goto errOut;
150 }
151
152 /* Initial cert verify state: verify with default system roots */
153 ctx->enableCertVerify = true;
154
155 /* Default for RSA blinding is ENABLED */
156 ctx->rsaBlindingEnable = true;
157
158 *contextPtr = ctx;
159 return noErr;
160
161 errOut:
162 sslFree(ctx);
163 return serr;
164 }
165
166
167 /*
168 * Dispose of an SSLContext.
169 */
170 OSStatus
171 SSLDisposeContext (SSLContext *ctx)
172 {
173 WaitingRecord *wait, *next;
174 SSLBuffer buf;
175
176 if(ctx == NULL) {
177 return paramErr;
178 }
179 sslDeleteCertificateChain(ctx->localCert, ctx);
180 sslDeleteCertificateChain(ctx->encryptCert, ctx);
181 sslDeleteCertificateChain(ctx->peerCert, ctx);
182 ctx->localCert = ctx->encryptCert = ctx->peerCert = NULL;
183 SSLFreeBuffer(ctx->partialReadBuffer, ctx);
184 if(ctx->peerSecTrust) {
185 CFRelease(ctx->peerSecTrust);
186 ctx->peerSecTrust = NULL;
187 }
188 wait = ctx->recordWriteQueue;
189 while (wait)
190 { SSLFreeBuffer(wait->data, ctx);
191 next = wait->next;
192 buf.data = (uint8*)wait;
193 buf.length = sizeof(WaitingRecord);
194 SSLFreeBuffer(buf, ctx);
195 wait = next;
196 }
197
198 #if APPLE_DH
199 SSLFreeBuffer(ctx->dhParamsPrime, ctx);
200 SSLFreeBuffer(ctx->dhParamsGenerator, ctx);
201 SSLFreeBuffer(ctx->dhParamsEncoded, ctx);
202 SSLFreeBuffer(ctx->dhPeerPublic, ctx);
203 SSLFreeBuffer(ctx->dhExchangePublic, ctx);
204 sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
205 #endif /* APPLE_DH */
206
207 CloseHash(SSLHashSHA1, ctx->shaState, ctx);
208 CloseHash(SSLHashMD5, ctx->md5State, ctx);
209
210 SSLFreeBuffer(ctx->sessionID, ctx);
211 SSLFreeBuffer(ctx->peerID, ctx);
212 SSLFreeBuffer(ctx->resumableSession, ctx);
213 SSLFreeBuffer(ctx->preMasterSecret, ctx);
214 SSLFreeBuffer(ctx->partialReadBuffer, ctx);
215 SSLFreeBuffer(ctx->fragmentedMessageCache, ctx);
216 SSLFreeBuffer(ctx->receivedDataBuffer, ctx);
217
218 if(ctx->peerDomainName) {
219 sslFree(ctx->peerDomainName);
220 ctx->peerDomainName = NULL;
221 ctx->peerDomainNameLen = 0;
222 }
223 SSLDisposeCipherSuite(&ctx->readCipher, ctx);
224 SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
225 SSLDisposeCipherSuite(&ctx->readPending, ctx);
226 SSLDisposeCipherSuite(&ctx->writePending, ctx);
227
228 sslFree(ctx->validCipherSpecs);
229 ctx->validCipherSpecs = NULL;
230 ctx->numValidCipherSpecs = 0;
231
232 /*
233 * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
234 * We really don't know what CSP the CL used to generate a public key (in fact,
235 * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
236 * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
237 * signingPubKey is not tecnically accurate. However, our public keys
238 * are all raw keys, and all Apple CSPs dispose of raw keys in the same
239 * way.
240 */
241 sslFreeKey(ctx->cspHand, &ctx->signingPubKey, NULL);
242 sslFreeKey(ctx->cspHand, &ctx->encryptPubKey, NULL);
243 sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
244
245 if(ctx->signingPrivKeyRef) {
246 CFRelease(ctx->signingPrivKeyRef);
247 }
248 if(ctx->encryptPrivKeyRef) {
249 CFRelease(ctx->encryptPrivKeyRef);
250 }
251 sslFreeTrustedRoots(ctx);
252
253 detachFromAll(ctx);
254
255 memset(ctx, 0, sizeof(SSLContext));
256 sslFree(ctx);
257 sslCleanupSession();
258 return noErr;
259 }
260
261 /*
262 * Determine the state of an SSL session.
263 */
264 OSStatus
265 SSLGetSessionState (SSLContextRef context,
266 SSLSessionState *state) /* RETURNED */
267 {
268 SSLSessionState rtnState = kSSLIdle;
269
270 if(context == NULL) {
271 return paramErr;
272 }
273 *state = rtnState;
274 switch(context->state) {
275 case SSL_HdskStateUninit:
276 case SSL_HdskStateServerUninit:
277 case SSL_HdskStateClientUninit:
278 rtnState = kSSLIdle;
279 break;
280 case SSL_HdskStateGracefulClose:
281 rtnState = kSSLClosed;
282 break;
283 case SSL_HdskStateErrorClose:
284 case SSL_HdskStateNoNotifyClose:
285 rtnState = kSSLAborted;
286 break;
287 case SSL_HdskStateServerReady:
288 case SSL_HdskStateClientReady:
289 rtnState = kSSLConnected;
290 break;
291 default:
292 assert((context->state >= SSL_HdskStateServerHello) &&
293 (context->state <= SSL2_HdskStateServerFinished));
294 rtnState = kSSLHandshake;
295 break;
296
297 }
298 *state = rtnState;
299 return noErr;
300 }
301
302 OSStatus
303 SSLSetIOFuncs (SSLContextRef ctx,
304 SSLReadFunc read,
305 SSLWriteFunc write)
306 {
307 if(ctx == NULL) {
308 return paramErr;
309 }
310 if(sslIsSessionActive(ctx)) {
311 /* can't do this with an active session */
312 return badReqErr;
313 }
314 ctx->ioCtx.read = read;
315 ctx->ioCtx.write = write;
316 return noErr;
317 }
318
319 OSStatus
320 SSLSetConnection (SSLContextRef ctx,
321 SSLConnectionRef connection)
322 {
323 if(ctx == NULL) {
324 return paramErr;
325 }
326 if(sslIsSessionActive(ctx)) {
327 /* can't do this with an active session */
328 return badReqErr;
329 }
330 ctx->ioCtx.ioRef = connection;
331 return noErr;
332 }
333
334 OSStatus
335 SSLGetConnection (SSLContextRef ctx,
336 SSLConnectionRef *connection)
337 {
338 if((ctx == NULL) || (connection == NULL)) {
339 return paramErr;
340 }
341 *connection = ctx->ioCtx.ioRef;
342 return noErr;
343 }
344
345 OSStatus
346 SSLSetPeerDomainName (SSLContextRef ctx,
347 const char *peerName,
348 size_t peerNameLen)
349 {
350 if(ctx == NULL) {
351 return paramErr;
352 }
353 if(sslIsSessionActive(ctx)) {
354 /* can't do this with an active session */
355 return badReqErr;
356 }
357
358 /* free possible existing name */
359 if(ctx->peerDomainName) {
360 sslFree(ctx->peerDomainName);
361 }
362
363 /* copy in */
364 ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
365 if(ctx->peerDomainName == NULL) {
366 return memFullErr;
367 }
368 memmove(ctx->peerDomainName, peerName, peerNameLen);
369 ctx->peerDomainNameLen = peerNameLen;
370 return noErr;
371 }
372
373 /*
374 * Determine the buffer size needed for SSLGetPeerDomainName().
375 */
376 OSStatus
377 SSLGetPeerDomainNameLength (SSLContextRef ctx,
378 size_t *peerNameLen) // RETURNED
379 {
380 if(ctx == NULL) {
381 return paramErr;
382 }
383 *peerNameLen = ctx->peerDomainNameLen;
384 return noErr;
385 }
386
387 OSStatus
388 SSLGetPeerDomainName (SSLContextRef ctx,
389 char *peerName, // returned here
390 size_t *peerNameLen) // IN/OUT
391 {
392 if(ctx == NULL) {
393 return paramErr;
394 }
395 if(*peerNameLen < ctx->peerDomainNameLen) {
396 return errSSLBufferOverflow;
397 }
398 memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
399 *peerNameLen = ctx->peerDomainNameLen;
400 return noErr;
401 }
402
403 /* concert between private SSLProtocolVersion and public SSLProtocol */
404 static SSLProtocol convertProtToExtern(SSLProtocolVersion prot)
405 {
406 switch(prot) {
407 case SSL_Version_Undetermined:
408 return kSSLProtocolUnknown;
409 case SSL_Version_2_0:
410 return kSSLProtocol2;
411 case SSL_Version_3_0:
412 return kSSLProtocol3;
413 case TLS_Version_1_0:
414 return kTLSProtocol1;
415 default:
416 sslErrorLog("convertProtToExtern: bad prot\n");
417 return kSSLProtocolUnknown;
418 }
419 /* not reached but make compiler happy */
420 return kSSLProtocolUnknown;
421 }
422
423 OSStatus
424 SSLSetProtocolVersionEnabled(SSLContextRef ctx,
425 SSLProtocol protocol,
426 Boolean enable) /* RETURNED */
427 {
428 if(ctx == NULL) {
429 return paramErr;
430 }
431 if(sslIsSessionActive(ctx)) {
432 /* can't do this with an active session */
433 return badReqErr;
434 }
435 switch(protocol) {
436 case kSSLProtocol2:
437 ctx->versionSsl2Enable = enable;
438 break;
439 case kSSLProtocol3:
440 ctx->versionSsl3Enable = enable;
441 break;
442 case kTLSProtocol1:
443 ctx->versionTls1Enable = enable;
444 break;
445 case kSSLProtocolAll:
446 ctx->versionTls1Enable = ctx->versionSsl3Enable =
447 ctx->versionSsl2Enable = enable;
448 break;
449 default:
450 return paramErr;
451 }
452 return noErr;
453 }
454
455 OSStatus
456 SSLGetProtocolVersionEnabled(SSLContextRef ctx,
457 SSLProtocol protocol,
458 Boolean *enable) /* RETURNED */
459 {
460 if(ctx == NULL) {
461 return paramErr;
462 }
463 switch(protocol) {
464 case kSSLProtocol2:
465 *enable = ctx->versionSsl2Enable;
466 break;
467 case kSSLProtocol3:
468 *enable = ctx->versionSsl3Enable;
469 break;
470 case kTLSProtocol1:
471 *enable = ctx->versionTls1Enable;
472 break;
473 case kSSLProtocolAll:
474 if(ctx->versionTls1Enable && ctx->versionSsl3Enable &&
475 ctx->versionSsl2Enable) {
476 *enable = true;
477 }
478 else {
479 *enable = false;
480 }
481 break;
482 default:
483 return paramErr;
484 }
485 return noErr;
486 }
487
488 /* deprecated */
489 OSStatus
490 SSLSetProtocolVersion (SSLContextRef ctx,
491 SSLProtocol version)
492 {
493 if(ctx == NULL) {
494 return paramErr;
495 }
496 if(sslIsSessionActive(ctx)) {
497 /* can't do this with an active session */
498 return badReqErr;
499 }
500
501 /* convert external representation to three booleans */
502 switch(version) {
503 case kSSLProtocolUnknown:
504 ctx->versionSsl2Enable = DEFAULT_SSL2_ENABLE;
505 ctx->versionSsl3Enable = DEFAULT_SSL3_ENABLE;
506 ctx->versionTls1Enable = DEFAULT_TLS1_ENABLE;
507 break;
508 case kSSLProtocol2:
509 ctx->versionSsl2Enable = true;
510 ctx->versionSsl3Enable = false;
511 ctx->versionTls1Enable = false;
512 break;
513 case kSSLProtocol3:
514 /* this tells us to do our best, up to 3.0, but allows 2.0 */
515 ctx->versionSsl2Enable = true;
516 ctx->versionSsl3Enable = true;
517 ctx->versionTls1Enable = false;
518 break;
519 case kSSLProtocol3Only:
520 ctx->versionSsl2Enable = false;
521 ctx->versionSsl3Enable = true;
522 ctx->versionTls1Enable = false;
523 break;
524 case kTLSProtocol1:
525 case kSSLProtocolAll:
526 /* this tells us to do our best, up to TLS, but allows 2.0 or 3.0 */
527 ctx->versionSsl2Enable = true;
528 ctx->versionSsl3Enable = true;
529 ctx->versionTls1Enable = true;
530 break;
531 case kTLSProtocol1Only:
532 ctx->versionSsl2Enable = false;
533 ctx->versionSsl3Enable = false;
534 ctx->versionTls1Enable = true;
535 break;
536 default:
537 return paramErr;
538 }
539 return noErr;
540 }
541
542 /* deprecated */
543 OSStatus
544 SSLGetProtocolVersion (SSLContextRef ctx,
545 SSLProtocol *protocol) /* RETURNED */
546 {
547 if(ctx == NULL) {
548 return paramErr;
549 }
550
551 /* translate array of booleans to public value; not all combinations
552 * are legal (i.e., meaningful) for this call */
553 if(ctx->versionTls1Enable) {
554 if(ctx->versionSsl2Enable) {
555 if(ctx->versionSsl3Enable) {
556 /* traditional 'all enabled' */
557 *protocol = kTLSProtocol1;
558 return noErr;
559 }
560 else {
561 /* SSL2 true, SSL3 false, TLS1 true - invalid here */
562 return paramErr;
563 }
564 }
565 else if(ctx->versionSsl3Enable) {
566 /* SSL2 false, SSL3 true, TLS1 true - invalid here */
567 return paramErr;
568 }
569 else {
570 *protocol = kTLSProtocol1Only;
571 return noErr;
572 }
573 }
574 else {
575 /* TLS1 false */
576 if(ctx->versionSsl3Enable) {
577 *protocol = ctx->versionSsl2Enable ?
578 kSSLProtocol3 : kSSLProtocol3Only;
579 return noErr;
580 }
581 else if(ctx->versionSsl2Enable) {
582 *protocol = kSSLProtocol2;
583 return noErr;
584 }
585 else {
586 /*
587 * Bogus state - no enables - the API does provide a way
588 * to get into this state. Other than this path, the app
589 * will discover this bogon when attempting to do the
590 * handshake; sslGetMaxProtVersion will detect this.
591 */
592 return paramErr;
593 }
594 }
595 /* NOT REACHED */
596 }
597
598 OSStatus
599 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx,
600 SSLProtocol *protocol) /* RETURNED */
601 {
602 if(ctx == NULL) {
603 return paramErr;
604 }
605 *protocol = convertProtToExtern(ctx->negProtocolVersion);
606 return noErr;
607 }
608
609 OSStatus
610 SSLSetEnableCertVerify (SSLContextRef ctx,
611 Boolean enableVerify)
612 {
613 if(ctx == NULL) {
614 return paramErr;
615 }
616 sslCertDebug("SSLSetEnableCertVerify %s",
617 enableVerify ? "true" : "false");
618 if(sslIsSessionActive(ctx)) {
619 /* can't do this with an active session */
620 return badReqErr;
621 }
622 ctx->enableCertVerify = enableVerify;
623 return noErr;
624 }
625
626 OSStatus
627 SSLGetEnableCertVerify (SSLContextRef ctx,
628 Boolean *enableVerify)
629 {
630 if(ctx == NULL) {
631 return paramErr;
632 }
633 *enableVerify = ctx->enableCertVerify;
634 return noErr;
635 }
636
637 OSStatus
638 SSLSetAllowsExpiredCerts(SSLContextRef ctx,
639 Boolean allowExpired)
640 {
641 if(ctx == NULL) {
642 return paramErr;
643 }
644 sslCertDebug("SSLSetAllowsExpiredCerts %s",
645 allowExpired ? "true" : "false");
646 if(sslIsSessionActive(ctx)) {
647 /* can't do this with an active session */
648 return badReqErr;
649 }
650 ctx->allowExpiredCerts = allowExpired;
651 return noErr;
652 }
653
654 OSStatus
655 SSLGetAllowsExpiredCerts (SSLContextRef ctx,
656 Boolean *allowExpired)
657 {
658 if(ctx == NULL) {
659 return paramErr;
660 }
661 *allowExpired = ctx->allowExpiredCerts;
662 return noErr;
663 }
664
665 OSStatus
666 SSLSetAllowsExpiredRoots(SSLContextRef ctx,
667 Boolean allowExpired)
668 {
669 if(ctx == NULL) {
670 return paramErr;
671 }
672 sslCertDebug("SSLSetAllowsExpiredRoots %s",
673 allowExpired ? "true" : "false");
674 if(sslIsSessionActive(ctx)) {
675 /* can't do this with an active session */
676 return badReqErr;
677 }
678 ctx->allowExpiredRoots = allowExpired;
679 return noErr;
680 }
681
682 OSStatus
683 SSLGetAllowsExpiredRoots (SSLContextRef ctx,
684 Boolean *allowExpired)
685 {
686 if(ctx == NULL) {
687 return paramErr;
688 }
689 *allowExpired = ctx->allowExpiredRoots;
690 return noErr;
691 }
692
693 OSStatus SSLSetAllowsAnyRoot(
694 SSLContextRef ctx,
695 Boolean anyRoot)
696 {
697 if(ctx == NULL) {
698 return paramErr;
699 }
700 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot ? "true" : "false");
701 ctx->allowAnyRoot = anyRoot;
702 return noErr;
703 }
704
705 OSStatus
706 SSLGetAllowsAnyRoot(
707 SSLContextRef ctx,
708 Boolean *anyRoot)
709 {
710 if(ctx == NULL) {
711 return paramErr;
712 }
713 *anyRoot = ctx->allowAnyRoot;
714 return noErr;
715 }
716
717 OSStatus
718 SSLSetTrustedRoots (SSLContextRef ctx,
719 CFArrayRef trustedRoots,
720 Boolean replaceExisting)
721 {
722 unsigned dex;
723 unsigned outDex;
724 unsigned numIncoming;
725 uint32 numCerts;
726 CSSM_DATA_PTR newRoots = NULL;
727 const CSSM_DATA *existAnchors = NULL;
728 uint32 numExistAnchors = 0;
729 OSStatus ortn = noErr;
730
731 if(ctx == NULL) {
732 return paramErr;
733 }
734 if(sslIsSessionActive(ctx)) {
735 /* can't do this with an active session */
736 return badReqErr;
737 }
738 numCerts = numIncoming = CFArrayGetCount(trustedRoots);
739 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
740 (int)numCerts, replaceExisting ? "true" : "false");
741 if(!replaceExisting) {
742 if(ctx->trustedCerts != NULL) {
743 /* adding to existing store */
744 existAnchors = ctx->trustedCerts;
745 numExistAnchors = ctx->numTrustedCerts;
746 }
747 else {
748 /* adding to system roots */
749 ortn = SecTrustGetCSSMAnchorCertificates(&existAnchors,
750 &numExistAnchors);
751 if(ortn) {
752 /* should never happen */
753 return ortn;
754 }
755 }
756 numCerts += numExistAnchors;
757 }
758 newRoots = (CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA));
759 memset(newRoots, 0, numCerts * sizeof(CSSM_DATA));
760
761 /* Caller's certs first */
762 for(dex=0, outDex=0; dex<numIncoming; dex++, outDex++) {
763 CSSM_DATA certData;
764 SecCertificateRef secCert = (SecCertificateRef)
765 CFArrayGetValueAtIndex(trustedRoots, dex);
766
767 if(CFGetTypeID(secCert) != SecCertificateGetTypeID()) {
768 /* elements of trustedRoots must be SecCertificateRefs */
769 ortn = paramErr;
770 goto abort;
771 }
772 ortn = SecCertificateGetData(secCert, &certData);
773 if(ortn) {
774 goto abort;
775 }
776 stSetUpCssmData(&newRoots[outDex], certData.Length);
777 memmove(newRoots[outDex].Data, certData.Data, certData.Length);
778 }
779
780 /* now existing roots - either ours, or the system's */
781 for(dex=0; dex<numExistAnchors; dex++, outDex++) {
782 stSetUpCssmData(&newRoots[outDex], existAnchors[dex].Length);
783 memmove(newRoots[outDex].Data, existAnchors[dex].Data,
784 existAnchors[dex].Length);
785 }
786
787 /* success - replace context values */
788 sslFreeTrustedRoots(ctx);
789 ctx->numTrustedCerts = numCerts;
790 ctx->trustedCerts = newRoots;
791 return noErr;
792
793 abort:
794 sslFree(newRoots);
795 return ortn;
796 }
797
798 OSStatus
799 SSLGetTrustedRoots (SSLContextRef ctx,
800 CFArrayRef *trustedRoots) /* RETURNED */
801 {
802 uint32 numCerts;
803 const CSSM_DATA *certs;
804 CFMutableArrayRef certArray;
805 unsigned dex;
806 SecCertificateRef secCert;
807 OSStatus ortn;
808
809 if(ctx == NULL) {
810 return paramErr;
811 }
812 if(ctx->trustedCerts != NULL) {
813 /* use ours */
814 certs = ctx->trustedCerts;
815 numCerts = ctx->numTrustedCerts;
816 }
817 else {
818 /* use default system roots */
819 OSStatus ortn = SecTrustGetCSSMAnchorCertificates(&certs,
820 &numCerts);
821 if(ortn) {
822 /* should never happen */
823 return ortn;
824 }
825 }
826
827 certArray = CFArrayCreateMutable(kCFAllocatorDefault,
828 (CFIndex)numCerts, &kCFTypeArrayCallBacks);
829 if(certArray == NULL) {
830 return memFullErr;
831 }
832 for(dex=0; dex<numCerts; dex++) {
833 ortn = SecCertificateCreateFromData(&certs[dex],
834 CSSM_CERT_X_509v3,
835 CSSM_CERT_ENCODING_DER,
836 &secCert);
837 if(ortn) {
838 CFRelease(certArray);
839 return ortn;
840 }
841 CFArrayAppendValue(certArray, secCert);
842 }
843 *trustedRoots = certArray;
844 return noErr;
845 }
846
847 OSStatus
848 SSLSetClientSideAuthenticate (SSLContext *ctx,
849 SSLAuthenticate auth)
850 {
851 if(ctx == NULL) {
852 return paramErr;
853 }
854 if(sslIsSessionActive(ctx)) {
855 /* can't do this with an active session */
856 return badReqErr;
857 }
858 ctx->clientAuth = auth;
859 switch(auth) {
860 case kNeverAuthenticate:
861 ctx->tryClientAuth = false;
862 break;
863 case kAlwaysAuthenticate:
864 case kTryAuthenticate:
865 ctx->tryClientAuth = true;
866 break;
867 }
868 return noErr;
869 }
870
871 OSStatus
872 SSLGetClientCertificateState (SSLContextRef ctx,
873 SSLClientCertificateState *clientState)
874 {
875 if(ctx == NULL) {
876 return paramErr;
877 }
878 *clientState = ctx->clientCertState;
879 return noErr;
880 }
881
882 OSStatus
883 SSLSetCertificate (SSLContextRef ctx,
884 CFArrayRef certRefs)
885 {
886 /*
887 * -- free localCerts if we have any
888 * -- Get raw cert data, convert to ctx->localCert
889 * -- get pub, priv keys from certRef[0]
890 * -- validate cert chain
891 */
892 if(ctx == NULL) {
893 return paramErr;
894 }
895 if(sslIsSessionActive(ctx)) {
896 /* can't do this with an active session */
897 return badReqErr;
898 }
899 return parseIncomingCerts(ctx,
900 certRefs,
901 &ctx->localCert,
902 &ctx->signingPubKey,
903 &ctx->signingPrivKeyRef);
904 }
905
906 OSStatus
907 SSLSetEncryptionCertificate (SSLContextRef ctx,
908 CFArrayRef certRefs)
909 {
910 /*
911 * -- free encryptCert if we have any
912 * -- Get raw cert data, convert to ctx->encryptCert
913 * -- get pub, priv keys from certRef[0]
914 * -- validate cert chain
915 */
916 if(ctx == NULL) {
917 return paramErr;
918 }
919 if(sslIsSessionActive(ctx)) {
920 /* can't do this with an active session */
921 return badReqErr;
922 }
923 return parseIncomingCerts(ctx,
924 certRefs,
925 &ctx->encryptCert,
926 &ctx->encryptPubKey,
927 &ctx->encryptPrivKeyRef);
928 }
929
930 OSStatus
931 SSLSetPeerID (SSLContext *ctx,
932 const void *peerID,
933 size_t peerIDLen)
934 {
935 OSStatus serr;
936
937 /* copy peerId to context->peerId */
938 if((ctx == NULL) ||
939 (peerID == NULL) ||
940 (peerIDLen == 0)) {
941 return paramErr;
942 }
943 if(sslIsSessionActive(ctx)) {
944 /* can't do this with an active session */
945 return badReqErr;
946 }
947 SSLFreeBuffer(ctx->peerID, ctx);
948 serr = SSLAllocBuffer(ctx->peerID, peerIDLen, ctx);
949 if(serr) {
950 return serr;
951 }
952 memmove(ctx->peerID.data, peerID, peerIDLen);
953 return noErr;
954 }
955
956 OSStatus
957 SSLGetPeerID (SSLContextRef ctx,
958 const void **peerID,
959 size_t *peerIDLen)
960 {
961 *peerID = ctx->peerID.data; // may be NULL
962 *peerIDLen = ctx->peerID.length;
963 return noErr;
964 }
965
966 OSStatus
967 SSLGetNegotiatedCipher (SSLContextRef ctx,
968 SSLCipherSuite *cipherSuite)
969 {
970 if(ctx == NULL) {
971 return paramErr;
972 }
973 if(!sslIsSessionActive(ctx)) {
974 return badReqErr;
975 }
976 *cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
977 return noErr;
978 }
979
980 /*
981 * Add an acceptable distinguished name (client authentication only).
982 */
983 OSStatus
984 SSLAddDistinguishedName(
985 SSLContextRef ctx,
986 const void *derDN,
987 size_t derDNLen)
988 {
989 DNListElem *dn;
990 OSStatus err;
991
992 dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
993 if(dn == NULL) {
994 return memFullErr;
995 }
996 if ((err = SSLAllocBuffer(dn->derDN, derDNLen, ctx)) != 0)
997 return err;
998 memcpy(dn->derDN.data, derDN, derDNLen);
999 dn->next = ctx->acceptableDNList;
1000 ctx->acceptableDNList = dn;
1001 return noErr;
1002 }
1003
1004 /*
1005 * Request peer certificates. Valid anytime, subsequent to
1006 * a handshake attempt.
1007 */
1008 OSStatus
1009 SSLGetPeerCertificates (SSLContextRef ctx,
1010 CFArrayRef *certs)
1011 {
1012 uint32 numCerts;
1013 CFMutableArrayRef ca;
1014 CFIndex i;
1015 SecCertificateRef cfd;
1016 OSStatus ortn;
1017 CSSM_DATA certData;
1018 SSLCertificate *scert;
1019
1020 if(ctx == NULL) {
1021 return paramErr;
1022 }
1023 *certs = NULL;
1024
1025 /*
1026 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
1027 * CFDataRefs, each of which is one DER-encoded cert.
1028 */
1029 numCerts = SSLGetCertificateChainLength(ctx->peerCert);
1030 if(numCerts == 0) {
1031 return noErr;
1032 }
1033 ca = CFArrayCreateMutable(kCFAllocatorDefault,
1034 (CFIndex)numCerts, &kCFTypeArrayCallBacks);
1035 if(ca == NULL) {
1036 return memFullErr;
1037 }
1038
1039 /*
1040 * Caller gets leaf cert first, the opposite of the way we store them.
1041 */
1042 scert = ctx->peerCert;
1043 for(i=0; (unsigned)i<numCerts; i++) {
1044 assert(scert != NULL); /* else SSLGetCertificateChainLength
1045 * broken */
1046 SSLBUF_TO_CSSM(&scert->derCert, &certData);
1047 ortn = SecCertificateCreateFromData(&certData,
1048 CSSM_CERT_X_509v3,
1049 CSSM_CERT_ENCODING_DER,
1050 &cfd);
1051 if(ortn) {
1052 CFRelease(ca);
1053 return ortn;
1054 }
1055 /* insert at head of array */
1056 CFArrayInsertValueAtIndex(ca, 0, cfd);
1057 scert = scert->next;
1058 }
1059 *certs = ca;
1060 return noErr;
1061 }
1062
1063 /*
1064 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1065 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1066 * been called, a set of process-wide parameters will be calculated. However
1067 * that can take a long time (30 seconds).
1068 */
1069 OSStatus SSLSetDiffieHellmanParams(
1070 SSLContextRef ctx,
1071 const void *dhParams,
1072 size_t dhParamsLen)
1073 {
1074 if(ctx == NULL) {
1075 return paramErr;
1076 }
1077 if(sslIsSessionActive(ctx)) {
1078 return badReqErr;
1079 }
1080 SSLFreeBuffer(ctx->dhParamsPrime, ctx);
1081 SSLFreeBuffer(ctx->dhParamsGenerator, ctx);
1082 SSLFreeBuffer(ctx->dhParamsEncoded, ctx);
1083
1084 OSStatus ortn;
1085 ortn = SSLCopyBufferFromData(dhParams, dhParamsLen,
1086 ctx->dhParamsEncoded);
1087 if(ortn) {
1088 return ortn;
1089 }
1090
1091 /* decode for use by server over the wire */
1092 SSLBuffer sParams;
1093 sParams.data = (UInt8 *)dhParams;
1094 sParams.length = dhParamsLen;
1095 return sslDecodeDhParams(&sParams, &ctx->dhParamsPrime,
1096 &ctx->dhParamsGenerator);
1097 }
1098
1099 /*
1100 * Return parameter block specified in SSLSetDiffieHellmanParams.
1101 * Returned data is not copied and belongs to the SSLContextRef.
1102 */
1103 OSStatus SSLGetDiffieHellmanParams(
1104 SSLContextRef ctx,
1105 const void **dhParams,
1106 size_t *dhParamsLen)
1107 {
1108 if(ctx == NULL) {
1109 return paramErr;
1110 }
1111 *dhParams = ctx->dhParamsEncoded.data;
1112 *dhParamsLen = ctx->dhParamsEncoded.length;
1113 return noErr;
1114 }
1115
1116 OSStatus SSLSetRsaBlinding(
1117 SSLContextRef ctx,
1118 Boolean blinding)
1119 {
1120 if(ctx == NULL) {
1121 return paramErr;
1122 }
1123 ctx->rsaBlindingEnable = blinding;
1124 return noErr;
1125 }
1126
1127 OSStatus SSLGetRsaBlinding(
1128 SSLContextRef ctx,
1129 Boolean *blinding)
1130 {
1131 if(ctx == NULL) {
1132 return paramErr;
1133 }
1134 *blinding = ctx->rsaBlindingEnable;
1135 return noErr;
1136 }
1137
1138 OSStatus SSLGetPeerSecTrust(
1139 SSLContextRef ctx,
1140 SecTrustRef *secTrust) /* RETURNED */
1141 {
1142 if(ctx == NULL) {
1143 return paramErr;
1144 }
1145 *secTrust = ctx->peerSecTrust;
1146 return noErr;
1147 }
1148
1149 OSStatus SSLInternalMasterSecret(
1150 SSLContextRef ctx,
1151 void *secret, // mallocd by caller, SSL_MASTER_SECRET_SIZE
1152 size_t *secretSize) // in/out
1153 {
1154 if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
1155 return paramErr;
1156 }
1157 if(*secretSize < SSL_MASTER_SECRET_SIZE) {
1158 return paramErr;
1159 }
1160 memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
1161 *secretSize = SSL_MASTER_SECRET_SIZE;
1162 return noErr;
1163 }
1164
1165 OSStatus SSLInternalServerRandom(
1166 SSLContextRef ctx,
1167 void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1168 size_t *randSize) // in/out
1169 {
1170 if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
1171 return paramErr;
1172 }
1173 if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
1174 return paramErr;
1175 }
1176 memmove(rand, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
1177 *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
1178 return noErr;
1179 }
1180
1181 OSStatus SSLInternalClientRandom(
1182 SSLContextRef ctx,
1183 void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1184 size_t *randSize) // in/out
1185 {
1186 if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
1187 return paramErr;
1188 }
1189 if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
1190 return paramErr;
1191 }
1192 memmove(rand, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
1193 *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
1194 return noErr;
1195 }
1196
1197 OSStatus
1198 SSLGetResumableSessionInfo(
1199 SSLContextRef ctx,
1200 Boolean *sessionWasResumed, // RETURNED
1201 void *sessionID, // RETURNED, mallocd by caller
1202 size_t *sessionIDLength) // IN/OUT
1203 {
1204 if((ctx == NULL) || (sessionWasResumed == NULL) ||
1205 (sessionID == NULL) || (sessionIDLength == NULL) ||
1206 (*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
1207 return paramErr;
1208 }
1209 if(ctx->sessionMatch) {
1210 assert(ctx->sessionID.data != NULL);
1211 *sessionWasResumed = true;
1212 if(ctx->sessionID.length > *sessionIDLength) {
1213 /* really should never happen - means ID > 32 */
1214 return paramErr;
1215 }
1216 memmove(sessionID, ctx->sessionID.data, ctx->sessionID.length);
1217 *sessionIDLength = ctx->sessionID.length;
1218 }
1219 else {
1220 *sessionWasResumed = false;
1221 *sessionIDLength = 0;
1222 }
1223 return noErr;
1224 }
1225
1226