]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/sslCipherSpecs.c
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_ssl / lib / sslCipherSpecs.c
1 /*
2 * Copyright (c) 1999-2001,2005-2011 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * cipherSpecs.c - SSLCipherSpec declarations
26 */
27
28 #include "sslBuildFlags.h"
29 #include "CipherSuite.h"
30 #include "sslContext.h"
31 #include "sslCipherSpecs.h"
32 #include "sslDebug.h"
33 #include "sslMemory.h"
34 #include "sslDebug.h"
35 #include "sslUtils.h"
36 #include "sslPriv.h"
37 #include "sslCrypto.h"
38
39 #include <string.h>
40 #include <assert.h>
41 #include <Security/SecBase.h>
42 #include <utilities/array_size.h>
43
44 #include <TargetConditionals.h>
45
46
47 #define ENABLE_RSA_DES_SHA_NONEXPORT ENABLE_DES
48 #define ENABLE_RSA_DES_MD5_NONEXPORT ENABLE_DES
49 #define ENABLE_RSA_DES_SHA_EXPORT ENABLE_DES
50 #define ENABLE_RSA_RC4_MD5_EXPORT ENABLE_RC4 /* the most common one */
51 #define ENABLE_RSA_RC4_MD5_NONEXPORT ENABLE_RC4
52 #define ENABLE_RSA_RC4_SHA_NONEXPORT ENABLE_RC4
53 #define ENABLE_RSA_RC2_MD5_EXPORT ENABLE_RC2
54 #define ENABLE_RSA_RC2_MD5_NONEXPORT ENABLE_RC2
55 #define ENABLE_RSA_3DES_SHA ENABLE_3DES
56 #define ENABLE_RSA_3DES_MD5 ENABLE_3DES
57
58 #define ENABLE_ECDH 1
59 #define ENABLE_AES_GCM 0
60
61 #define ENABLE_PSK 1
62
63 #if APPLE_DH
64 #define ENABLE_DH_ANON 1
65 #define ENABLE_DH_EPHEM_RSA 1
66 #if USE_CDSA_CRYPTO
67 #define ENABLE_DH_EPHEM_DSA 1
68 #else
69 #define ENABLE_DH_EPHEM_DSA 0
70 #endif
71 #else
72 #define ENABLE_DH_ANON 0
73 #define ENABLE_DH_EPHEM_RSA 0
74 #define ENABLE_DH_EPHEM_DSA 0
75 #endif /* APPLE_DH */
76
77 /*
78 * List of all CipherSpecs we implement. Depending on a context's
79 * exportable flag, not all of these might be available for use.
80 */
81 /* Order by preference, domestic first */
82 static const SSLCipherSuite KnownCipherSuites[] = {
83 #if ENABLE_AES_GCM
84 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
85 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
86 #endif
87 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
88 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
89 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
90 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
91 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
92 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
93 #if ENABLE_AES_GCM
94 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
95 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
96 #endif
97 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
98 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
99 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
100 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
101 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
102 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
103 #if ENABLE_ECDH
104 #if ENABLE_AES_GCM
105 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
106 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
107 #endif
108 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
109 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
110 #if ENABLE_AES_GCM
111 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
112 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
113 #endif
114 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
115 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
116 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
117 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
118 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
119 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
120 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
121 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
122 TLS_ECDH_RSA_WITH_RC4_128_SHA,
123 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
124 #endif
125 #if ENABLE_AES_GCM
126 TLS_RSA_WITH_AES_256_GCM_SHA384,
127 TLS_RSA_WITH_AES_128_GCM_SHA256,
128 #endif
129 TLS_RSA_WITH_AES_256_CBC_SHA256,
130 TLS_RSA_WITH_AES_128_CBC_SHA256,
131 TLS_RSA_WITH_AES_128_CBC_SHA,
132 SSL_RSA_WITH_RC4_128_SHA,
133 SSL_RSA_WITH_RC4_128_MD5,
134 TLS_RSA_WITH_AES_256_CBC_SHA,
135 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
136 #if ENABLE_SSLV2
137 SSL_RSA_WITH_3DES_EDE_CBC_MD5,
138 #endif
139 #if ENABLE_DES
140 SSL_RSA_WITH_DES_CBC_SHA,
141 #endif
142 #if ENABLE_SSLV2
143 SSL_RSA_WITH_DES_CBC_MD5,
144 #endif
145 #if ENABLE_RC2
146 SSL_RSA_WITH_RC2_CBC_MD5,
147 #endif
148 #if ENABLE_AES_GCM
149 # if ENABLE_DH_EPHEM_DSA
150 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
151 # endif // ENABLE_DH_EPHEM_DSA
152 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
153 # if ENABLE_DH_EPHEM_DSA
154 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
155 # endif // ENABLE_DH_EPHEM_DSA
156 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
157 #endif // ENABLE_AES_GCM
158 #if ENABLE_DH_EPHEM_DSA
159 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
160 #endif
161 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
162 #if ENABLE_DH_EPHEM_DSA
163 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
164 #endif
165 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
166 #if ENABLE_DH_EPHEM_DSA
167 TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
168 #endif
169 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
170 #if ENABLE_DH_EPHEM_DSA
171 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
172 #endif
173 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
174 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
175 #if ENABLE_DES
176 SSL_DHE_RSA_WITH_DES_CBC_SHA,
177 #endif
178 #if ENABLE_DH_EPHEM_DSA
179 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
180 #if ENABLE_DES
181 SSL_DHE_DSS_WITH_DES_CBC_SHA,
182 #endif
183 #endif
184 #if ENABLE_AES_GCM
185 TLS_DH_anon_WITH_AES_256_GCM_SHA384,
186 TLS_DH_anon_WITH_AES_128_GCM_SHA256,
187 #endif
188 TLS_DH_anon_WITH_AES_128_CBC_SHA256,
189 TLS_DH_anon_WITH_AES_256_CBC_SHA256,
190 TLS_DH_anon_WITH_AES_128_CBC_SHA,
191 TLS_DH_anon_WITH_AES_256_CBC_SHA,
192 SSL_DH_anon_WITH_RC4_128_MD5,
193 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
194 #if ENABLE_DES
195 SSL_DH_anon_WITH_DES_CBC_SHA,
196 #endif
197 TLS_ECDHE_ECDSA_WITH_NULL_SHA,
198 TLS_ECDHE_RSA_WITH_NULL_SHA,
199 #if ENABLE_ECDH
200 TLS_ECDH_ECDSA_WITH_NULL_SHA,
201 TLS_ECDH_RSA_WITH_NULL_SHA,
202 #endif
203
204 #if ENABLE_PSK
205 TLS_PSK_WITH_AES_256_CBC_SHA384,
206 TLS_PSK_WITH_AES_128_CBC_SHA256,
207 TLS_PSK_WITH_AES_256_CBC_SHA,
208 TLS_PSK_WITH_AES_128_CBC_SHA,
209 TLS_PSK_WITH_RC4_128_SHA,
210 TLS_PSK_WITH_3DES_EDE_CBC_SHA,
211 TLS_PSK_WITH_NULL_SHA384,
212 TLS_PSK_WITH_NULL_SHA256,
213 TLS_PSK_WITH_NULL_SHA,
214 #endif
215
216 TLS_RSA_WITH_NULL_SHA256,
217 SSL_RSA_WITH_NULL_SHA,
218 SSL_RSA_WITH_NULL_MD5
219
220 #if 0
221 /* We don't support these yet. */
222 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
223 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
224 TLS_RSA_WITH_RC4_128_SHA,
225 TLS_RSA_WITH_3DES_EDE_CBC_SHA,
226 TLS_RSA_WITH_RC4_128_MD5,
227 TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
228 TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
229 TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
230 TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
231 TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
232 TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
233 TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
234 TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
235 TLS_DH_DSS_WITH_AES_256_CBC_SHA,
236 TLS_DH_RSA_WITH_AES_256_CBC_SHA,
237 TLS_DH_DSS_WITH_AES_128_CBC_SHA,
238 TLS_DH_RSA_WITH_AES_128_CBC_SHA,
239 TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
240 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
241 TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
242 TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
243 TLS_ECDH_anon_WITH_RC4_128_SHA,
244 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
245 TLS_ECDH_anon_WITH_NULL_SHA,
246 #endif
247 };
248
249 static const unsigned CipherSuiteCount = array_size(KnownCipherSuites);
250
251
252 /*
253 * Given a valid ctx->validCipherSpecs array, calculate how many of those
254 * cipherSpecs are *not* SSLv2 only, storing result in
255 * ctx->numValidNonSSLv2Specs. ClientHello routines need this to set
256 * up outgoing cipherSpecs arrays correctly.
257 *
258 * Also determines if any ECDSA/ECDH ciphers are enabled; we need to know
259 * that when creating a hello message.
260 */
261 static void sslAnalyzeCipherSpecs(SSLContext *ctx)
262 {
263 unsigned dex;
264 const SSLCipherSuite *cipherSuite;
265
266 #if ENABLE_SSLV2
267 ctx->numValidNonSSLv2Suites = 0;
268 #endif
269 cipherSuite = &ctx->validCipherSuites[0];
270 ctx->ecdsaEnable = false;
271 for(dex=0; dex<ctx->numValidCipherSuites; dex++, cipherSuite++) {
272 #if ENABLE_SSLV2
273 if(!CIPHER_SPEC_IS_SSLv2(*cipherSuite)) {
274 ctx->numValidNonSSLv2Suites++;
275 }
276 #endif
277 switch(sslCipherSuiteGetKeyExchangeMethod(*cipherSuite)) {
278 case SSL_ECDH_ECDSA:
279 case SSL_ECDHE_ECDSA:
280 case SSL_ECDH_RSA:
281 case SSL_ECDHE_RSA:
282 case SSL_ECDH_anon:
283 ctx->ecdsaEnable = true;
284 break;
285 default:
286 break;
287 }
288 }
289 }
290
291 /*
292 * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
293 * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
294 * not been called).
295 */
296 OSStatus sslBuildCipherSuiteArray(SSLContext *ctx)
297 {
298 size_t size;
299 unsigned dex;
300
301 assert(ctx != NULL);
302 assert(ctx->validCipherSuites == NULL);
303
304 ctx->numValidCipherSuites = CipherSuiteCount;
305 size = CipherSuiteCount * sizeof(SSLCipherSuite);
306 ctx->validCipherSuites = (SSLCipherSuite *)sslMalloc(size);
307 if(ctx->validCipherSuites == NULL) {
308 ctx->numValidCipherSuites = 0;
309 return errSecAllocate;
310 }
311
312 /*
313 * Trim out inappropriate ciphers:
314 * -- trim anonymous ciphers if !ctx->anonCipherEnable
315 * -- trim ECDSA ciphers for server side if appropriate
316 * -- trim ECDSA ciphers if TLSv1 disable or SSLv2 enabled (since
317 * we MUST do the Client Hello extensions to make these ciphers
318 * work reliably)
319 * -- trim Stream ciphers if DTLSv1 enable
320 */
321 SSLCipherSuite *dst = ctx->validCipherSuites;
322 const SSLCipherSuite *src = KnownCipherSuites;
323
324 bool trimECDSA = false;
325 if((ctx->protocolSide == kSSLServerSide) && !SSL_ECDSA_SERVER) {
326 trimECDSA = true;
327 }
328 if(ctx->minProtocolVersion == SSL_Version_2_0
329 || ctx->maxProtocolVersion == SSL_Version_3_0) {
330 /* We trim ECDSA cipher suites if SSL2 is enabled or
331 The maximum allowed protocol is SSL3. Note that this
332 won't trim ECDSA cipherspecs for DTLS which should be
333 the right thing to do here. */
334 trimECDSA = true;
335 }
336
337 /* trim Stream Ciphers for DTLS */
338 bool trimRC4 = ctx->isDTLS;
339
340 bool trimDHE = (ctx->protocolSide == kSSLServerSide) &&
341 !ctx->dhParamsEncoded.length;
342
343 for(dex=0; dex<CipherSuiteCount; dex++) {
344 KeyExchangeMethod kem = sslCipherSuiteGetKeyExchangeMethod(*src);
345 uint8_t keySize = sslCipherSuiteGetSymmetricCipherKeySize(*src);
346 HMAC_Algs mac = sslCipherSuiteGetMacAlgorithm(*src);
347 SSL_CipherAlgorithm cipher = sslCipherSuiteGetSymmetricCipherAlgorithm(*src);
348 /* First skip ECDSA ciphers as appropriate */
349 switch(kem) {
350 case SSL_ECDH_ECDSA:
351 case SSL_ECDHE_ECDSA:
352 case SSL_ECDH_RSA:
353 case SSL_ECDHE_RSA:
354 case SSL_ECDH_anon:
355 if(trimECDSA) {
356 /* Skip this one */
357 ctx->numValidCipherSuites--;
358 src++;
359 continue;
360 }
361 else {
362 break;
363 }
364 default:
365 break;
366 }
367 if(!ctx->anonCipherEnable) {
368 /* trim out the anonymous (and null-auth-cipher) ciphers */
369 if(mac == HA_Null) {
370 /* skip this one */
371 ctx->numValidCipherSuites--;
372 src++;
373 continue;
374 }
375 switch(kem) {
376 case SSL_DH_anon:
377 case SSL_DH_anon_EXPORT:
378 case SSL_ECDH_anon:
379 /* skip this one */
380 ctx->numValidCipherSuites--;
381 src++;
382 continue;
383 default:
384 break;
385 }
386 }
387 if(ctx->falseStartEnabled) {
388 switch(kem){
389 case SSL_ECDHE_ECDSA:
390 case SSL_ECDHE_RSA:
391 case SSL_DHE_RSA:
392 case SSL_DHE_DSS:
393 /* Ok for false start */
394 break;
395 default:
396 /* Not ok, skip */
397 ctx->numValidCipherSuites--;
398 src++;
399 continue;
400 }
401 switch(cipher) {
402 case SSL_CipherAlgorithmAES_128_CBC:
403 case SSL_CipherAlgorithmAES_128_GCM:
404 case SSL_CipherAlgorithmAES_256_CBC:
405 case SSL_CipherAlgorithmAES_256_GCM:
406 case SSL_CipherAlgorithmRC4_128:
407 /* Ok for false start */
408 break;
409 default:
410 /* Not ok, skip*/
411 ctx->numValidCipherSuites--;
412 src++;
413 continue;
414 }
415 }
416
417 /* This will skip the simple DES cipher suites, but not the NULL cipher ones */
418 if (keySize == 8)
419 {
420 /* skip this one */
421 ctx->numValidCipherSuites--;
422 src++;
423 continue;
424 }
425
426 /* Trim PSK ciphersuites, they need to be enabled explicitely */
427 if (kem==TLS_PSK) {
428 ctx->numValidCipherSuites--;
429 src++;
430 continue;
431 }
432
433 if (trimDHE) {
434 switch(kem) {
435 case SSL_DHE_DSS:
436 case SSL_DHE_DSS_EXPORT:
437 case SSL_DHE_RSA:
438 case SSL_DHE_RSA_EXPORT:
439 /* skip this one */
440 ctx->numValidCipherSuites--;
441 src++;
442 continue;
443 default:
444 break;
445 }
446 }
447
448 if (trimRC4 && (cipher==SSL_CipherAlgorithmRC4_128)) {
449 ctx->numValidCipherSuites--;
450 src++;
451 continue;
452 }
453
454 if(cipher==SSL_CipherAlgorithmNull) {
455 ctx->numValidCipherSuites--;
456 src++;
457 continue;
458 }
459
460 /* This one is good to go */
461 *dst++ = *src++;
462 }
463 sslAnalyzeCipherSpecs(ctx);
464 return errSecSuccess;
465 }
466
467 /*
468 * Convert an array of SSLCipherSuites (which is always KnownCipherSpecs)
469 * to an array of SSLCipherSuites.
470 */
471 static OSStatus
472 cipherSuitesToCipherSuites(
473 size_t numCipherSuites,
474 const SSLCipherSuite *cipherSuites,
475 SSLCipherSuite *ciphers, /* RETURNED */
476 size_t *numCiphers) /* IN/OUT */
477 {
478 if(*numCiphers < numCipherSuites) {
479 return errSSLBufferOverflow;
480 }
481 memcpy(ciphers, cipherSuites, numCipherSuites * sizeof(SSLCipherSuite));
482 *numCiphers = numCipherSuites;
483 return errSecSuccess;
484 }
485
486 /***
487 *** Publically exported functions declared in SecureTransport.h
488 ***/
489
490 /*
491 * Determine number and values of all of the SSLCipherSuites we support.
492 * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
493 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
494 * will be returned.
495 */
496 OSStatus
497 SSLGetNumberSupportedCiphers (SSLContextRef ctx,
498 size_t *numCiphers)
499 {
500 if((ctx == NULL) || (numCiphers == NULL)) {
501 return errSecParam;
502 }
503 *numCiphers = CipherSuiteCount;
504 return errSecSuccess;
505 }
506
507 OSStatus
508 SSLGetSupportedCiphers (SSLContextRef ctx,
509 SSLCipherSuite *ciphers, /* RETURNED */
510 size_t *numCiphers) /* IN/OUT */
511 {
512 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
513 return errSecParam;
514 }
515 return cipherSuitesToCipherSuites(CipherSuiteCount,
516 KnownCipherSuites,
517 ciphers,
518 numCiphers);
519 }
520
521 /*
522 * Specify a (typically) restricted set of SSLCipherSuites to be enabled by
523 * the current SSLContext. Can only be called when no session is active. Default
524 * set of enabled SSLCipherSuites is NOT the same as the complete set of supported
525 * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
526 */
527 OSStatus
528 SSLSetEnabledCiphers (SSLContextRef ctx,
529 const SSLCipherSuite *ciphers,
530 size_t numCiphers)
531 {
532 size_t size;
533 size_t foundCiphers=0;
534 unsigned callerDex;
535 unsigned tableDex;
536
537 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
538 return errSecParam;
539 }
540 if(sslIsSessionActive(ctx)) {
541 /* can't do this with an active session */
542 return errSecBadReq;
543 }
544 size = numCiphers * sizeof(SSLCipherSuite);
545 ctx->validCipherSuites = (SSLCipherSuite *)sslMalloc(size);
546 if(ctx->validCipherSuites == NULL) {
547 ctx->numValidCipherSuites = 0;
548 return errSecAllocate;
549 }
550
551 /*
552 * Run thru caller's specs, keep only the supported ones.
553 */
554 for(callerDex=0; callerDex<numCiphers; callerDex++) {
555 /* find matching CipherSpec in our known table */
556 for(tableDex=0; tableDex<CipherSuiteCount; tableDex++) {
557 if(ciphers[callerDex] == KnownCipherSuites[tableDex]) {
558 ctx->validCipherSuites[foundCiphers] = KnownCipherSuites[tableDex];
559 foundCiphers++;
560 break;
561 }
562 }
563 }
564
565 if(foundCiphers==0) {
566 /* caller specified only unsupported ciphersuites */
567 sslFree(ctx->validCipherSuites);
568 ctx->validCipherSuites = NULL;
569 return errSSLBadCipherSuite;
570 }
571
572 /* success */
573 ctx->numValidCipherSuites = foundCiphers;
574 sslAnalyzeCipherSpecs(ctx);
575 return errSecSuccess;
576 }
577
578 /*
579 * Determine number and values of all of the SSLCipherSuites currently enabled.
580 * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
581 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
582 * will be returned.
583 */
584 OSStatus
585 SSLGetNumberEnabledCiphers (SSLContextRef ctx,
586 size_t *numCiphers)
587 {
588 if((ctx == NULL) || (numCiphers == NULL)) {
589 return errSecParam;
590 }
591 if(ctx->validCipherSuites == NULL) {
592 /* hasn't been set; use default */
593 *numCiphers = CipherSuiteCount;
594 }
595 else {
596 /* caller set via SSLSetEnabledCiphers */
597 *numCiphers = ctx->numValidCipherSuites;
598 }
599 return errSecSuccess;
600 }
601
602 OSStatus
603 SSLGetEnabledCiphers (SSLContextRef ctx,
604 SSLCipherSuite *ciphers, /* RETURNED */
605 size_t *numCiphers) /* IN/OUT */
606 {
607 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
608 return errSecParam;
609 }
610 if(ctx->validCipherSuites == NULL) {
611 /* hasn't been set; use default */
612 return cipherSuitesToCipherSuites(CipherSuiteCount,
613 KnownCipherSuites,
614 ciphers,
615 numCiphers);
616 }
617 else {
618 /* use the ones specified in SSLSetEnabledCiphers() */
619 return cipherSuitesToCipherSuites(ctx->numValidCipherSuites,
620 ctx->validCipherSuites,
621 ciphers,
622 numCiphers);
623 }
624 }
625
626 /***
627 *** End of publically exported functions declared in SecureTransport.h
628 ***/
629
630 void InitCipherSpecParams(SSLContext *ctx)
631 {
632 SSLCipherSpecParams *dst = &ctx->selectedCipherSpecParams;
633 dst->cipherSpec = ctx->selectedCipher;
634 dst->macSize = sslCipherSuiteGetMacSize(ctx->selectedCipher);
635 dst->macAlg = sslCipherSuiteGetMacAlgorithm(ctx->selectedCipher);
636 dst->keySize = sslCipherSuiteGetSymmetricCipherKeySize(ctx->selectedCipher);
637 dst->blockSize = sslCipherSuiteGetSymmetricCipherBlockIvSize(ctx->selectedCipher);
638 dst->ivSize = dst->blockSize;
639 dst->keyExchangeMethod = sslCipherSuiteGetKeyExchangeMethod(ctx->selectedCipher);
640 };
641
642
643 OSStatus
644 FindCipherSpec(SSLContext *ctx)
645 {
646 unsigned i;
647
648 assert(ctx != NULL);
649 assert(ctx->validCipherSuites != NULL);
650
651 for (i=0; i<ctx->numValidCipherSuites; i++)
652 {
653 if (ctx->validCipherSuites[i] == ctx->selectedCipher) {
654 InitCipherSpecParams(ctx);
655 /* Make sure we're configured to handle this cipherSuite. */
656 return sslVerifySelectedCipher(ctx);
657 }
658 }
659 /* Not found */
660 return errSSLNegotiation;
661 }