]>
Commit | Line | Data |
---|---|---|
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 | |
46 | static 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 | 62 | static 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 |
91 | OSStatus |
92 | SSLNewContext (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 | ||
161 | errOut: | |
162 | sslFree(ctx); | |
5a719ac8 | 163 | return serr; |
bac41a7b A |
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; | |
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 | */ | |
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) { | |
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 | ||
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 | ||
df0e469f A |
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 | ||
29654253 A |
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 */ | |
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 | */ | |
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 | ||
df0e469f A |
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 */ | |
bac41a7b A |
489 | OSStatus |
490 | SSLSetProtocolVersion (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 |
543 | OSStatus |
544 | SSLGetProtocolVersion (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 | ||
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 | ||
5a719ac8 A |
609 | OSStatus |
610 | SSLSetEnableCertVerify (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 | ||
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 | ||
bac41a7b | 637 | OSStatus |
29654253 | 638 | SSLSetAllowsExpiredCerts(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 | ||
654 | OSStatus | |
29654253 | 655 | SSLGetAllowsExpiredCerts (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 |
665 | OSStatus |
666 | SSLSetAllowsExpiredRoots(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 | ||
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 | ||
29654253 | 693 | OSStatus 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 | ||
705 | OSStatus | |
29654253 | 706 | SSLGetAllowsAnyRoot( |
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 |
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); | |
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 | ||
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 | ||
bac41a7b A |
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: | |
bac41a7b A |
865 | ctx->tryClientAuth = true; |
866 | break; | |
867 | } | |
868 | return noErr; | |
869 | } | |
bac41a7b | 870 | |
5a719ac8 A |
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 | } | |
bac41a7b A |
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, | |
9a27adb2 | 903 | &ctx->signingPrivKeyRef); |
bac41a7b | 904 | } |
bac41a7b | 905 | |
bac41a7b A |
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, | |
9a27adb2 | 927 | &ctx->encryptPrivKeyRef); |
bac41a7b A |
928 | } |
929 | ||
bac41a7b A |
930 | OSStatus |
931 | SSLSetPeerID (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 | ||
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; | |
bac41a7b A |
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 | /* | |
5a719ac8 | 981 | * Add an acceptable distinguished name (client authentication only). |
bac41a7b | 982 | */ |
5a719ac8 A |
983 | OSStatus |
984 | SSLAddDistinguishedName( | |
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 | */ | |
1008 | OSStatus | |
1009 | SSLGetPeerCertificates (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 | */ | |
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 | ||
5a719ac8 A |
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 | ||
df0e469f A |
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 | } | |
bac41a7b A |
1225 | |
1226 |