aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-20 22:48:41 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-20 22:48:41 +0100
commitdd2577f21a55e5a4d039590f76efa3f7faa3a135 (patch)
tree86425e9d25a609cafd591821b5f723bd990c31ef /networking/tls.c
parent0af5265180877f4e8fbf8f1d9f2999b3fd2205d3 (diff)
downloadbusybox-w32-dd2577f21a55e5a4d039590f76efa3f7faa3a135.tar.gz
busybox-w32-dd2577f21a55e5a4d039590f76efa3f7faa3a135.tar.bz2
busybox-w32-dd2577f21a55e5a4d039590f76efa3f7faa3a135.zip
tls: send SNI in the client hello
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c71
1 files changed, 52 insertions, 19 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 80e3bc662..8fa532947 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -228,6 +228,8 @@ struct record_hdr {
228typedef struct tls_state { 228typedef struct tls_state {
229 int fd; 229 int fd;
230 230
231//TODO: store just the DER key here, parse/use/delete it when sending client key
232//this way it will stay key type agnostic here.
231 psRsaKey_t server_rsa_pub_key; 233 psRsaKey_t server_rsa_pub_key;
232 234
233 sha256_ctx_t handshake_sha256_ctx; 235 sha256_ctx_t handshake_sha256_ctx;
@@ -1066,7 +1068,7 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
1066/* 1068/*
1067 * TLS Handshake routines 1069 * TLS Handshake routines
1068 */ 1070 */
1069static int xread_tls_handshake_block(tls_state_t *tls, int min_len) 1071static int tls_xread_handshake_block(tls_state_t *tls, int min_len)
1070{ 1072{
1071 struct record_hdr *xhdr; 1073 struct record_hdr *xhdr;
1072 int len = tls_xread_record(tls); 1074 int len = tls_xread_record(tls);
@@ -1098,7 +1100,7 @@ static ALWAYS_INLINE void fill_handshake_record_hdr(void *buf, unsigned type, un
1098} 1100}
1099 1101
1100//TODO: implement RFC 5746 (Renegotiation Indication Extension) - some servers will refuse to work with us otherwise 1102//TODO: implement RFC 5746 (Renegotiation Indication Extension) - some servers will refuse to work with us otherwise
1101static void send_client_hello(tls_state_t *tls) 1103static void send_client_hello(tls_state_t *tls, const char *sni)
1102{ 1104{
1103 struct client_hello { 1105 struct client_hello {
1104 uint8_t type; 1106 uint8_t type;
@@ -1111,28 +1113,58 @@ static void send_client_hello(tls_state_t *tls)
1111 uint8_t cipherid[2 * 1]; /* actually variable */ 1113 uint8_t cipherid[2 * 1]; /* actually variable */
1112 uint8_t comprtypes_len; 1114 uint8_t comprtypes_len;
1113 uint8_t comprtypes[1]; /* actually variable */ 1115 uint8_t comprtypes[1]; /* actually variable */
1116 /* Extensions (SNI shown):
1117 * hi,lo // len of all extensions
1118 * 0x00,0x00 // extension_type: "Server Name"
1119 * 0x00,0x0e // list len (there can be more than one SNI)
1120 * 0x00,0x0c // len of 1st Server Name Indication
1121 * 0x00 // name type: host_name
1122 * 0x00,0x09 // name len
1123 * "localhost" // name
1124 */
1114 }; 1125 };
1115 struct client_hello *record = tls_get_outbuf(tls, sizeof(*record)); 1126 struct client_hello *record;
1116 1127 int len;
1117 fill_handshake_record_hdr(record, HANDSHAKE_CLIENT_HELLO, sizeof(*record)); 1128 int sni_len = sni ? strnlen(sni, 127) : 0;
1129
1130 len = sizeof(*record);
1131 if (sni_len)
1132 len += 11 + strlen(sni);
1133 record = tls_get_outbuf(tls, len);
1134 memset(record, 0, len);
1135 fill_handshake_record_hdr(record, HANDSHAKE_CLIENT_HELLO, len);
1118 record->proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ 1136 record->proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */
1119 record->proto_min = TLS_MIN; /* can be higher than one in record headers */ 1137 record->proto_min = TLS_MIN; /* can be higher than one in record headers */
1120 tls_get_random(record->rand32, sizeof(record->rand32)); 1138 tls_get_random(record->rand32, sizeof(record->rand32));
1121 if (TLS_DEBUG_FIXED_SECRETS) 1139 if (TLS_DEBUG_FIXED_SECRETS)
1122 memset(record->rand32, 0x11, sizeof(record->rand32)); 1140 memset(record->rand32, 0x11, sizeof(record->rand32));
1123 memcpy(tls->client_and_server_rand32, record->rand32, sizeof(record->rand32)); 1141 memcpy(tls->client_and_server_rand32, record->rand32, sizeof(record->rand32));
1124 record->session_id_len = 0; 1142 /* record->session_id_len = 0; - already is */
1125 record->cipherid_len16_hi = 0; 1143 /* record->cipherid_len16_hi = 0; */
1126 record->cipherid_len16_lo = 2 * 1; 1144 record->cipherid_len16_lo = 2 * 1;
1127 record->cipherid[0] = CIPHER_ID >> 8; 1145 record->cipherid[0] = CIPHER_ID >> 8;
1128 record->cipherid[1] = CIPHER_ID & 0xff; 1146 record->cipherid[1] = CIPHER_ID & 0xff;
1129 record->comprtypes_len = 1; 1147 record->comprtypes_len = 1;
1130 record->comprtypes[0] = 0; 1148 /* record->comprtypes[0] = 0; */
1131 1149
1132//TODO: send options, at least SNI. 1150 if (sni_len) {
1151 uint8_t *p = (void*)(record + 1);
1152 //p[0] = 0; //
1153 p[1] = sni_len + 9; //ext_len
1154 //p[2] = 0; //
1155 //p[3] = 0; //extension_type
1156 //p[4] = 0; //
1157 p[5] = sni_len + 5; //list len
1158 //p[6] = 0; //
1159 p[7] = sni_len + 3; //len of 1st SNI
1160 //p[8] = 0; //name type
1161 //p[9] = 0; //
1162 p[10] = sni_len; //name len
1163 memcpy(&p[11], sni, sni_len);
1164 }
1133 1165
1134 dbg(">> CLIENT_HELLO\n"); 1166 dbg(">> CLIENT_HELLO\n");
1135 xwrite_and_update_handshake_hash(tls, sizeof(*record)); 1167 xwrite_and_update_handshake_hash(tls, len);
1136} 1168}
1137 1169
1138static void get_server_hello(tls_state_t *tls) 1170static void get_server_hello(tls_state_t *tls)
@@ -1149,10 +1181,11 @@ static void get_server_hello(tls_state_t *tls)
1149 uint8_t comprtype; 1181 uint8_t comprtype;
1150 /* extensions may follow, but only those which client offered in its Hello */ 1182 /* extensions may follow, but only those which client offered in its Hello */
1151 }; 1183 };
1184
1152 struct server_hello *hp; 1185 struct server_hello *hp;
1153 uint8_t *cipherid; 1186 uint8_t *cipherid;
1154 1187
1155 xread_tls_handshake_block(tls, 74); 1188 tls_xread_handshake_block(tls, 74);
1156 1189
1157 hp = (void*)tls->inbuf; 1190 hp = (void*)tls->inbuf;
1158 // 74 bytes: 1191 // 74 bytes:
@@ -1199,7 +1232,7 @@ static void get_server_cert(tls_state_t *tls)
1199 uint8_t *certbuf; 1232 uint8_t *certbuf;
1200 int len, len1; 1233 int len, len1;
1201 1234
1202 len = xread_tls_handshake_block(tls, 10); 1235 len = tls_xread_handshake_block(tls, 10);
1203 1236
1204 xhdr = (void*)tls->inbuf; 1237 xhdr = (void*)tls->inbuf;
1205 certbuf = (void*)(xhdr + 1); 1238 certbuf = (void*)(xhdr + 1);
@@ -1416,7 +1449,7 @@ static void send_client_finished(tls_state_t *tls)
1416 xwrite_encrypted(tls, sizeof(*record), RECORD_TYPE_HANDSHAKE); 1449 xwrite_encrypted(tls, sizeof(*record), RECORD_TYPE_HANDSHAKE);
1417} 1450}
1418 1451
1419static void tls_handshake(tls_state_t *tls) 1452static void tls_handshake(tls_state_t *tls, const char *sni)
1420{ 1453{
1421 // Client RFC 5246 Server 1454 // Client RFC 5246 Server
1422 // (*) - optional messages, not always sent 1455 // (*) - optional messages, not always sent
@@ -1437,7 +1470,7 @@ static void tls_handshake(tls_state_t *tls)
1437 // Application Data <------> Application Data 1470 // Application Data <------> Application Data
1438 int len; 1471 int len;
1439 1472
1440 send_client_hello(tls); 1473 send_client_hello(tls, sni);
1441 get_server_hello(tls); 1474 get_server_hello(tls);
1442 1475
1443 // RFC 5246 1476 // RFC 5246
@@ -1451,7 +1484,7 @@ static void tls_handshake(tls_state_t *tls)
1451 // (for example, kernel.org does not even accept DH_anon cipher id) 1484 // (for example, kernel.org does not even accept DH_anon cipher id)
1452 get_server_cert(tls); 1485 get_server_cert(tls);
1453 1486
1454 len = xread_tls_handshake_block(tls, 4); 1487 len = tls_xread_handshake_block(tls, 4);
1455 if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_SERVER_KEY_EXCHANGE) { 1488 if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_SERVER_KEY_EXCHANGE) {
1456 // 459 bytes: 1489 // 459 bytes:
1457 // 0c 00|01|c7 03|00|17|41|04|87|94|2e|2f|68|d0|c9|f4|97|a8|2d|ef|ed|67|ea|c6|f3|b3|56|47|5d|27|b6|bd|ee|70|25|30|5e|b0|8e|f6|21|5a... 1490 // 0c 00|01|c7 03|00|17|41|04|87|94|2e|2f|68|d0|c9|f4|97|a8|2d|ef|ed|67|ea|c6|f3|b3|56|47|5d|27|b6|bd|ee|70|25|30|5e|b0|8e|f6|21|5a...
@@ -1460,7 +1493,7 @@ static void tls_handshake(tls_state_t *tls)
1460 // 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75... 1493 // 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75...
1461 dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len); 1494 dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len);
1462//probably need to save it 1495//probably need to save it
1463 xread_tls_handshake_block(tls, 4); 1496 tls_xread_handshake_block(tls, 4);
1464 } 1497 }
1465 1498
1466// if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) { 1499// if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) {
@@ -1472,7 +1505,7 @@ static void tls_handshake(tls_state_t *tls)
1472// Client certificates are sent using the Certificate structure 1505// Client certificates are sent using the Certificate structure
1473// defined in Section 7.4.2." 1506// defined in Section 7.4.2."
1474// (i.e. the same format as server certs) 1507// (i.e. the same format as server certs)
1475// xread_tls_handshake_block(tls, 4); 1508// tls_xread_handshake_block(tls, 4);
1476// } 1509// }
1477 1510
1478 if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE) 1511 if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE)
@@ -1546,7 +1579,7 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1546 1579
1547 tls = new_tls_state(); 1580 tls = new_tls_state();
1548 tls->fd = cfd; 1581 tls->fd = cfd;
1549 tls_handshake(tls); 1582 tls_handshake(tls, argv[1]);
1550 1583
1551 /* Select loop copying stdin to cfd, and cfd to stdout */ 1584 /* Select loop copying stdin to cfd, and cfd to stdout */
1552 FD_ZERO(&readfds); 1585 FD_ZERO(&readfds);