diff options
author | jsing <> | 2014-09-22 14:26:22 +0000 |
---|---|---|
committer | jsing <> | 2014-09-22 14:26:22 +0000 |
commit | ad04e6a1deb1fa849ae2c9a7ce2393dfee765f3f (patch) | |
tree | ef3f69bededfcfdd462563f261382712b92f9f73 | |
parent | 93a144bf193161ecec0ea955305c15f5f141bd08 (diff) | |
download | openbsd-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.c | 22 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/t1_lib.c | 198 | ||||
-rw-r--r-- | src/lib/libssl/ssl_sess.c | 22 | ||||
-rw-r--r-- | src/lib/libssl/t1_lib.c | 198 |
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 | ||
242 | static int pref_list[] = { | 242 | static 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) */ | 248 | static 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 | ||
273 | int | 276 | int |
@@ -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: | |||
1476 | int | 1520 | int |
1477 | ssl_prepare_clienthello_tlsext(SSL *s) | 1521 | ssl_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 | ||
242 | static int pref_list[] = { | 242 | static 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) */ | 248 | static 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 | ||
273 | int | 276 | int |
@@ -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: | |||
1476 | int | 1520 | int |
1477 | ssl_prepare_clienthello_tlsext(SSL *s) | 1521 | ssl_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 | ||