1 /*
2 * cipherSuite.c
3 * Release $Name: MATRIXSSL-3-3-0-OPEN $
4 *
5 * Wrappers for the various cipher suites.
6 * Enable specific suites at compile time in matrixsslConfig.h
7 */
8 /*
9 * Copyright (c) AuthenTec, Inc. 2011-2012
10 * Copyright (c) PeerSec Networks, 2002-2011
11 * All Rights Reserved
12 *
13 * The latest version of this code is available at http://www.matrixssl.org
14 *
15 * This software is open source; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This General Public License does NOT permit incorporating this software
21 * into proprietary programs. If you are unable to comply with the GPL, a
22 * commercial license for this software may be purchased from AuthenTec at
23 * http://www.authentec.com/Products/EmbeddedSecurity/SecurityToolkits.aspx
24 *
25 * This program is distributed in WITHOUT ANY WARRANTY; without even the
26 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27 * See the GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 * http://www.gnu.org/copyleft/gpl.html
33 */
34 /******************************************************************************/
35
36 #include "matrixsslApi.h"
37
38 /******************************************************************************/
39 /* Symmetric cipher initializtion wrappers for cipher suites */
40 /******************************************************************************/
41 /*
42 SSL_NULL_WITH_NULL_NULL cipher functions
43 Used in handshaking before SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC message
44 */
csNullInit(sslSec_t * sec,int32 type,uint32 keysize)45 static int32 csNullInit(sslSec_t *sec, int32 type, uint32 keysize)
46 {
47 return 0;
48 }
49
50 /******************************************************************************/
51 #ifdef USE_ARC4_CIPHER_SUITE
52 /******************************************************************************/
csArc4Init(sslSec_t * sec,int32 type,uint32 keysize)53 static int32 csArc4Init(sslSec_t *sec, int32 type, uint32 keysize)
54 {
55 if (type == INIT_ENCRYPT_CIPHER) {
56 memset(&(sec->encryptCtx), 0, sizeof(psRc4Key_t));
57 psArc4Init(&(sec->encryptCtx), sec->writeKey, keysize);
58 } else {
59 memset(&(sec->decryptCtx), 0, sizeof(psRc4Key_t));
60 psArc4Init(&(sec->decryptCtx), sec->readKey, keysize);
61 }
62 return PS_SUCCESS;
63 }
64 #endif /* USE_ARC4_CIPHER_SUITE */
65 /******************************************************************************/
66
67 /******************************************************************************/
68 #ifdef USE_3DES_CIPHER_SUITE
69 /******************************************************************************/
csDes3Init(sslSec_t * sec,int32 type,uint32 keysize)70 static int32 csDes3Init(sslSec_t *sec, int32 type, uint32 keysize)
71 {
72 int32 err;
73
74 psAssert(keysize == DES3_KEY_LEN);
75
76 if (type == INIT_ENCRYPT_CIPHER) {
77 memset(&(sec->encryptCtx), 0, sizeof(des3_CBC));
78 if ((err = psDes3Init(&(sec->encryptCtx), sec->writeIV, sec->writeKey,
79 DES3_KEY_LEN)) < 0) {
80 return err;
81 }
82 #ifdef USE_TLS_1_1
83 if (sec->explicitIv) {
84 sec->encryptCtx.des3.explicitIV = 1;
85 }
86 #endif /* USE_TLS_1_1 */
87 } else {
88 memset(&(sec->decryptCtx), 0, sizeof(des3_CBC));
89 if ((err = psDes3Init(&(sec->decryptCtx), sec->readIV, sec->readKey,
90 DES3_KEY_LEN)) < 0) {
91 return err;
92 }
93 #ifdef USE_TLS_1_1
94 if (sec->explicitIv) {
95 sec->decryptCtx.des3.explicitIV = 1;
96 }
97 #endif /* USE_TLS_1_1 */
98 }
99 return PS_SUCCESS;
100 }
101 #endif /* USE_3DES_CIPHER_SUITE */
102 /******************************************************************************/
103
104
105 #ifdef USE_AES_CIPHER_SUITE
106 /******************************************************************************/
csAesInit(sslSec_t * sec,int32 type,uint32 keysize)107 static int32 csAesInit(sslSec_t *sec, int32 type, uint32 keysize)
108 {
109 int32 err;
110
111 if (type == INIT_ENCRYPT_CIPHER) {
112 memset(&(sec->encryptCtx), 0, sizeof(aes_CBC));
113 if ((err = psAesInit(&(sec->encryptCtx), sec->writeIV, sec->writeKey,
114 keysize)) < 0) {
115 return err;
116 }
117 #ifdef USE_TLS_1_1
118 if (sec->explicitIv) {
119 sec->encryptCtx.aes.explicitIV = 1;
120 }
121 #endif /* USE_TLS_1_1 */
122 } else {
123 memset(&(sec->decryptCtx), 0, sizeof(aes_CBC));
124 if ((err = psAesInit(&(sec->decryptCtx), sec->readIV, sec->readKey,
125 keysize)) < 0) {
126 return err;
127 }
128 #ifdef USE_TLS_1_1
129 if (sec->explicitIv) {
130 sec->decryptCtx.aes.explicitIV = 1;
131 }
132 #endif /* USE_TLS_1_1 */
133 }
134 return PS_SUCCESS;
135 }
136 #endif /* USE_AES_CIPHER_SUITE */
137 /******************************************************************************/
138
139
140
141 /******************************************************************************/
142 /* Null cipher crypto */
143 /******************************************************************************/
csNullEncrypt(psCipherContext_t * ctx,unsigned char * in,unsigned char * out,uint32 len)144 static int32 csNullEncrypt(psCipherContext_t *ctx, unsigned char *in,
145 unsigned char *out, uint32 len)
146 {
147 if (out != in) {
148 memcpy(out, in, len);
149 }
150 return len;
151 }
152
csNullDecrypt(psCipherContext_t * ctx,unsigned char * in,unsigned char * out,uint32 len)153 static int32 csNullDecrypt(psCipherContext_t *ctx, unsigned char *in,
154 unsigned char *out, uint32 len)
155 {
156 if (out != in) {
157 memmove(out, in, len);
158 }
159 return len;
160 }
161
162 /******************************************************************************/
163 /* HMAC wrappers for cipher suites */
164 /******************************************************************************/
csNullGenerateMac(void * ssl,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)165 static int32 csNullGenerateMac(void *ssl, unsigned char type,
166 unsigned char *data, uint32 len, unsigned char *mac)
167 {
168 return 0;
169 }
170
csNullVerifyMac(void * ssl,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)171 static int32 csNullVerifyMac(void *ssl, unsigned char type,
172 unsigned char *data, uint32 len, unsigned char *mac)
173 {
174 return 0;
175 }
176
177 #ifdef USE_SHA_MAC
178 /******************************************************************************/
csShaGenerateMac(void * sslv,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)179 static int32 csShaGenerateMac(void *sslv, unsigned char type,
180 unsigned char *data, uint32 len, unsigned char *mac)
181 {
182 ssl_t *ssl = (ssl_t*)sslv;
183
184 #ifdef USE_TLS
185 if (ssl->flags & SSL_FLAGS_TLS) {
186 return tlsHMACSha1(ssl, HMAC_CREATE, type, data, len, mac);
187 } else {
188 #endif /* USE_TLS */
189 #ifndef DISABLE_SSLV3
190 return ssl3HMACSha1(ssl->sec.writeMAC, ssl->sec.seq, type, data,
191 len, mac);
192 #else
193 return PS_ARG_FAIL;
194 #endif /* DISABLE_SSLV3 */
195 #ifdef USE_TLS
196 }
197 #endif /* USE_TLS */
198 }
199
csShaVerifyMac(void * sslv,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)200 static int32 csShaVerifyMac(void *sslv, unsigned char type,
201 unsigned char *data, uint32 len, unsigned char *mac)
202 {
203 int32 hashSize;
204 unsigned char buf[MAX_HASH_SIZE];
205 ssl_t *ssl = (ssl_t*)sslv;
206
207 hashSize = SHA1_HASH_SIZE;
208 #ifdef USE_TLS
209 if (ssl->flags & SSL_FLAGS_TLS) {
210 tlsHMACSha1(ssl, HMAC_VERIFY, type, data, len, buf);
211 } else {
212 #endif /* USE_TLS */
213 #ifndef DISABLE_SSLV3
214 ssl3HMACSha1(ssl->sec.readMAC, ssl->sec.remSeq, type, data, len, buf);
215 #endif /* DISABLE_SSLV3 */
216 #ifdef USE_TLS
217 }
218 #endif /* USE_TLS */
219 if (memcmp(buf, mac, hashSize) == 0) {
220 return PS_SUCCESS;
221 }
222 return PS_FAILURE;
223 }
224 #endif /* USE_SHA_MAC */
225 /******************************************************************************/
226
227 /******************************************************************************/
228 #ifdef USE_MD5_MAC
229 /******************************************************************************/
csMd5GenerateMac(void * sslv,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)230 static int32 csMd5GenerateMac(void *sslv, unsigned char type,
231 unsigned char *data, uint32 len, unsigned char *mac)
232 {
233 ssl_t *ssl = (ssl_t*)sslv;
234 #ifdef USE_TLS
235 if (ssl->flags & SSL_FLAGS_TLS) {
236 return tlsHMACMd5(ssl, HMAC_CREATE, type, data, len, mac);
237 } else {
238 #endif /* USE_TLS */
239 #ifndef DISABLE_SSLV3
240 return ssl3HMACMd5(ssl->sec.writeMAC, ssl->sec.seq, type, data,
241 len, mac);
242 #else
243 return PS_ARG_FAIL;
244 #endif /* DISABLE_SSLV3 */
245 #ifdef USE_TLS
246 }
247 #endif /* USE_TLS */
248 }
249
csMd5VerifyMac(void * sslv,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)250 static int32 csMd5VerifyMac(void *sslv, unsigned char type, unsigned char *data,
251 uint32 len, unsigned char *mac)
252 {
253 unsigned char buf[MD5_HASH_SIZE];
254 ssl_t *ssl = (ssl_t*)sslv;
255
256 #ifdef USE_TLS
257 if (ssl->flags & SSL_FLAGS_TLS) {
258 tlsHMACMd5(ssl, HMAC_VERIFY, type, data, len, buf);
259 } else {
260 #endif /* USE_TLS */
261 #ifndef DISABLE_SSLV3
262 ssl3HMACMd5(ssl->sec.readMAC, ssl->sec.remSeq, type, data, len, buf);
263 #endif /* DISABLE_SSLV3 */
264 #ifdef USE_TLS
265 }
266 #endif /* USE_TLS */
267 if (memcmp(buf, mac, MD5_HASH_SIZE) == 0) {
268 return PS_SUCCESS;
269 }
270 return PS_FAILURE;
271 }
272 #endif /* USE_MD5_MAC */
273 /******************************************************************************/
274
275 /******************************************************************************/
276 /* Public Key operations wrappers for cipher suites */
277 /******************************************************************************/
278 /******************************************************************************/
279 /******************************************************************************/
280
csRsaEncryptPub(psPool_t * pool,psPubKey_t * key,unsigned char * in,uint32 inlen,unsigned char * out,uint32 outlen)281 int32 csRsaEncryptPub(psPool_t *pool, psPubKey_t *key,
282 unsigned char *in, uint32 inlen, unsigned char *out, uint32 outlen)
283 {
284 psAssert(key->type == PS_RSA);
285 return psRsaEncryptPub(pool, (psRsaKey_t*)key->key, in, inlen, out, outlen);
286 }
287
csRsaDecryptPub(psPool_t * pool,psPubKey_t * key,unsigned char * in,uint32 inlen,unsigned char * out,uint32 outlen)288 int32 csRsaDecryptPub(psPool_t *pool, psPubKey_t *key,
289 unsigned char *in, uint32 inlen, unsigned char *out, uint32 outlen)
290 {
291 psAssert(key->type == PS_RSA);
292 return psRsaDecryptPub(pool, (psRsaKey_t*)key->key, in, inlen, out, outlen);
293 }
294
csRsaEncryptPriv(psPool_t * pool,psPubKey_t * key,unsigned char * in,uint32 inlen,unsigned char * out,uint32 outlen)295 int32 csRsaEncryptPriv(psPool_t *pool, psPubKey_t *key,
296 unsigned char *in, uint32 inlen, unsigned char *out, uint32 outlen)
297 {
298 return PS_UNSUPPORTED_FAIL;
299 }
300
csRsaDecryptPriv(psPool_t * pool,psPubKey_t * key,unsigned char * in,uint32 inlen,unsigned char * out,uint32 outlen)301 int32 csRsaDecryptPriv(psPool_t *pool, psPubKey_t *key,
302 unsigned char *in, uint32 inlen, unsigned char *out, uint32 outlen)
303 {
304 psAssert(key->type == PS_RSA);
305 return psRsaDecryptPriv(pool, (psRsaKey_t*)key->key, in, inlen, out, outlen);
306 }
307 /******************************************************************************/
308
309
310 static sslCipherSpec_t supportedCiphers[] = {
311 /*
312 New ciphers should be added here, similar to the ones below
313
314 Ciphers are listed in order of greater security at top... this generally
315 means the slower ones are on top as well.
316 */
317
318 #ifdef USE_TLS_RSA_WITH_AES_256_CBC_SHA
319 {TLS_RSA_WITH_AES_256_CBC_SHA,
320 CS_RSA,
321 CRYPTO_FLAGS_AES256 | CRYPTO_FLAGS_SHA1,
322 20, /* macSize */
323 32, /* keySize */
324 16, /* ivSize */
325 16, /* blocksize */
326 csAesInit,
327 psAesEncrypt,
328 psAesDecrypt,
329 csShaGenerateMac,
330 csShaVerifyMac},
331 #endif /* USE_TLS_RSA_WITH_AES_256_CBC_SHA */
332
333 #ifdef USE_TLS_RSA_WITH_AES_128_CBC_SHA
334 {TLS_RSA_WITH_AES_128_CBC_SHA,
335 CS_RSA,
336 CRYPTO_FLAGS_AES | CRYPTO_FLAGS_SHA1,
337 20, /* macSize */
338 16, /* keySize */
339 16, /* ivSize */
340 16, /* blocksize */
341 csAesInit,
342 psAesEncrypt,
343 psAesDecrypt,
344 csShaGenerateMac,
345 csShaVerifyMac},
346 #endif /* USE_TLS_RSA_WITH_AES_128_CBC_SHA */
347
348
349 #ifdef USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA
350 {SSL_RSA_WITH_3DES_EDE_CBC_SHA,
351 CS_RSA,
352 CRYPTO_FLAGS_3DES | CRYPTO_FLAGS_SHA1,
353 20, /* macSize */
354 24, /* keySize */
355 8, /* ivSize */
356 8, /* blocksize */
357 csDes3Init,
358 psDes3Encrypt,
359 psDes3Decrypt,
360 csShaGenerateMac,
361 csShaVerifyMac},
362 #endif /* USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA */
363
364 #ifdef USE_SSL_RSA_WITH_RC4_128_SHA
365 {SSL_RSA_WITH_RC4_128_SHA,
366 CS_RSA,
367 CRYPTO_FLAGS_ARC4 | CRYPTO_FLAGS_SHA1,
368 20, /* macSize */
369 16, /* keySize */
370 0, /* ivSize */
371 1, /* blocksize */
372 csArc4Init,
373 psArc4,
374 psArc4,
375 csShaGenerateMac,
376 csShaVerifyMac},
377 #endif /* USE_SSL_RSA_WITH_RC4_128_SHA */
378
379 #ifdef USE_SSL_RSA_WITH_RC4_128_MD5
380 {SSL_RSA_WITH_RC4_128_MD5,
381 CS_RSA,
382 CRYPTO_FLAGS_ARC4 | CRYPTO_FLAGS_MD5,
383 16, /* macSize */
384 16, /* keySize */
385 0, /* ivSize */
386 1, /* blocksize */
387 csArc4Init,
388 psArc4,
389 psArc4,
390 csMd5GenerateMac,
391 csMd5VerifyMac},
392 #endif /* USE_SSL_RSA_WITH_RC4_128_MD5 */
393
394
395 /*
396 These two USE_SSL_RSA_WITH_NULL ciphers are not recommended for use
397 in production applications.
398 */
399 #ifdef USE_SSL_RSA_WITH_NULL_SHA
400 {SSL_RSA_WITH_NULL_SHA,
401 CS_RSA,
402 CRYPTO_FLAGS_SHA1,
403 20, /* macSize */
404 0, /* keySize */
405 0, /* ivSize */
406 0, /* blocksize */
407 csNullInit,
408 csNullEncrypt,
409 csNullDecrypt,
410 csShaGenerateMac,
411 csShaVerifyMac},
412 #endif /* USE_SSL_RSA_WITH_NULL_SHA */
413
414 #ifdef USE_SSL_RSA_WITH_NULL_MD5
415 {SSL_RSA_WITH_NULL_MD5,
416 CS_RSA,
417 CRYPTO_FLAGS_MD5,
418 16, /* macSize */
419 0, /* keySize */
420 0, /* ivSize */
421 0, /* blocksize */
422 csNullInit,
423 csNullEncrypt,
424 csNullDecrypt,
425 csMd5GenerateMac,
426 csMd5VerifyMac},
427 #endif /* USE_SSL_RSA_WITH_NULL_MD5 */
428
429 /*
430 The NULL Cipher suite must exist and be the last in this list
431 */
432 {SSL_NULL_WITH_NULL_NULL,
433 CS_NULL,
434 0,
435 0,
436 0,
437 0,
438 0,
439 csNullInit,
440 csNullEncrypt,
441 csNullDecrypt,
442 csNullGenerateMac,
443 csNullVerifyMac}
444 };
445
446 #ifdef USE_SERVER_SIDE_SSL
447 /******************************************************************************/
448 /*
449 Disable and re-enable ciphers suites on a global or per-session level.
450 This is only a server-side feature because the client is always able to
451 nominate the specific cipher it wishes to use. Servers may want to disable
452 specific ciphers for a given session (or globally without having to
453 rebuild the library).
454
455 This function must be called immediately after matrixSslNewServerSession
456
457 If ssl is NULL, the setting will be global. If a cipher is globally
458 disabled, the per-session setting will be ignored.
459
460 flags:
461 PS_TRUE to reenable (always enabled by default if compiled in)
462 PS_FALSE to disable cipher suite
463 */
matrixSslSetCipherSuiteEnabledStatus(ssl_t * ssl,uint16 cipherId,uint32 flags)464 int32 matrixSslSetCipherSuiteEnabledStatus(ssl_t *ssl, uint16 cipherId,
465 uint32 flags)
466 {
467 uint16 i, j;
468
469 if (ssl && !(ssl->flags & SSL_FLAGS_SERVER)) {
470 return PS_UNSUPPORTED_FAIL;
471 }
472 if (flags != PS_TRUE && flags != PS_FALSE) {
473 return PS_ARG_FAIL;
474 }
475 for (i = 0; supportedCiphers[i].ident != SSL_NULL_WITH_NULL_NULL; i++) {
476 if (supportedCiphers[i].ident == cipherId) {
477 if (ssl == NULL) {
478 /*
479 Global status of cipher suite. Disabled status takes
480 precident over session setting
481 */
482 if (flags == PS_TRUE) {
483 supportedCiphers[i].flags &= ~CRYPTO_FLAGS_DISABLED;
484 } else {
485 supportedCiphers[i].flags |= CRYPTO_FLAGS_DISABLED;
486 }
487 return PS_SUCCESS;
488 } else {
489 /*
490 Status of this suite for a specific session
491 */
492 for (j = 0; j < SSL_MAX_DISABLED_CIPHERS; j++) {
493 if (flags == PS_FALSE) {
494 /* Find first empty spot to add disabled cipher */
495 if (ssl->disabledCiphers[j] == 0x0 ||
496 ssl->disabledCiphers[j] == cipherId) {
497 ssl->disabledCiphers[j] = cipherId;
498 return PS_SUCCESS;
499 }
500 } else {
501 if (ssl->disabledCiphers[j] == cipherId) {
502 ssl->disabledCiphers[j] = 0x0;
503 return PS_SUCCESS;
504 }
505 }
506 }
507 if (flags == PS_FALSE) {
508 return PS_LIMIT_FAIL; /* No empty spot in disabledCiphers */
509 } else {
510 /* Tried to re-enabled a cipher that wasn't disabled */
511 return PS_SUCCESS;
512 }
513 }
514 }
515 }
516 return PS_FAILURE; /* Cipher not found */
517 }
518 #endif /* USE_SERVER_SIDE_SSL */
519
520 #ifdef VALIDATE_KEY_MATERIAL
521 /*
522 TODO: these currently allow any cert in the chain to return success but
523 it would be better to force only the parent-most(?) to be checked
524 */
haveCorrectKeyAlg(psX509Cert_t * cert,int32 keyAlg)525 static int32 haveCorrectKeyAlg(psX509Cert_t *cert, int32 keyAlg)
526 {
527 while (cert) {
528 if (cert->pubKeyAlgorithm == keyAlg) {
529 return PS_SUCCESS;
530 }
531 cert = cert->next;
532 }
533 return PS_FAILURE;
534 }
535
536
537 /******************************************************************************/
538 /*
539 Don't report a matching cipher suite if the user hasn't loaded the
540 proper public key material to support it
541 */
haveKeyMaterial(ssl_t * ssl,int32 cipherType)542 static int32 haveKeyMaterial(ssl_t *ssl, int32 cipherType)
543 {
544 /*
545 Standard RSA ciphers types
546 */
547 if (cipherType == CS_RSA) {
548 if (ssl->flags & SSL_FLAGS_SERVER) {
549 #ifdef USE_SERVER_SIDE_SSL
550 if (ssl->keys == NULL || ssl->keys->cert == NULL ||
551 ssl->keys->privKey == NULL) {
552 return PS_FAILURE;
553 }
554 if (haveCorrectKeyAlg(ssl->keys->cert, OID_RSA_KEY_ALG) < 0) {
555 return PS_FAILURE;
556 }
557 #else
558 return PS_FAILURE;
559 #endif /* USE_SERVER_SIDE_SSL */
560
561 #ifdef USE_CLIENT_SIDE_SSL
562 } else {
563 if (ssl->keys == NULL || ssl->keys->CAcerts == NULL) {
564 return PS_FAILURE;
565 }
566 if (haveCorrectKeyAlg(ssl->keys->CAcerts, OID_RSA_KEY_ALG) < 0) {
567 return PS_FAILURE;
568 }
569 #endif /* USE_CLIENT_SIDE_SSL */
570 }
571 }
572
573
574
575
576 return PS_SUCCESS;
577 }
578 #endif /* VALIDATE_KEY_MATERIAL */
579
580 /******************************************************************************/
581 /*
582 Lookup the given cipher spec ID and return a pointer to the structure
583 if found. This is used when negotiating security, to find out what suites
584 we support.
585 */
sslGetCipherSpec(ssl_t * ssl,uint32 id)586 sslCipherSpec_t *sslGetCipherSpec(ssl_t *ssl, uint32 id)
587 {
588 int16 i;
589 #ifdef USE_SERVER_SIDE_SSL
590 int16 j;
591 #endif /* USE_SERVER_SIDE_SSL */
592
593 i = 0;
594 do {
595 if (supportedCiphers[i].ident == id) {
596 #ifdef USE_SERVER_SIDE_SSL
597 /*
598 Globally disabled?
599 */
600 if (supportedCiphers[i].flags & CRYPTO_FLAGS_DISABLED) {
601 psTraceIntInfo("Matched cipher suite %d but disabled by user\n",
602 id);
603 return NULL;
604 }
605 /*
606 Disabled for session?
607 */
608 if (id != 0) { /* Disable NULL_WITH_NULL_NULL not possible */
609 for (j = 0; j < SSL_MAX_DISABLED_CIPHERS; j++) {
610 if (ssl->disabledCiphers[j] == id) {
611 psTraceIntInfo("Matched cipher suite %d but disabled by user\n",
612 id);
613 return NULL;
614 }
615 }
616 }
617 #endif /* USE_SERVER_SIDE_SSL */
618 /*
619 Unusable due to key material not available?
620 */
621 #ifdef VALIDATE_KEY_MATERIAL
622 if (haveKeyMaterial(ssl, supportedCiphers[i].type) == PS_SUCCESS) {
623 return &supportedCiphers[i];
624 }
625 psTraceIntInfo("Matched cipher suite %d but no supporting keys\n",
626 id);
627 #else
628 return &supportedCiphers[i];
629 #endif /* VALIDATE_KEY_MATERIAL */
630 }
631 } while (supportedCiphers[i++].ident != SSL_NULL_WITH_NULL_NULL) ;
632
633 return NULL;
634 }
635
636
637 /******************************************************************************/
638 /*
639 Write out a list of the supported cipher suites to the caller's buffer
640 First 2 bytes are the number of cipher suite bytes, the remaining bytes are
641 the cipher suites, as two byte, network byte order values.
642 */
sslGetCipherSpecList(ssl_t * ssl,unsigned char * c,int32 len,int32 addScsv)643 int32 sslGetCipherSpecList(ssl_t *ssl, unsigned char *c, int32 len,
644 int32 addScsv)
645 {
646 unsigned char *end, *p;
647 unsigned short i;
648 int32 ignored;
649
650 if (len < 4) {
651 return -1;
652 }
653 end = c + len;
654 p = c; c += 2;
655
656 ignored = 0;
657 for (i = 0; supportedCiphers[i].ident != SSL_NULL_WITH_NULL_NULL; i++) {
658 if (end - c < 2) {
659 return -1;
660 }
661 #ifdef VALIDATE_KEY_MATERIAL
662 if (haveKeyMaterial(ssl, supportedCiphers[i].type) != PS_SUCCESS) {
663 ignored += 2;
664 continue;
665 }
666 #endif
667 *c = (unsigned char)((supportedCiphers[i].ident & 0xFF00) >> 8); c++;
668 *c = (unsigned char)(supportedCiphers[i].ident & 0xFF); c++;
669 }
670 i *= 2;
671 i -= (unsigned short)ignored;
672 #ifdef ENABLE_SECURE_REHANDSHAKES
673 if (addScsv == 1) {
674 *c = ((TLS_EMPTY_RENEGOTIATION_INFO_SCSV & 0xFF00) >> 8); c++;
675 *c = TLS_EMPTY_RENEGOTIATION_INFO_SCSV & 0xFF; c++;
676 i += 2;
677 }
678 #endif
679 *p = (unsigned char)(i >> 8); p++;
680 *p = (unsigned char)(i & 0xFF);
681 return i + 2;
682 }
683
684 /******************************************************************************/
685 /*
686 Return the length of the cipher spec list, including initial length bytes,
687 (minus any suites that we don't have the key material to support)
688 */
sslGetCipherSpecListLen(ssl_t * ssl)689 int32 sslGetCipherSpecListLen(ssl_t *ssl)
690 {
691 int32 i, ignored;
692
693 ignored = 0;
694 for (i = 0; supportedCiphers[i].ident != SSL_NULL_WITH_NULL_NULL; i++) {
695 #ifdef VALIDATE_KEY_MATERIAL
696 if (haveKeyMaterial(ssl, supportedCiphers[i].type) != PS_SUCCESS) {
697 ignored += 2;
698 }
699 #endif
700 }
701 return (i * 2) + 2 - ignored;
702 }
703
704 /******************************************************************************/
705
706