diff options
| author | doug <> | 2017-08-11 05:06:34 +0000 |
|---|---|---|
| committer | doug <> | 2017-08-11 05:06:34 +0000 |
| commit | 1236d23d3a61cbaa7533a335e9756c6ca7578afa (patch) | |
| tree | cf9f734a8e9d38d5af29ff18c56720f241220b61 /src/lib/libssl/t1_lib.c | |
| parent | 52c5bafe628bfaf1072a7e4cd721523f818d1bcf (diff) | |
| download | openbsd-1236d23d3a61cbaa7533a335e9756c6ca7578afa.tar.gz openbsd-1236d23d3a61cbaa7533a335e9756c6ca7578afa.tar.bz2 openbsd-1236d23d3a61cbaa7533a335e9756c6ca7578afa.zip | |
Rewrite the ECPointFormats TLS extension handling using CBB/CBS and the
new extension framework.
input + ok jsing@
Diffstat (limited to 'src/lib/libssl/t1_lib.c')
| -rw-r--r-- | src/lib/libssl/t1_lib.c | 150 |
1 files changed, 6 insertions, 144 deletions
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 42fd18fe2d..2e90d3e9df 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.124 2017/08/10 17:18:38 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.125 2017/08/11 05:06:34 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 | * |
| @@ -342,7 +342,7 @@ tls1_ec_nid2curve_id(int nid) | |||
| 342 | * the client/session formats. Otherwise return the custom format list if one | 342 | * the client/session formats. Otherwise return the custom format list if one |
| 343 | * exists, or the default formats if a custom list has not been specified. | 343 | * exists, or the default formats if a custom list has not been specified. |
| 344 | */ | 344 | */ |
| 345 | static void | 345 | void |
| 346 | tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, | 346 | tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, |
| 347 | size_t *pformatslen) | 347 | size_t *pformatslen) |
| 348 | { | 348 | { |
| @@ -699,34 +699,11 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 699 | ret += len; | 699 | ret += len; |
| 700 | 700 | ||
| 701 | if (using_ecc) { | 701 | if (using_ecc) { |
| 702 | size_t curveslen, formatslen, lenmax; | 702 | size_t curveslen, lenmax; |
| 703 | const uint16_t *curves; | 703 | const uint16_t *curves; |
| 704 | const uint8_t *formats; | ||
| 705 | int i; | 704 | int i; |
| 706 | 705 | ||
| 707 | /* | 706 | /* |
| 708 | * Add TLS extension ECPointFormats to the ClientHello message. | ||
| 709 | */ | ||
| 710 | tls1_get_formatlist(s, 0, &formats, &formatslen); | ||
| 711 | |||
| 712 | if ((size_t)(limit - ret) < 5) | ||
| 713 | return NULL; | ||
| 714 | |||
| 715 | lenmax = limit - ret - 5; | ||
| 716 | if (formatslen > lenmax) | ||
| 717 | return NULL; | ||
| 718 | if (formatslen > 255) { | ||
| 719 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 720 | return NULL; | ||
| 721 | } | ||
| 722 | |||
| 723 | s2n(TLSEXT_TYPE_ec_point_formats, ret); | ||
| 724 | s2n(formatslen + 1, ret); | ||
| 725 | *(ret++) = (unsigned char)formatslen; | ||
| 726 | memcpy(ret, formats, formatslen); | ||
| 727 | ret += formatslen; | ||
| 728 | |||
| 729 | /* | ||
| 730 | * Add TLS extension EllipticCurves to the ClientHello message. | 707 | * Add TLS extension EllipticCurves to the ClientHello message. |
| 731 | */ | 708 | */ |
| 732 | tls1_get_curvelist(s, 0, &curves, &curveslen); | 709 | tls1_get_curvelist(s, 0, &curves, &curveslen); |
| @@ -931,14 +908,12 @@ skip_ext: | |||
| 931 | unsigned char * | 908 | unsigned char * |
| 932 | ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | 909 | ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) |
| 933 | { | 910 | { |
| 934 | int using_ecc, extdatalen = 0; | 911 | int extdatalen = 0; |
| 935 | unsigned char *ret = p; | 912 | unsigned char *ret = p; |
| 936 | int next_proto_neg_seen; | 913 | int next_proto_neg_seen; |
| 937 | size_t len; | 914 | size_t len; |
| 938 | CBB cbb; | 915 | CBB cbb; |
| 939 | 916 | ||
| 940 | using_ecc = ssl_using_ecc_cipher(s); | ||
| 941 | |||
| 942 | ret += 2; | 917 | ret += 2; |
| 943 | if (ret >= limit) | 918 | if (ret >= limit) |
| 944 | return NULL; /* this really never occurs, but ... */ | 919 | return NULL; /* this really never occurs, but ... */ |
| @@ -957,33 +932,6 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 957 | return NULL; | 932 | return NULL; |
| 958 | ret += len; | 933 | ret += len; |
| 959 | 934 | ||
| 960 | if (using_ecc && s->version != DTLS1_VERSION) { | ||
| 961 | const unsigned char *formats; | ||
| 962 | size_t formatslen, lenmax; | ||
| 963 | |||
| 964 | /* | ||
| 965 | * Add TLS extension ECPointFormats to the ServerHello message. | ||
| 966 | */ | ||
| 967 | tls1_get_formatlist(s, 0, &formats, &formatslen); | ||
| 968 | |||
| 969 | if ((size_t)(limit - ret) < 5) | ||
| 970 | return NULL; | ||
| 971 | |||
| 972 | lenmax = limit - ret - 5; | ||
| 973 | if (formatslen > lenmax) | ||
| 974 | return NULL; | ||
| 975 | if (formatslen > 255) { | ||
| 976 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 977 | return NULL; | ||
| 978 | } | ||
| 979 | |||
| 980 | s2n(TLSEXT_TYPE_ec_point_formats, ret); | ||
| 981 | s2n(formatslen + 1, ret); | ||
| 982 | *(ret++) = (unsigned char)formatslen; | ||
| 983 | memcpy(ret, formats, formatslen); | ||
| 984 | ret += formatslen; | ||
| 985 | } | ||
| 986 | |||
| 987 | /* | 935 | /* |
| 988 | * Currently the server should not respond with a SupportedCurves | 936 | * Currently the server should not respond with a SupportedCurves |
| 989 | * extension. | 937 | * extension. |
| @@ -1194,38 +1142,7 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1194 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) | 1142 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) |
| 1195 | return 0; | 1143 | return 0; |
| 1196 | 1144 | ||
| 1197 | if (type == TLSEXT_TYPE_ec_point_formats && | 1145 | if (type == TLSEXT_TYPE_elliptic_curves && |
| 1198 | s->version != DTLS1_VERSION) { | ||
| 1199 | unsigned char *sdata = data; | ||
| 1200 | size_t formatslen; | ||
| 1201 | uint8_t *formats; | ||
| 1202 | |||
| 1203 | if (size < 1) { | ||
| 1204 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1205 | return 0; | ||
| 1206 | } | ||
| 1207 | formatslen = *(sdata++); | ||
| 1208 | if (formatslen != size - 1) { | ||
| 1209 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1210 | return 0; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | if (!s->internal->hit) { | ||
| 1214 | free(SSI(s)->tlsext_ecpointformatlist); | ||
| 1215 | SSI(s)->tlsext_ecpointformatlist = NULL; | ||
| 1216 | SSI(s)->tlsext_ecpointformatlist_length = 0; | ||
| 1217 | |||
| 1218 | if ((formats = reallocarray(NULL, formatslen, | ||
| 1219 | sizeof(uint8_t))) == NULL) { | ||
| 1220 | *al = TLS1_AD_INTERNAL_ERROR; | ||
| 1221 | return 0; | ||
| 1222 | } | ||
| 1223 | memcpy(formats, sdata, formatslen); | ||
| 1224 | SSI(s)->tlsext_ecpointformatlist = formats; | ||
| 1225 | SSI(s)->tlsext_ecpointformatlist_length = | ||
| 1226 | formatslen; | ||
| 1227 | } | ||
| 1228 | } else if (type == TLSEXT_TYPE_elliptic_curves && | ||
| 1229 | s->version != DTLS1_VERSION) { | 1146 | s->version != DTLS1_VERSION) { |
| 1230 | unsigned char *sdata = data; | 1147 | unsigned char *sdata = data; |
| 1231 | size_t curveslen, i; | 1148 | size_t curveslen, i; |
| @@ -1510,39 +1427,7 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al) | |||
| 1510 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) | 1427 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) |
| 1511 | return 0; | 1428 | return 0; |
| 1512 | 1429 | ||
| 1513 | if (type == TLSEXT_TYPE_ec_point_formats && | 1430 | if (type == TLSEXT_TYPE_session_ticket) { |
| 1514 | s->version != DTLS1_VERSION) { | ||
| 1515 | unsigned char *sdata = data; | ||
| 1516 | size_t formatslen; | ||
| 1517 | uint8_t *formats; | ||
| 1518 | |||
| 1519 | if (size < 1) { | ||
| 1520 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1521 | return 0; | ||
| 1522 | } | ||
| 1523 | formatslen = *(sdata++); | ||
| 1524 | if (formatslen != size - 1) { | ||
| 1525 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1526 | return 0; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | if (!s->internal->hit) { | ||
| 1530 | free(SSI(s)->tlsext_ecpointformatlist); | ||
| 1531 | SSI(s)->tlsext_ecpointformatlist = NULL; | ||
| 1532 | SSI(s)->tlsext_ecpointformatlist_length = 0; | ||
| 1533 | |||
| 1534 | if ((formats = reallocarray(NULL, formatslen, | ||
| 1535 | sizeof(uint8_t))) == NULL) { | ||
| 1536 | *al = TLS1_AD_INTERNAL_ERROR; | ||
| 1537 | return 0; | ||
| 1538 | } | ||
| 1539 | memcpy(formats, sdata, formatslen); | ||
| 1540 | SSI(s)->tlsext_ecpointformatlist = formats; | ||
| 1541 | SSI(s)->tlsext_ecpointformatlist_length = | ||
| 1542 | formatslen; | ||
| 1543 | } | ||
| 1544 | } | ||
| 1545 | else if (type == TLSEXT_TYPE_session_ticket) { | ||
| 1546 | if (s->internal->tls_session_ticket_ext_cb && | 1431 | if (s->internal->tls_session_ticket_ext_cb && |
| 1547 | !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) { | 1432 | !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) { |
| 1548 | *al = TLS1_AD_INTERNAL_ERROR; | 1433 | *al = TLS1_AD_INTERNAL_ERROR; |
| @@ -1779,29 +1664,6 @@ ssl_check_serverhello_tlsext(SSL *s) | |||
| 1779 | int ret = SSL_TLSEXT_ERR_NOACK; | 1664 | int ret = SSL_TLSEXT_ERR_NOACK; |
| 1780 | int al = SSL_AD_UNRECOGNIZED_NAME; | 1665 | int al = SSL_AD_UNRECOGNIZED_NAME; |
| 1781 | 1666 | ||
| 1782 | /* If we are client and using an elliptic curve cryptography cipher | ||
| 1783 | * suite, then if server returns an EC point formats lists extension | ||
| 1784 | * it must contain uncompressed. | ||
| 1785 | */ | ||
| 1786 | if (ssl_using_ecc_cipher(s) && | ||
| 1787 | s->internal->tlsext_ecpointformatlist != NULL && | ||
| 1788 | s->internal->tlsext_ecpointformatlist_length > 0) { | ||
| 1789 | /* we are using an ECC cipher */ | ||
| 1790 | size_t i; | ||
| 1791 | unsigned char *list; | ||
| 1792 | int found_uncompressed = 0; | ||
| 1793 | list = SSI(s)->tlsext_ecpointformatlist; | ||
| 1794 | for (i = 0; i < SSI(s)->tlsext_ecpointformatlist_length; i++) { | ||
| 1795 | if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { | ||
| 1796 | found_uncompressed = 1; | ||
| 1797 | break; | ||
| 1798 | } | ||
| 1799 | } | ||
| 1800 | if (!found_uncompressed) { | ||
| 1801 | SSLerror(s, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); | ||
| 1802 | return -1; | ||
| 1803 | } | ||
| 1804 | } | ||
| 1805 | ret = SSL_TLSEXT_ERR_OK; | 1667 | ret = SSL_TLSEXT_ERR_OK; |
| 1806 | 1668 | ||
| 1807 | if (s->ctx != NULL && s->ctx->internal->tlsext_servername_callback != 0) | 1669 | if (s->ctx != NULL && s->ctx->internal->tlsext_servername_callback != 0) |
