diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/t1_lib.c | 155 |
1 files changed, 152 insertions, 3 deletions
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 8a7553e3e7..5df45ab359 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.71 2014/12/06 13:51:06 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.72 2014/12/10 14:58:56 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 | * |
| @@ -878,6 +878,18 @@ skip_ext: | |||
| 878 | } | 878 | } |
| 879 | #endif | 879 | #endif |
| 880 | 880 | ||
| 881 | if (s->alpn_client_proto_list != NULL && | ||
| 882 | s->s3->tmp.finish_md_len == 0) { | ||
| 883 | if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) | ||
| 884 | return (NULL); | ||
| 885 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
| 886 | s2n(2 + s->alpn_client_proto_list_len, ret); | ||
| 887 | s2n(s->alpn_client_proto_list_len, ret); | ||
| 888 | memcpy(ret, s->alpn_client_proto_list, | ||
| 889 | s->alpn_client_proto_list_len); | ||
| 890 | ret += s->alpn_client_proto_list_len; | ||
| 891 | } | ||
| 892 | |||
| 881 | #ifndef OPENSSL_NO_SRTP | 893 | #ifndef OPENSSL_NO_SRTP |
| 882 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { | 894 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { |
| 883 | int el; | 895 | int el; |
| @@ -1107,6 +1119,20 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 1107 | } | 1119 | } |
| 1108 | #endif | 1120 | #endif |
| 1109 | 1121 | ||
| 1122 | if (s->s3->alpn_selected != NULL) { | ||
| 1123 | const unsigned char *selected = s->s3->alpn_selected; | ||
| 1124 | unsigned int len = s->s3->alpn_selected_len; | ||
| 1125 | |||
| 1126 | if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) | ||
| 1127 | return (NULL); | ||
| 1128 | s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); | ||
| 1129 | s2n(3 + len, ret); | ||
| 1130 | s2n(1 + len, ret); | ||
| 1131 | *ret++ = len; | ||
| 1132 | memcpy(ret, selected, len); | ||
| 1133 | ret += len; | ||
| 1134 | } | ||
| 1135 | |||
| 1110 | if ((extdatalen = ret - p - 2) == 0) | 1136 | if ((extdatalen = ret - p - 2) == 0) |
| 1111 | return p; | 1137 | return p; |
| 1112 | 1138 | ||
| @@ -1114,6 +1140,76 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 1114 | return ret; | 1140 | return ret; |
| 1115 | } | 1141 | } |
| 1116 | 1142 | ||
| 1143 | /* | ||
| 1144 | * tls1_alpn_handle_client_hello is called to process the ALPN extension in a | ||
| 1145 | * ClientHello. | ||
| 1146 | * data: the contents of the extension, not including the type and length. | ||
| 1147 | * data_len: the number of bytes in data. | ||
| 1148 | * al: a pointer to the alert value to send in the event of a non-zero | ||
| 1149 | * return. | ||
| 1150 | * returns: 1 on success. | ||
| 1151 | */ | ||
| 1152 | static int | ||
| 1153 | tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, | ||
| 1154 | unsigned int data_len, int *al) | ||
| 1155 | { | ||
| 1156 | const unsigned char *selected; | ||
| 1157 | unsigned char selected_len; | ||
| 1158 | unsigned int proto_len; | ||
| 1159 | unsigned int i; | ||
| 1160 | int r; | ||
| 1161 | |||
| 1162 | if (s->ctx->alpn_select_cb == NULL) | ||
| 1163 | return (1); | ||
| 1164 | |||
| 1165 | if (data_len < 2) | ||
| 1166 | goto parse_error; | ||
| 1167 | |||
| 1168 | /* | ||
| 1169 | * data should contain a uint16 length followed by a series of 8-bit, | ||
| 1170 | * length-prefixed strings. | ||
| 1171 | */ | ||
| 1172 | i = ((unsigned int)data[0]) << 8 | ((unsigned int)data[1]); | ||
| 1173 | data_len -= 2; | ||
| 1174 | data += 2; | ||
| 1175 | if (data_len != i) | ||
| 1176 | goto parse_error; | ||
| 1177 | |||
| 1178 | if (data_len < 2) | ||
| 1179 | goto parse_error; | ||
| 1180 | |||
| 1181 | for (i = 0; i < data_len; ) { | ||
| 1182 | proto_len = data[i]; | ||
| 1183 | i++; | ||
| 1184 | |||
| 1185 | if (proto_len == 0) | ||
| 1186 | goto parse_error; | ||
| 1187 | |||
| 1188 | if (i + proto_len < i || i + proto_len > data_len) | ||
| 1189 | goto parse_error; | ||
| 1190 | |||
| 1191 | i += proto_len; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | r = s->ctx->alpn_select_cb(s, &selected, &selected_len, | ||
| 1195 | data, data_len, s->ctx->alpn_select_cb_arg); | ||
| 1196 | if (r == SSL_TLSEXT_ERR_OK) { | ||
| 1197 | free(s->s3->alpn_selected); | ||
| 1198 | if ((s->s3->alpn_selected = malloc(selected_len)) == NULL) { | ||
| 1199 | *al = SSL_AD_INTERNAL_ERROR; | ||
| 1200 | return (-1); | ||
| 1201 | } | ||
| 1202 | memcpy(s->s3->alpn_selected, selected, selected_len); | ||
| 1203 | s->s3->alpn_selected_len = selected_len; | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | return (1); | ||
| 1207 | |||
| 1208 | parse_error: | ||
| 1209 | *al = SSL_AD_DECODE_ERROR; | ||
| 1210 | return (0); | ||
| 1211 | } | ||
| 1212 | |||
| 1117 | /* ssl_check_for_safari attempts to fingerprint Safari using OS X | 1213 | /* ssl_check_for_safari attempts to fingerprint Safari using OS X |
| 1118 | * SecureTransport using the TLS extension block in |d|, of length |n|. | 1214 | * SecureTransport using the TLS extension block in |d|, of length |n|. |
| 1119 | * Safari, since 10.6, sends exactly these extensions, in this order: | 1215 | * Safari, since 10.6, sends exactly these extensions, in this order: |
| @@ -1211,6 +1307,8 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1211 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1307 | #ifndef OPENSSL_NO_NEXTPROTONEG |
| 1212 | s->s3->next_proto_neg_seen = 0; | 1308 | s->s3->next_proto_neg_seen = 0; |
| 1213 | #endif | 1309 | #endif |
| 1310 | free(s->s3->alpn_selected); | ||
| 1311 | s->s3->alpn_selected = NULL; | ||
| 1214 | 1312 | ||
| 1215 | if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) | 1313 | if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) |
| 1216 | ssl_check_for_safari(s, data, d, n); | 1314 | ssl_check_for_safari(s, data, d, n); |
| @@ -1520,7 +1618,8 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1520 | } | 1618 | } |
| 1521 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1619 | #ifndef OPENSSL_NO_NEXTPROTONEG |
| 1522 | else if (type == TLSEXT_TYPE_next_proto_neg && | 1620 | else if (type == TLSEXT_TYPE_next_proto_neg && |
| 1523 | s->s3->tmp.finish_md_len == 0) { | 1621 | s->s3->tmp.finish_md_len == 0 && |
| 1622 | s->s3->alpn_selected == NULL) { | ||
| 1524 | /* We shouldn't accept this extension on a | 1623 | /* We shouldn't accept this extension on a |
| 1525 | * renegotiation. | 1624 | * renegotiation. |
| 1526 | * | 1625 | * |
| @@ -1539,6 +1638,16 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1539 | s->s3->next_proto_neg_seen = 1; | 1638 | s->s3->next_proto_neg_seen = 1; |
| 1540 | } | 1639 | } |
| 1541 | #endif | 1640 | #endif |
| 1641 | else if (type == | ||
| 1642 | TLSEXT_TYPE_application_layer_protocol_negotiation && | ||
| 1643 | s->ctx->alpn_select_cb != NULL && | ||
| 1644 | s->s3->tmp.finish_md_len == 0) { | ||
| 1645 | if (tls1_alpn_handle_client_hello(s, data, | ||
| 1646 | size, al) != 1) | ||
| 1647 | return (0); | ||
| 1648 | /* ALPN takes precedence over NPN. */ | ||
| 1649 | s->s3->next_proto_neg_seen = 0; | ||
| 1650 | } | ||
| 1542 | 1651 | ||
| 1543 | /* session ticket processed earlier */ | 1652 | /* session ticket processed earlier */ |
| 1544 | #ifndef OPENSSL_NO_SRTP | 1653 | #ifndef OPENSSL_NO_SRTP |
| @@ -1601,6 +1710,8 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1601 | #ifndef OPENSSL_NO_NEXTPROTONEG | 1710 | #ifndef OPENSSL_NO_NEXTPROTONEG |
| 1602 | s->s3->next_proto_neg_seen = 0; | 1711 | s->s3->next_proto_neg_seen = 0; |
| 1603 | #endif | 1712 | #endif |
| 1713 | free(s->s3->alpn_selected); | ||
| 1714 | s->s3->alpn_selected = NULL; | ||
| 1604 | 1715 | ||
| 1605 | if (data >= (d + n - 2)) | 1716 | if (data >= (d + n - 2)) |
| 1606 | goto ri_check; | 1717 | goto ri_check; |
| @@ -1716,7 +1827,45 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1716 | s->s3->next_proto_neg_seen = 1; | 1827 | s->s3->next_proto_neg_seen = 1; |
| 1717 | } | 1828 | } |
| 1718 | #endif | 1829 | #endif |
| 1719 | else if (type == TLSEXT_TYPE_renegotiate) { | 1830 | else if (type == |
| 1831 | TLSEXT_TYPE_application_layer_protocol_negotiation) { | ||
| 1832 | unsigned int len; | ||
| 1833 | |||
| 1834 | /* We must have requested it. */ | ||
| 1835 | if (s->alpn_client_proto_list == NULL) { | ||
| 1836 | *al = TLS1_AD_UNSUPPORTED_EXTENSION; | ||
| 1837 | return 0; | ||
| 1838 | } | ||
| 1839 | if (size < 4) { | ||
| 1840 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1841 | return (0); | ||
| 1842 | } | ||
| 1843 | |||
| 1844 | /* The extension data consists of: | ||
| 1845 | * uint16 list_length | ||
| 1846 | * uint8 proto_length; | ||
| 1847 | * uint8 proto[proto_length]; */ | ||
| 1848 | len = ((unsigned int)data[0]) << 8 | | ||
| 1849 | ((unsigned int)data[1]); | ||
| 1850 | if (len != (unsigned int)size - 2) { | ||
| 1851 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1852 | return (0); | ||
| 1853 | } | ||
| 1854 | len = data[2]; | ||
| 1855 | if (len != (unsigned int)size - 3) { | ||
| 1856 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1857 | return (0); | ||
| 1858 | } | ||
| 1859 | free(s->s3->alpn_selected); | ||
| 1860 | s->s3->alpn_selected = malloc(len); | ||
| 1861 | if (s->s3->alpn_selected == NULL) { | ||
| 1862 | *al = TLS1_AD_INTERNAL_ERROR; | ||
| 1863 | return (0); | ||
| 1864 | } | ||
| 1865 | memcpy(s->s3->alpn_selected, data + 3, len); | ||
| 1866 | s->s3->alpn_selected_len = len; | ||
| 1867 | |||
| 1868 | } else if (type == TLSEXT_TYPE_renegotiate) { | ||
| 1720 | if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) | 1869 | if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) |
| 1721 | return 0; | 1870 | return 0; |
| 1722 | renegotiate_seen = 1; | 1871 | renegotiate_seen = 1; |
