]> git.saurik.com Git - apple/security.git/blame - SecureTransport/sslContext.cpp
Security-176.tar.gz
[apple/security.git] / SecureTransport / sslContext.cpp
CommitLineData
bac41a7b
A
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/*
5a719ac8 20 File: sslContext.cpp
bac41a7b
A
21
22 Contains: SSLContext accessors
23
5a719ac8 24 Written by: Doug Mitchell
bac41a7b
A
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28*/
bac41a7b
A
29
30#include "ssl.h"
5a719ac8
A
31#include "sslContext.h"
32#include "sslMemory.h"
bac41a7b 33#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
5a719ac8 34#include "sslDigests.h"
bac41a7b
A
35#include "sslDebug.h"
36#include "appleCdsa.h"
bac41a7b 37#include "sslKeychain.h"
5a719ac8 38#include "sslUtils.h"
bac41a7b 39#include "cipherSpecs.h"
29654253 40#include "appleSession.h"
df0e469f 41#include "sslBER.h"
bac41a7b 42#include <string.h>
29654253 43#include <Security/SecCertificate.h>
5a719ac8 44#include <Security/SecTrust.h>
bac41a7b
A
45
46static void sslFreeDnList(
47 SSLContext *ctx)
48{
49 DNListElem *dn, *nextDN;
bac41a7b
A
50
51 dn = ctx->acceptableDNList;
bac41a7b
A
52 while (dn)
53 {
5a719ac8 54 SSLFreeBuffer(dn->derDN, ctx);
bac41a7b 55 nextDN = dn->next;
5a719ac8 56 sslFree(dn);
bac41a7b
A
57 dn = nextDN;
58 }
59 ctx->acceptableDNList = NULL;
60}
61
5a719ac8 62static OSStatus sslFreeTrustedRoots(
bac41a7b
A
63 SSLContext *ctx)
64{
5a719ac8 65 unsigned i;
bac41a7b 66
5a719ac8 67 assert(ctx != NULL);
bac41a7b
A
68 if((ctx->numTrustedCerts == 0) || (ctx->trustedCerts == NULL)) {
69 /* they really should both be zero, right? */
5a719ac8 70 assert((ctx->numTrustedCerts == 0) && (ctx->trustedCerts == NULL));
bac41a7b
A
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);
5a719ac8 81 return noErr;
bac41a7b
A
82}
83
29654253 84/*
df0e469f 85 * Default version enables.
29654253 86 */
df0e469f
A
87#define DEFAULT_SSL2_ENABLE true
88#define DEFAULT_SSL3_ENABLE true
89#define DEFAULT_TLS1_ENABLE true
29654253 90
bac41a7b
A
91OSStatus
92SSLNewContext (Boolean isServer,
93 SSLContextRef *contextPtr) /* RETURNED */
94{
95 SSLContext *ctx;
5a719ac8 96 OSStatus serr;
bac41a7b
A
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));
5a719ac8
A
109 ctx->state = SSL_HdskStateUninit;
110 ctx->clientCertState = kSSLClientCertNone;
111
df0e469f
A
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
bac41a7b
A
117 if(isServer) {
118 ctx->protocolSide = SSL_ServerSide;
bac41a7b
A
119 }
120 else {
121 ctx->protocolSide = SSL_ClientSide;
bac41a7b 122 }
df0e469f 123
29654253
A
124 /* Default value so we can send and receive hello msgs */
125 ctx->sslTslCalls = &Ssl3Callouts;
bac41a7b
A
126
127 /* Initialize the cipher state to NULL_WITH_NULL_NULL */
29654253
A
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;
bac41a7b
A
133 ctx->writeCipher.symCipher = ctx->selectedCipherSpec->cipher;
134
bac41a7b
A
135 /* these two are invariant */
136 ctx->writeCipher.encrypting = 1;
137 ctx->writePending.encrypting = 1;
bac41a7b
A
138
139 /* this gets init'd on first call to SSLHandshake() */
140 ctx->validCipherSpecs = NULL;
141 ctx->numValidCipherSpecs = 0;
142
29654253
A
143 ctx->peerDomainName = NULL;
144 ctx->peerDomainNameLen = 0;
145
bac41a7b
A
146 /* attach to CSP, CL, TP */
147 serr = attachToAll(ctx);
148 if(serr) {
bac41a7b
A
149 goto errOut;
150 }
151
5a719ac8
A
152 /* Initial cert verify state: verify with default system roots */
153 ctx->enableCertVerify = true;
154
df0e469f
A
155 /* Default for RSA blinding is ENABLED */
156 ctx->rsaBlindingEnable = true;
bac41a7b
A
157
158 *contextPtr = ctx;
159 return noErr;
160
161errOut:
162 sslFree(ctx);
5a719ac8 163 return serr;
bac41a7b
A
164}
165
166
167/*
168 * Dispose of an SSLContext.
169 */
170OSStatus
171SSLDisposeContext (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;
5a719ac8 183 SSLFreeBuffer(ctx->partialReadBuffer, ctx);
df0e469f
A
184 if(ctx->peerSecTrust) {
185 CFRelease(ctx->peerSecTrust);
186 ctx->peerSecTrust = NULL;
187 }
bac41a7b
A
188 wait = ctx->recordWriteQueue;
189 while (wait)
5a719ac8 190 { SSLFreeBuffer(wait->data, ctx);
bac41a7b
A
191 next = wait->next;
192 buf.data = (uint8*)wait;
193 buf.length = sizeof(WaitingRecord);
5a719ac8 194 SSLFreeBuffer(buf, ctx);
bac41a7b
A
195 wait = next;
196 }
197
df0e469f
A
198 #if APPLE_DH
199 SSLFreeBuffer(ctx->dhParamsPrime, ctx);
200 SSLFreeBuffer(ctx->dhParamsGenerator, ctx);
201 SSLFreeBuffer(ctx->dhParamsEncoded, ctx);
5a719ac8
A
202 SSLFreeBuffer(ctx->dhPeerPublic, ctx);
203 SSLFreeBuffer(ctx->dhExchangePublic, ctx);
df0e469f
A
204 sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
205 #endif /* APPLE_DH */
206
5a719ac8
A
207 CloseHash(SSLHashSHA1, ctx->shaState, ctx);
208 CloseHash(SSLHashMD5, ctx->md5State, ctx);
bac41a7b 209
5a719ac8
A
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);
bac41a7b 217
29654253
A
218 if(ctx->peerDomainName) {
219 sslFree(ctx->peerDomainName);
220 ctx->peerDomainName = NULL;
221 ctx->peerDomainNameLen = 0;
222 }
bac41a7b
A
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
29654253
A
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 */
9a27adb2
A
241 sslFreeKey(ctx->cspHand, &ctx->signingPubKey, NULL);
242 sslFreeKey(ctx->cspHand, &ctx->encryptPubKey, NULL);
bac41a7b
A
243 sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
244
9a27adb2
A
245 if(ctx->signingPrivKeyRef) {
246 CFRelease(ctx->signingPrivKeyRef);
247 }
248 if(ctx->encryptPrivKeyRef) {
249 CFRelease(ctx->encryptPrivKeyRef);
250 }
bac41a7b
A
251 sslFreeTrustedRoots(ctx);
252
253 detachFromAll(ctx);
254
bac41a7b
A
255 memset(ctx, 0, sizeof(SSLContext));
256 sslFree(ctx);
29654253
A
257 sslCleanupSession();
258 return noErr;
bac41a7b
A
259}
260
261/*
262 * Determine the state of an SSL session.
263 */
264OSStatus
265SSLGetSessionState (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) {
5a719ac8
A
275 case SSL_HdskStateUninit:
276 case SSL_HdskStateServerUninit:
277 case SSL_HdskStateClientUninit:
bac41a7b
A
278 rtnState = kSSLIdle;
279 break;
5a719ac8 280 case SSL_HdskStateGracefulClose:
bac41a7b
A
281 rtnState = kSSLClosed;
282 break;
5a719ac8
A
283 case SSL_HdskStateErrorClose:
284 case SSL_HdskStateNoNotifyClose:
bac41a7b
A
285 rtnState = kSSLAborted;
286 break;
df0e469f
A
287 case SSL_HdskStateServerReady:
288 case SSL_HdskStateClientReady:
bac41a7b
A
289 rtnState = kSSLConnected;
290 break;
291 default:
5a719ac8
A
292 assert((context->state >= SSL_HdskStateServerHello) &&
293 (context->state <= SSL2_HdskStateServerFinished));
bac41a7b
A
294 rtnState = kSSLHandshake;
295 break;
296
297 }
298 *state = rtnState;
299 return noErr;
300}
301
302OSStatus
303SSLSetIOFuncs (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
319OSStatus
320SSLSetConnection (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
df0e469f
A
334OSStatus
335SSLGetConnection (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
29654253
A
345OSStatus
346SSLSetPeerDomainName (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 */
5a719ac8 364 ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
29654253
A
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 */
376OSStatus
377SSLGetPeerDomainNameLength (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
387OSStatus
388SSLGetPeerDomainName (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
df0e469f
A
403/* concert between private SSLProtocolVersion and public SSLProtocol */
404static 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
423OSStatus
424SSLSetProtocolVersionEnabled(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
455OSStatus
456SSLGetProtocolVersionEnabled(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 */
bac41a7b
A
489OSStatus
490SSLSetProtocolVersion (SSLContextRef ctx,
491 SSLProtocol version)
492{
bac41a7b
A
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
df0e469f 501 /* convert external representation to three booleans */
bac41a7b
A
502 switch(version) {
503 case kSSLProtocolUnknown:
df0e469f
A
504 ctx->versionSsl2Enable = DEFAULT_SSL2_ENABLE;
505 ctx->versionSsl3Enable = DEFAULT_SSL3_ENABLE;
506 ctx->versionTls1Enable = DEFAULT_TLS1_ENABLE;
bac41a7b
A
507 break;
508 case kSSLProtocol2:
df0e469f
A
509 ctx->versionSsl2Enable = true;
510 ctx->versionSsl3Enable = false;
511 ctx->versionTls1Enable = false;
bac41a7b
A
512 break;
513 case kSSLProtocol3:
df0e469f
A
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;
bac41a7b
A
518 break;
519 case kSSLProtocol3Only:
df0e469f
A
520 ctx->versionSsl2Enable = false;
521 ctx->versionSsl3Enable = true;
522 ctx->versionTls1Enable = false;
29654253
A
523 break;
524 case kTLSProtocol1:
df0e469f
A
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;
29654253
A
530 break;
531 case kTLSProtocol1Only:
df0e469f
A
532 ctx->versionSsl2Enable = false;
533 ctx->versionSsl3Enable = false;
534 ctx->versionTls1Enable = true;
bac41a7b
A
535 break;
536 default:
537 return paramErr;
538 }
bac41a7b
A
539 return noErr;
540}
541
df0e469f 542/* deprecated */
bac41a7b
A
543OSStatus
544SSLGetProtocolVersion (SSLContextRef ctx,
545 SSLProtocol *protocol) /* RETURNED */
546{
547 if(ctx == NULL) {
548 return paramErr;
549 }
df0e469f
A
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 */
bac41a7b
A
596}
597
598OSStatus
599SSLGetNegotiatedProtocolVersion (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
5a719ac8
A
609OSStatus
610SSLSetEnableCertVerify (SSLContextRef ctx,
611 Boolean enableVerify)
612{
613 if(ctx == NULL) {
614 return paramErr;
615 }
df0e469f
A
616 sslCertDebug("SSLSetEnableCertVerify %s",
617 enableVerify ? "true" : "false");
5a719ac8
A
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
626OSStatus
627SSLGetEnableCertVerify (SSLContextRef ctx,
628 Boolean *enableVerify)
629{
630 if(ctx == NULL) {
631 return paramErr;
632 }
633 *enableVerify = ctx->enableCertVerify;
634 return noErr;
635}
636
bac41a7b 637OSStatus
29654253 638SSLSetAllowsExpiredCerts(SSLContextRef ctx,
bac41a7b
A
639 Boolean allowExpired)
640{
641 if(ctx == NULL) {
642 return paramErr;
643 }
df0e469f
A
644 sslCertDebug("SSLSetAllowsExpiredCerts %s",
645 allowExpired ? "true" : "false");
bac41a7b
A
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
654OSStatus
29654253 655SSLGetAllowsExpiredCerts (SSLContextRef ctx,
bac41a7b
A
656 Boolean *allowExpired)
657{
658 if(ctx == NULL) {
659 return paramErr;
660 }
661 *allowExpired = ctx->allowExpiredCerts;
662 return noErr;
663}
664
5a719ac8
A
665OSStatus
666SSLSetAllowsExpiredRoots(SSLContextRef ctx,
667 Boolean allowExpired)
668{
669 if(ctx == NULL) {
670 return paramErr;
671 }
df0e469f
A
672 sslCertDebug("SSLSetAllowsExpiredRoots %s",
673 allowExpired ? "true" : "false");
5a719ac8
A
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
682OSStatus
683SSLGetAllowsExpiredRoots (SSLContextRef ctx,
684 Boolean *allowExpired)
685{
686 if(ctx == NULL) {
687 return paramErr;
688 }
689 *allowExpired = ctx->allowExpiredRoots;
690 return noErr;
691}
692
29654253 693OSStatus SSLSetAllowsAnyRoot(
bac41a7b
A
694 SSLContextRef ctx,
695 Boolean anyRoot)
696{
697 if(ctx == NULL) {
698 return paramErr;
699 }
df0e469f 700 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot ? "true" : "false");
bac41a7b
A
701 ctx->allowAnyRoot = anyRoot;
702 return noErr;
703}
704
705OSStatus
29654253 706SSLGetAllowsAnyRoot(
bac41a7b
A
707 SSLContextRef ctx,
708 Boolean *anyRoot)
709{
710 if(ctx == NULL) {
711 return paramErr;
712 }
713 *anyRoot = ctx->allowAnyRoot;
714 return noErr;
715}
716
5a719ac8
A
717OSStatus
718SSLSetTrustedRoots (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);
df0e469f
A
739 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
740 (int)numCerts, replaceExisting ? "true" : "false");
5a719ac8
A
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
793abort:
794 sslFree(newRoots);
795 return ortn;
796}
797
798OSStatus
799SSLGetTrustedRoots (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
bac41a7b
A
847OSStatus
848SSLSetClientSideAuthenticate (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:
bac41a7b
A
865 ctx->tryClientAuth = true;
866 break;
867 }
868 return noErr;
869}
bac41a7b 870
5a719ac8
A
871OSStatus
872SSLGetClientCertificateState (SSLContextRef ctx,
873 SSLClientCertificateState *clientState)
874{
875 if(ctx == NULL) {
876 return paramErr;
877 }
878 *clientState = ctx->clientCertState;
879 return noErr;
880}
bac41a7b
A
881
882OSStatus
883SSLSetCertificate (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,
9a27adb2 903 &ctx->signingPrivKeyRef);
bac41a7b 904}
bac41a7b 905
bac41a7b
A
906OSStatus
907SSLSetEncryptionCertificate (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,
9a27adb2 927 &ctx->encryptPrivKeyRef);
bac41a7b
A
928}
929
bac41a7b
A
930OSStatus
931SSLSetPeerID (SSLContext *ctx,
29654253
A
932 const void *peerID,
933 size_t peerIDLen)
bac41a7b 934{
5a719ac8 935 OSStatus serr;
bac41a7b
A
936
937 /* copy peerId to context->peerId */
938 if((ctx == NULL) ||
939 (peerID == NULL) ||
29654253 940 (peerIDLen == 0)) {
bac41a7b
A
941 return paramErr;
942 }
943 if(sslIsSessionActive(ctx)) {
944 /* can't do this with an active session */
945 return badReqErr;
946 }
5a719ac8
A
947 SSLFreeBuffer(ctx->peerID, ctx);
948 serr = SSLAllocBuffer(ctx->peerID, peerIDLen, ctx);
bac41a7b 949 if(serr) {
5a719ac8 950 return serr;
bac41a7b 951 }
29654253
A
952 memmove(ctx->peerID.data, peerID, peerIDLen);
953 return noErr;
954}
955
956OSStatus
957SSLGetPeerID (SSLContextRef ctx,
958 const void **peerID,
959 size_t *peerIDLen)
960{
961 *peerID = ctx->peerID.data; // may be NULL
962 *peerIDLen = ctx->peerID.length;
bac41a7b
A
963 return noErr;
964}
965
966OSStatus
967SSLGetNegotiatedCipher (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/*
5a719ac8 981 * Add an acceptable distinguished name (client authentication only).
bac41a7b 982 */
5a719ac8
A
983OSStatus
984SSLAddDistinguishedName(
985 SSLContextRef ctx,
986 const void *derDN,
987 size_t derDNLen)
988{
bac41a7b 989 DNListElem *dn;
5a719ac8 990 OSStatus err;
bac41a7b 991
5a719ac8
A
992 dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
993 if(dn == NULL) {
994 return memFullErr;
995 }
996 if ((err = SSLAllocBuffer(dn->derDN, derDNLen, ctx)) != 0)
bac41a7b 997 return err;
5a719ac8 998 memcpy(dn->derDN.data, derDN, derDNLen);
bac41a7b
A
999 dn->next = ctx->acceptableDNList;
1000 ctx->acceptableDNList = dn;
5a719ac8 1001 return noErr;
bac41a7b 1002}
bac41a7b
A
1003
1004/*
1005 * Request peer certificates. Valid anytime, subsequent to
1006 * a handshake attempt.
1007 */
1008OSStatus
1009SSLGetPeerCertificates (SSLContextRef ctx,
1010 CFArrayRef *certs)
1011{
1012 uint32 numCerts;
1013 CFMutableArrayRef ca;
1014 CFIndex i;
29654253
A
1015 SecCertificateRef cfd;
1016 OSStatus ortn;
1017 CSSM_DATA certData;
bac41a7b
A
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 }
29654253 1033 ca = CFArrayCreateMutable(kCFAllocatorDefault,
bac41a7b
A
1034 (CFIndex)numCerts, &kCFTypeArrayCallBacks);
1035 if(ca == NULL) {
1036 return memFullErr;
1037 }
1038
1039 /*
29654253 1040 * Caller gets leaf cert first, the opposite of the way we store them.
bac41a7b
A
1041 */
1042 scert = ctx->peerCert;
5a719ac8
A
1043 for(i=0; (unsigned)i<numCerts; i++) {
1044 assert(scert != NULL); /* else SSLGetCertificateChainLength
bac41a7b 1045 * broken */
29654253
A
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) {
bac41a7b 1052 CFRelease(ca);
29654253 1053 return ortn;
bac41a7b 1054 }
29654253
A
1055 /* insert at head of array */
1056 CFArrayInsertValueAtIndex(ca, 0, cfd);
bac41a7b
A
1057 scert = scert->next;
1058 }
1059 *certs = ca;
1060 return noErr;
1061}
1062
df0e469f
A
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 */
1069OSStatus 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 */
1103OSStatus 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
1116OSStatus 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
1127OSStatus 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
1138OSStatus 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
5a719ac8
A
1149OSStatus 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
1165OSStatus 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
1181OSStatus 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
df0e469f
A
1197OSStatus
1198SSLGetResumableSessionInfo(
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}
bac41a7b
A
1225
1226