diff options
| author | doug <> | 2017-08-11 20:14:13 +0000 |
|---|---|---|
| committer | doug <> | 2017-08-11 20:14:13 +0000 |
| commit | cd73f263c3adc239b4b8eece31644dd823fca563 (patch) | |
| tree | 6353018cdfeb368812f1bd5d7a1c6f6435ca9e1d /src/lib | |
| parent | ca0f57365762ec3e5a661aa179a61d0a6632fc19 (diff) | |
| download | openbsd-cd73f263c3adc239b4b8eece31644dd823fca563.tar.gz openbsd-cd73f263c3adc239b4b8eece31644dd823fca563.tar.bz2 openbsd-cd73f263c3adc239b4b8eece31644dd823fca563.zip | |
Rewrite EllipticCurves TLS extension handling using CBB/CBS and the new
extension framework.
input + ok jsing@
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/libssl/ssl_locl.h | 4 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 121 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.h | 10 | ||||
| -rw-r--r-- | src/lib/libssl/t1_lib.c | 76 |
4 files changed, 135 insertions, 76 deletions
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 84bb6879b0..52e4b6c5e9 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.186 2017/08/11 17:54:41 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.187 2017/08/11 20:14:13 doug 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 | * |
| @@ -1382,6 +1382,8 @@ void SSL_error_internal(const SSL *s, int r, char *f, int l); | |||
| 1382 | 1382 | ||
| 1383 | void tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, | 1383 | void tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, |
| 1384 | size_t *pformatslen); | 1384 | size_t *pformatslen); |
| 1385 | void tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves, | ||
| 1386 | size_t *pcurveslen); | ||
| 1385 | 1387 | ||
| 1386 | __END_HIDDEN_DECLS | 1388 | __END_HIDDEN_DECLS |
| 1387 | 1389 | ||
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index ad30f43389..c050224c70 100644 --- a/src/lib/libssl/ssl_tlsext.c +++ b/src/lib/libssl/ssl_tlsext.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_tlsext.c,v 1.5 2017/08/11 06:30:41 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.6 2017/08/11 20:14:13 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
| @@ -21,6 +21,116 @@ | |||
| 21 | #include "bytestring.h" | 21 | #include "bytestring.h" |
| 22 | #include "ssl_tlsext.h" | 22 | #include "ssl_tlsext.h" |
| 23 | 23 | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Supported Elliptic Curves - RFC 4492 section 5.1.1 | ||
| 27 | */ | ||
| 28 | int | ||
| 29 | tlsext_ec_clienthello_needs(SSL *s) | ||
| 30 | { | ||
| 31 | return ssl_has_ecc_ciphers(s); | ||
| 32 | } | ||
| 33 | |||
| 34 | int | ||
| 35 | tlsext_ec_clienthello_build(SSL *s, CBB *cbb) | ||
| 36 | { | ||
| 37 | CBB curvelist; | ||
| 38 | size_t curves_len; | ||
| 39 | int i; | ||
| 40 | const uint16_t *curves; | ||
| 41 | |||
| 42 | tls1_get_curvelist(s, 0, &curves, &curves_len); | ||
| 43 | |||
| 44 | if (curves_len == 0) { | ||
| 45 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | if (!CBB_add_u16_length_prefixed(cbb, &curvelist)) | ||
| 50 | return 0; | ||
| 51 | |||
| 52 | for (i = 0; i < curves_len; i++) { | ||
| 53 | if (!CBB_add_u16(&curvelist, curves[i])) | ||
| 54 | return 0; | ||
| 55 | } | ||
| 56 | |||
| 57 | if (!CBB_flush(cbb)) | ||
| 58 | return 0; | ||
| 59 | |||
| 60 | return 1; | ||
| 61 | } | ||
| 62 | |||
| 63 | int | ||
| 64 | tlsext_ec_clienthello_parse(SSL *s, CBS *cbs, int *alert) | ||
| 65 | { | ||
| 66 | CBS curvelist; | ||
| 67 | size_t curves_len; | ||
| 68 | |||
| 69 | if (!CBS_get_u16_length_prefixed(cbs, &curvelist)) | ||
| 70 | goto err; | ||
| 71 | if (CBS_len(cbs) != 0) | ||
| 72 | goto err; | ||
| 73 | |||
| 74 | curves_len = CBS_len(&curvelist); | ||
| 75 | if (curves_len == 0 || curves_len % 2 != 0) | ||
| 76 | goto err; | ||
| 77 | curves_len /= 2; | ||
| 78 | |||
| 79 | if (!s->internal->hit) { | ||
| 80 | int i; | ||
| 81 | uint16_t *curves; | ||
| 82 | |||
| 83 | if (SSI(s)->tlsext_supportedgroups != NULL) | ||
| 84 | goto err; | ||
| 85 | |||
| 86 | if ((curves = reallocarray(NULL, curves_len, | ||
| 87 | sizeof(uint16_t))) == NULL) { | ||
| 88 | *alert = TLS1_AD_INTERNAL_ERROR; | ||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | for (i = 0; i < curves_len; i++) { | ||
| 93 | if (!CBS_get_u16(&curvelist, &curves[i])) { | ||
| 94 | free(curves); | ||
| 95 | goto err; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | if (CBS_len(&curvelist) != 0) { | ||
| 100 | free(curves); | ||
| 101 | goto err; | ||
| 102 | } | ||
| 103 | |||
| 104 | SSI(s)->tlsext_supportedgroups = curves; | ||
| 105 | SSI(s)->tlsext_supportedgroups_length = curves_len; | ||
| 106 | } | ||
| 107 | |||
| 108 | return 1; | ||
| 109 | |||
| 110 | err: | ||
| 111 | *alert = TLS1_AD_DECODE_ERROR; | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | /* This extension is never used by the server. */ | ||
| 116 | int | ||
| 117 | tlsext_ec_serverhello_needs(SSL *s) | ||
| 118 | { | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | int | ||
| 123 | tlsext_ec_serverhello_build(SSL *s, CBB *cbb) | ||
| 124 | { | ||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | int | ||
| 129 | tlsext_ec_serverhello_parse(SSL *s, CBS *cbs, int *alert) | ||
| 130 | { | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 24 | /* | 134 | /* |
| 25 | * Supported Point Formats Extension - RFC 4492 section 5.1.2 | 135 | * Supported Point Formats Extension - RFC 4492 section 5.1.2 |
| 26 | */ | 136 | */ |
| @@ -420,6 +530,15 @@ static struct tls_extension tls_extensions[] = { | |||
| 420 | .serverhello_build = tlsext_ecpf_serverhello_build, | 530 | .serverhello_build = tlsext_ecpf_serverhello_build, |
| 421 | .serverhello_parse = tlsext_ecpf_serverhello_parse, | 531 | .serverhello_parse = tlsext_ecpf_serverhello_parse, |
| 422 | }, | 532 | }, |
| 533 | { | ||
| 534 | .type = TLSEXT_TYPE_elliptic_curves, | ||
| 535 | .clienthello_needs = tlsext_ec_clienthello_needs, | ||
| 536 | .clienthello_build = tlsext_ec_clienthello_build, | ||
| 537 | .clienthello_parse = tlsext_ec_clienthello_parse, | ||
| 538 | .serverhello_needs = tlsext_ec_serverhello_needs, | ||
| 539 | .serverhello_build = tlsext_ec_serverhello_build, | ||
| 540 | .serverhello_parse = tlsext_ec_serverhello_parse, | ||
| 541 | }, | ||
| 423 | }; | 542 | }; |
| 424 | 543 | ||
| 425 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) | 544 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) |
diff --git a/src/lib/libssl/ssl_tlsext.h b/src/lib/libssl/ssl_tlsext.h index 6f79755f81..38f8ffaa65 100644 --- a/src/lib/libssl/ssl_tlsext.h +++ b/src/lib/libssl/ssl_tlsext.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_tlsext.h,v 1.4 2017/08/11 06:30:41 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.h,v 1.5 2017/08/11 20:14:13 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
| @@ -30,6 +30,13 @@ int tlsext_sni_serverhello_needs(SSL *s); | |||
| 30 | int tlsext_sni_serverhello_build(SSL *s, CBB *cbb); | 30 | int tlsext_sni_serverhello_build(SSL *s, CBB *cbb); |
| 31 | int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert); | 31 | int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert); |
| 32 | 32 | ||
| 33 | int tlsext_ec_clienthello_needs(SSL *s); | ||
| 34 | int tlsext_ec_clienthello_build(SSL *s, CBB *cbb); | ||
| 35 | int tlsext_ec_clienthello_parse(SSL *s, CBS *cbs, int *alert); | ||
| 36 | int tlsext_ec_serverhello_needs(SSL *s); | ||
| 37 | int tlsext_ec_serverhello_build(SSL *s, CBB *cbb); | ||
| 38 | int tlsext_ec_serverhello_parse(SSL *s, CBS *cbs, int *alert); | ||
| 39 | |||
| 33 | int tlsext_ecpf_clienthello_needs(SSL *s); | 40 | int tlsext_ecpf_clienthello_needs(SSL *s); |
| 34 | int tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb); | 41 | int tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb); |
| 35 | int tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert); | 42 | int tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert); |
| @@ -37,6 +44,7 @@ int tlsext_ecpf_serverhello_needs(SSL *s); | |||
| 37 | int tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb); | 44 | int tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb); |
| 38 | int tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert); | 45 | int tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert); |
| 39 | 46 | ||
| 47 | |||
| 40 | int tlsext_clienthello_build(SSL *s, CBB *cbb); | 48 | int tlsext_clienthello_build(SSL *s, CBB *cbb); |
| 41 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, | 49 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, |
| 42 | int *alert); | 50 | int *alert); |
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 2e90d3e9df..4983ad27fa 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.125 2017/08/11 05:06:34 doug Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.126 2017/08/11 20:14:13 doug 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 | * |
| @@ -365,7 +365,7 @@ tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, | |||
| 365 | * the client/session curves. Otherwise return the custom curve list if one | 365 | * the client/session curves. Otherwise return the custom curve list if one |
| 366 | * exists, or the default curves if a custom list has not been specified. | 366 | * exists, or the default curves if a custom list has not been specified. |
| 367 | */ | 367 | */ |
| 368 | static void | 368 | void |
| 369 | tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves, | 369 | tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves, |
| 370 | size_t *pcurveslen) | 370 | size_t *pcurveslen) |
| 371 | { | 371 | { |
| @@ -674,12 +674,9 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 674 | { | 674 | { |
| 675 | int extdatalen = 0; | 675 | int extdatalen = 0; |
| 676 | unsigned char *ret = p; | 676 | unsigned char *ret = p; |
| 677 | int using_ecc; | ||
| 678 | size_t len; | 677 | size_t len; |
| 679 | CBB cbb; | 678 | CBB cbb; |
| 680 | 679 | ||
| 681 | using_ecc = ssl_has_ecc_ciphers(s); | ||
| 682 | |||
| 683 | ret += 2; | 680 | ret += 2; |
| 684 | if (ret >= limit) | 681 | if (ret >= limit) |
| 685 | return NULL; /* this really never occurs, but ... */ | 682 | return NULL; /* this really never occurs, but ... */ |
| @@ -698,40 +695,6 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 698 | return NULL; | 695 | return NULL; |
| 699 | ret += len; | 696 | ret += len; |
| 700 | 697 | ||
| 701 | if (using_ecc) { | ||
| 702 | size_t curveslen, lenmax; | ||
| 703 | const uint16_t *curves; | ||
| 704 | int i; | ||
| 705 | |||
| 706 | /* | ||
| 707 | * Add TLS extension EllipticCurves to the ClientHello message. | ||
| 708 | */ | ||
| 709 | tls1_get_curvelist(s, 0, &curves, &curveslen); | ||
| 710 | |||
| 711 | if ((size_t)(limit - ret) < 6) | ||
| 712 | return NULL; | ||
| 713 | |||
| 714 | lenmax = limit - ret - 6; | ||
| 715 | if (curveslen * 2 > lenmax) | ||
| 716 | return NULL; | ||
| 717 | if (curveslen * 2 > 65532) { | ||
| 718 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 719 | return NULL; | ||
| 720 | } | ||
| 721 | |||
| 722 | s2n(TLSEXT_TYPE_elliptic_curves, ret); | ||
| 723 | s2n((curveslen * 2) + 2, ret); | ||
| 724 | |||
| 725 | /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for | ||
| 726 | * elliptic_curve_list, but the examples use two bytes. | ||
| 727 | * https://www1.ietf.org/mail-archive/web/tls/current/msg00538.html | ||
| 728 | * resolves this to two bytes. | ||
| 729 | */ | ||
| 730 | s2n(curveslen * 2, ret); | ||
| 731 | for (i = 0; i < curveslen; i++) | ||
| 732 | s2n(curves[i], ret); | ||
| 733 | } | ||
| 734 | |||
| 735 | if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { | 698 | if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { |
| 736 | int ticklen; | 699 | int ticklen; |
| 737 | if (!s->internal->new_session && s->session && s->session->tlsext_tick) | 700 | if (!s->internal->new_session && s->session && s->session->tlsext_tick) |
| @@ -1142,40 +1105,7 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1142 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) | 1105 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) |
| 1143 | return 0; | 1106 | return 0; |
| 1144 | 1107 | ||
| 1145 | if (type == TLSEXT_TYPE_elliptic_curves && | 1108 | if (type == TLSEXT_TYPE_session_ticket) { |
| 1146 | s->version != DTLS1_VERSION) { | ||
| 1147 | unsigned char *sdata = data; | ||
| 1148 | size_t curveslen, i; | ||
| 1149 | uint16_t *curves; | ||
| 1150 | |||
| 1151 | if (size < 2) { | ||
| 1152 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1153 | return 0; | ||
| 1154 | } | ||
| 1155 | n2s(sdata, curveslen); | ||
| 1156 | if (curveslen != size - 2 || curveslen % 2 != 0) { | ||
| 1157 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1158 | return 0; | ||
| 1159 | } | ||
| 1160 | curveslen /= 2; | ||
| 1161 | |||
| 1162 | if (!s->internal->hit) { | ||
| 1163 | if (SSI(s)->tlsext_supportedgroups) { | ||
| 1164 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1165 | return 0; | ||
| 1166 | } | ||
| 1167 | SSI(s)->tlsext_supportedgroups_length = 0; | ||
| 1168 | if ((curves = reallocarray(NULL, curveslen, | ||
| 1169 | sizeof(uint16_t))) == NULL) { | ||
| 1170 | *al = TLS1_AD_INTERNAL_ERROR; | ||
| 1171 | return 0; | ||
| 1172 | } | ||
| 1173 | for (i = 0; i < curveslen; i++) | ||
| 1174 | n2s(sdata, curves[i]); | ||
| 1175 | SSI(s)->tlsext_supportedgroups = curves; | ||
| 1176 | SSI(s)->tlsext_supportedgroups_length = curveslen; | ||
| 1177 | } | ||
| 1178 | } else if (type == TLSEXT_TYPE_session_ticket) { | ||
| 1179 | if (s->internal->tls_session_ticket_ext_cb && | 1109 | if (s->internal->tls_session_ticket_ext_cb && |
| 1180 | !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) { | 1110 | !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) { |
| 1181 | *al = TLS1_AD_INTERNAL_ERROR; | 1111 | *al = TLS1_AD_INTERNAL_ERROR; |
