summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2014-12-06 13:51:06 +0000
committerjsing <>2014-12-06 13:51:06 +0000
commita657ba9d9f7c27a3001f24d121b111838c1dc856 (patch)
treebf970ac74fc18ba45834070bde1e0c9b24cc24fc /src/lib
parent737df48ca584850ed0b5d4bb60494b65386a5d5f (diff)
downloadopenbsd-a657ba9d9f7c27a3001f24d121b111838c1dc856.tar.gz
openbsd-a657ba9d9f7c27a3001f24d121b111838c1dc856.tar.bz2
openbsd-a657ba9d9f7c27a3001f24d121b111838c1dc856.zip
Use appropriate internal types for EC curves and formats, rather than
storing and processing in wire encoded form. Inspired by boringssl. ok miod@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/src/ssl/ssl.h11
-rw-r--r--src/lib/libssl/src/ssl/ssl_locl.h6
-rw-r--r--src/lib/libssl/src/ssl/t1_lib.c218
-rw-r--r--src/lib/libssl/ssl.h11
-rw-r--r--src/lib/libssl/ssl_locl.h6
-rw-r--r--src/lib/libssl/t1_lib.c218
6 files changed, 248 insertions, 222 deletions
diff --git a/src/lib/libssl/src/ssl/ssl.h b/src/lib/libssl/src/ssl/ssl.h
index 2416b46d46..2b14116e4c 100644
--- a/src/lib/libssl/src/ssl/ssl.h
+++ b/src/lib/libssl/src/ssl/ssl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl.h,v 1.72 2014/11/18 05:33:43 miod Exp $ */ 1/* $OpenBSD: ssl.h,v 1.73 2014/12/06 13:51:06 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 *
@@ -500,9 +500,10 @@ struct ssl_session_st {
500 struct ssl_session_st *prev, *next; 500 struct ssl_session_st *prev, *next;
501 char *tlsext_hostname; 501 char *tlsext_hostname;
502 size_t tlsext_ecpointformatlist_length; 502 size_t tlsext_ecpointformatlist_length;
503 unsigned char *tlsext_ecpointformatlist; /* peer's list */ 503 uint8_t *tlsext_ecpointformatlist; /* peer's list */
504 size_t tlsext_ellipticcurvelist_length; 504 size_t tlsext_ellipticcurvelist_length;
505 unsigned char *tlsext_ellipticcurvelist; /* peer's list */ 505 uint16_t *tlsext_ellipticcurvelist; /* peer's list */
506
506 /* RFC4507 info */ 507 /* RFC4507 info */
507 unsigned char *tlsext_tick; /* Session ticket */ 508 unsigned char *tlsext_tick; /* Session ticket */
508 size_t tlsext_ticklen; /* Session ticket length */ 509 size_t tlsext_ticklen; /* Session ticket length */
@@ -1142,9 +1143,9 @@ struct ssl_st {
1142 /* RFC4507 session ticket expected to be received or sent */ 1143 /* RFC4507 session ticket expected to be received or sent */
1143 int tlsext_ticket_expected; 1144 int tlsext_ticket_expected;
1144 size_t tlsext_ecpointformatlist_length; 1145 size_t tlsext_ecpointformatlist_length;
1145 unsigned char *tlsext_ecpointformatlist; /* our list */ 1146 uint8_t *tlsext_ecpointformatlist; /* our list */
1146 size_t tlsext_ellipticcurvelist_length; 1147 size_t tlsext_ellipticcurvelist_length;
1147 unsigned char *tlsext_ellipticcurvelist; /* our list */ 1148 uint16_t *tlsext_ellipticcurvelist; /* our list */
1148 1149
1149 /* TLS Session Ticket extension override */ 1150 /* TLS Session Ticket extension override */
1150 TLS_SESSION_TICKET_EXT *tlsext_session_ticket; 1151 TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
diff --git a/src/lib/libssl/src/ssl/ssl_locl.h b/src/lib/libssl/src/ssl/ssl_locl.h
index 74cacd4eec..c425f67a5a 100644
--- a/src/lib/libssl/src/ssl/ssl_locl.h
+++ b/src/lib/libssl/src/ssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.77 2014/11/18 05:33:43 miod Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.78 2014/12/06 13:51:06 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 *
@@ -800,8 +800,8 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
800 800
801SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); 801SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
802 802
803int tls1_ec_curve_id2nid(int curve_id); 803int tls1_ec_curve_id2nid(uint16_t curve_id);
804int tls1_ec_nid2curve_id(int nid); 804uint16_t tls1_ec_nid2curve_id(int nid);
805int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); 805int tls1_check_curve(SSL *s, const unsigned char *p, size_t len);
806int tls1_get_shared_curve(SSL *s); 806int tls1_get_shared_curve(SSL *s);
807 807
diff --git a/src/lib/libssl/src/ssl/t1_lib.c b/src/lib/libssl/src/ssl/t1_lib.c
index 5a6c0ddba0..8a7553e3e7 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.70 2014/12/06 13:28:56 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.71 2014/12/06 13:51:06 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 *
@@ -240,45 +240,45 @@ static int nid_list[] = {
240 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */ 240 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */
241}; 241};
242 242
243static const unsigned char ecformats_default[] = { 243static const uint8_t ecformats_default[] = {
244 TLSEXT_ECPOINTFORMAT_uncompressed, 244 TLSEXT_ECPOINTFORMAT_uncompressed,
245 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, 245 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
246 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 246 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
247}; 247};
248 248
249static const unsigned char eccurves_default[] = { 249static const uint16_t eccurves_default[] = {
250 0,14, /* sect571r1 (14) */ 250 14, /* sect571r1 (14) */
251 0,13, /* sect571k1 (13) */ 251 13, /* sect571k1 (13) */
252 0,25, /* secp521r1 (25) */ 252 25, /* secp521r1 (25) */
253 0,28, /* brainpool512r1 (28) */ 253 28, /* brainpool512r1 (28) */
254 0,11, /* sect409k1 (11) */ 254 11, /* sect409k1 (11) */
255 0,12, /* sect409r1 (12) */ 255 12, /* sect409r1 (12) */
256 0,27, /* brainpoolP384r1 (27) */ 256 27, /* brainpoolP384r1 (27) */
257 0,24, /* secp384r1 (24) */ 257 24, /* secp384r1 (24) */
258 0,9, /* sect283k1 (9) */ 258 9, /* sect283k1 (9) */
259 0,10, /* sect283r1 (10) */ 259 10, /* sect283r1 (10) */
260 0,26, /* brainpoolP256r1 (26) */ 260 26, /* brainpoolP256r1 (26) */
261 0,22, /* secp256k1 (22) */ 261 22, /* secp256k1 (22) */
262 0,23, /* secp256r1 (23) */ 262 23, /* secp256r1 (23) */
263 0,8, /* sect239k1 (8) */ 263 8, /* sect239k1 (8) */
264 0,6, /* sect233k1 (6) */ 264 6, /* sect233k1 (6) */
265 0,7, /* sect233r1 (7) */ 265 7, /* sect233r1 (7) */
266 0,20, /* secp224k1 (20) */ 266 20, /* secp224k1 (20) */
267 0,21, /* secp224r1 (21) */ 267 21, /* secp224r1 (21) */
268 0,4, /* sect193r1 (4) */ 268 4, /* sect193r1 (4) */
269 0,5, /* sect193r2 (5) */ 269 5, /* sect193r2 (5) */
270 0,18, /* secp192k1 (18) */ 270 18, /* secp192k1 (18) */
271 0,19, /* secp192r1 (19) */ 271 19, /* secp192r1 (19) */
272 0,1, /* sect163k1 (1) */ 272 1, /* sect163k1 (1) */
273 0,2, /* sect163r1 (2) */ 273 2, /* sect163r1 (2) */
274 0,3, /* sect163r2 (3) */ 274 3, /* sect163r2 (3) */
275 0,15, /* secp160k1 (15) */ 275 15, /* secp160k1 (15) */
276 0,16, /* secp160r1 (16) */ 276 16, /* secp160r1 (16) */
277 0,17, /* secp160r2 (17) */ 277 17, /* secp160r2 (17) */
278}; 278};
279 279
280int 280int
281tls1_ec_curve_id2nid(int curve_id) 281tls1_ec_curve_id2nid(uint16_t curve_id)
282{ 282{
283 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ 283 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
284 if ((curve_id < 1) || 284 if ((curve_id < 1) ||
@@ -287,7 +287,7 @@ tls1_ec_curve_id2nid(int curve_id)
287 return nid_list[curve_id - 1]; 287 return nid_list[curve_id - 1];
288} 288}
289 289
290int 290uint16_t
291tls1_ec_nid2curve_id(int nid) 291tls1_ec_nid2curve_id(int nid)
292{ 292{
293 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ 293 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
@@ -359,7 +359,7 @@ tls1_ec_nid2curve_id(int nid)
359 * exists, or the default formats if a custom list has not been specified. 359 * exists, or the default formats if a custom list has not been specified.
360 */ 360 */
361static void 361static void
362tls1_get_formatlist(SSL *s, int client_formats, const unsigned char **pformats, 362tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats,
363 size_t *pformatslen) 363 size_t *pformatslen)
364{ 364{
365 if (client_formats != 0) { 365 if (client_formats != 0) {
@@ -382,7 +382,7 @@ tls1_get_formatlist(SSL *s, int client_formats, const unsigned char **pformats,
382 * exists, or the default curves if a custom list has not been specified. 382 * exists, or the default curves if a custom list has not been specified.
383 */ 383 */
384static void 384static void
385tls1_get_curvelist(SSL *s, int client_curves, const unsigned char **pcurves, 385tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves,
386 size_t *pcurveslen) 386 size_t *pcurveslen)
387{ 387{
388 if (client_curves != 0) { 388 if (client_curves != 0) {
@@ -403,17 +403,20 @@ tls1_get_curvelist(SSL *s, int client_curves, const unsigned char **pcurves,
403int 403int
404tls1_check_curve(SSL *s, const unsigned char *p, size_t len) 404tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
405{ 405{
406 const unsigned char *curves; 406 const uint16_t *curves;
407 size_t curveslen, i; 407 size_t curveslen, i;
408 uint16_t cid;
408 409
409 /* Only named curves are supported. */ 410 /* Only named curves are supported. */
410 if (len != 3 || p[0] != NAMED_CURVE_TYPE) 411 if (len != 3 || p[0] != NAMED_CURVE_TYPE)
411 return (0); 412 return (0);
412 413
414 cid = (p[1] << 8) | p[2];
415
413 tls1_get_curvelist(s, 0, &curves, &curveslen); 416 tls1_get_curvelist(s, 0, &curves, &curveslen);
414 417
415 for (i = 0; i < curveslen; i += 2, curves += 2) { 418 for (i = 0; i < curveslen; i++) {
416 if (p[1] == curves[0] && p[2] == curves[1]) 419 if (curves[i] == cid)
417 return (1); 420 return (1);
418 } 421 }
419 return (0); 422 return (0);
@@ -422,10 +425,9 @@ tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
422int 425int
423tls1_get_shared_curve(SSL *s) 426tls1_get_shared_curve(SSL *s)
424{ 427{
425 const unsigned char *pref, *supp, *tsupp;
426 size_t preflen, supplen, i, j; 428 size_t preflen, supplen, i, j;
429 const uint16_t *pref, *supp;
427 unsigned long server_pref; 430 unsigned long server_pref;
428 int id;
429 431
430 /* Cannot do anything on the client side. */ 432 /* Cannot do anything on the client side. */
431 if (s->server == 0) 433 if (s->server == 0)
@@ -436,13 +438,10 @@ tls1_get_shared_curve(SSL *s)
436 tls1_get_curvelist(s, (server_pref == 0), &pref, &preflen); 438 tls1_get_curvelist(s, (server_pref == 0), &pref, &preflen);
437 tls1_get_curvelist(s, (server_pref != 0), &supp, &supplen); 439 tls1_get_curvelist(s, (server_pref != 0), &supp, &supplen);
438 440
439 for (i = 0; i < preflen; i += 2, pref += 2) { 441 for (i = 0; i < preflen; i++) {
440 tsupp = supp; 442 for (j = 0; j < supplen; j++) {
441 for (j = 0; j < supplen; j += 2, tsupp += 2) { 443 if (pref[i] == supp[j])
442 if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) { 444 return (tls1_ec_curve_id2nid(pref[i]));
443 id = (pref[0] << 8) | pref[1];
444 return (tls1_ec_curve_id2nid(id));
445 }
446 } 445 }
447 } 446 }
448 return (NID_undef); 447 return (NID_undef);
@@ -450,7 +449,7 @@ tls1_get_shared_curve(SSL *s)
450 449
451/* For an EC key set TLS ID and required compression based on parameters. */ 450/* For an EC key set TLS ID and required compression based on parameters. */
452static int 451static int
453tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec) 452tls1_set_ec_id(uint16_t *curve_id, uint8_t *comp_id, EC_KEY *ec)
454{ 453{
455 const EC_GROUP *grp; 454 const EC_GROUP *grp;
456 const EC_METHOD *meth; 455 const EC_METHOD *meth;
@@ -473,13 +472,10 @@ tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec)
473 id = tls1_ec_nid2curve_id(nid); 472 id = tls1_ec_nid2curve_id(nid);
474 473
475 /* If we have an ID set it, otherwise set arbitrary explicit curve. */ 474 /* If we have an ID set it, otherwise set arbitrary explicit curve. */
476 if (id != 0) { 475 if (id != 0)
477 curve_id[0] = 0; 476 *curve_id = id;
478 curve_id[1] = (unsigned char)id; 477 else
479 } else { 478 *curve_id = is_prime ? 0xff01 : 0xff02;
480 curve_id[0] = 0xff;
481 curve_id[1] = is_prime ? 0x01 : 0x02;
482 }
483 479
484 /* Specify the compression identifier. */ 480 /* Specify the compression identifier. */
485 if (comp_id != NULL) { 481 if (comp_id != NULL) {
@@ -499,10 +495,11 @@ tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec)
499 495
500/* Check that an EC key is compatible with extensions. */ 496/* Check that an EC key is compatible with extensions. */
501static int 497static int
502tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id) 498tls1_check_ec_key(SSL *s, const uint16_t *curve_id, const uint8_t *comp_id)
503{ 499{
504 const unsigned char *curves, *formats;
505 size_t curveslen, formatslen, i; 500 size_t curveslen, formatslen, i;
501 const uint16_t *curves;
502 const uint8_t *formats;
506 503
507 /* 504 /*
508 * Check point formats extension if present, otherwise everything 505 * Check point formats extension if present, otherwise everything
@@ -510,8 +507,8 @@ tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id)
510 */ 507 */
511 tls1_get_formatlist(s, 1, &formats, &formatslen); 508 tls1_get_formatlist(s, 1, &formats, &formatslen);
512 if (comp_id != NULL && formats != NULL) { 509 if (comp_id != NULL && formats != NULL) {
513 for (i = 0; i < formatslen; i++, formats++) { 510 for (i = 0; i < formatslen; i++) {
514 if (*comp_id == *formats) 511 if (formats[i] == *comp_id)
515 break; 512 break;
516 } 513 }
517 if (i == formatslen) 514 if (i == formatslen)
@@ -522,10 +519,9 @@ tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id)
522 * Check curve list if present, otherwise everything is supported. 519 * Check curve list if present, otherwise everything is supported.
523 */ 520 */
524 tls1_get_curvelist(s, 1, &curves, &curveslen); 521 tls1_get_curvelist(s, 1, &curves, &curveslen);
525 if (curves != NULL) { 522 if (curve_id != NULL && curves != NULL) {
526 for (i = 0; i < curveslen; i += 2, curves += 2) { 523 for (i = 0; i < curveslen; i++) {
527 if (curves[0] == curve_id[0] && 524 if (curves[i] == *curve_id)
528 curves[1] == curve_id[1])
529 break; 525 break;
530 } 526 }
531 if (i == curveslen) 527 if (i == curveslen)
@@ -540,7 +536,8 @@ int
540tls1_check_ec_server_key(SSL *s) 536tls1_check_ec_server_key(SSL *s)
541{ 537{
542 CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC; 538 CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC;
543 unsigned char comp_id, curve_id[2]; 539 uint16_t curve_id;
540 uint8_t comp_id;
544 EVP_PKEY *pkey; 541 EVP_PKEY *pkey;
545 int rv; 542 int rv;
546 543
@@ -548,12 +545,12 @@ tls1_check_ec_server_key(SSL *s)
548 return (0); 545 return (0);
549 if ((pkey = X509_get_pubkey(cpk->x509)) == NULL) 546 if ((pkey = X509_get_pubkey(cpk->x509)) == NULL)
550 return (0); 547 return (0);
551 rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec); 548 rv = tls1_set_ec_id(&curve_id, &comp_id, pkey->pkey.ec);
552 EVP_PKEY_free(pkey); 549 EVP_PKEY_free(pkey);
553 if (rv != 1) 550 if (rv != 1)
554 return (0); 551 return (0);
555 552
556 return tls1_check_ec_key(s, curve_id, &comp_id); 553 return tls1_check_ec_key(s, &curve_id, &comp_id);
557} 554}
558 555
559/* Check EC temporary key is compatible with client extensions. */ 556/* Check EC temporary key is compatible with client extensions. */
@@ -561,7 +558,7 @@ int
561tls1_check_ec_tmp_key(SSL *s) 558tls1_check_ec_tmp_key(SSL *s)
562{ 559{
563 EC_KEY *ec = s->cert->ecdh_tmp; 560 EC_KEY *ec = s->cert->ecdh_tmp;
564 unsigned char curve_id[2]; 561 uint16_t curve_id;
565 562
566 if (s->cert->ecdh_tmp_auto != 0) { 563 if (s->cert->ecdh_tmp_auto != 0) {
567 /* Need a shared curve. */ 564 /* Need a shared curve. */
@@ -575,10 +572,10 @@ tls1_check_ec_tmp_key(SSL *s)
575 return (1); 572 return (1);
576 return (0); 573 return (0);
577 } 574 }
578 if (tls1_set_ec_id(curve_id, NULL, ec) != 1) 575 if (tls1_set_ec_id(&curve_id, NULL, ec) != 1)
579 return (0); 576 return (0);
580 577
581 return tls1_check_ec_key(s, curve_id, NULL); 578 return tls1_check_ec_key(s, &curve_id, NULL);
582} 579}
583 580
584/* 581/*
@@ -723,8 +720,10 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
723 } 720 }
724 721
725 if (using_ecc) { 722 if (using_ecc) {
726 const unsigned char *curves, *formats;
727 size_t curveslen, formatslen, lenmax; 723 size_t curveslen, formatslen, lenmax;
724 const uint16_t *curves;
725 const uint8_t *formats;
726 int i;
728 727
729 /* 728 /*
730 * Add TLS extension ECPointFormats to the ClientHello message. 729 * Add TLS extension ECPointFormats to the ClientHello message.
@@ -767,16 +766,16 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
767 } 766 }
768 767
769 s2n(TLSEXT_TYPE_elliptic_curves, ret); 768 s2n(TLSEXT_TYPE_elliptic_curves, ret);
770 s2n(curveslen + 2, ret); 769 s2n((curveslen * 2) + 2, ret);
771 770
772 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for 771 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
773 * elliptic_curve_list, but the examples use two bytes. 772 * elliptic_curve_list, but the examples use two bytes.
774 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html 773 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
775 * resolves this to two bytes. 774 * resolves this to two bytes.
776 */ 775 */
777 s2n(curveslen, ret); 776 s2n(curveslen * 2, ret);
778 memcpy(ret, curves, curveslen); 777 for (i = 0; i < curveslen; i++)
779 ret += curveslen; 778 s2n(curves[i], ret);
780 } 779 }
781 780
782 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { 781 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
@@ -1334,60 +1333,66 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1334 else if (type == TLSEXT_TYPE_ec_point_formats && 1333 else if (type == TLSEXT_TYPE_ec_point_formats &&
1335 s->version != DTLS1_VERSION) { 1334 s->version != DTLS1_VERSION) {
1336 unsigned char *sdata = data; 1335 unsigned char *sdata = data;
1337 int ecpointformatlist_length; 1336 size_t formatslen;
1337 uint8_t *formats;
1338 1338
1339 if (size < 1) { 1339 if (size < 1) {
1340 *al = SSL_AD_DECODE_ERROR; 1340 *al = TLS1_AD_DECODE_ERROR;
1341 return 0; 1341 return 0;
1342 } 1342 }
1343 ecpointformatlist_length = *(sdata++); 1343 formatslen = *(sdata++);
1344 1344 if (formatslen != size - 1) {
1345 if (ecpointformatlist_length != size - 1) {
1346 *al = TLS1_AD_DECODE_ERROR; 1345 *al = TLS1_AD_DECODE_ERROR;
1347 return 0; 1346 return 0;
1348 } 1347 }
1348
1349 if (!s->hit) { 1349 if (!s->hit) {
1350 free(s->session->tlsext_ecpointformatlist); 1350 free(s->session->tlsext_ecpointformatlist);
1351 s->session->tlsext_ecpointformatlist = NULL;
1351 s->session->tlsext_ecpointformatlist_length = 0; 1352 s->session->tlsext_ecpointformatlist_length = 0;
1352 if ((s->session->tlsext_ecpointformatlist = 1353
1353 malloc(ecpointformatlist_length)) == NULL) { 1354 if ((formats = reallocarray(NULL, formatslen,
1355 sizeof(uint8_t))) == NULL) {
1354 *al = TLS1_AD_INTERNAL_ERROR; 1356 *al = TLS1_AD_INTERNAL_ERROR;
1355 return 0; 1357 return 0;
1356 } 1358 }
1357 s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; 1359 memcpy(formats, sdata, formatslen);
1358 memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); 1360 s->session->tlsext_ecpointformatlist = formats;
1361 s->session->tlsext_ecpointformatlist_length =
1362 formatslen;
1359 } 1363 }
1360 } else if (type == TLSEXT_TYPE_elliptic_curves && 1364 } else if (type == TLSEXT_TYPE_elliptic_curves &&
1361 s->version != DTLS1_VERSION) { 1365 s->version != DTLS1_VERSION) {
1362 unsigned char *sdata = data; 1366 unsigned char *sdata = data;
1363 int ellipticcurvelist_length; 1367 size_t curveslen, i;
1368 uint16_t *curves;
1364 1369
1365 if (size < 2) { 1370 if (size < 2) {
1366 *al = SSL_AD_DECODE_ERROR; 1371 *al = TLS1_AD_DECODE_ERROR;
1367 return 0; 1372 return 0;
1368 } 1373 }
1369 ellipticcurvelist_length = (*(sdata++) << 8); 1374 n2s(sdata, curveslen);
1370 ellipticcurvelist_length += (*(sdata++)); 1375 if (curveslen != size - 2 || curveslen % 2 != 0) {
1371
1372 if (ellipticcurvelist_length != size - 2 ||
1373 ellipticcurvelist_length < 1 ||
1374 ellipticcurvelist_length % 2 != 0) {
1375 *al = TLS1_AD_DECODE_ERROR; 1376 *al = TLS1_AD_DECODE_ERROR;
1376 return 0; 1377 return 0;
1377 } 1378 }
1379 curveslen /= 2;
1380
1378 if (!s->hit) { 1381 if (!s->hit) {
1379 if (s->session->tlsext_ellipticcurvelist) { 1382 if (s->session->tlsext_ellipticcurvelist) {
1380 *al = TLS1_AD_DECODE_ERROR; 1383 *al = TLS1_AD_DECODE_ERROR;
1381 return 0; 1384 return 0;
1382 } 1385 }
1383 s->session->tlsext_ellipticcurvelist_length = 0; 1386 s->session->tlsext_ellipticcurvelist_length = 0;
1384 if ((s->session->tlsext_ellipticcurvelist = 1387 if ((curves = reallocarray(NULL, curveslen,
1385 malloc(ellipticcurvelist_length)) == NULL) { 1388 sizeof(uint16_t))) == NULL) {
1386 *al = TLS1_AD_INTERNAL_ERROR; 1389 *al = TLS1_AD_INTERNAL_ERROR;
1387 return 0; 1390 return 0;
1388 } 1391 }
1389 s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length; 1392 for (i = 0; i < curveslen; i++)
1390 memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); 1393 n2s(sdata, curves[i]);
1394 s->session->tlsext_ellipticcurvelist = curves;
1395 s->session->tlsext_ellipticcurvelist_length = curveslen;
1391 } 1396 }
1392 } 1397 }
1393 else if (type == TLSEXT_TYPE_session_ticket) { 1398 else if (type == TLSEXT_TYPE_session_ticket) {
@@ -1628,26 +1633,33 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1628 else if (type == TLSEXT_TYPE_ec_point_formats && 1633 else if (type == TLSEXT_TYPE_ec_point_formats &&
1629 s->version != DTLS1_VERSION) { 1634 s->version != DTLS1_VERSION) {
1630 unsigned char *sdata = data; 1635 unsigned char *sdata = data;
1631 int ecpointformatlist_length = *(sdata++); 1636 size_t formatslen;
1637 uint8_t *formats;
1632 1638
1633 if (ecpointformatlist_length != size - 1 || 1639 if (size < 1) {
1634 ecpointformatlist_length < 1) {
1635 *al = TLS1_AD_DECODE_ERROR; 1640 *al = TLS1_AD_DECODE_ERROR;
1636 return 0; 1641 return 0;
1637 } 1642 }
1643 formatslen = *(sdata++);
1644 if (formatslen != size - 1) {
1645 *al = TLS1_AD_DECODE_ERROR;
1646 return 0;
1647 }
1648
1638 if (!s->hit) { 1649 if (!s->hit) {
1639 free(s->session->tlsext_ecpointformatlist); 1650 free(s->session->tlsext_ecpointformatlist);
1651 s->session->tlsext_ecpointformatlist = NULL;
1640 s->session->tlsext_ecpointformatlist_length = 0; 1652 s->session->tlsext_ecpointformatlist_length = 0;
1641 1653
1642 if ((s->session->tlsext_ecpointformatlist = 1654 if ((formats = reallocarray(NULL, formatslen,
1643 malloc(ecpointformatlist_length)) == NULL) { 1655 sizeof(uint8_t))) == NULL) {
1644 *al = TLS1_AD_INTERNAL_ERROR; 1656 *al = TLS1_AD_INTERNAL_ERROR;
1645 return 0; 1657 return 0;
1646 } 1658 }
1659 memcpy(formats, sdata, formatslen);
1660 s->session->tlsext_ecpointformatlist = formats;
1647 s->session->tlsext_ecpointformatlist_length = 1661 s->session->tlsext_ecpointformatlist_length =
1648 ecpointformatlist_length; 1662 formatslen;
1649 memcpy(s->session->tlsext_ecpointformatlist,
1650 sdata, ecpointformatlist_length);
1651 } 1663 }
1652 } 1664 }
1653 else if (type == TLSEXT_TYPE_session_ticket) { 1665 else if (type == TLSEXT_TYPE_session_ticket) {
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index 2416b46d46..2b14116e4c 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl.h,v 1.72 2014/11/18 05:33:43 miod Exp $ */ 1/* $OpenBSD: ssl.h,v 1.73 2014/12/06 13:51:06 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 *
@@ -500,9 +500,10 @@ struct ssl_session_st {
500 struct ssl_session_st *prev, *next; 500 struct ssl_session_st *prev, *next;
501 char *tlsext_hostname; 501 char *tlsext_hostname;
502 size_t tlsext_ecpointformatlist_length; 502 size_t tlsext_ecpointformatlist_length;
503 unsigned char *tlsext_ecpointformatlist; /* peer's list */ 503 uint8_t *tlsext_ecpointformatlist; /* peer's list */
504 size_t tlsext_ellipticcurvelist_length; 504 size_t tlsext_ellipticcurvelist_length;
505 unsigned char *tlsext_ellipticcurvelist; /* peer's list */ 505 uint16_t *tlsext_ellipticcurvelist; /* peer's list */
506
506 /* RFC4507 info */ 507 /* RFC4507 info */
507 unsigned char *tlsext_tick; /* Session ticket */ 508 unsigned char *tlsext_tick; /* Session ticket */
508 size_t tlsext_ticklen; /* Session ticket length */ 509 size_t tlsext_ticklen; /* Session ticket length */
@@ -1142,9 +1143,9 @@ struct ssl_st {
1142 /* RFC4507 session ticket expected to be received or sent */ 1143 /* RFC4507 session ticket expected to be received or sent */
1143 int tlsext_ticket_expected; 1144 int tlsext_ticket_expected;
1144 size_t tlsext_ecpointformatlist_length; 1145 size_t tlsext_ecpointformatlist_length;
1145 unsigned char *tlsext_ecpointformatlist; /* our list */ 1146 uint8_t *tlsext_ecpointformatlist; /* our list */
1146 size_t tlsext_ellipticcurvelist_length; 1147 size_t tlsext_ellipticcurvelist_length;
1147 unsigned char *tlsext_ellipticcurvelist; /* our list */ 1148 uint16_t *tlsext_ellipticcurvelist; /* our list */
1148 1149
1149 /* TLS Session Ticket extension override */ 1150 /* TLS Session Ticket extension override */
1150 TLS_SESSION_TICKET_EXT *tlsext_session_ticket; 1151 TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 74cacd4eec..c425f67a5a 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.77 2014/11/18 05:33:43 miod Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.78 2014/12/06 13:51:06 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 *
@@ -800,8 +800,8 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
800 800
801SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); 801SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
802 802
803int tls1_ec_curve_id2nid(int curve_id); 803int tls1_ec_curve_id2nid(uint16_t curve_id);
804int tls1_ec_nid2curve_id(int nid); 804uint16_t tls1_ec_nid2curve_id(int nid);
805int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); 805int tls1_check_curve(SSL *s, const unsigned char *p, size_t len);
806int tls1_get_shared_curve(SSL *s); 806int tls1_get_shared_curve(SSL *s);
807 807
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 5a6c0ddba0..8a7553e3e7 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.70 2014/12/06 13:28:56 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.71 2014/12/06 13:51:06 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 *
@@ -240,45 +240,45 @@ static int nid_list[] = {
240 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */ 240 NID_brainpoolP512r1 /* brainpoolP512r1 (28) */
241}; 241};
242 242
243static const unsigned char ecformats_default[] = { 243static const uint8_t ecformats_default[] = {
244 TLSEXT_ECPOINTFORMAT_uncompressed, 244 TLSEXT_ECPOINTFORMAT_uncompressed,
245 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, 245 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
246 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 246 TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
247}; 247};
248 248
249static const unsigned char eccurves_default[] = { 249static const uint16_t eccurves_default[] = {
250 0,14, /* sect571r1 (14) */ 250 14, /* sect571r1 (14) */
251 0,13, /* sect571k1 (13) */ 251 13, /* sect571k1 (13) */
252 0,25, /* secp521r1 (25) */ 252 25, /* secp521r1 (25) */
253 0,28, /* brainpool512r1 (28) */ 253 28, /* brainpool512r1 (28) */
254 0,11, /* sect409k1 (11) */ 254 11, /* sect409k1 (11) */
255 0,12, /* sect409r1 (12) */ 255 12, /* sect409r1 (12) */
256 0,27, /* brainpoolP384r1 (27) */ 256 27, /* brainpoolP384r1 (27) */
257 0,24, /* secp384r1 (24) */ 257 24, /* secp384r1 (24) */
258 0,9, /* sect283k1 (9) */ 258 9, /* sect283k1 (9) */
259 0,10, /* sect283r1 (10) */ 259 10, /* sect283r1 (10) */
260 0,26, /* brainpoolP256r1 (26) */ 260 26, /* brainpoolP256r1 (26) */
261 0,22, /* secp256k1 (22) */ 261 22, /* secp256k1 (22) */
262 0,23, /* secp256r1 (23) */ 262 23, /* secp256r1 (23) */
263 0,8, /* sect239k1 (8) */ 263 8, /* sect239k1 (8) */
264 0,6, /* sect233k1 (6) */ 264 6, /* sect233k1 (6) */
265 0,7, /* sect233r1 (7) */ 265 7, /* sect233r1 (7) */
266 0,20, /* secp224k1 (20) */ 266 20, /* secp224k1 (20) */
267 0,21, /* secp224r1 (21) */ 267 21, /* secp224r1 (21) */
268 0,4, /* sect193r1 (4) */ 268 4, /* sect193r1 (4) */
269 0,5, /* sect193r2 (5) */ 269 5, /* sect193r2 (5) */
270 0,18, /* secp192k1 (18) */ 270 18, /* secp192k1 (18) */
271 0,19, /* secp192r1 (19) */ 271 19, /* secp192r1 (19) */
272 0,1, /* sect163k1 (1) */ 272 1, /* sect163k1 (1) */
273 0,2, /* sect163r1 (2) */ 273 2, /* sect163r1 (2) */
274 0,3, /* sect163r2 (3) */ 274 3, /* sect163r2 (3) */
275 0,15, /* secp160k1 (15) */ 275 15, /* secp160k1 (15) */
276 0,16, /* secp160r1 (16) */ 276 16, /* secp160r1 (16) */
277 0,17, /* secp160r2 (17) */ 277 17, /* secp160r2 (17) */
278}; 278};
279 279
280int 280int
281tls1_ec_curve_id2nid(int curve_id) 281tls1_ec_curve_id2nid(uint16_t curve_id)
282{ 282{
283 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ 283 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
284 if ((curve_id < 1) || 284 if ((curve_id < 1) ||
@@ -287,7 +287,7 @@ tls1_ec_curve_id2nid(int curve_id)
287 return nid_list[curve_id - 1]; 287 return nid_list[curve_id - 1];
288} 288}
289 289
290int 290uint16_t
291tls1_ec_nid2curve_id(int nid) 291tls1_ec_nid2curve_id(int nid)
292{ 292{
293 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ 293 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
@@ -359,7 +359,7 @@ tls1_ec_nid2curve_id(int nid)
359 * exists, or the default formats if a custom list has not been specified. 359 * exists, or the default formats if a custom list has not been specified.
360 */ 360 */
361static void 361static void
362tls1_get_formatlist(SSL *s, int client_formats, const unsigned char **pformats, 362tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats,
363 size_t *pformatslen) 363 size_t *pformatslen)
364{ 364{
365 if (client_formats != 0) { 365 if (client_formats != 0) {
@@ -382,7 +382,7 @@ tls1_get_formatlist(SSL *s, int client_formats, const unsigned char **pformats,
382 * exists, or the default curves if a custom list has not been specified. 382 * exists, or the default curves if a custom list has not been specified.
383 */ 383 */
384static void 384static void
385tls1_get_curvelist(SSL *s, int client_curves, const unsigned char **pcurves, 385tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves,
386 size_t *pcurveslen) 386 size_t *pcurveslen)
387{ 387{
388 if (client_curves != 0) { 388 if (client_curves != 0) {
@@ -403,17 +403,20 @@ tls1_get_curvelist(SSL *s, int client_curves, const unsigned char **pcurves,
403int 403int
404tls1_check_curve(SSL *s, const unsigned char *p, size_t len) 404tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
405{ 405{
406 const unsigned char *curves; 406 const uint16_t *curves;
407 size_t curveslen, i; 407 size_t curveslen, i;
408 uint16_t cid;
408 409
409 /* Only named curves are supported. */ 410 /* Only named curves are supported. */
410 if (len != 3 || p[0] != NAMED_CURVE_TYPE) 411 if (len != 3 || p[0] != NAMED_CURVE_TYPE)
411 return (0); 412 return (0);
412 413
414 cid = (p[1] << 8) | p[2];
415
413 tls1_get_curvelist(s, 0, &curves, &curveslen); 416 tls1_get_curvelist(s, 0, &curves, &curveslen);
414 417
415 for (i = 0; i < curveslen; i += 2, curves += 2) { 418 for (i = 0; i < curveslen; i++) {
416 if (p[1] == curves[0] && p[2] == curves[1]) 419 if (curves[i] == cid)
417 return (1); 420 return (1);
418 } 421 }
419 return (0); 422 return (0);
@@ -422,10 +425,9 @@ tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
422int 425int
423tls1_get_shared_curve(SSL *s) 426tls1_get_shared_curve(SSL *s)
424{ 427{
425 const unsigned char *pref, *supp, *tsupp;
426 size_t preflen, supplen, i, j; 428 size_t preflen, supplen, i, j;
429 const uint16_t *pref, *supp;
427 unsigned long server_pref; 430 unsigned long server_pref;
428 int id;
429 431
430 /* Cannot do anything on the client side. */ 432 /* Cannot do anything on the client side. */
431 if (s->server == 0) 433 if (s->server == 0)
@@ -436,13 +438,10 @@ tls1_get_shared_curve(SSL *s)
436 tls1_get_curvelist(s, (server_pref == 0), &pref, &preflen); 438 tls1_get_curvelist(s, (server_pref == 0), &pref, &preflen);
437 tls1_get_curvelist(s, (server_pref != 0), &supp, &supplen); 439 tls1_get_curvelist(s, (server_pref != 0), &supp, &supplen);
438 440
439 for (i = 0; i < preflen; i += 2, pref += 2) { 441 for (i = 0; i < preflen; i++) {
440 tsupp = supp; 442 for (j = 0; j < supplen; j++) {
441 for (j = 0; j < supplen; j += 2, tsupp += 2) { 443 if (pref[i] == supp[j])
442 if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) { 444 return (tls1_ec_curve_id2nid(pref[i]));
443 id = (pref[0] << 8) | pref[1];
444 return (tls1_ec_curve_id2nid(id));
445 }
446 } 445 }
447 } 446 }
448 return (NID_undef); 447 return (NID_undef);
@@ -450,7 +449,7 @@ tls1_get_shared_curve(SSL *s)
450 449
451/* For an EC key set TLS ID and required compression based on parameters. */ 450/* For an EC key set TLS ID and required compression based on parameters. */
452static int 451static int
453tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec) 452tls1_set_ec_id(uint16_t *curve_id, uint8_t *comp_id, EC_KEY *ec)
454{ 453{
455 const EC_GROUP *grp; 454 const EC_GROUP *grp;
456 const EC_METHOD *meth; 455 const EC_METHOD *meth;
@@ -473,13 +472,10 @@ tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec)
473 id = tls1_ec_nid2curve_id(nid); 472 id = tls1_ec_nid2curve_id(nid);
474 473
475 /* If we have an ID set it, otherwise set arbitrary explicit curve. */ 474 /* If we have an ID set it, otherwise set arbitrary explicit curve. */
476 if (id != 0) { 475 if (id != 0)
477 curve_id[0] = 0; 476 *curve_id = id;
478 curve_id[1] = (unsigned char)id; 477 else
479 } else { 478 *curve_id = is_prime ? 0xff01 : 0xff02;
480 curve_id[0] = 0xff;
481 curve_id[1] = is_prime ? 0x01 : 0x02;
482 }
483 479
484 /* Specify the compression identifier. */ 480 /* Specify the compression identifier. */
485 if (comp_id != NULL) { 481 if (comp_id != NULL) {
@@ -499,10 +495,11 @@ tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec)
499 495
500/* Check that an EC key is compatible with extensions. */ 496/* Check that an EC key is compatible with extensions. */
501static int 497static int
502tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id) 498tls1_check_ec_key(SSL *s, const uint16_t *curve_id, const uint8_t *comp_id)
503{ 499{
504 const unsigned char *curves, *formats;
505 size_t curveslen, formatslen, i; 500 size_t curveslen, formatslen, i;
501 const uint16_t *curves;
502 const uint8_t *formats;
506 503
507 /* 504 /*
508 * Check point formats extension if present, otherwise everything 505 * Check point formats extension if present, otherwise everything
@@ -510,8 +507,8 @@ tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id)
510 */ 507 */
511 tls1_get_formatlist(s, 1, &formats, &formatslen); 508 tls1_get_formatlist(s, 1, &formats, &formatslen);
512 if (comp_id != NULL && formats != NULL) { 509 if (comp_id != NULL && formats != NULL) {
513 for (i = 0; i < formatslen; i++, formats++) { 510 for (i = 0; i < formatslen; i++) {
514 if (*comp_id == *formats) 511 if (formats[i] == *comp_id)
515 break; 512 break;
516 } 513 }
517 if (i == formatslen) 514 if (i == formatslen)
@@ -522,10 +519,9 @@ tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id)
522 * Check curve list if present, otherwise everything is supported. 519 * Check curve list if present, otherwise everything is supported.
523 */ 520 */
524 tls1_get_curvelist(s, 1, &curves, &curveslen); 521 tls1_get_curvelist(s, 1, &curves, &curveslen);
525 if (curves != NULL) { 522 if (curve_id != NULL && curves != NULL) {
526 for (i = 0; i < curveslen; i += 2, curves += 2) { 523 for (i = 0; i < curveslen; i++) {
527 if (curves[0] == curve_id[0] && 524 if (curves[i] == *curve_id)
528 curves[1] == curve_id[1])
529 break; 525 break;
530 } 526 }
531 if (i == curveslen) 527 if (i == curveslen)
@@ -540,7 +536,8 @@ int
540tls1_check_ec_server_key(SSL *s) 536tls1_check_ec_server_key(SSL *s)
541{ 537{
542 CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC; 538 CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC;
543 unsigned char comp_id, curve_id[2]; 539 uint16_t curve_id;
540 uint8_t comp_id;
544 EVP_PKEY *pkey; 541 EVP_PKEY *pkey;
545 int rv; 542 int rv;
546 543
@@ -548,12 +545,12 @@ tls1_check_ec_server_key(SSL *s)
548 return (0); 545 return (0);
549 if ((pkey = X509_get_pubkey(cpk->x509)) == NULL) 546 if ((pkey = X509_get_pubkey(cpk->x509)) == NULL)
550 return (0); 547 return (0);
551 rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec); 548 rv = tls1_set_ec_id(&curve_id, &comp_id, pkey->pkey.ec);
552 EVP_PKEY_free(pkey); 549 EVP_PKEY_free(pkey);
553 if (rv != 1) 550 if (rv != 1)
554 return (0); 551 return (0);
555 552
556 return tls1_check_ec_key(s, curve_id, &comp_id); 553 return tls1_check_ec_key(s, &curve_id, &comp_id);
557} 554}
558 555
559/* Check EC temporary key is compatible with client extensions. */ 556/* Check EC temporary key is compatible with client extensions. */
@@ -561,7 +558,7 @@ int
561tls1_check_ec_tmp_key(SSL *s) 558tls1_check_ec_tmp_key(SSL *s)
562{ 559{
563 EC_KEY *ec = s->cert->ecdh_tmp; 560 EC_KEY *ec = s->cert->ecdh_tmp;
564 unsigned char curve_id[2]; 561 uint16_t curve_id;
565 562
566 if (s->cert->ecdh_tmp_auto != 0) { 563 if (s->cert->ecdh_tmp_auto != 0) {
567 /* Need a shared curve. */ 564 /* Need a shared curve. */
@@ -575,10 +572,10 @@ tls1_check_ec_tmp_key(SSL *s)
575 return (1); 572 return (1);
576 return (0); 573 return (0);
577 } 574 }
578 if (tls1_set_ec_id(curve_id, NULL, ec) != 1) 575 if (tls1_set_ec_id(&curve_id, NULL, ec) != 1)
579 return (0); 576 return (0);
580 577
581 return tls1_check_ec_key(s, curve_id, NULL); 578 return tls1_check_ec_key(s, &curve_id, NULL);
582} 579}
583 580
584/* 581/*
@@ -723,8 +720,10 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
723 } 720 }
724 721
725 if (using_ecc) { 722 if (using_ecc) {
726 const unsigned char *curves, *formats;
727 size_t curveslen, formatslen, lenmax; 723 size_t curveslen, formatslen, lenmax;
724 const uint16_t *curves;
725 const uint8_t *formats;
726 int i;
728 727
729 /* 728 /*
730 * Add TLS extension ECPointFormats to the ClientHello message. 729 * Add TLS extension ECPointFormats to the ClientHello message.
@@ -767,16 +766,16 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
767 } 766 }
768 767
769 s2n(TLSEXT_TYPE_elliptic_curves, ret); 768 s2n(TLSEXT_TYPE_elliptic_curves, ret);
770 s2n(curveslen + 2, ret); 769 s2n((curveslen * 2) + 2, ret);
771 770
772 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for 771 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
773 * elliptic_curve_list, but the examples use two bytes. 772 * elliptic_curve_list, but the examples use two bytes.
774 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html 773 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
775 * resolves this to two bytes. 774 * resolves this to two bytes.
776 */ 775 */
777 s2n(curveslen, ret); 776 s2n(curveslen * 2, ret);
778 memcpy(ret, curves, curveslen); 777 for (i = 0; i < curveslen; i++)
779 ret += curveslen; 778 s2n(curves[i], ret);
780 } 779 }
781 780
782 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { 781 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
@@ -1334,60 +1333,66 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1334 else if (type == TLSEXT_TYPE_ec_point_formats && 1333 else if (type == TLSEXT_TYPE_ec_point_formats &&
1335 s->version != DTLS1_VERSION) { 1334 s->version != DTLS1_VERSION) {
1336 unsigned char *sdata = data; 1335 unsigned char *sdata = data;
1337 int ecpointformatlist_length; 1336 size_t formatslen;
1337 uint8_t *formats;
1338 1338
1339 if (size < 1) { 1339 if (size < 1) {
1340 *al = SSL_AD_DECODE_ERROR; 1340 *al = TLS1_AD_DECODE_ERROR;
1341 return 0; 1341 return 0;
1342 } 1342 }
1343 ecpointformatlist_length = *(sdata++); 1343 formatslen = *(sdata++);
1344 1344 if (formatslen != size - 1) {
1345 if (ecpointformatlist_length != size - 1) {
1346 *al = TLS1_AD_DECODE_ERROR; 1345 *al = TLS1_AD_DECODE_ERROR;
1347 return 0; 1346 return 0;
1348 } 1347 }
1348
1349 if (!s->hit) { 1349 if (!s->hit) {
1350 free(s->session->tlsext_ecpointformatlist); 1350 free(s->session->tlsext_ecpointformatlist);
1351 s->session->tlsext_ecpointformatlist = NULL;
1351 s->session->tlsext_ecpointformatlist_length = 0; 1352 s->session->tlsext_ecpointformatlist_length = 0;
1352 if ((s->session->tlsext_ecpointformatlist = 1353
1353 malloc(ecpointformatlist_length)) == NULL) { 1354 if ((formats = reallocarray(NULL, formatslen,
1355 sizeof(uint8_t))) == NULL) {
1354 *al = TLS1_AD_INTERNAL_ERROR; 1356 *al = TLS1_AD_INTERNAL_ERROR;
1355 return 0; 1357 return 0;
1356 } 1358 }
1357 s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; 1359 memcpy(formats, sdata, formatslen);
1358 memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); 1360 s->session->tlsext_ecpointformatlist = formats;
1361 s->session->tlsext_ecpointformatlist_length =
1362 formatslen;
1359 } 1363 }
1360 } else if (type == TLSEXT_TYPE_elliptic_curves && 1364 } else if (type == TLSEXT_TYPE_elliptic_curves &&
1361 s->version != DTLS1_VERSION) { 1365 s->version != DTLS1_VERSION) {
1362 unsigned char *sdata = data; 1366 unsigned char *sdata = data;
1363 int ellipticcurvelist_length; 1367 size_t curveslen, i;
1368 uint16_t *curves;
1364 1369
1365 if (size < 2) { 1370 if (size < 2) {
1366 *al = SSL_AD_DECODE_ERROR; 1371 *al = TLS1_AD_DECODE_ERROR;
1367 return 0; 1372 return 0;
1368 } 1373 }
1369 ellipticcurvelist_length = (*(sdata++) << 8); 1374 n2s(sdata, curveslen);
1370 ellipticcurvelist_length += (*(sdata++)); 1375 if (curveslen != size - 2 || curveslen % 2 != 0) {
1371
1372 if (ellipticcurvelist_length != size - 2 ||
1373 ellipticcurvelist_length < 1 ||
1374 ellipticcurvelist_length % 2 != 0) {
1375 *al = TLS1_AD_DECODE_ERROR; 1376 *al = TLS1_AD_DECODE_ERROR;
1376 return 0; 1377 return 0;
1377 } 1378 }
1379 curveslen /= 2;
1380
1378 if (!s->hit) { 1381 if (!s->hit) {
1379 if (s->session->tlsext_ellipticcurvelist) { 1382 if (s->session->tlsext_ellipticcurvelist) {
1380 *al = TLS1_AD_DECODE_ERROR; 1383 *al = TLS1_AD_DECODE_ERROR;
1381 return 0; 1384 return 0;
1382 } 1385 }
1383 s->session->tlsext_ellipticcurvelist_length = 0; 1386 s->session->tlsext_ellipticcurvelist_length = 0;
1384 if ((s->session->tlsext_ellipticcurvelist = 1387 if ((curves = reallocarray(NULL, curveslen,
1385 malloc(ellipticcurvelist_length)) == NULL) { 1388 sizeof(uint16_t))) == NULL) {
1386 *al = TLS1_AD_INTERNAL_ERROR; 1389 *al = TLS1_AD_INTERNAL_ERROR;
1387 return 0; 1390 return 0;
1388 } 1391 }
1389 s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length; 1392 for (i = 0; i < curveslen; i++)
1390 memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); 1393 n2s(sdata, curves[i]);
1394 s->session->tlsext_ellipticcurvelist = curves;
1395 s->session->tlsext_ellipticcurvelist_length = curveslen;
1391 } 1396 }
1392 } 1397 }
1393 else if (type == TLSEXT_TYPE_session_ticket) { 1398 else if (type == TLSEXT_TYPE_session_ticket) {
@@ -1628,26 +1633,33 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1628 else if (type == TLSEXT_TYPE_ec_point_formats && 1633 else if (type == TLSEXT_TYPE_ec_point_formats &&
1629 s->version != DTLS1_VERSION) { 1634 s->version != DTLS1_VERSION) {
1630 unsigned char *sdata = data; 1635 unsigned char *sdata = data;
1631 int ecpointformatlist_length = *(sdata++); 1636 size_t formatslen;
1637 uint8_t *formats;
1632 1638
1633 if (ecpointformatlist_length != size - 1 || 1639 if (size < 1) {
1634 ecpointformatlist_length < 1) {
1635 *al = TLS1_AD_DECODE_ERROR; 1640 *al = TLS1_AD_DECODE_ERROR;
1636 return 0; 1641 return 0;
1637 } 1642 }
1643 formatslen = *(sdata++);
1644 if (formatslen != size - 1) {
1645 *al = TLS1_AD_DECODE_ERROR;
1646 return 0;
1647 }
1648
1638 if (!s->hit) { 1649 if (!s->hit) {
1639 free(s->session->tlsext_ecpointformatlist); 1650 free(s->session->tlsext_ecpointformatlist);
1651 s->session->tlsext_ecpointformatlist = NULL;
1640 s->session->tlsext_ecpointformatlist_length = 0; 1652 s->session->tlsext_ecpointformatlist_length = 0;
1641 1653
1642 if ((s->session->tlsext_ecpointformatlist = 1654 if ((formats = reallocarray(NULL, formatslen,
1643 malloc(ecpointformatlist_length)) == NULL) { 1655 sizeof(uint8_t))) == NULL) {
1644 *al = TLS1_AD_INTERNAL_ERROR; 1656 *al = TLS1_AD_INTERNAL_ERROR;
1645 return 0; 1657 return 0;
1646 } 1658 }
1659 memcpy(formats, sdata, formatslen);
1660 s->session->tlsext_ecpointformatlist = formats;
1647 s->session->tlsext_ecpointformatlist_length = 1661 s->session->tlsext_ecpointformatlist_length =
1648 ecpointformatlist_length; 1662 formatslen;
1649 memcpy(s->session->tlsext_ecpointformatlist,
1650 sdata, ecpointformatlist_length);
1651 } 1663 }
1652 } 1664 }
1653 else if (type == TLSEXT_TYPE_session_ticket) { 1665 else if (type == TLSEXT_TYPE_session_ticket) {