]> git.saurik.com Git - apple/security.git/blob - SecureTransport/cipherSpecs.c
Security-28.tar.gz
[apple/security.git] / SecureTransport / cipherSpecs.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 File: cipherSpecs.c
21
22 Contains: SSLCipherSpec declarations
23
24 Written by: Doug Mitchell, based on Netscape RSARef 3.0
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "sslctx.h"
31 #include "cryptType.h"
32 #include "symCipher.h"
33 #include "cipherSpecs.h"
34 #include "sslDebug.h"
35 #include "sslalloc.h"
36 #include "sslDebug.h"
37 #include "sslutil.h"
38 #include <string.h>
39 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
40
41 /* FIXME - domestic suites do not work in server side in level 3 */
42
43 #define ENABLE_3DES 1 /* normally enabled, our first preference */
44 #define ENABLE_RC4 1 /* normally enabled, the most common one */
45 #define ENABLE_DES 1 /* normally enabled */
46 #define ENABLE_RC2 1 /* normally enabled */
47
48 #define ENABLE_RSA_DES_SHA_NONEXPORT ENABLE_DES
49 #define ENABLE_RSA_DES_MD5_NONEXPORT ENABLE_DES
50 #define ENABLE_RSA_DES_SHA_EXPORT ENABLE_DES
51 #define ENABLE_RSA_RC4_MD5_EXPORT ENABLE_RC4 /* the most common one */
52 #define ENABLE_RSA_RC4_MD5_NONEXPORT ENABLE_RC4
53 #define ENABLE_RSA_RC4_SHA_NONEXPORT ENABLE_RC4
54 #define ENABLE_RSA_RC2_MD5_EXPORT ENABLE_RC2
55 #define ENABLE_RSA_RC2_MD5_NONEXPORT ENABLE_RC2
56 #define ENABLE_RSA_3DES_SHA ENABLE_3DES
57 #define ENABLE_RSA_3DES_MD5 ENABLE_3DES
58
59 extern SSLSymmetricCipher SSLCipherNull; /* in nullciph.c */
60
61 /*
62 * The symmetric ciphers currently supported (in addition to the
63 * NULL cipher in nullciph.c).
64 */
65 #if ENABLE_DES
66 static const SSLSymmetricCipher SSLCipherDES_CBC = {
67 8, /* Key size in bytes */
68 8, /* Secret key size = 64 bits */
69 8, /* IV size */
70 8, /* Block size */
71 CSSM_ALGID_DES,
72 CSSM_ALGID_DES,
73 /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
74 * for us */
75 CSSM_ALGMODE_CBC_IV8,
76 CSSM_PADDING_NONE,
77 CDSASymmInit,
78 CDSASymmEncrypt,
79 CDSASymmDecrypt,
80 CDSASymmFinish
81 };
82
83 static const SSLSymmetricCipher SSLCipherDES40_CBC = {
84 8, /* Key size in bytes */
85 5, /* Secret key size = 40 bits */
86 8, /* IV size */
87 8, /* Block size */
88 CSSM_ALGID_DES,
89 CSSM_ALGID_DES,
90 CSSM_ALGMODE_CBC_IV8,
91 CSSM_PADDING_NONE,
92 CDSASymmInit,
93 CDSASymmEncrypt,
94 CDSASymmDecrypt,
95 CDSASymmFinish
96 };
97 #endif /* ENABLE_DES */
98
99 #if ENABLE_3DES
100 static const SSLSymmetricCipher SSLCipher3DES_CBC = {
101 24, /* Key size in bytes */
102 24, /* Secret key size = 192 bits */
103 8, /* IV size */
104 8, /* Block size */
105 CSSM_ALGID_3DES_3KEY, // key gen
106 CSSM_ALGID_3DES_3KEY_EDE, // encryption
107 /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
108 * for us */
109 CSSM_ALGMODE_CBC_IV8,
110 CSSM_PADDING_NONE,
111 CDSASymmInit,
112 CDSASymmEncrypt,
113 CDSASymmDecrypt,
114 CDSASymmFinish
115 };
116 #endif /* ENABLE_3DES */
117
118 #if ENABLE_RC4
119 static const SSLSymmetricCipher SSLCipherRC4_40 = {
120 16, /* Key size in bytes */
121 5, /* Secret key size = 40 bits */
122 0, /* IV size */
123 0, /* Block size */
124 CSSM_ALGID_RC4,
125 CSSM_ALGID_RC4,
126 CSSM_ALGMODE_NONE,
127 CSSM_PADDING_NONE,
128 CDSASymmInit,
129 CDSASymmEncrypt,
130 CDSASymmDecrypt,
131 CDSASymmFinish
132 };
133
134 static const SSLSymmetricCipher SSLCipherRC4_128 = {
135 16, /* Key size in bytes */
136 16, /* Secret key size = 128 bits */
137 0, /* IV size */
138 0, /* Block size */
139 CSSM_ALGID_RC4,
140 CSSM_ALGID_RC4,
141 CSSM_ALGMODE_NONE,
142 CSSM_PADDING_NONE,
143 CDSASymmInit,
144 CDSASymmEncrypt,
145 CDSASymmDecrypt,
146 CDSASymmFinish
147 };
148 #endif /* ENABLE_RC4 */
149
150 #if ENABLE_RC2
151 static const SSLSymmetricCipher SSLCipherRC2_40 = {
152 16, /* Key size in bytes */
153 5, /* Secret key size = 40 bits */
154 8, /* IV size */
155 8, /* Block size */
156 CSSM_ALGID_RC2,
157 CSSM_ALGID_RC2,
158 CSSM_ALGMODE_CBC_IV8,
159 CSSM_PADDING_NONE,
160 CDSASymmInit,
161 CDSASymmEncrypt,
162 CDSASymmDecrypt,
163 CDSASymmFinish
164 };
165
166 static const SSLSymmetricCipher SSLCipherRC2_128 = {
167 16, /* Key size in bytes */
168 16, /* Secret key size = 40 bits */
169 8, /* IV size */
170 8, /* Block size */
171 CSSM_ALGID_RC2,
172 CSSM_ALGID_RC2,
173 CSSM_ALGMODE_CBC_IV8,
174 CSSM_PADDING_NONE,
175 CDSASymmInit,
176 CDSASymmEncrypt,
177 CDSASymmDecrypt,
178 CDSASymmFinish
179 };
180
181 #endif /* ENABLE_RC2*/
182
183
184 /* Even if we don't support NULL_WITH_NULL_NULL for transport,
185 * we need a reference for startup */
186 const SSLCipherSpec SSL_NULL_WITH_NULL_NULL_CipherSpec =
187 { SSL_NULL_WITH_NULL_NULL,
188 Exportable,
189 SSL_NULL_auth,
190 &SSLHashNull,
191 &SSLCipherNull
192 };
193
194 /*
195 * List of all CipherSpecs we implement. Depending on a context's
196 * exportable flag, not all of these might be available for use.
197 *
198 * FIXME - I'm not sure the distinction between e.g. SSL_RSA and SSL_RSA_EXPORT
199 * makes any sense here. See comments for the definition of
200 * KeyExchangeMethod in cryptType.h.
201 */
202 /* Order by preference, domestic first */
203 static const SSLCipherSpec KnownCipherSpecs[] =
204 {
205 /*** domestic only ***/
206 #if ENABLE_RSA_3DES_SHA
207 {
208 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
209 NotExportable,
210 SSL_RSA,
211 &SSLHashSHA1,
212 &SSLCipher3DES_CBC
213 },
214 #endif
215 #if ENABLE_RSA_3DES_MD5
216 {
217 SSL_RSA_WITH_3DES_EDE_CBC_MD5,
218 NotExportable,
219 SSL_RSA,
220 &SSLHashMD5,
221 &SSLCipher3DES_CBC
222 },
223 #endif
224 #if ENABLE_RSA_RC4_SHA_NONEXPORT
225 {
226 SSL_RSA_WITH_RC4_128_SHA,
227 NotExportable,
228 SSL_RSA,
229 &SSLHashSHA1,
230 &SSLCipherRC4_128
231 },
232 #endif
233 #if ENABLE_RSA_RC4_MD5_NONEXPORT
234 {
235 SSL_RSA_WITH_RC4_128_MD5,
236 NotExportable,
237 SSL_RSA,
238 &SSLHashMD5,
239 &SSLCipherRC4_128
240 },
241 #endif
242 #if ENABLE_RSA_DES_SHA_NONEXPORT
243 {
244 SSL_RSA_WITH_DES_CBC_SHA,
245 NotExportable,
246 SSL_RSA,
247 &SSLHashSHA1,
248 &SSLCipherDES_CBC
249 },
250 #endif
251 #if ENABLE_RSA_DES_MD5_NONEXPORT
252 {
253 SSL_RSA_WITH_DES_CBC_MD5,
254 NotExportable,
255 SSL_RSA,
256 &SSLHashMD5,
257 &SSLCipherDES_CBC
258 },
259 #endif
260 /*** exportable ***/
261 #if ENABLE_RSA_RC4_MD5_EXPORT
262 {
263 SSL_RSA_EXPORT_WITH_RC4_40_MD5,
264 Exportable,
265 SSL_RSA_EXPORT,
266 &SSLHashMD5,
267 &SSLCipherRC4_40
268 },
269 #endif
270 #if APPLE_DH
271 /* Apple CSP doesn't support D-H yet */
272 {
273 SSL_DH_anon_WITH_RC4_128_MD5,
274 NotExportable,
275 SSL_DH_anon,
276 &SSLHashMD5,
277 &SSLCipherRC4_128
278 },
279 #endif
280 #if ENABLE_RSA_DES_SHA_EXPORT
281 {
282 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
283 Exportable,
284 SSL_RSA_EXPORT,
285 &SSLHashSHA1,
286 &SSLCipherDES40_CBC
287 },
288 #endif
289
290 #if ENABLE_RSA_RC2_MD5_EXPORT
291 {
292 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
293 Exportable,
294 SSL_RSA_EXPORT,
295 &SSLHashMD5,
296 &SSLCipherRC2_40
297 },
298 #endif
299 #if ENABLE_RSA_RC2_MD5_NONEXPORT
300 {
301 SSL_RSA_WITH_RC2_CBC_MD5,
302 NotExportable,
303 SSL_RSA,
304 &SSLHashMD5,
305 &SSLCipherRC2_128
306 },
307 #endif
308 {
309 SSL_RSA_WITH_NULL_MD5,
310 Exportable,
311 SSL_RSA,
312 &SSLHashMD5,
313 &SSLCipherNull
314 }
315 };
316
317 static const int CipherSpecCount = sizeof(KnownCipherSpecs) / sizeof(SSLCipherSpec);
318
319 /*
320 * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
321 * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
322 * not been called).
323 */
324 SSLErr sslBuildCipherSpecArray(SSLContext *ctx)
325 {
326 unsigned size;
327
328 CASSERT(ctx != NULL);
329 CASSERT(ctx->validCipherSpecs == NULL);
330
331 ctx->numValidCipherSpecs = CipherSpecCount;
332 size = CipherSpecCount * sizeof(SSLCipherSpec);
333 ctx->validCipherSpecs = sslMalloc(size);
334 if(ctx->validCipherSpecs == NULL) {
335 ctx->numValidCipherSpecs = 0;
336 return SSLMemoryErr;
337 }
338 memmove(ctx->validCipherSpecs, KnownCipherSpecs, size);
339 return SSLNoErr;
340 }
341
342 /*
343 * Convert an array of SSLCipherSpecs (which is either KnownCipherSpecs or
344 * ctx->validCipherSpecs) to an array of SSLCipherSuites.
345 */
346 static OSStatus
347 cipherSpecsToCipherSuites(
348 UInt32 numCipherSpecs, /* size of cipherSpecs */
349 const SSLCipherSpec *cipherSpecs,
350 SSLCipherSuite *ciphers, /* RETURNED */
351 UInt32 *numCiphers) /* IN/OUT */
352 {
353 unsigned dex;
354
355 if(*numCiphers < numCipherSpecs) {
356 return errSSLBufferOverflow;
357 }
358 for(dex=0; dex<numCipherSpecs; dex++) {
359 ciphers[dex] = cipherSpecs[dex].cipherSpec;
360 }
361 *numCiphers = numCipherSpecs;
362 return noErr;
363 }
364
365 /***
366 *** Publically exported functions declared in SecureTransport.h
367 ***/
368
369 /*
370 * Determine number and values of all of the SSLCipherSuites we support.
371 * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
372 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
373 * will be returned.
374 */
375 OSStatus
376 SSLGetNumberSupportedCiphers (SSLContextRef ctx,
377 UInt32 *numCiphers)
378 {
379 if((ctx == NULL) || (numCiphers == NULL)) {
380 return paramErr;
381 }
382 *numCiphers = CipherSpecCount;
383 return noErr;
384 }
385
386 OSStatus
387 SSLGetSupportedCiphers (SSLContextRef ctx,
388 SSLCipherSuite *ciphers, /* RETURNED */
389 UInt32 *numCiphers) /* IN/OUT */
390 {
391 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
392 return paramErr;
393 }
394 return cipherSpecsToCipherSuites(CipherSpecCount,
395 KnownCipherSpecs,
396 ciphers,
397 numCiphers);
398 }
399
400 /*
401 * Specify a (typlically) restricted set of SSLCipherSuites to be enabled by
402 * the current SSLContext. Can only be called when no session is active. Default
403 * set of enabled SSLCipherSuites is the same as the complete set of supported
404 * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
405 */
406 OSStatus
407 SSLSetEnabledCiphers (SSLContextRef ctx,
408 const SSLCipherSuite *ciphers,
409 UInt32 numCiphers)
410 {
411 unsigned size;
412 unsigned callerDex;
413 unsigned tableDex;
414
415 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
416 return paramErr;
417 }
418 if(sslIsSessionActive(ctx)) {
419 /* can't do this with an active session */
420 return badReqErr;
421 }
422 size = numCiphers * sizeof(SSLCipherSpec);
423 ctx->validCipherSpecs = sslMalloc(size);
424 if(ctx->validCipherSpecs == NULL) {
425 ctx->numValidCipherSpecs = 0;
426 return SSLMemoryErr;
427 }
428
429 /*
430 * Run thru caller's specs, finding a matching SSLCipherSpec for each one.
431 * If caller specifies one we don't know about, abort.
432 */
433 for(callerDex=0; callerDex<numCiphers; callerDex++) {
434 /* find matching CipherSpec in our known table */
435 int foundOne = 0;
436 for(tableDex=0; tableDex<CipherSpecCount; tableDex++) {
437 if(ciphers[callerDex] == KnownCipherSpecs[tableDex].cipherSpec) {
438 ctx->validCipherSpecs[callerDex] = KnownCipherSpecs[tableDex];
439 foundOne = 1;
440 break;
441 }
442 }
443 if(!foundOne) {
444 /* caller specified one we don't implement */
445 sslFree(ctx->validCipherSpecs);
446 ctx->validCipherSpecs = NULL;
447 return errSSLBadCipherSuite;
448 }
449 }
450
451 /* success */
452 ctx->numValidCipherSpecs = numCiphers;
453 return noErr;
454 }
455
456 /*
457 * Determine number and values of all of the SSLCipherSuites currently enabled.
458 * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
459 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
460 * will be returned.
461 */
462 OSStatus
463 SSLGetNumberEnabledCiphers (SSLContextRef ctx,
464 UInt32 *numCiphers)
465 {
466 if((ctx == NULL) || (numCiphers == NULL)) {
467 return paramErr;
468 }
469 if(ctx->validCipherSpecs == NULL) {
470 /* hasn't been set; use default */
471 *numCiphers = CipherSpecCount;
472 }
473 else {
474 /* caller set via SSLSetEnabledCiphers */
475 *numCiphers = ctx->numValidCipherSpecs;
476 }
477 return noErr;
478 }
479
480 OSStatus
481 SSLGetEnabledCiphers (SSLContextRef ctx,
482 SSLCipherSuite *ciphers, /* RETURNED */
483 UInt32 *numCiphers) /* IN/OUT */
484 {
485 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
486 return paramErr;
487 }
488 if(ctx->validCipherSpecs == NULL) {
489 /* hasn't been set; use default */
490 return cipherSpecsToCipherSuites(CipherSpecCount,
491 KnownCipherSpecs,
492 ciphers,
493 numCiphers);
494 }
495 else {
496 /* use the ones specified in SSLSetEnabledCiphers() */
497 return cipherSpecsToCipherSuites(ctx->numValidCipherSpecs,
498 ctx->validCipherSpecs,
499 ciphers,
500 numCiphers);
501 }
502 }
503
504 /***
505 *** End of publically exported functions declared in SecureTransport.h
506 ***/
507
508 /*
509 * Given a valid ctx->selectedCipher and ctx->validCipherSpecs, set
510 * ctx->selectedCipherSpec as appropriate.
511 */
512 SSLErr
513 FindCipherSpec(SSLContext *ctx)
514 {
515
516 unsigned i;
517
518 CASSERT(ctx != NULL);
519 CASSERT(ctx->validCipherSpecs != NULL);
520
521 ctx->selectedCipherSpec = NULL;
522 for (i=0; i<ctx->numValidCipherSpecs; i++)
523 { if (ctx->validCipherSpecs[i].cipherSpec == ctx->selectedCipher) {
524 ctx->selectedCipherSpec = &ctx->validCipherSpecs[i];
525 break;
526 }
527 }
528 if (ctx->selectedCipherSpec == NULL) /* Not found */
529 return SSLNegotiationErr;
530 return SSLNoErr;
531 }
532