summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2014-09-22 14:26:22 +0000
committerjsing <>2014-09-22 14:26:22 +0000
commitad04e6a1deb1fa849ae2c9a7ce2393dfee765f3f (patch)
treeef3f69bededfcfdd462563f261382712b92f9f73
parent93a144bf193161ecec0ea955305c15f5f141bd08 (diff)
downloadopenbsd-ad04e6a1deb1fa849ae2c9a7ce2393dfee765f3f.tar.gz
openbsd-ad04e6a1deb1fa849ae2c9a7ce2393dfee765f3f.tar.bz2
openbsd-ad04e6a1deb1fa849ae2c9a7ce2393dfee765f3f.zip
Refactor and simplify the ECC extension handling. The existing code
effectively built two "static" data structures - instead of doing this, just use static data structures to start with. From OpenSSL (part of a larger commit). ok miod@
-rw-r--r--src/lib/libssl/src/ssl/ssl_sess.c22
-rw-r--r--src/lib/libssl/src/ssl/t1_lib.c198
-rw-r--r--src/lib/libssl/ssl_sess.c22
-rw-r--r--src/lib/libssl/t1_lib.c198
4 files changed, 196 insertions, 244 deletions
diff --git a/src/lib/libssl/src/ssl/ssl_sess.c b/src/lib/libssl/src/ssl/ssl_sess.c
index 8e285ea9b1..3ffd7078a5 100644
--- a/src/lib/libssl/src/ssl/ssl_sess.c
+++ b/src/lib/libssl/src/ssl/ssl_sess.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_sess.c,v 1.40 2014/08/11 01:06:22 jsing Exp $ */ 1/* $OpenBSD: ssl_sess.c,v 1.41 2014/09/22 14:26:22 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -375,26 +375,6 @@ sess_id_done:
375 return 0; 375 return 0;
376 } 376 }
377 } 377 }
378 if (s->tlsext_ecpointformatlist) {
379 free(ss->tlsext_ecpointformatlist);
380 if ((ss->tlsext_ecpointformatlist = malloc(s->tlsext_ecpointformatlist_length)) == NULL) {
381 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
382 SSL_SESSION_free(ss);
383 return 0;
384 }
385 ss->tlsext_ecpointformatlist_length = s->tlsext_ecpointformatlist_length;
386 memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
387 }
388 if (s->tlsext_ellipticcurvelist) {
389 free(ss->tlsext_ellipticcurvelist);
390 if ((ss->tlsext_ellipticcurvelist = malloc(s->tlsext_ellipticcurvelist_length)) == NULL) {
391 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
392 SSL_SESSION_free(ss);
393 return 0;
394 }
395 ss->tlsext_ellipticcurvelist_length = s->tlsext_ellipticcurvelist_length;
396 memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
397 }
398 } else { 378 } else {
399 ss->session_id_length = 0; 379 ss->session_id_length = 0;
400 } 380 }
diff --git a/src/lib/libssl/src/ssl/t1_lib.c b/src/lib/libssl/src/ssl/t1_lib.c
index 87a65e3db2..7e4aba7f23 100644
--- a/src/lib/libssl/src/ssl/t1_lib.c
+++ b/src/lib/libssl/src/ssl/t1_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_lib.c,v 1.55 2014/09/21 17:11:04 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.56 2014/09/22 14:26:22 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -239,35 +239,38 @@ static int nid_list[] = {
239 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */ 239 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */
240}; 240};
241 241
242static int pref_list[] = { 242static const unsigned char ecformats_default[] = {
243 NID_sect571r1, /* sect571r1 (14) */ 243 TLSEXT_ECPOINTFORMAT_uncompressed,
244 NID_sect571k1, /* sect571k1 (13) */ 244 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
245 NID_secp521r1, /* secp521r1 (25) */ 245 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
246 NID_brainpoolP512r1, /* brainpoolP512r1 (28) */ 246};
247 NID_sect409k1, /* sect409k1 (11) */ 247
248 NID_sect409r1, /* sect409r1 (12) */ 248static const unsigned char eccurves_default[] = {
249 NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ 249 0,14, /* sect571r1 (14) */
250 NID_secp384r1, /* secp384r1 (24) */ 250 0,13, /* sect571k1 (13) */
251 NID_sect283k1, /* sect283k1 (9) */ 251 0,25, /* secp521r1 (25) */
252 NID_sect283r1, /* sect283r1 (10) */ 252 0,11, /* sect409k1 (11) */
253 NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ 253 0,12, /* sect409r1 (12) */
254 NID_secp256k1, /* secp256k1 (22) */ 254 0,24, /* secp384r1 (24) */
255 NID_X9_62_prime256v1, /* secp256r1 (23) */ 255 0,9, /* sect283k1 (9) */
256 NID_sect239k1, /* sect239k1 (8) */ 256 0,10, /* sect283r1 (10) */
257 NID_sect233k1, /* sect233k1 (6) */ 257 0,22, /* secp256k1 (22) */
258 NID_sect233r1, /* sect233r1 (7) */ 258 0,23, /* secp256r1 (23) */
259 NID_secp224k1, /* secp224k1 (20) */ 259 0,8, /* sect239k1 (8) */
260 NID_secp224r1, /* secp224r1 (21) */ 260 0,6, /* sect233k1 (6) */
261 NID_sect193r1, /* sect193r1 (4) */ 261 0,7, /* sect233r1 (7) */
262 NID_sect193r2, /* sect193r2 (5) */ 262 0,20, /* secp224k1 (20) */
263 NID_secp192k1, /* secp192k1 (18) */ 263 0,21, /* secp224r1 (21) */
264 NID_X9_62_prime192v1, /* secp192r1 (19) */ 264 0,4, /* sect193r1 (4) */
265 NID_sect163k1, /* sect163k1 (1) */ 265 0,5, /* sect193r2 (5) */
266 NID_sect163r1, /* sect163r1 (2) */ 266 0,18, /* secp192k1 (18) */
267 NID_sect163r2, /* sect163r2 (3) */ 267 0,19, /* secp192r1 (19) */
268 NID_secp160k1, /* secp160k1 (15) */ 268 0,1, /* sect163k1 (1) */
269 NID_secp160r1, /* secp160r1 (16) */ 269 0,2, /* sect163r1 (2) */
270 NID_secp160r2, /* secp160r2 (17) */ 270 0,3, /* sect163r2 (3) */
271 0,15, /* secp160k1 (15) */
272 0,16, /* secp160r1 (16) */
273 0,17, /* secp160r2 (17) */
271}; 274};
272 275
273int 276int
@@ -388,6 +391,27 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
388{ 391{
389 int extdatalen = 0; 392 int extdatalen = 0;
390 unsigned char *ret = p; 393 unsigned char *ret = p;
394 int using_ecc = 0;
395
396 /* See if we support any ECC ciphersuites. */
397 if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) {
398 STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
399 unsigned long alg_k, alg_a;
400 int i;
401
402 for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
403 SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
404
405 alg_k = c->algorithm_mkey;
406 alg_a = c->algorithm_auth;
407
408 if ((alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe) ||
409 (alg_a & SSL_aECDSA))) {
410 using_ecc = 1;
411 break;
412 }
413 }
414 }
391 415
392 /* don't add extensions for SSLv3 unless doing secure renegotiation */ 416 /* don't add extensions for SSLv3 unless doing secure renegotiation */
393 if (s->client_version == SSL3_VERSION && 417 if (s->client_version == SSL3_VERSION &&
@@ -458,60 +482,80 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
458 ret += el; 482 ret += el;
459 } 483 }
460 484
461 485 if (using_ecc) {
462 if (s->tlsext_ecpointformatlist != NULL && 486 /*
463 s->version != DTLS1_VERSION) { 487 * Add TLS extension ECPointFormats to the ClientHello message.
464 /* Add TLS extension ECPointFormats to the ClientHello message */ 488 */
465 size_t lenmax; 489 size_t lenmax;
490 const unsigned char *plist;
491 size_t plistlen;
492
493 /*
494 * If we have a custom point format list use it otherwise
495 * use default.
496 */
497 plist = s->tlsext_ecpointformatlist;
498 plistlen = s->tlsext_ecpointformatlist_length;
499 if (plist == NULL) {
500 plist = ecformats_default;
501 plistlen = sizeof(ecformats_default);
502 }
466 503
467 if ((size_t)(limit - ret) < 5) 504 if ((size_t)(limit - ret) < 5)
468 return NULL; 505 return NULL;
469 506
470 lenmax = limit - ret - 5; 507 lenmax = limit - ret - 5;
471 if (s->tlsext_ecpointformatlist_length > lenmax) 508 if (plistlen > lenmax)
472 return NULL; 509 return NULL;
473 if (s->tlsext_ecpointformatlist_length > 255) { 510 if (plistlen > 255) {
474 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, 511 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
475 ERR_R_INTERNAL_ERROR); 512 ERR_R_INTERNAL_ERROR);
476 return NULL; 513 return NULL;
477 } 514 }
478 515
479 s2n(TLSEXT_TYPE_ec_point_formats, ret); 516 s2n(TLSEXT_TYPE_ec_point_formats, ret);
480 s2n(s->tlsext_ecpointformatlist_length + 1, ret); 517 s2n(plistlen + 1, ret);
481 *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length; 518 *(ret++) = (unsigned char)plistlen;
482 memcpy(ret, s->tlsext_ecpointformatlist, 519 memcpy(ret, plist, plistlen);
483 s->tlsext_ecpointformatlist_length); 520 ret += plistlen;
484 ret += s->tlsext_ecpointformatlist_length; 521
485 } 522 /*
486 if (s->tlsext_ellipticcurvelist != NULL && 523 * Add TLS extension EllipticCurves to the ClientHello message.
487 s->version != DTLS1_VERSION) { 524 */
488 /* Add TLS extension EllipticCurves to the ClientHello message */ 525 plist = s->tlsext_ellipticcurvelist;
489 size_t lenmax; 526 plistlen = s->tlsext_ellipticcurvelist_length;
527
528 /*
529 * If we have a custom curve list use it otherwise use default.
530 */
531 if (plist == NULL) {
532 plist = eccurves_default;
533 plistlen = sizeof(eccurves_default);
534 }
490 535
491 if ((size_t)(limit - ret) < 6) 536 if ((size_t)(limit - ret) < 6)
492 return NULL; 537 return NULL;
493 538
494 lenmax = limit - ret - 6; 539 lenmax = limit - ret - 6;
495 if (s->tlsext_ellipticcurvelist_length > lenmax) 540 if (plistlen > lenmax)
496 return NULL; 541 return NULL;
497 if (s->tlsext_ellipticcurvelist_length > 65532) { 542 if (plistlen > 65532) {
498 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, 543 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
499 ERR_R_INTERNAL_ERROR); 544 ERR_R_INTERNAL_ERROR);
500 return NULL; 545 return NULL;
501 } 546 }
502 547
503 s2n(TLSEXT_TYPE_elliptic_curves, ret); 548 s2n(TLSEXT_TYPE_elliptic_curves, ret);
504 s2n(s->tlsext_ellipticcurvelist_length + 2, ret); 549 s2n(plistlen + 2, ret);
505 550
506 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for 551 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
507 * elliptic_curve_list, but the examples use two bytes. 552 * elliptic_curve_list, but the examples use two bytes.
508 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html 553 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
509 * resolves this to two bytes. 554 * resolves this to two bytes.
510 */ 555 */
511 s2n(s->tlsext_ellipticcurvelist_length, ret); 556 s2n(plistlen, ret);
512 memcpy(ret, s->tlsext_ellipticcurvelist, 557 memcpy(ret, plist, plistlen);
513 s->tlsext_ellipticcurvelist_length); 558 ret += plistlen;
514 ret += s->tlsext_ellipticcurvelist_length;
515 } 559 }
516 560
517 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { 561 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
@@ -1476,54 +1520,6 @@ ri_check:
1476int 1520int
1477ssl_prepare_clienthello_tlsext(SSL *s) 1521ssl_prepare_clienthello_tlsext(SSL *s)
1478{ 1522{
1479 /* If we are client and using an elliptic curve cryptography cipher suite, send the point formats
1480 * and elliptic curves we support.
1481 */
1482 int using_ecc = 0;
1483 int i;
1484 unsigned char *j;
1485 unsigned long alg_k, alg_a;
1486 STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
1487
1488 for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
1489 SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
1490
1491 alg_k = c->algorithm_mkey;
1492 alg_a = c->algorithm_auth;
1493 if ((alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe) ||
1494 (alg_a & SSL_aECDSA))) {
1495 using_ecc = 1;
1496 break;
1497 }
1498 }
1499 using_ecc = using_ecc && (s->version >= TLS1_VERSION);
1500 if (using_ecc) {
1501 free(s->tlsext_ecpointformatlist);
1502 if ((s->tlsext_ecpointformatlist = malloc(3)) == NULL) {
1503 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
1504 ERR_R_MALLOC_FAILURE);
1505 return -1;
1506 }
1507 s->tlsext_ecpointformatlist_length = 3;
1508 s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
1509 s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
1510 s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
1511
1512 /* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
1513 free(s->tlsext_ellipticcurvelist);
1514 s->tlsext_ellipticcurvelist_length = sizeof(pref_list) / sizeof(pref_list[0]) * 2;
1515 if ((s->tlsext_ellipticcurvelist = malloc(s->tlsext_ellipticcurvelist_length)) == NULL) {
1516 s->tlsext_ellipticcurvelist_length = 0;
1517 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
1518 ERR_R_MALLOC_FAILURE);
1519 return -1;
1520 }
1521 for (i = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i < sizeof(pref_list) / sizeof(pref_list[0]); i++) {
1522 int id = tls1_ec_nid2curve_id(pref_list[i]);
1523 s2n(id, j);
1524 }
1525 }
1526
1527 return 1; 1523 return 1;
1528} 1524}
1529 1525
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c
index 8e285ea9b1..3ffd7078a5 100644
--- a/src/lib/libssl/ssl_sess.c
+++ b/src/lib/libssl/ssl_sess.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_sess.c,v 1.40 2014/08/11 01:06:22 jsing Exp $ */ 1/* $OpenBSD: ssl_sess.c,v 1.41 2014/09/22 14:26:22 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -375,26 +375,6 @@ sess_id_done:
375 return 0; 375 return 0;
376 } 376 }
377 } 377 }
378 if (s->tlsext_ecpointformatlist) {
379 free(ss->tlsext_ecpointformatlist);
380 if ((ss->tlsext_ecpointformatlist = malloc(s->tlsext_ecpointformatlist_length)) == NULL) {
381 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
382 SSL_SESSION_free(ss);
383 return 0;
384 }
385 ss->tlsext_ecpointformatlist_length = s->tlsext_ecpointformatlist_length;
386 memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
387 }
388 if (s->tlsext_ellipticcurvelist) {
389 free(ss->tlsext_ellipticcurvelist);
390 if ((ss->tlsext_ellipticcurvelist = malloc(s->tlsext_ellipticcurvelist_length)) == NULL) {
391 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
392 SSL_SESSION_free(ss);
393 return 0;
394 }
395 ss->tlsext_ellipticcurvelist_length = s->tlsext_ellipticcurvelist_length;
396 memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
397 }
398 } else { 378 } else {
399 ss->session_id_length = 0; 379 ss->session_id_length = 0;
400 } 380 }
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 87a65e3db2..7e4aba7f23 100644
--- a/src/lib/libssl/t1_lib.c
+++ b/src/lib/libssl/t1_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_lib.c,v 1.55 2014/09/21 17:11:04 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.56 2014/09/22 14:26:22 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -239,35 +239,38 @@ static int nid_list[] = {
239 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */ 239 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */
240}; 240};
241 241
242static int pref_list[] = { 242static const unsigned char ecformats_default[] = {
243 NID_sect571r1, /* sect571r1 (14) */ 243 TLSEXT_ECPOINTFORMAT_uncompressed,
244 NID_sect571k1, /* sect571k1 (13) */ 244 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
245 NID_secp521r1, /* secp521r1 (25) */ 245 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
246 NID_brainpoolP512r1, /* brainpoolP512r1 (28) */ 246};
247 NID_sect409k1, /* sect409k1 (11) */ 247
248 NID_sect409r1, /* sect409r1 (12) */ 248static const unsigned char eccurves_default[] = {
249 NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ 249 0,14, /* sect571r1 (14) */
250 NID_secp384r1, /* secp384r1 (24) */ 250 0,13, /* sect571k1 (13) */
251 NID_sect283k1, /* sect283k1 (9) */ 251 0,25, /* secp521r1 (25) */
252 NID_sect283r1, /* sect283r1 (10) */ 252 0,11, /* sect409k1 (11) */
253 NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ 253 0,12, /* sect409r1 (12) */
254 NID_secp256k1, /* secp256k1 (22) */ 254 0,24, /* secp384r1 (24) */
255 NID_X9_62_prime256v1, /* secp256r1 (23) */ 255 0,9, /* sect283k1 (9) */
256 NID_sect239k1, /* sect239k1 (8) */ 256 0,10, /* sect283r1 (10) */
257 NID_sect233k1, /* sect233k1 (6) */ 257 0,22, /* secp256k1 (22) */
258 NID_sect233r1, /* sect233r1 (7) */ 258 0,23, /* secp256r1 (23) */
259 NID_secp224k1, /* secp224k1 (20) */ 259 0,8, /* sect239k1 (8) */
260 NID_secp224r1, /* secp224r1 (21) */ 260 0,6, /* sect233k1 (6) */
261 NID_sect193r1, /* sect193r1 (4) */ 261 0,7, /* sect233r1 (7) */
262 NID_sect193r2, /* sect193r2 (5) */ 262 0,20, /* secp224k1 (20) */
263 NID_secp192k1, /* secp192k1 (18) */ 263 0,21, /* secp224r1 (21) */
264 NID_X9_62_prime192v1, /* secp192r1 (19) */ 264 0,4, /* sect193r1 (4) */
265 NID_sect163k1, /* sect163k1 (1) */ 265 0,5, /* sect193r2 (5) */
266 NID_sect163r1, /* sect163r1 (2) */ 266 0,18, /* secp192k1 (18) */
267 NID_sect163r2, /* sect163r2 (3) */ 267 0,19, /* secp192r1 (19) */
268 NID_secp160k1, /* secp160k1 (15) */ 268 0,1, /* sect163k1 (1) */
269 NID_secp160r1, /* secp160r1 (16) */ 269 0,2, /* sect163r1 (2) */
270 NID_secp160r2, /* secp160r2 (17) */ 270 0,3, /* sect163r2 (3) */
271 0,15, /* secp160k1 (15) */
272 0,16, /* secp160r1 (16) */
273 0,17, /* secp160r2 (17) */
271}; 274};
272 275
273int 276int
@@ -388,6 +391,27 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
388{ 391{
389 int extdatalen = 0; 392 int extdatalen = 0;
390 unsigned char *ret = p; 393 unsigned char *ret = p;
394 int using_ecc = 0;
395
396 /* See if we support any ECC ciphersuites. */
397 if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) {
398 STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
399 unsigned long alg_k, alg_a;
400 int i;
401
402 for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
403 SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
404
405 alg_k = c->algorithm_mkey;
406 alg_a = c->algorithm_auth;
407
408 if ((alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe) ||
409 (alg_a & SSL_aECDSA))) {
410 using_ecc = 1;
411 break;
412 }
413 }
414 }
391 415
392 /* don't add extensions for SSLv3 unless doing secure renegotiation */ 416 /* don't add extensions for SSLv3 unless doing secure renegotiation */
393 if (s->client_version == SSL3_VERSION && 417 if (s->client_version == SSL3_VERSION &&
@@ -458,60 +482,80 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
458 ret += el; 482 ret += el;
459 } 483 }
460 484
461 485 if (using_ecc) {
462 if (s->tlsext_ecpointformatlist != NULL && 486 /*
463 s->version != DTLS1_VERSION) { 487 * Add TLS extension ECPointFormats to the ClientHello message.
464 /* Add TLS extension ECPointFormats to the ClientHello message */ 488 */
465 size_t lenmax; 489 size_t lenmax;
490 const unsigned char *plist;
491 size_t plistlen;
492
493 /*
494 * If we have a custom point format list use it otherwise
495 * use default.
496 */
497 plist = s->tlsext_ecpointformatlist;
498 plistlen = s->tlsext_ecpointformatlist_length;
499 if (plist == NULL) {
500 plist = ecformats_default;
501 plistlen = sizeof(ecformats_default);
502 }
466 503
467 if ((size_t)(limit - ret) < 5) 504 if ((size_t)(limit - ret) < 5)
468 return NULL; 505 return NULL;
469 506
470 lenmax = limit - ret - 5; 507 lenmax = limit - ret - 5;
471 if (s->tlsext_ecpointformatlist_length > lenmax) 508 if (plistlen > lenmax)
472 return NULL; 509 return NULL;
473 if (s->tlsext_ecpointformatlist_length > 255) { 510 if (plistlen > 255) {
474 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, 511 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
475 ERR_R_INTERNAL_ERROR); 512 ERR_R_INTERNAL_ERROR);
476 return NULL; 513 return NULL;
477 } 514 }
478 515
479 s2n(TLSEXT_TYPE_ec_point_formats, ret); 516 s2n(TLSEXT_TYPE_ec_point_formats, ret);
480 s2n(s->tlsext_ecpointformatlist_length + 1, ret); 517 s2n(plistlen + 1, ret);
481 *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length; 518 *(ret++) = (unsigned char)plistlen;
482 memcpy(ret, s->tlsext_ecpointformatlist, 519 memcpy(ret, plist, plistlen);
483 s->tlsext_ecpointformatlist_length); 520 ret += plistlen;
484 ret += s->tlsext_ecpointformatlist_length; 521
485 } 522 /*
486 if (s->tlsext_ellipticcurvelist != NULL && 523 * Add TLS extension EllipticCurves to the ClientHello message.
487 s->version != DTLS1_VERSION) { 524 */
488 /* Add TLS extension EllipticCurves to the ClientHello message */ 525 plist = s->tlsext_ellipticcurvelist;
489 size_t lenmax; 526 plistlen = s->tlsext_ellipticcurvelist_length;
527
528 /*
529 * If we have a custom curve list use it otherwise use default.
530 */
531 if (plist == NULL) {
532 plist = eccurves_default;
533 plistlen = sizeof(eccurves_default);
534 }
490 535
491 if ((size_t)(limit - ret) < 6) 536 if ((size_t)(limit - ret) < 6)
492 return NULL; 537 return NULL;
493 538
494 lenmax = limit - ret - 6; 539 lenmax = limit - ret - 6;
495 if (s->tlsext_ellipticcurvelist_length > lenmax) 540 if (plistlen > lenmax)
496 return NULL; 541 return NULL;
497 if (s->tlsext_ellipticcurvelist_length > 65532) { 542 if (plistlen > 65532) {
498 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, 543 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
499 ERR_R_INTERNAL_ERROR); 544 ERR_R_INTERNAL_ERROR);
500 return NULL; 545 return NULL;
501 } 546 }
502 547
503 s2n(TLSEXT_TYPE_elliptic_curves, ret); 548 s2n(TLSEXT_TYPE_elliptic_curves, ret);
504 s2n(s->tlsext_ellipticcurvelist_length + 2, ret); 549 s2n(plistlen + 2, ret);
505 550
506 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for 551 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
507 * elliptic_curve_list, but the examples use two bytes. 552 * elliptic_curve_list, but the examples use two bytes.
508 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html 553 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
509 * resolves this to two bytes. 554 * resolves this to two bytes.
510 */ 555 */
511 s2n(s->tlsext_ellipticcurvelist_length, ret); 556 s2n(plistlen, ret);
512 memcpy(ret, s->tlsext_ellipticcurvelist, 557 memcpy(ret, plist, plistlen);
513 s->tlsext_ellipticcurvelist_length); 558 ret += plistlen;
514 ret += s->tlsext_ellipticcurvelist_length;
515 } 559 }
516 560
517 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { 561 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
@@ -1476,54 +1520,6 @@ ri_check:
1476int 1520int
1477ssl_prepare_clienthello_tlsext(SSL *s) 1521ssl_prepare_clienthello_tlsext(SSL *s)
1478{ 1522{
1479 /* If we are client and using an elliptic curve cryptography cipher suite, send the point formats
1480 * and elliptic curves we support.
1481 */
1482 int using_ecc = 0;
1483 int i;
1484 unsigned char *j;
1485 unsigned long alg_k, alg_a;
1486 STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
1487
1488 for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
1489 SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
1490
1491 alg_k = c->algorithm_mkey;
1492 alg_a = c->algorithm_auth;
1493 if ((alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe) ||
1494 (alg_a & SSL_aECDSA))) {
1495 using_ecc = 1;
1496 break;
1497 }
1498 }
1499 using_ecc = using_ecc && (s->version >= TLS1_VERSION);
1500 if (using_ecc) {
1501 free(s->tlsext_ecpointformatlist);
1502 if ((s->tlsext_ecpointformatlist = malloc(3)) == NULL) {
1503 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
1504 ERR_R_MALLOC_FAILURE);
1505 return -1;
1506 }
1507 s->tlsext_ecpointformatlist_length = 3;
1508 s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
1509 s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
1510 s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
1511
1512 /* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
1513 free(s->tlsext_ellipticcurvelist);
1514 s->tlsext_ellipticcurvelist_length = sizeof(pref_list) / sizeof(pref_list[0]) * 2;
1515 if ((s->tlsext_ellipticcurvelist = malloc(s->tlsext_ellipticcurvelist_length)) == NULL) {
1516 s->tlsext_ellipticcurvelist_length = 0;
1517 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
1518 ERR_R_MALLOC_FAILURE);
1519 return -1;
1520 }
1521 for (i = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i < sizeof(pref_list) / sizeof(pref_list[0]); i++) {
1522 int id = tls1_ec_nid2curve_id(pref_list[i]);
1523 s2n(id, j);
1524 }
1525 }
1526
1527 return 1; 1523 return 1;
1528} 1524}
1529 1525