]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslContext.cpp
835f65508c0ad7cf98f77ce35050fc520ddca520
[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->signingKeyCsp, &ctx->signingPubKey, NULL);
242 sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPubKey, NULL);
243 sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
244
245 sslFreeTrustedRoots(ctx);
246
247 detachFromAll(ctx);
248
249 memset(ctx, 0, sizeof(SSLContext));
250 sslFree(ctx);
251 sslCleanupSession();
252 return noErr;
253 }
254
255 /*
256 * Determine the state of an SSL session.
257 */
258 OSStatus
259 SSLGetSessionState (SSLContextRef context,
260 SSLSessionState *state) /* RETURNED */
261 {
262 SSLSessionState rtnState = kSSLIdle;
263
264 if(context == NULL) {
265 return paramErr;
266 }
267 *state = rtnState;
268 switch(context->state) {
269 case SSL_HdskStateUninit:
270 case SSL_HdskStateServerUninit:
271 case SSL_HdskStateClientUninit:
272 rtnState = kSSLIdle;
273 break;
274 case SSL_HdskStateGracefulClose:
275 rtnState = kSSLClosed;
276 break;
277 case SSL_HdskStateErrorClose:
278 case SSL_HdskStateNoNotifyClose:
279 rtnState = kSSLAborted;
280 break;
281 case SSL_HdskStateServerReady:
282 case SSL_HdskStateClientReady:
283 rtnState = kSSLConnected;
284 break;
285 default:
286 assert((context->state >= SSL_HdskStateServerHello) &&
287 (context->state <= SSL2_HdskStateServerFinished));
288 rtnState = kSSLHandshake;
289 break;
290
291 }
292 *state = rtnState;
293 return noErr;
294 }
295
296 OSStatus
297 SSLSetIOFuncs (SSLContextRef ctx,
298 SSLReadFunc read,
299 SSLWriteFunc write)
300 {
301 if(ctx == NULL) {
302 return paramErr;
303 }
304 if(sslIsSessionActive(ctx)) {
305 /* can't do this with an active session */
306 return badReqErr;
307 }
308 ctx->ioCtx.read = read;
309 ctx->ioCtx.write = write;
310 return noErr;
311 }
312
313 OSStatus
314 SSLSetConnection (SSLContextRef ctx,
315 SSLConnectionRef connection)
316 {
317 if(ctx == NULL) {
318 return paramErr;
319 }
320 if(sslIsSessionActive(ctx)) {
321 /* can't do this with an active session */
322 return badReqErr;
323 }
324 ctx->ioCtx.ioRef = connection;
325 return noErr;
326 }
327
328 OSStatus
329 SSLGetConnection (SSLContextRef ctx,
330 SSLConnectionRef *connection)
331 {
332 if((ctx == NULL) || (connection == NULL)) {
333 return paramErr;
334 }
335 *connection = ctx->ioCtx.ioRef;
336 return noErr;
337 }
338
339 OSStatus
340 SSLSetPeerDomainName (SSLContextRef ctx,
341 const char *peerName,
342 size_t peerNameLen)
343 {
344 if(ctx == NULL) {
345 return paramErr;
346 }
347 if(sslIsSessionActive(ctx)) {
348 /* can't do this with an active session */
349 return badReqErr;
350 }
351
352 /* free possible existing name */
353 if(ctx->peerDomainName) {
354 sslFree(ctx->peerDomainName);
355 }
356
357 /* copy in */
358 ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
359 if(ctx->peerDomainName == NULL) {
360 return memFullErr;
361 }
362 memmove(ctx->peerDomainName, peerName, peerNameLen);
363 ctx->peerDomainNameLen = peerNameLen;
364 return noErr;
365 }
366
367 /*
368 * Determine the buffer size needed for SSLGetPeerDomainName().
369 */
370 OSStatus
371 SSLGetPeerDomainNameLength (SSLContextRef ctx,
372 size_t *peerNameLen) // RETURNED
373 {
374 if(ctx == NULL) {
375 return paramErr;
376 }
377 *peerNameLen = ctx->peerDomainNameLen;
378 return noErr;
379 }
380
381 OSStatus
382 SSLGetPeerDomainName (SSLContextRef ctx,
383 char *peerName, // returned here
384 size_t *peerNameLen) // IN/OUT
385 {
386 if(ctx == NULL) {
387 return paramErr;
388 }
389 if(*peerNameLen < ctx->peerDomainNameLen) {
390 return errSSLBufferOverflow;
391 }
392 memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
393 *peerNameLen = ctx->peerDomainNameLen;
394 return noErr;
395 }
396
397 /* concert between private SSLProtocolVersion and public SSLProtocol */
398 static SSLProtocol convertProtToExtern(SSLProtocolVersion prot)
399 {
400 switch(prot) {
401 case SSL_Version_Undetermined:
402 return kSSLProtocolUnknown;
403 case SSL_Version_2_0:
404 return kSSLProtocol2;
405 case SSL_Version_3_0:
406 return kSSLProtocol3;
407 case TLS_Version_1_0:
408 return kTLSProtocol1;
409 default:
410 sslErrorLog("convertProtToExtern: bad prot\n");
411 return kSSLProtocolUnknown;
412 }
413 /* not reached but make compiler happy */
414 return kSSLProtocolUnknown;
415 }
416
417 OSStatus
418 SSLSetProtocolVersionEnabled(SSLContextRef ctx,
419 SSLProtocol protocol,
420 Boolean enable) /* RETURNED */
421 {
422 if(ctx == NULL) {
423 return paramErr;
424 }
425 if(sslIsSessionActive(ctx)) {
426 /* can't do this with an active session */
427 return badReqErr;
428 }
429 switch(protocol) {
430 case kSSLProtocol2:
431 ctx->versionSsl2Enable = enable;
432 break;
433 case kSSLProtocol3:
434 ctx->versionSsl3Enable = enable;
435 break;
436 case kTLSProtocol1:
437 ctx->versionTls1Enable = enable;
438 break;
439 case kSSLProtocolAll:
440 ctx->versionTls1Enable = ctx->versionSsl3Enable =
441 ctx->versionSsl2Enable = enable;
442 break;
443 default:
444 return paramErr;
445 }
446 return noErr;
447 }
448
449 OSStatus
450 SSLGetProtocolVersionEnabled(SSLContextRef ctx,
451 SSLProtocol protocol,
452 Boolean *enable) /* RETURNED */
453 {
454 if(ctx == NULL) {
455 return paramErr;
456 }
457 switch(protocol) {
458 case kSSLProtocol2:
459 *enable = ctx->versionSsl2Enable;
460 break;
461 case kSSLProtocol3:
462 *enable = ctx->versionSsl3Enable;
463 break;
464 case kTLSProtocol1:
465 *enable = ctx->versionTls1Enable;
466 break;
467 case kSSLProtocolAll:
468 if(ctx->versionTls1Enable && ctx->versionSsl3Enable &&
469 ctx->versionSsl2Enable) {
470 *enable = true;
471 }
472 else {
473 *enable = false;
474 }
475 break;
476 default:
477 return paramErr;
478 }
479 return noErr;
480 }
481
482 /* deprecated */
483 OSStatus
484 SSLSetProtocolVersion (SSLContextRef ctx,
485 SSLProtocol version)
486 {
487 if(ctx == NULL) {
488 return paramErr;
489 }
490 if(sslIsSessionActive(ctx)) {
491 /* can't do this with an active session */
492 return badReqErr;
493 }
494
495 /* convert external representation to three booleans */
496 switch(version) {
497 case kSSLProtocolUnknown:
498 ctx->versionSsl2Enable = DEFAULT_SSL2_ENABLE;
499 ctx->versionSsl3Enable = DEFAULT_SSL3_ENABLE;
500 ctx->versionTls1Enable = DEFAULT_TLS1_ENABLE;
501 break;
502 case kSSLProtocol2:
503 ctx->versionSsl2Enable = true;
504 ctx->versionSsl3Enable = false;
505 ctx->versionTls1Enable = false;
506 break;
507 case kSSLProtocol3:
508 /* this tells us to do our best, up to 3.0, but allows 2.0 */
509 ctx->versionSsl2Enable = true;
510 ctx->versionSsl3Enable = true;
511 ctx->versionTls1Enable = false;
512 break;
513 case kSSLProtocol3Only:
514 ctx->versionSsl2Enable = false;
515 ctx->versionSsl3Enable = true;
516 ctx->versionTls1Enable = false;
517 break;
518 case kTLSProtocol1:
519 case kSSLProtocolAll:
520 /* this tells us to do our best, up to TLS, but allows 2.0 or 3.0 */
521 ctx->versionSsl2Enable = true;
522 ctx->versionSsl3Enable = true;
523 ctx->versionTls1Enable = true;
524 break;
525 case kTLSProtocol1Only:
526 ctx->versionSsl2Enable = false;
527 ctx->versionSsl3Enable = false;
528 ctx->versionTls1Enable = true;
529 break;
530 default:
531 return paramErr;
532 }
533 return noErr;
534 }
535
536 /* deprecated */
537 OSStatus
538 SSLGetProtocolVersion (SSLContextRef ctx,
539 SSLProtocol *protocol) /* RETURNED */
540 {
541 if(ctx == NULL) {
542 return paramErr;
543 }
544
545 /* translate array of booleans to public value; not all combinations
546 * are legal (i.e., meaningful) for this call */
547 if(ctx->versionTls1Enable) {
548 if(ctx->versionSsl2Enable) {
549 if(ctx->versionSsl3Enable) {
550 /* traditional 'all enabled' */
551 *protocol = kTLSProtocol1;
552 return noErr;
553 }
554 else {
555 /* SSL2 true, SSL3 false, TLS1 true - invalid here */
556 return paramErr;
557 }
558 }
559 else if(ctx->versionSsl3Enable) {
560 /* SSL2 false, SSL3 true, TLS1 true - invalid here */
561 return paramErr;
562 }
563 else {
564 *protocol = kTLSProtocol1Only;
565 return noErr;
566 }
567 }
568 else {
569 /* TLS1 false */
570 if(ctx->versionSsl3Enable) {
571 *protocol = ctx->versionSsl2Enable ?
572 kSSLProtocol3 : kSSLProtocol3Only;
573 return noErr;
574 }
575 else if(ctx->versionSsl2Enable) {
576 *protocol = kSSLProtocol2;
577 return noErr;
578 }
579 else {
580 /*
581 * Bogus state - no enables - the API does provide a way
582 * to get into this state. Other than this path, the app
583 * will discover this bogon when attempting to do the
584 * handshake; sslGetMaxProtVersion will detect this.
585 */
586 return paramErr;
587 }
588 }
589 /* NOT REACHED */
590 }
591
592 OSStatus
593 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx,
594 SSLProtocol *protocol) /* RETURNED */
595 {
596 if(ctx == NULL) {
597 return paramErr;
598 }
599 *protocol = convertProtToExtern(ctx->negProtocolVersion);
600 return noErr;
601 }
602
603 OSStatus
604 SSLSetEnableCertVerify (SSLContextRef ctx,
605 Boolean enableVerify)
606 {
607 if(ctx == NULL) {
608 return paramErr;
609 }
610 sslCertDebug("SSLSetEnableCertVerify %s",
611 enableVerify ? "true" : "false");
612 if(sslIsSessionActive(ctx)) {
613 /* can't do this with an active session */
614 return badReqErr;
615 }
616 ctx->enableCertVerify = enableVerify;
617 return noErr;
618 }
619
620 OSStatus
621 SSLGetEnableCertVerify (SSLContextRef ctx,
622 Boolean *enableVerify)
623 {
624 if(ctx == NULL) {
625 return paramErr;
626 }
627 *enableVerify = ctx->enableCertVerify;
628 return noErr;
629 }
630
631 OSStatus
632 SSLSetAllowsExpiredCerts(SSLContextRef ctx,
633 Boolean allowExpired)
634 {
635 if(ctx == NULL) {
636 return paramErr;
637 }
638 sslCertDebug("SSLSetAllowsExpiredCerts %s",
639 allowExpired ? "true" : "false");
640 if(sslIsSessionActive(ctx)) {
641 /* can't do this with an active session */
642 return badReqErr;
643 }
644 ctx->allowExpiredCerts = allowExpired;
645 return noErr;
646 }
647
648 OSStatus
649 SSLGetAllowsExpiredCerts (SSLContextRef ctx,
650 Boolean *allowExpired)
651 {
652 if(ctx == NULL) {
653 return paramErr;
654 }
655 *allowExpired = ctx->allowExpiredCerts;
656 return noErr;
657 }
658
659 OSStatus
660 SSLSetAllowsExpiredRoots(SSLContextRef ctx,
661 Boolean allowExpired)
662 {
663 if(ctx == NULL) {
664 return paramErr;
665 }
666 sslCertDebug("SSLSetAllowsExpiredRoots %s",
667 allowExpired ? "true" : "false");
668 if(sslIsSessionActive(ctx)) {
669 /* can't do this with an active session */
670 return badReqErr;
671 }
672 ctx->allowExpiredRoots = allowExpired;
673 return noErr;
674 }
675
676 OSStatus
677 SSLGetAllowsExpiredRoots (SSLContextRef ctx,
678 Boolean *allowExpired)
679 {
680 if(ctx == NULL) {
681 return paramErr;
682 }
683 *allowExpired = ctx->allowExpiredRoots;
684 return noErr;
685 }
686
687 OSStatus SSLSetAllowsAnyRoot(
688 SSLContextRef ctx,
689 Boolean anyRoot)
690 {
691 if(ctx == NULL) {
692 return paramErr;
693 }
694 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot ? "true" : "false");
695 ctx->allowAnyRoot = anyRoot;
696 return noErr;
697 }
698
699 OSStatus
700 SSLGetAllowsAnyRoot(
701 SSLContextRef ctx,
702 Boolean *anyRoot)
703 {
704 if(ctx == NULL) {
705 return paramErr;
706 }
707 *anyRoot = ctx->allowAnyRoot;
708 return noErr;
709 }
710
711 OSStatus
712 SSLSetTrustedRoots (SSLContextRef ctx,
713 CFArrayRef trustedRoots,
714 Boolean replaceExisting)
715 {
716 unsigned dex;
717 unsigned outDex;
718 unsigned numIncoming;
719 uint32 numCerts;
720 CSSM_DATA_PTR newRoots = NULL;
721 const CSSM_DATA *existAnchors = NULL;
722 uint32 numExistAnchors = 0;
723 OSStatus ortn = noErr;
724
725 if(ctx == NULL) {
726 return paramErr;
727 }
728 if(sslIsSessionActive(ctx)) {
729 /* can't do this with an active session */
730 return badReqErr;
731 }
732 numCerts = numIncoming = CFArrayGetCount(trustedRoots);
733 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
734 (int)numCerts, replaceExisting ? "true" : "false");
735 if(!replaceExisting) {
736 if(ctx->trustedCerts != NULL) {
737 /* adding to existing store */
738 existAnchors = ctx->trustedCerts;
739 numExistAnchors = ctx->numTrustedCerts;
740 }
741 else {
742 /* adding to system roots */
743 ortn = SecTrustGetCSSMAnchorCertificates(&existAnchors,
744 &numExistAnchors);
745 if(ortn) {
746 /* should never happen */
747 return ortn;
748 }
749 }
750 numCerts += numExistAnchors;
751 }
752 newRoots = (CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA));
753 memset(newRoots, 0, numCerts * sizeof(CSSM_DATA));
754
755 /* Caller's certs first */
756 for(dex=0, outDex=0; dex<numIncoming; dex++, outDex++) {
757 CSSM_DATA certData;
758 SecCertificateRef secCert = (SecCertificateRef)
759 CFArrayGetValueAtIndex(trustedRoots, dex);
760
761 if(CFGetTypeID(secCert) != SecCertificateGetTypeID()) {
762 /* elements of trustedRoots must be SecCertificateRefs */
763 ortn = paramErr;
764 goto abort;
765 }
766 ortn = SecCertificateGetData(secCert, &certData);
767 if(ortn) {
768 goto abort;
769 }
770 stSetUpCssmData(&newRoots[outDex], certData.Length);
771 memmove(newRoots[outDex].Data, certData.Data, certData.Length);
772 }
773
774 /* now existing roots - either ours, or the system's */
775 for(dex=0; dex<numExistAnchors; dex++, outDex++) {
776 stSetUpCssmData(&newRoots[outDex], existAnchors[dex].Length);
777 memmove(newRoots[outDex].Data, existAnchors[dex].Data,
778 existAnchors[dex].Length);
779 }
780
781 /* success - replace context values */
782 sslFreeTrustedRoots(ctx);
783 ctx->numTrustedCerts = numCerts;
784 ctx->trustedCerts = newRoots;
785 return noErr;
786
787 abort:
788 sslFree(newRoots);
789 return ortn;
790 }
791
792 OSStatus
793 SSLGetTrustedRoots (SSLContextRef ctx,
794 CFArrayRef *trustedRoots) /* RETURNED */
795 {
796 uint32 numCerts;
797 const CSSM_DATA *certs;
798 CFMutableArrayRef certArray;
799 unsigned dex;
800 SecCertificateRef secCert;
801 OSStatus ortn;
802
803 if(ctx == NULL) {
804 return paramErr;
805 }
806 if(ctx->trustedCerts != NULL) {
807 /* use ours */
808 certs = ctx->trustedCerts;
809 numCerts = ctx->numTrustedCerts;
810 }
811 else {
812 /* use default system roots */
813 OSStatus ortn = SecTrustGetCSSMAnchorCertificates(&certs,
814 &numCerts);
815 if(ortn) {
816 /* should never happen */
817 return ortn;
818 }
819 }
820
821 certArray = CFArrayCreateMutable(kCFAllocatorDefault,
822 (CFIndex)numCerts, &kCFTypeArrayCallBacks);
823 if(certArray == NULL) {
824 return memFullErr;
825 }
826 for(dex=0; dex<numCerts; dex++) {
827 ortn = SecCertificateCreateFromData(&certs[dex],
828 CSSM_CERT_X_509v3,
829 CSSM_CERT_ENCODING_DER,
830 &secCert);
831 if(ortn) {
832 CFRelease(certArray);
833 return ortn;
834 }
835 CFArrayAppendValue(certArray, secCert);
836 }
837 *trustedRoots = certArray;
838 return noErr;
839 }
840
841 OSStatus
842 SSLSetClientSideAuthenticate (SSLContext *ctx,
843 SSLAuthenticate auth)
844 {
845 if(ctx == NULL) {
846 return paramErr;
847 }
848 if(sslIsSessionActive(ctx)) {
849 /* can't do this with an active session */
850 return badReqErr;
851 }
852 ctx->clientAuth = auth;
853 switch(auth) {
854 case kNeverAuthenticate:
855 ctx->tryClientAuth = false;
856 break;
857 case kAlwaysAuthenticate:
858 case kTryAuthenticate:
859 ctx->tryClientAuth = true;
860 break;
861 }
862 return noErr;
863 }
864
865 OSStatus
866 SSLGetClientCertificateState (SSLContextRef ctx,
867 SSLClientCertificateState *clientState)
868 {
869 if(ctx == NULL) {
870 return paramErr;
871 }
872 *clientState = ctx->clientCertState;
873 return noErr;
874 }
875
876 OSStatus
877 SSLSetCertificate (SSLContextRef ctx,
878 CFArrayRef certRefs)
879 {
880 /*
881 * -- free localCerts if we have any
882 * -- Get raw cert data, convert to ctx->localCert
883 * -- get pub, priv keys from certRef[0]
884 * -- validate cert chain
885 */
886 if(ctx == NULL) {
887 return paramErr;
888 }
889 if(sslIsSessionActive(ctx)) {
890 /* can't do this with an active session */
891 return badReqErr;
892 }
893 return parseIncomingCerts(ctx,
894 certRefs,
895 &ctx->localCert,
896 &ctx->signingPubKey,
897 &ctx->signingPrivKey,
898 &ctx->signingKeyCsp
899 #if ST_KC_KEYS_NEED_REF
900 ,
901 &ctx->signingKeyRef
902 #else
903 );
904 #endif
905 }
906
907 OSStatus
908 SSLSetEncryptionCertificate (SSLContextRef ctx,
909 CFArrayRef certRefs)
910 {
911 /*
912 * -- free encryptCert if we have any
913 * -- Get raw cert data, convert to ctx->encryptCert
914 * -- get pub, priv keys from certRef[0]
915 * -- validate cert chain
916 */
917 if(ctx == NULL) {
918 return paramErr;
919 }
920 if(sslIsSessionActive(ctx)) {
921 /* can't do this with an active session */
922 return badReqErr;
923 }
924 return parseIncomingCerts(ctx,
925 certRefs,
926 &ctx->encryptCert,
927 &ctx->encryptPubKey,
928 &ctx->encryptPrivKey,
929 &ctx->encryptKeyCsp);
930 }
931
932 OSStatus
933 SSLSetPeerID (SSLContext *ctx,
934 const void *peerID,
935 size_t peerIDLen)
936 {
937 OSStatus serr;
938
939 /* copy peerId to context->peerId */
940 if((ctx == NULL) ||
941 (peerID == NULL) ||
942 (peerIDLen == 0)) {
943 return paramErr;
944 }
945 if(sslIsSessionActive(ctx)) {
946 /* can't do this with an active session */
947 return badReqErr;
948 }
949 SSLFreeBuffer(ctx->peerID, ctx);
950 serr = SSLAllocBuffer(ctx->peerID, peerIDLen, ctx);
951 if(serr) {
952 return serr;
953 }
954 memmove(ctx->peerID.data, peerID, peerIDLen);
955 return noErr;
956 }
957
958 OSStatus
959 SSLGetPeerID (SSLContextRef ctx,
960 const void **peerID,
961 size_t *peerIDLen)
962 {
963 *peerID = ctx->peerID.data; // may be NULL
964 *peerIDLen = ctx->peerID.length;
965 return noErr;
966 }
967
968 OSStatus
969 SSLGetNegotiatedCipher (SSLContextRef ctx,
970 SSLCipherSuite *cipherSuite)
971 {
972 if(ctx == NULL) {
973 return paramErr;
974 }
975 if(!sslIsSessionActive(ctx)) {
976 return badReqErr;
977 }
978 *cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
979 return noErr;
980 }
981
982 /*
983 * Add an acceptable distinguished name (client authentication only).
984 */
985 OSStatus
986 SSLAddDistinguishedName(
987 SSLContextRef ctx,
988 const void *derDN,
989 size_t derDNLen)
990 {
991 DNListElem *dn;
992 OSStatus err;
993
994 dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
995 if(dn == NULL) {
996 return memFullErr;
997 }
998 if ((err = SSLAllocBuffer(dn->derDN, derDNLen, ctx)) != 0)
999 return err;
1000 memcpy(dn->derDN.data, derDN, derDNLen);
1001 dn->next = ctx->acceptableDNList;
1002 ctx->acceptableDNList = dn;
1003 return noErr;
1004 }
1005
1006 /*
1007 * Request peer certificates. Valid anytime, subsequent to
1008 * a handshake attempt.
1009 */
1010 OSStatus
1011 SSLGetPeerCertificates (SSLContextRef ctx,
1012 CFArrayRef *certs)
1013 {
1014 uint32 numCerts;
1015 CFMutableArrayRef ca;
1016 CFIndex i;
1017 SecCertificateRef cfd;
1018 OSStatus ortn;
1019 CSSM_DATA certData;
1020 SSLCertificate *scert;
1021
1022 if(ctx == NULL) {
1023 return paramErr;
1024 }
1025 *certs = NULL;
1026
1027 /*
1028 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
1029 * CFDataRefs, each of which is one DER-encoded cert.
1030 */
1031 numCerts = SSLGetCertificateChainLength(ctx->peerCert);
1032 if(numCerts == 0) {
1033 return noErr;
1034 }
1035 ca = CFArrayCreateMutable(kCFAllocatorDefault,
1036 (CFIndex)numCerts, &kCFTypeArrayCallBacks);
1037 if(ca == NULL) {
1038 return memFullErr;
1039 }
1040
1041 /*
1042 * Caller gets leaf cert first, the opposite of the way we store them.
1043 */
1044 scert = ctx->peerCert;
1045 for(i=0; (unsigned)i<numCerts; i++) {
1046 assert(scert != NULL); /* else SSLGetCertificateChainLength
1047 * broken */
1048 SSLBUF_TO_CSSM(&scert->derCert, &certData);
1049 ortn = SecCertificateCreateFromData(&certData,
1050 CSSM_CERT_X_509v3,
1051 CSSM_CERT_ENCODING_DER,
1052 &cfd);
1053 if(ortn) {
1054 CFRelease(ca);
1055 return ortn;
1056 }
1057 /* insert at head of array */
1058 CFArrayInsertValueAtIndex(ca, 0, cfd);
1059 scert = scert->next;
1060 }
1061 *certs = ca;
1062 return noErr;
1063 }
1064
1065 /*
1066 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1067 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1068 * been called, a set of process-wide parameters will be calculated. However
1069 * that can take a long time (30 seconds).
1070 */
1071 OSStatus SSLSetDiffieHellmanParams(
1072 SSLContextRef ctx,
1073 const void *dhParams,
1074 size_t dhParamsLen)
1075 {
1076 if(ctx == NULL) {
1077 return paramErr;
1078 }
1079 if(sslIsSessionActive(ctx)) {
1080 return badReqErr;
1081 }
1082 SSLFreeBuffer(ctx->dhParamsPrime, ctx);
1083 SSLFreeBuffer(ctx->dhParamsGenerator, ctx);
1084 SSLFreeBuffer(ctx->dhParamsEncoded, ctx);
1085
1086 OSStatus ortn;
1087 ortn = SSLCopyBufferFromData(dhParams, dhParamsLen,
1088 ctx->dhParamsEncoded);
1089 if(ortn) {
1090 return ortn;
1091 }
1092
1093 /* decode for use by server over the wire */
1094 SSLBuffer sParams;
1095 sParams.data = (UInt8 *)dhParams;
1096 sParams.length = dhParamsLen;
1097 return sslDecodeDhParams(&sParams, &ctx->dhParamsPrime,
1098 &ctx->dhParamsGenerator);
1099 }
1100
1101 /*
1102 * Return parameter block specified in SSLSetDiffieHellmanParams.
1103 * Returned data is not copied and belongs to the SSLContextRef.
1104 */
1105 OSStatus SSLGetDiffieHellmanParams(
1106 SSLContextRef ctx,
1107 const void **dhParams,
1108 size_t *dhParamsLen)
1109 {
1110 if(ctx == NULL) {
1111 return paramErr;
1112 }
1113 *dhParams = ctx->dhParamsEncoded.data;
1114 *dhParamsLen = ctx->dhParamsEncoded.length;
1115 return noErr;
1116 }
1117
1118 OSStatus SSLSetRsaBlinding(
1119 SSLContextRef ctx,
1120 Boolean blinding)
1121 {
1122 if(ctx == NULL) {
1123 return paramErr;
1124 }
1125 ctx->rsaBlindingEnable = blinding;
1126 return noErr;
1127 }
1128
1129 OSStatus SSLGetRsaBlinding(
1130 SSLContextRef ctx,
1131 Boolean *blinding)
1132 {
1133 if(ctx == NULL) {
1134 return paramErr;
1135 }
1136 *blinding = ctx->rsaBlindingEnable;
1137 return noErr;
1138 }
1139
1140 OSStatus SSLGetPeerSecTrust(
1141 SSLContextRef ctx,
1142 SecTrustRef *secTrust) /* RETURNED */
1143 {
1144 if(ctx == NULL) {
1145 return paramErr;
1146 }
1147 *secTrust = ctx->peerSecTrust;
1148 return noErr;
1149 }
1150
1151 OSStatus SSLInternalMasterSecret(
1152 SSLContextRef ctx,
1153 void *secret, // mallocd by caller, SSL_MASTER_SECRET_SIZE
1154 size_t *secretSize) // in/out
1155 {
1156 if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
1157 return paramErr;
1158 }
1159 if(*secretSize < SSL_MASTER_SECRET_SIZE) {
1160 return paramErr;
1161 }
1162 memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
1163 *secretSize = SSL_MASTER_SECRET_SIZE;
1164 return noErr;
1165 }
1166
1167 OSStatus SSLInternalServerRandom(
1168 SSLContextRef ctx,
1169 void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1170 size_t *randSize) // in/out
1171 {
1172 if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
1173 return paramErr;
1174 }
1175 if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
1176 return paramErr;
1177 }
1178 memmove(rand, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
1179 *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
1180 return noErr;
1181 }
1182
1183 OSStatus SSLInternalClientRandom(
1184 SSLContextRef ctx,
1185 void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1186 size_t *randSize) // in/out
1187 {
1188 if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
1189 return paramErr;
1190 }
1191 if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
1192 return paramErr;
1193 }
1194 memmove(rand, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
1195 *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
1196 return noErr;
1197 }
1198
1199 OSStatus
1200 SSLGetResumableSessionInfo(
1201 SSLContextRef ctx,
1202 Boolean *sessionWasResumed, // RETURNED
1203 void *sessionID, // RETURNED, mallocd by caller
1204 size_t *sessionIDLength) // IN/OUT
1205 {
1206 if((ctx == NULL) || (sessionWasResumed == NULL) ||
1207 (sessionID == NULL) || (sessionIDLength == NULL) ||
1208 (*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
1209 return paramErr;
1210 }
1211 if(ctx->sessionMatch) {
1212 assert(ctx->sessionID.data != NULL);
1213 *sessionWasResumed = true;
1214 if(ctx->sessionID.length > *sessionIDLength) {
1215 /* really should never happen - means ID > 32 */
1216 return paramErr;
1217 }
1218 memmove(sessionID, ctx->sessionID.data, ctx->sessionID.length);
1219 *sessionIDLength = ctx->sessionID.length;
1220 }
1221 else {
1222 *sessionWasResumed = false;
1223 *sessionIDLength = 0;
1224 }
1225 return noErr;
1226 }
1227
1228