]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslContext.cpp
Security-54.1.3.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 <string.h>
42 #include <Security/SecCertificate.h>
43 #include <Security/SecTrust.h>
44
45 static void sslFreeDnList(
46 SSLContext *ctx)
47 {
48 DNListElem *dn, *nextDN;
49
50 dn = ctx->acceptableDNList;
51 while (dn)
52 {
53 SSLFreeBuffer(dn->derDN, ctx);
54 nextDN = dn->next;
55 sslFree(dn);
56 dn = nextDN;
57 }
58 ctx->acceptableDNList = NULL;
59 }
60
61 static OSStatus sslFreeTrustedRoots(
62 SSLContext *ctx)
63 {
64 unsigned i;
65
66 assert(ctx != NULL);
67 if((ctx->numTrustedCerts == 0) || (ctx->trustedCerts == NULL)) {
68 /* they really should both be zero, right? */
69 assert((ctx->numTrustedCerts == 0) && (ctx->trustedCerts == NULL));
70 }
71 else {
72 for(i=0; i<ctx->numTrustedCerts; i++) {
73 stFreeCssmData(&ctx->trustedCerts[i], CSSM_FALSE);
74 }
75 sslFree(ctx->trustedCerts);
76 }
77 ctx->numTrustedCerts = 0;
78 ctx->trustedCerts = NULL;
79 sslFreeDnList(ctx);
80 return noErr;
81 }
82
83 /*
84 * Default attempted version.
85 */
86 #define DEFAULT_MAX_VERSION TLS_Version_1_0
87
88 OSStatus
89 SSLNewContext (Boolean isServer,
90 SSLContextRef *contextPtr) /* RETURNED */
91 {
92 SSLContext *ctx;
93 OSStatus serr;
94
95 if(contextPtr == NULL) {
96 return paramErr;
97 }
98 *contextPtr = NULL;
99 ctx = (SSLContext *)sslMalloc(sizeof(SSLContext));
100 if(ctx == NULL) {
101 return memFullErr;
102 }
103 /* subsequent errors to errOut: */
104
105 memset(ctx, 0, sizeof(SSLContext));
106 ctx->state = SSL_HdskStateUninit;
107 ctx->clientCertState = kSSLClientCertNone;
108
109 /* different defaults for client and server ... */
110 if(isServer) {
111 ctx->protocolSide = SSL_ServerSide;
112 ctx->reqProtocolVersion = DEFAULT_MAX_VERSION;
113 }
114 else {
115 ctx->protocolSide = SSL_ClientSide;
116 ctx->reqProtocolVersion = SSL_Version_Undetermined;
117 }
118 ctx->negProtocolVersion = SSL_Version_Undetermined;
119 ctx->maxProtocolVersion = DEFAULT_MAX_VERSION;
120 /* Default value so we can send and receive hello msgs */
121 ctx->sslTslCalls = &Ssl3Callouts;
122
123 /* Initialize the cipher state to NULL_WITH_NULL_NULL */
124 ctx->selectedCipherSpec = &SSL_NULL_WITH_NULL_NULL_CipherSpec;
125 ctx->selectedCipher = ctx->selectedCipherSpec->cipherSpec;
126 ctx->writeCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
127 ctx->readCipher.macRef = ctx->selectedCipherSpec->macAlgorithm;
128 ctx->readCipher.symCipher = ctx->selectedCipherSpec->cipher;
129 ctx->writeCipher.symCipher = ctx->selectedCipherSpec->cipher;
130
131 /* these two are invariant */
132 ctx->writeCipher.encrypting = 1;
133 ctx->writePending.encrypting = 1;
134
135 /* this gets init'd on first call to SSLHandshake() */
136 ctx->validCipherSpecs = NULL;
137 ctx->numValidCipherSpecs = 0;
138
139 ctx->peerDomainName = NULL;
140 ctx->peerDomainNameLen = 0;
141
142 /* attach to CSP, CL, TP */
143 serr = attachToAll(ctx);
144 if(serr) {
145 goto errOut;
146 }
147
148 /* Initial cert verify state: verify with default system roots */
149 ctx->enableCertVerify = true;
150
151 /* snag root certs from Keychain, tolerate error */
152 addBuiltInCerts(ctx);
153
154 *contextPtr = ctx;
155 return noErr;
156
157 errOut:
158 sslFree(ctx);
159 return serr;
160 }
161
162
163 /*
164 * Dispose of an SSLContext.
165 */
166 OSStatus
167 SSLDisposeContext (SSLContext *ctx)
168 {
169 WaitingRecord *wait, *next;
170 SSLBuffer buf;
171
172 if(ctx == NULL) {
173 return paramErr;
174 }
175 sslDeleteCertificateChain(ctx->localCert, ctx);
176 sslDeleteCertificateChain(ctx->encryptCert, ctx);
177 sslDeleteCertificateChain(ctx->peerCert, ctx);
178 ctx->localCert = ctx->encryptCert = ctx->peerCert = NULL;
179 SSLFreeBuffer(ctx->partialReadBuffer, ctx);
180
181 wait = ctx->recordWriteQueue;
182 while (wait)
183 { SSLFreeBuffer(wait->data, ctx);
184 next = wait->next;
185 buf.data = (uint8*)wait;
186 buf.length = sizeof(WaitingRecord);
187 SSLFreeBuffer(buf, ctx);
188 wait = next;
189 }
190
191 SSLFreeBuffer(ctx->dhPeerPublic, ctx);
192 SSLFreeBuffer(ctx->dhExchangePublic, ctx);
193 SSLFreeBuffer(ctx->dhPrivate, ctx);
194
195 CloseHash(SSLHashSHA1, ctx->shaState, ctx);
196 CloseHash(SSLHashMD5, ctx->md5State, ctx);
197
198 SSLFreeBuffer(ctx->sessionID, ctx);
199 SSLFreeBuffer(ctx->peerID, ctx);
200 SSLFreeBuffer(ctx->resumableSession, ctx);
201 SSLFreeBuffer(ctx->preMasterSecret, ctx);
202 SSLFreeBuffer(ctx->partialReadBuffer, ctx);
203 SSLFreeBuffer(ctx->fragmentedMessageCache, ctx);
204 SSLFreeBuffer(ctx->receivedDataBuffer, ctx);
205
206 if(ctx->peerDomainName) {
207 sslFree(ctx->peerDomainName);
208 ctx->peerDomainName = NULL;
209 ctx->peerDomainNameLen = 0;
210 }
211 SSLDisposeCipherSuite(&ctx->readCipher, ctx);
212 SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
213 SSLDisposeCipherSuite(&ctx->readPending, ctx);
214 SSLDisposeCipherSuite(&ctx->writePending, ctx);
215
216 sslFree(ctx->validCipherSpecs);
217 ctx->validCipherSpecs = NULL;
218 ctx->numValidCipherSpecs = 0;
219
220 /*
221 * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
222 * We really don't know what CSP the CL used to generate a public key (in fact,
223 * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
224 * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
225 * signingPubKey is not tecnically accurate. However, our public keys
226 * are all raw keys, and all Apple CSPs dispose of raw keys in the same
227 * way.
228 */
229 sslFreeKey(ctx->signingKeyCsp, &ctx->signingPubKey, NULL);
230 sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPubKey, NULL);
231 sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
232
233 sslFreeTrustedRoots(ctx);
234
235 detachFromAll(ctx);
236
237 memset(ctx, 0, sizeof(SSLContext));
238 sslFree(ctx);
239 sslCleanupSession();
240 return noErr;
241 }
242
243 /*
244 * Determine the state of an SSL session.
245 */
246 OSStatus
247 SSLGetSessionState (SSLContextRef context,
248 SSLSessionState *state) /* RETURNED */
249 {
250 SSLSessionState rtnState = kSSLIdle;
251
252 if(context == NULL) {
253 return paramErr;
254 }
255 *state = rtnState;
256 switch(context->state) {
257 case SSL_HdskStateUninit:
258 case SSL_HdskStateServerUninit:
259 case SSL_HdskStateClientUninit:
260 rtnState = kSSLIdle;
261 break;
262 case SSL_HdskStateGracefulClose:
263 rtnState = kSSLClosed;
264 break;
265 case SSL_HdskStateErrorClose:
266 case SSL_HdskStateNoNotifyClose:
267 rtnState = kSSLAborted;
268 break;
269 case SSL2_HdskStateServerReady:
270 case SSL2_HdskStateClientReady:
271 rtnState = kSSLConnected;
272 break;
273 default:
274 assert((context->state >= SSL_HdskStateServerHello) &&
275 (context->state <= SSL2_HdskStateServerFinished));
276 rtnState = kSSLHandshake;
277 break;
278
279 }
280 *state = rtnState;
281 return noErr;
282 }
283
284 OSStatus
285 SSLSetIOFuncs (SSLContextRef ctx,
286 SSLReadFunc read,
287 SSLWriteFunc write)
288 {
289 if(ctx == NULL) {
290 return paramErr;
291 }
292 if(sslIsSessionActive(ctx)) {
293 /* can't do this with an active session */
294 return badReqErr;
295 }
296 ctx->ioCtx.read = read;
297 ctx->ioCtx.write = write;
298 return noErr;
299 }
300
301 OSStatus
302 SSLSetConnection (SSLContextRef ctx,
303 SSLConnectionRef connection)
304 {
305 if(ctx == NULL) {
306 return paramErr;
307 }
308 if(sslIsSessionActive(ctx)) {
309 /* can't do this with an active session */
310 return badReqErr;
311 }
312 ctx->ioCtx.ioRef = connection;
313 return noErr;
314 }
315
316 OSStatus
317 SSLSetPeerDomainName (SSLContextRef ctx,
318 const char *peerName,
319 size_t peerNameLen)
320 {
321 if(ctx == NULL) {
322 return paramErr;
323 }
324 if(sslIsSessionActive(ctx)) {
325 /* can't do this with an active session */
326 return badReqErr;
327 }
328
329 /* free possible existing name */
330 if(ctx->peerDomainName) {
331 sslFree(ctx->peerDomainName);
332 }
333
334 /* copy in */
335 ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
336 if(ctx->peerDomainName == NULL) {
337 return memFullErr;
338 }
339 memmove(ctx->peerDomainName, peerName, peerNameLen);
340 ctx->peerDomainNameLen = peerNameLen;
341 return noErr;
342 }
343
344 /*
345 * Determine the buffer size needed for SSLGetPeerDomainName().
346 */
347 OSStatus
348 SSLGetPeerDomainNameLength (SSLContextRef ctx,
349 size_t *peerNameLen) // RETURNED
350 {
351 if(ctx == NULL) {
352 return paramErr;
353 }
354 *peerNameLen = ctx->peerDomainNameLen;
355 return noErr;
356 }
357
358 OSStatus
359 SSLGetPeerDomainName (SSLContextRef ctx,
360 char *peerName, // returned here
361 size_t *peerNameLen) // IN/OUT
362 {
363 if(ctx == NULL) {
364 return paramErr;
365 }
366 if(*peerNameLen < ctx->peerDomainNameLen) {
367 return errSSLBufferOverflow;
368 }
369 memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
370 *peerNameLen = ctx->peerDomainNameLen;
371 return noErr;
372 }
373
374 OSStatus
375 SSLSetProtocolVersion (SSLContextRef ctx,
376 SSLProtocol version)
377 {
378 SSLProtocolVersion versInt;
379 SSLProtocolVersion versMax;
380
381 if(ctx == NULL) {
382 return paramErr;
383 }
384 if(sslIsSessionActive(ctx)) {
385 /* can't do this with an active session */
386 return badReqErr;
387 }
388
389 /* convert external representation to private */
390 switch(version) {
391 case kSSLProtocolUnknown:
392 versInt = SSL_Version_Undetermined;
393 versMax = DEFAULT_MAX_VERSION;
394 break;
395 case kSSLProtocol2:
396 versInt = versMax = SSL_Version_2_0;
397 break;
398 case kSSLProtocol3:
399 /* this tells us to do our best but allows 2.0 */
400 versInt = SSL_Version_Undetermined;
401 versMax = SSL_Version_3_0;
402 break;
403 case kSSLProtocol3Only:
404 versInt = SSL_Version_3_0_Only;
405 versMax = SSL_Version_3_0;
406 break;
407 case kTLSProtocol1:
408 /* this tells us to do our best but allows 2.0 */
409 versInt = SSL_Version_Undetermined;
410 versMax = TLS_Version_1_0;
411 break;
412 case kTLSProtocol1Only:
413 versInt = TLS_Version_1_0_Only;
414 versMax = TLS_Version_1_0;
415 break;
416 default:
417 return paramErr;
418 }
419 ctx->reqProtocolVersion = ctx->negProtocolVersion = versInt;
420 ctx->maxProtocolVersion = versMax;
421 return noErr;
422 }
423
424 static SSLProtocol convertProtToExtern(SSLProtocolVersion prot)
425 {
426 switch(prot) {
427 case SSL_Version_Undetermined:
428 return kSSLProtocolUnknown;
429 case SSL_Version_3_0_Only:
430 return kSSLProtocol3Only;
431 case SSL_Version_2_0:
432 return kSSLProtocol2;
433 case SSL_Version_3_0:
434 return kSSLProtocol3;
435 case TLS_Version_1_0_Only:
436 return kTLSProtocol1Only;
437 case TLS_Version_1_0:
438 return kTLSProtocol1;
439 /* this can happen in an intermediate state while negotiation
440 * is active...right? */
441 case SSL_Version_3_0_With_2_0_Hello:
442 return kSSLProtocolUnknown;
443 default:
444 sslErrorLog("convertProtToExtern: bad prot\n");
445 return kSSLProtocolUnknown;
446 }
447 /* not reached but make compiler happy */
448 return kSSLProtocolUnknown;
449 }
450
451 OSStatus
452 SSLGetProtocolVersion (SSLContextRef ctx,
453 SSLProtocol *protocol) /* RETURNED */
454 {
455 if(ctx == NULL) {
456 return paramErr;
457 }
458 *protocol = convertProtToExtern(ctx->reqProtocolVersion);
459 return noErr;
460 }
461
462 OSStatus
463 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx,
464 SSLProtocol *protocol) /* RETURNED */
465 {
466 if(ctx == NULL) {
467 return paramErr;
468 }
469 *protocol = convertProtToExtern(ctx->negProtocolVersion);
470 return noErr;
471 }
472
473 OSStatus
474 SSLSetEnableCertVerify (SSLContextRef ctx,
475 Boolean enableVerify)
476 {
477 if(ctx == NULL) {
478 return paramErr;
479 }
480 if(sslIsSessionActive(ctx)) {
481 /* can't do this with an active session */
482 return badReqErr;
483 }
484 ctx->enableCertVerify = enableVerify;
485 return noErr;
486 }
487
488 OSStatus
489 SSLGetEnableCertVerify (SSLContextRef ctx,
490 Boolean *enableVerify)
491 {
492 if(ctx == NULL) {
493 return paramErr;
494 }
495 *enableVerify = ctx->enableCertVerify;
496 return noErr;
497 }
498
499 OSStatus
500 SSLSetAllowsExpiredCerts(SSLContextRef ctx,
501 Boolean allowExpired)
502 {
503 if(ctx == NULL) {
504 return paramErr;
505 }
506 if(sslIsSessionActive(ctx)) {
507 /* can't do this with an active session */
508 return badReqErr;
509 }
510 ctx->allowExpiredCerts = allowExpired;
511 return noErr;
512 }
513
514 OSStatus
515 SSLGetAllowsExpiredCerts (SSLContextRef ctx,
516 Boolean *allowExpired)
517 {
518 if(ctx == NULL) {
519 return paramErr;
520 }
521 *allowExpired = ctx->allowExpiredCerts;
522 return noErr;
523 }
524
525 OSStatus
526 SSLSetAllowsExpiredRoots(SSLContextRef ctx,
527 Boolean allowExpired)
528 {
529 if(ctx == NULL) {
530 return paramErr;
531 }
532 if(sslIsSessionActive(ctx)) {
533 /* can't do this with an active session */
534 return badReqErr;
535 }
536 ctx->allowExpiredRoots = allowExpired;
537 return noErr;
538 }
539
540 OSStatus
541 SSLGetAllowsExpiredRoots (SSLContextRef ctx,
542 Boolean *allowExpired)
543 {
544 if(ctx == NULL) {
545 return paramErr;
546 }
547 *allowExpired = ctx->allowExpiredRoots;
548 return noErr;
549 }
550
551 OSStatus SSLSetAllowsAnyRoot(
552 SSLContextRef ctx,
553 Boolean anyRoot)
554 {
555 if(ctx == NULL) {
556 return paramErr;
557 }
558 ctx->allowAnyRoot = anyRoot;
559 return noErr;
560 }
561
562 OSStatus
563 SSLGetAllowsAnyRoot(
564 SSLContextRef ctx,
565 Boolean *anyRoot)
566 {
567 if(ctx == NULL) {
568 return paramErr;
569 }
570 *anyRoot = ctx->allowAnyRoot;
571 return noErr;
572 }
573
574 OSStatus
575 SSLSetTrustedRoots (SSLContextRef ctx,
576 CFArrayRef trustedRoots,
577 Boolean replaceExisting)
578 {
579 unsigned dex;
580 unsigned outDex;
581 unsigned numIncoming;
582 uint32 numCerts;
583 CSSM_DATA_PTR newRoots = NULL;
584 const CSSM_DATA *existAnchors = NULL;
585 uint32 numExistAnchors = 0;
586 OSStatus ortn = noErr;
587
588 if(ctx == NULL) {
589 return paramErr;
590 }
591 if(sslIsSessionActive(ctx)) {
592 /* can't do this with an active session */
593 return badReqErr;
594 }
595 numCerts = numIncoming = CFArrayGetCount(trustedRoots);
596 if(!replaceExisting) {
597 if(ctx->trustedCerts != NULL) {
598 /* adding to existing store */
599 existAnchors = ctx->trustedCerts;
600 numExistAnchors = ctx->numTrustedCerts;
601 }
602 else {
603 /* adding to system roots */
604 ortn = SecTrustGetCSSMAnchorCertificates(&existAnchors,
605 &numExistAnchors);
606 if(ortn) {
607 /* should never happen */
608 return ortn;
609 }
610 }
611 numCerts += numExistAnchors;
612 }
613 newRoots = (CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA));
614 memset(newRoots, 0, numCerts * sizeof(CSSM_DATA));
615
616 /* Caller's certs first */
617 for(dex=0, outDex=0; dex<numIncoming; dex++, outDex++) {
618 CSSM_DATA certData;
619 SecCertificateRef secCert = (SecCertificateRef)
620 CFArrayGetValueAtIndex(trustedRoots, dex);
621
622 if(CFGetTypeID(secCert) != SecCertificateGetTypeID()) {
623 /* elements of trustedRoots must be SecCertificateRefs */
624 ortn = paramErr;
625 goto abort;
626 }
627 ortn = SecCertificateGetData(secCert, &certData);
628 if(ortn) {
629 goto abort;
630 }
631 stSetUpCssmData(&newRoots[outDex], certData.Length);
632 memmove(newRoots[outDex].Data, certData.Data, certData.Length);
633 }
634
635 /* now existing roots - either ours, or the system's */
636 for(dex=0; dex<numExistAnchors; dex++, outDex++) {
637 stSetUpCssmData(&newRoots[outDex], existAnchors[dex].Length);
638 memmove(newRoots[outDex].Data, existAnchors[dex].Data,
639 existAnchors[dex].Length);
640 }
641
642 /* success - replace context values */
643 sslFreeTrustedRoots(ctx);
644 ctx->numTrustedCerts = numCerts;
645 ctx->trustedCerts = newRoots;
646 return noErr;
647
648 abort:
649 sslFree(newRoots);
650 return ortn;
651 }
652
653 OSStatus
654 SSLGetTrustedRoots (SSLContextRef ctx,
655 CFArrayRef *trustedRoots) /* RETURNED */
656 {
657 uint32 numCerts;
658 const CSSM_DATA *certs;
659 CFMutableArrayRef certArray;
660 unsigned dex;
661 SecCertificateRef secCert;
662 OSStatus ortn;
663
664 if(ctx == NULL) {
665 return paramErr;
666 }
667 if(ctx->trustedCerts != NULL) {
668 /* use ours */
669 certs = ctx->trustedCerts;
670 numCerts = ctx->numTrustedCerts;
671 }
672 else {
673 /* use default system roots */
674 OSStatus ortn = SecTrustGetCSSMAnchorCertificates(&certs,
675 &numCerts);
676 if(ortn) {
677 /* should never happen */
678 return ortn;
679 }
680 }
681
682 certArray = CFArrayCreateMutable(kCFAllocatorDefault,
683 (CFIndex)numCerts, &kCFTypeArrayCallBacks);
684 if(certArray == NULL) {
685 return memFullErr;
686 }
687 for(dex=0; dex<numCerts; dex++) {
688 ortn = SecCertificateCreateFromData(&certs[dex],
689 CSSM_CERT_X_509v3,
690 CSSM_CERT_ENCODING_DER,
691 &secCert);
692 if(ortn) {
693 CFRelease(certArray);
694 return ortn;
695 }
696 CFArrayAppendValue(certArray, secCert);
697 }
698 *trustedRoots = certArray;
699 return noErr;
700 }
701
702 OSStatus
703 SSLSetClientSideAuthenticate (SSLContext *ctx,
704 SSLAuthenticate auth)
705 {
706 if(ctx == NULL) {
707 return paramErr;
708 }
709 if(sslIsSessionActive(ctx)) {
710 /* can't do this with an active session */
711 return badReqErr;
712 }
713 ctx->clientAuth = auth;
714 switch(auth) {
715 case kNeverAuthenticate:
716 ctx->tryClientAuth = false;
717 break;
718 case kAlwaysAuthenticate:
719 case kTryAuthenticate:
720 ctx->tryClientAuth = true;
721 break;
722 }
723 return noErr;
724 }
725
726 OSStatus
727 SSLGetClientCertificateState (SSLContextRef ctx,
728 SSLClientCertificateState *clientState)
729 {
730 if(ctx == NULL) {
731 return paramErr;
732 }
733 *clientState = ctx->clientCertState;
734 return noErr;
735 }
736
737 OSStatus
738 SSLSetCertificate (SSLContextRef ctx,
739 CFArrayRef certRefs)
740 {
741 /*
742 * -- free localCerts if we have any
743 * -- Get raw cert data, convert to ctx->localCert
744 * -- get pub, priv keys from certRef[0]
745 * -- validate cert chain
746 */
747 if(ctx == NULL) {
748 return paramErr;
749 }
750 if(sslIsSessionActive(ctx)) {
751 /* can't do this with an active session */
752 return badReqErr;
753 }
754 return parseIncomingCerts(ctx,
755 certRefs,
756 &ctx->localCert,
757 &ctx->signingPubKey,
758 &ctx->signingPrivKey,
759 &ctx->signingKeyCsp
760 #if ST_KC_KEYS_NEED_REF
761 ,
762 &ctx->signingKeyRef
763 #else
764 );
765 #endif
766 }
767
768 OSStatus
769 SSLSetEncryptionCertificate (SSLContextRef ctx,
770 CFArrayRef certRefs)
771 {
772 /*
773 * -- free encryptCert if we have any
774 * -- Get raw cert data, convert to ctx->encryptCert
775 * -- get pub, priv keys from certRef[0]
776 * -- validate cert chain
777 */
778 if(ctx == NULL) {
779 return paramErr;
780 }
781 if(sslIsSessionActive(ctx)) {
782 /* can't do this with an active session */
783 return badReqErr;
784 }
785 return parseIncomingCerts(ctx,
786 certRefs,
787 &ctx->encryptCert,
788 &ctx->encryptPubKey,
789 &ctx->encryptPrivKey,
790 &ctx->encryptKeyCsp
791 #if ST_KC_KEYS_NEED_REF
792 ,
793 &ctx->encryptKeyRef);
794 #else
795 );
796 #endif
797 }
798
799 #if ST_MANAGES_TRUSTED_ROOTS
800
801 /*
802 * Add (optional, additional) trusted root certs.
803 */
804 OSStatus
805 SSLSetTrustedRootCertKC (SSLContextRef ctx,
806 KCRef keyChainRef,
807 Boolean deleteExisting)
808 {
809 /*
810 * -- free trustedCerts if deleteExisting
811 * -- Get raw cert data, add to ctx->trustedCerts
812 * -- verify that each of these is a valid (self-verifying)
813 * root cert
814 * -- add each subject name to acceptableDNList
815 */
816 if((ctx == NULL) || (keyChainRef == nil)) {
817 return paramErr;
818 }
819 if(sslIsSessionActive(ctx)) {
820 /* can't do this with an active session */
821 return badReqErr;
822 }
823 if(deleteExisting) {
824 sslFreeTrustedRoots(ctx);
825 }
826 return parseTrustedKeychain(ctx, keyChainRef);
827 }
828
829 OSStatus
830 SSLSetNewRootKC (SSLContextRef ctx,
831 KCRef keyChainRef,
832 void *accessCreds)
833 {
834 if((ctx == NULL) || (keyChainRef == nil)) {
835 return paramErr;
836 }
837 if(sslIsSessionActive(ctx)) {
838 /* can't do this with an active session */
839 return badReqErr;
840 }
841 if(ctx->newRootCertKc != NULL) {
842 /* can't do this multiple times */
843 return badReqErr;
844 }
845 ctx->newRootCertKc = keyChainRef;
846 ctx->accessCreds = accessCreds;
847 return noErr;
848 }
849 #endif /* ST_MANAGES_TRUSTED_ROOTS */
850
851 OSStatus
852 SSLSetPeerID (SSLContext *ctx,
853 const void *peerID,
854 size_t peerIDLen)
855 {
856 OSStatus serr;
857
858 /* copy peerId to context->peerId */
859 if((ctx == NULL) ||
860 (peerID == NULL) ||
861 (peerIDLen == 0)) {
862 return paramErr;
863 }
864 if(sslIsSessionActive(ctx)) {
865 /* can't do this with an active session */
866 return badReqErr;
867 }
868 SSLFreeBuffer(ctx->peerID, ctx);
869 serr = SSLAllocBuffer(ctx->peerID, peerIDLen, ctx);
870 if(serr) {
871 return serr;
872 }
873 memmove(ctx->peerID.data, peerID, peerIDLen);
874 return noErr;
875 }
876
877 OSStatus
878 SSLGetPeerID (SSLContextRef ctx,
879 const void **peerID,
880 size_t *peerIDLen)
881 {
882 *peerID = ctx->peerID.data; // may be NULL
883 *peerIDLen = ctx->peerID.length;
884 return noErr;
885 }
886
887 OSStatus
888 SSLGetNegotiatedCipher (SSLContextRef ctx,
889 SSLCipherSuite *cipherSuite)
890 {
891 if(ctx == NULL) {
892 return paramErr;
893 }
894 if(!sslIsSessionActive(ctx)) {
895 return badReqErr;
896 }
897 *cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
898 return noErr;
899 }
900
901 /*
902 * Add an acceptable distinguished name (client authentication only).
903 */
904 OSStatus
905 SSLAddDistinguishedName(
906 SSLContextRef ctx,
907 const void *derDN,
908 size_t derDNLen)
909 {
910 DNListElem *dn;
911 OSStatus err;
912
913 dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
914 if(dn == NULL) {
915 return memFullErr;
916 }
917 if ((err = SSLAllocBuffer(dn->derDN, derDNLen, ctx)) != 0)
918 return err;
919 memcpy(dn->derDN.data, derDN, derDNLen);
920 dn->next = ctx->acceptableDNList;
921 ctx->acceptableDNList = dn;
922 return noErr;
923 }
924
925 /*
926 * Request peer certificates. Valid anytime, subsequent to
927 * a handshake attempt.
928 */
929 OSStatus
930 SSLGetPeerCertificates (SSLContextRef ctx,
931 CFArrayRef *certs)
932 {
933 uint32 numCerts;
934 CFMutableArrayRef ca;
935 CFIndex i;
936 SecCertificateRef cfd;
937 OSStatus ortn;
938 CSSM_DATA certData;
939 SSLCertificate *scert;
940
941 if(ctx == NULL) {
942 return paramErr;
943 }
944 *certs = NULL;
945
946 /*
947 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
948 * CFDataRefs, each of which is one DER-encoded cert.
949 */
950 numCerts = SSLGetCertificateChainLength(ctx->peerCert);
951 if(numCerts == 0) {
952 return noErr;
953 }
954 ca = CFArrayCreateMutable(kCFAllocatorDefault,
955 (CFIndex)numCerts, &kCFTypeArrayCallBacks);
956 if(ca == NULL) {
957 return memFullErr;
958 }
959
960 /*
961 * Caller gets leaf cert first, the opposite of the way we store them.
962 */
963 scert = ctx->peerCert;
964 for(i=0; (unsigned)i<numCerts; i++) {
965 assert(scert != NULL); /* else SSLGetCertificateChainLength
966 * broken */
967 SSLBUF_TO_CSSM(&scert->derCert, &certData);
968 ortn = SecCertificateCreateFromData(&certData,
969 CSSM_CERT_X_509v3,
970 CSSM_CERT_ENCODING_DER,
971 &cfd);
972 if(ortn) {
973 CFRelease(ca);
974 return ortn;
975 }
976 /* insert at head of array */
977 CFArrayInsertValueAtIndex(ca, 0, cfd);
978 scert = scert->next;
979 }
980 *certs = ca;
981 return noErr;
982 }
983
984 OSStatus SSLInternalMasterSecret(
985 SSLContextRef ctx,
986 void *secret, // mallocd by caller, SSL_MASTER_SECRET_SIZE
987 size_t *secretSize) // in/out
988 {
989 if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
990 return paramErr;
991 }
992 if(*secretSize < SSL_MASTER_SECRET_SIZE) {
993 return paramErr;
994 }
995 memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
996 *secretSize = SSL_MASTER_SECRET_SIZE;
997 return noErr;
998 }
999
1000 OSStatus SSLInternalServerRandom(
1001 SSLContextRef ctx,
1002 void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1003 size_t *randSize) // in/out
1004 {
1005 if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
1006 return paramErr;
1007 }
1008 if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
1009 return paramErr;
1010 }
1011 memmove(rand, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
1012 *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
1013 return noErr;
1014 }
1015
1016 OSStatus SSLInternalClientRandom(
1017 SSLContextRef ctx,
1018 void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1019 size_t *randSize) // in/out
1020 {
1021 if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) {
1022 return paramErr;
1023 }
1024 if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
1025 return paramErr;
1026 }
1027 memmove(rand, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
1028 *randSize = SSL_CLIENT_SRVR_RAND_SIZE;
1029 return noErr;
1030 }
1031
1032
1033