diff options
author | jsing <> | 2014-12-06 13:51:06 +0000 |
---|---|---|
committer | jsing <> | 2014-12-06 13:51:06 +0000 |
commit | a657ba9d9f7c27a3001f24d121b111838c1dc856 (patch) | |
tree | bf970ac74fc18ba45834070bde1e0c9b24cc24fc /src/lib | |
parent | 737df48ca584850ed0b5d4bb60494b65386a5d5f (diff) | |
download | openbsd-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.h | 11 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl_locl.h | 6 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/t1_lib.c | 218 | ||||
-rw-r--r-- | src/lib/libssl/ssl.h | 11 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 6 | ||||
-rw-r--r-- | src/lib/libssl/t1_lib.c | 218 |
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 | ||
801 | SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); | 801 | SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); |
802 | 802 | ||
803 | int tls1_ec_curve_id2nid(int curve_id); | 803 | int tls1_ec_curve_id2nid(uint16_t curve_id); |
804 | int tls1_ec_nid2curve_id(int nid); | 804 | uint16_t tls1_ec_nid2curve_id(int nid); |
805 | int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); | 805 | int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); |
806 | int tls1_get_shared_curve(SSL *s); | 806 | int 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 | ||
243 | static const unsigned char ecformats_default[] = { | 243 | static 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 | ||
249 | static const unsigned char eccurves_default[] = { | 249 | static 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 | ||
280 | int | 280 | int |
281 | tls1_ec_curve_id2nid(int curve_id) | 281 | tls1_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 | ||
290 | int | 290 | uint16_t |
291 | tls1_ec_nid2curve_id(int nid) | 291 | tls1_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 | */ |
361 | static void | 361 | static void |
362 | tls1_get_formatlist(SSL *s, int client_formats, const unsigned char **pformats, | 362 | tls1_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 | */ |
384 | static void | 384 | static void |
385 | tls1_get_curvelist(SSL *s, int client_curves, const unsigned char **pcurves, | 385 | tls1_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, | |||
403 | int | 403 | int |
404 | tls1_check_curve(SSL *s, const unsigned char *p, size_t len) | 404 | tls1_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) | |||
422 | int | 425 | int |
423 | tls1_get_shared_curve(SSL *s) | 426 | tls1_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. */ |
452 | static int | 451 | static int |
453 | tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec) | 452 | tls1_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. */ |
501 | static int | 497 | static int |
502 | tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id) | 498 | tls1_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 | |||
540 | tls1_check_ec_server_key(SSL *s) | 536 | tls1_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 | |||
561 | tls1_check_ec_tmp_key(SSL *s) | 558 | tls1_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 | ||
801 | SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); | 801 | SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); |
802 | 802 | ||
803 | int tls1_ec_curve_id2nid(int curve_id); | 803 | int tls1_ec_curve_id2nid(uint16_t curve_id); |
804 | int tls1_ec_nid2curve_id(int nid); | 804 | uint16_t tls1_ec_nid2curve_id(int nid); |
805 | int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); | 805 | int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); |
806 | int tls1_get_shared_curve(SSL *s); | 806 | int 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 | ||
243 | static const unsigned char ecformats_default[] = { | 243 | static 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 | ||
249 | static const unsigned char eccurves_default[] = { | 249 | static 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 | ||
280 | int | 280 | int |
281 | tls1_ec_curve_id2nid(int curve_id) | 281 | tls1_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 | ||
290 | int | 290 | uint16_t |
291 | tls1_ec_nid2curve_id(int nid) | 291 | tls1_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 | */ |
361 | static void | 361 | static void |
362 | tls1_get_formatlist(SSL *s, int client_formats, const unsigned char **pformats, | 362 | tls1_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 | */ |
384 | static void | 384 | static void |
385 | tls1_get_curvelist(SSL *s, int client_curves, const unsigned char **pcurves, | 385 | tls1_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, | |||
403 | int | 403 | int |
404 | tls1_check_curve(SSL *s, const unsigned char *p, size_t len) | 404 | tls1_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) | |||
422 | int | 425 | int |
423 | tls1_get_shared_curve(SSL *s) | 426 | tls1_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. */ |
452 | static int | 451 | static int |
453 | tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec) | 452 | tls1_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. */ |
501 | static int | 497 | static int |
502 | tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id) | 498 | tls1_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 | |||
540 | tls1_check_ec_server_key(SSL *s) | 536 | tls1_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 | |||
561 | tls1_check_ec_tmp_key(SSL *s) | 558 | tls1_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) { |