diff options
| author | jsing <> | 2014-12-06 13:51:06 +0000 |
|---|---|---|
| committer | jsing <> | 2014-12-06 13:51:06 +0000 |
| commit | 9c3c275d21d2d69204d9b0ba8ac08101083cb082 (patch) | |
| tree | bf970ac74fc18ba45834070bde1e0c9b24cc24fc /src/lib/libssl/t1_lib.c | |
| parent | 334a4892a7feb061e43aedcdcd147161b689e008 (diff) | |
| download | openbsd-9c3c275d21d2d69204d9b0ba8ac08101083cb082.tar.gz openbsd-9c3c275d21d2d69204d9b0ba8ac08101083cb082.tar.bz2 openbsd-9c3c275d21d2d69204d9b0ba8ac08101083cb082.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 '')
| -rw-r--r-- | src/lib/libssl/t1_lib.c | 218 |
1 files changed, 115 insertions, 103 deletions
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) { |
