diff options
Diffstat (limited to 'src/lib/libssl/t1_lib.c')
-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; |