summaryrefslogtreecommitdiff
path: root/src/lib/libssl/t1_lib.c
diff options
context:
space:
mode:
authorjsing <>2017-07-16 18:14:37 +0000
committerjsing <>2017-07-16 18:14:37 +0000
commit231770c97badca4c3da92986469ccbd7bf13471d (patch)
treed9fc4f0686256f704a616fd78164deb16cbfba14 /src/lib/libssl/t1_lib.c
parent78c8f5de9ccfc2a6133cb7cb00d67a257d2d4f46 (diff)
downloadopenbsd-231770c97badca4c3da92986469ccbd7bf13471d.tar.gz
openbsd-231770c97badca4c3da92986469ccbd7bf13471d.tar.bz2
openbsd-231770c97badca4c3da92986469ccbd7bf13471d.zip
Start rewriting TLS extension handling.
Introduce a TLS extension handling framework that has per-extension type functions to determine if an extension is needed, to build the extension data and parse the extension data. This is somewhat analogous to BoringSSL, however these build and parse functions are intentionally symetrical. The framework is hooked into the existing TLS handling code in such a way that we can gradual convert the extension handling code. Convert the TLS Server Name Indication extension to the new framework, while rewriting it to use CBB/CBS and be more strict in the process. Discussed with beck@ ok inoguchi@
Diffstat (limited to '')
-rw-r--r--src/lib/libssl/t1_lib.c173
1 files changed, 34 insertions, 139 deletions
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index eb2314ac26..e3046fec09 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.117 2017/05/07 04:22:24 beck Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.118 2017/07/16 18:14:37 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 *
@@ -117,7 +117,9 @@
117#include <openssl/ocsp.h> 117#include <openssl/ocsp.h>
118 118
119#include "ssl_locl.h" 119#include "ssl_locl.h"
120
120#include "bytestring.h" 121#include "bytestring.h"
122#include "ssl_tlsext.h"
121 123
122static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, 124static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
123 const unsigned char *sess_id, int sesslen, 125 const unsigned char *sess_id, int sesslen,
@@ -678,6 +680,8 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
678 int extdatalen = 0; 680 int extdatalen = 0;
679 unsigned char *ret = p; 681 unsigned char *ret = p;
680 int using_ecc = 0; 682 int using_ecc = 0;
683 size_t len;
684 CBB cbb;
681 685
682 /* See if we support any ECC ciphersuites. */ 686 /* See if we support any ECC ciphersuites. */
683 if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) { 687 if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) {
@@ -699,43 +703,21 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
699 } 703 }
700 704
701 ret += 2; 705 ret += 2;
702
703 if (ret >= limit) 706 if (ret >= limit)
704 return NULL; /* this really never occurs, but ... */ 707 return NULL; /* this really never occurs, but ... */
705 708
706 if (s->tlsext_hostname != NULL) { 709 CBB_init_fixed(&cbb, ret, limit - ret);
707 /* Add TLS extension servername to the Client Hello message */ 710 if (!tlsext_clienthello_build(s, &cbb)) {
708 size_t size_str, lenmax; 711 CBB_cleanup(&cbb);
709 712 return NULL;
710 /* check for enough space. 713 }
711 4 for the servername type and extension length 714 if (!CBB_finish(&cbb, NULL, &len)) {
712 2 for servernamelist length 715 CBB_cleanup(&cbb);
713 1 for the hostname type 716 return NULL;
714 2 for hostname length
715 + hostname length
716 */
717
718 if ((size_t)(limit - ret) < 9)
719 return NULL;
720
721 lenmax = limit - ret - 9;
722 if ((size_str = strlen(s->tlsext_hostname)) > lenmax)
723 return NULL;
724
725 /* extension type and length */
726 s2n(TLSEXT_TYPE_server_name, ret);
727
728 s2n(size_str + 5, ret);
729
730 /* length of servername list */
731 s2n(size_str + 3, ret);
732
733 /* hostname type, length and hostname */
734 *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
735 s2n(size_str, ret);
736 memcpy(ret, s->tlsext_hostname, size_str);
737 ret += size_str;
738 } 717 }
718 if (len > (limit - ret))
719 return NULL;
720 ret += len;
739 721
740 /* Add RI if renegotiating */ 722 /* Add RI if renegotiating */
741 if (s->internal->renegotiate) { 723 if (s->internal->renegotiate) {
@@ -997,6 +979,8 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
997 unsigned long alg_a, alg_k; 979 unsigned long alg_a, alg_k;
998 unsigned char *ret = p; 980 unsigned char *ret = p;
999 int next_proto_neg_seen; 981 int next_proto_neg_seen;
982 size_t len;
983 CBB cbb;
1000 984
1001 alg_a = S3I(s)->hs.new_cipher->algorithm_auth; 985 alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
1002 alg_k = S3I(s)->hs.new_cipher->algorithm_mkey; 986 alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
@@ -1007,14 +991,18 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
1007 if (ret >= limit) 991 if (ret >= limit)
1008 return NULL; /* this really never occurs, but ... */ 992 return NULL; /* this really never occurs, but ... */
1009 993
1010 if (!s->internal->hit && s->internal->servername_done == 1 && 994 CBB_init_fixed(&cbb, ret, limit - ret);
1011 s->session->tlsext_hostname != NULL) { 995 if (!tlsext_serverhello_build(s, &cbb)) {
1012 if ((size_t)(limit - ret) < 4) 996 CBB_cleanup(&cbb);
1013 return NULL; 997 return NULL;
1014
1015 s2n(TLSEXT_TYPE_server_name, ret);
1016 s2n(0, ret);
1017 } 998 }
999 if (!CBB_finish(&cbb, NULL, &len)) {
1000 CBB_cleanup(&cbb);
1001 return NULL;
1002 }
1003 if (len > (limit - ret))
1004 return NULL;
1005 ret += len;
1018 1006
1019 if (S3I(s)->send_connection_binding) { 1007 if (S3I(s)->send_connection_binding) {
1020 int el; 1008 int el;
@@ -1241,6 +1229,7 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1241 unsigned char *end = d + n; 1229 unsigned char *end = d + n;
1242 int renegotiate_seen = 0; 1230 int renegotiate_seen = 0;
1243 int sigalg_seen = 0; 1231 int sigalg_seen = 0;
1232 CBS cbs;
1244 1233
1245 s->internal->servername_done = 0; 1234 s->internal->servername_done = 0;
1246 s->tlsext_status_type = -1; 1235 s->tlsext_status_type = -1;
@@ -1269,106 +1258,12 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1269 if (s->internal->tlsext_debug_cb) 1258 if (s->internal->tlsext_debug_cb)
1270 s->internal->tlsext_debug_cb(s, 0, type, data, size, 1259 s->internal->tlsext_debug_cb(s, 0, type, data, size,
1271 s->internal->tlsext_debug_arg); 1260 s->internal->tlsext_debug_arg);
1272/* The servername extension is treated as follows:
1273
1274 - Only the hostname type is supported with a maximum length of 255.
1275 - The servername is rejected if too long or if it contains zeros,
1276 in which case an fatal alert is generated.
1277 - The servername field is maintained together with the session cache.
1278 - When a session is resumed, the servername call back invoked in order
1279 to allow the application to position itself to the right context.
1280 - The servername is acknowledged if it is new for a session or when
1281 it is identical to a previously used for the same session.
1282 Applications can control the behaviour. They can at any time
1283 set a 'desirable' servername for a new SSL object. This can be the
1284 case for example with HTTPS when a Host: header field is received and
1285 a renegotiation is requested. In this case, a possible servername
1286 presented in the new client hello is only acknowledged if it matches
1287 the value of the Host: field.
1288 - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
1289 if they provide for changing an explicit servername context for the session,
1290 i.e. when the session has been established with a servername extension.
1291 - On session reconnect, the servername extension may be absent.
1292
1293*/
1294
1295 if (type == TLSEXT_TYPE_server_name) {
1296 unsigned char *sdata;
1297 int servname_type;
1298 int dsize;
1299 1261
1300 if (size < 2) { 1262 CBS_init(&cbs, data, size);
1301 *al = SSL_AD_DECODE_ERROR; 1263 if (!tlsext_clienthello_parse_one(s, &cbs, type, al))
1302 return 0; 1264 return 0;
1303 }
1304 n2s(data, dsize);
1305
1306 size -= 2;
1307 if (dsize > size) {
1308 *al = SSL_AD_DECODE_ERROR;
1309 return 0;
1310 }
1311
1312 sdata = data;
1313 while (dsize > 3) {
1314 servname_type = *(sdata++);
1315
1316 n2s(sdata, len);
1317 dsize -= 3;
1318
1319 if (len > dsize) {
1320 *al = SSL_AD_DECODE_ERROR;
1321 return 0;
1322 }
1323 if (s->internal->servername_done == 0)
1324 switch (servname_type) {
1325 case TLSEXT_NAMETYPE_host_name:
1326 if (!s->internal->hit) {
1327 if (s->session->tlsext_hostname) {
1328 *al = SSL_AD_DECODE_ERROR;
1329 return 0;
1330 }
1331 if (len > TLSEXT_MAXLEN_host_name) {
1332 *al = TLS1_AD_UNRECOGNIZED_NAME;
1333 return 0;
1334 }
1335 if ((s->session->tlsext_hostname =
1336 malloc(len + 1)) == NULL) {
1337 *al = TLS1_AD_INTERNAL_ERROR;
1338 return 0;
1339 }
1340 memcpy(s->session->tlsext_hostname, sdata, len);
1341 s->session->tlsext_hostname[len] = '\0';
1342 if (strlen(s->session->tlsext_hostname) != len) {
1343 free(s->session->tlsext_hostname);
1344 s->session->tlsext_hostname = NULL;
1345 *al = TLS1_AD_UNRECOGNIZED_NAME;
1346 return 0;
1347 }
1348 s->internal->servername_done = 1;
1349
1350
1351 } else {
1352 s->internal->servername_done = s->session->tlsext_hostname &&
1353 strlen(s->session->tlsext_hostname) == len &&
1354 strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
1355 }
1356 break;
1357
1358 default:
1359 break;
1360 }
1361
1362 dsize -= len;
1363 }
1364 if (dsize != 0) {
1365 *al = SSL_AD_DECODE_ERROR;
1366 return 0;
1367 }
1368
1369 }
1370 1265
1371 else if (type == TLSEXT_TYPE_ec_point_formats && 1266 if (type == TLSEXT_TYPE_ec_point_formats &&
1372 s->version != DTLS1_VERSION) { 1267 s->version != DTLS1_VERSION) {
1373 unsigned char *sdata = data; 1268 unsigned char *sdata = data;
1374 size_t formatslen; 1269 size_t formatslen;