aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-15 02:17:03 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-15 02:17:03 +0100
commitc5540d61f6b411967fc3e30f1eb1e8af5077c2e5 (patch)
treea3f99e304812d378a5ab4671773b58a33a505442 /networking/tls.c
parentf78ad0938b76112aed0317d2e7d1ecbf469c3731 (diff)
downloadbusybox-w32-c5540d61f6b411967fc3e30f1eb1e8af5077c2e5.tar.gz
busybox-w32-c5540d61f6b411967fc3e30f1eb1e8af5077c2e5.tar.bz2
busybox-w32-c5540d61f6b411967fc3e30f1eb1e8af5077c2e5.zip
tls: send CHANGE_CIPHER_SPEC
To "actually implement it" will take more work... Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c82
1 files changed, 45 insertions, 37 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 79afe58b0..71e5ac3a5 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -269,6 +269,23 @@ static int xread_tls_block(tls_state_t *tls)
269 return target; 269 return target;
270} 270}
271 271
272static int xread_tls_handshake_block(tls_state_t *tls, int min_len)
273{
274 struct record_hdr *xhdr;
275 int len = xread_tls_block(tls);
276
277 xhdr = (void*)tls->inbuf;
278 if (len < min_len
279 || xhdr->type != RECORD_TYPE_HANDSHAKE
280 || xhdr->proto_maj != TLS_MAJ
281 || xhdr->proto_min != TLS_MIN
282 ) {
283 tls_error_die(tls);
284 }
285 dbg("got HANDSHAKE\n");
286 return len;
287}
288
272static void send_client_hello(tls_state_t *tls) 289static void send_client_hello(tls_state_t *tls)
273{ 290{
274 struct client_hello { 291 struct client_hello {
@@ -296,8 +313,8 @@ static void send_client_hello(tls_state_t *tls)
296 //hello.len24_hi = 0; 313 //hello.len24_hi = 0;
297 //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8; 314 //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8;
298 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4); 315 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4);
299 hello.proto_maj = TLS_MAJ; 316 hello.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */
300 hello.proto_min = TLS_MIN; 317 hello.proto_min = TLS_MIN; /* can be higher than one in record headers */
301 tls_get_random(hello.rand32, sizeof(hello.rand32)); 318 tls_get_random(hello.rand32, sizeof(hello.rand32));
302 //hello.session_id_len = 0; 319 //hello.session_id_len = 0;
303 //hello.cipherid_len16_hi = 0; 320 //hello.cipherid_len16_hi = 0;
@@ -325,20 +342,10 @@ static void get_server_hello_or_die(tls_state_t *tls)
325 /* extensions may follow, but only those which client offered in its Hello */ 342 /* extensions may follow, but only those which client offered in its Hello */
326 }; 343 };
327 struct server_hello *hp; 344 struct server_hello *hp;
328 int len;
329 345
330 len = xread_tls_block(tls); 346 xread_tls_handshake_block(tls, 74);
331 347
332 hp = (void*)tls->inbuf; 348 hp = (void*)tls->inbuf;
333 if (len != 74 /* TODO: if we accept extensions, should be < instead of != */
334 || hp->xhdr.type != RECORD_TYPE_HANDSHAKE
335 || hp->xhdr.proto_maj != TLS_MAJ
336 || hp->xhdr.proto_min != TLS_MIN
337 ) {
338 /* example: RECORD_TYPE_ALERT if server can't support our ciphers */
339 tls_error_die(tls);
340 }
341 dbg("got HANDSHAKE\n");
342 // 74 bytes: 349 // 74 bytes:
343 // 02 000046 03|03 58|78|cf|c1 50|a5|49|ee|7e|29|48|71|fe|97|fa|e8|2d|19|87|72|90|84|9d|37|a3|f0|cb|6f|5f|e3|3c|2f |20 |d8|1a|78|96|52|d6|91|01|24|b3|d6|5b|b7|d0|6c|b3|e1|78|4e|3c|95|de|74|a0|ba|eb|a7|3a|ff|bd|a2|bf |00|9c |00| 350 // 02 000046 03|03 58|78|cf|c1 50|a5|49|ee|7e|29|48|71|fe|97|fa|e8|2d|19|87|72|90|84|9d|37|a3|f0|cb|6f|5f|e3|3c|2f |20 |d8|1a|78|96|52|d6|91|01|24|b3|d6|5b|b7|d0|6c|b3|e1|78|4e|3c|95|de|74|a0|ba|eb|a7|3a|ff|bd|a2|bf |00|9c |00|
344 //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel 351 //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel
@@ -572,16 +579,9 @@ static void get_server_cert_or_die(tls_state_t *tls)
572 uint8_t *certbuf; 579 uint8_t *certbuf;
573 int len, len1; 580 int len, len1;
574 581
575 len = xread_tls_block(tls); 582 len = xread_tls_handshake_block(tls, 10);
583
576 xhdr = (void*)tls->inbuf; 584 xhdr = (void*)tls->inbuf;
577 if (len < sizeof(*xhdr) + 10
578 || xhdr->type != RECORD_TYPE_HANDSHAKE
579 || xhdr->proto_maj != TLS_MAJ
580 || xhdr->proto_min != TLS_MIN
581 ) {
582 tls_error_die(tls);
583 }
584 dbg("got HANDSHAKE\n");
585 certbuf = (void*)(xhdr + 1); 585 certbuf = (void*)(xhdr + 1);
586 if (certbuf[0] != HANDSHAKE_CERTIFICATE) 586 if (certbuf[0] != HANDSHAKE_CERTIFICATE)
587 tls_error_die(tls); 587 tls_error_die(tls);
@@ -703,6 +703,15 @@ static void send_client_key_exchange(tls_state_t *tls)
703 xwrite(tls->fd, &record, sizeof(record)); 703 xwrite(tls->fd, &record, sizeof(record));
704} 704}
705 705
706static void send_change_cipher_spec(tls_state_t *tls)
707{
708 static const uint8_t rec[] = {
709 RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01,
710 01
711 };
712 xwrite(tls->fd, rec, sizeof(rec));
713}
714
706static void tls_handshake(tls_state_t *tls) 715static void tls_handshake(tls_state_t *tls)
707{ 716{
708 // Client RFC 5246 Server 717 // Client RFC 5246 Server
@@ -754,29 +763,28 @@ static void tls_handshake(tls_state_t *tls)
754 // (for example, kernel.org does not even accept DH_anon cipher id) 763 // (for example, kernel.org does not even accept DH_anon cipher id)
755 get_server_cert_or_die(tls); 764 get_server_cert_or_die(tls);
756 765
757 len = xread_tls_block(tls); 766 len = xread_tls_handshake_block(tls, 4);
758 /* Next handshake type is not predetermined */ 767 if (tls->inbuf[5] == HANDSHAKE_SERVER_KEY_EXCHANGE) {
759 switch (tls->inbuf[5]) {
760 case HANDSHAKE_SERVER_KEY_EXCHANGE:
761 // 459 bytes: 768 // 459 bytes:
762 // 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... 769 // 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...
763 //SvKey len=455^ 770 //SvKey len=455^
764 // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes: 771 // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes:
765 // 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... 772 // 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...
766 dbg("got SERVER_KEY_EXCHANGE\n"); 773 dbg("got SERVER_KEY_EXCHANGE len:%u\n", len);
767 len = xread_tls_block(tls); 774//need to save it
768 break; 775 xread_tls_handshake_block(tls, 4);
769 case HANDSHAKE_CERTIFICATE_REQUEST: 776 }
770 dbg("got CERTIFICATE_REQUEST\n"); 777// if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) {
771 len = xread_tls_block(tls); 778// dbg("got CERTIFICATE_REQUEST\n");
772 break; 779// xread_tls_handshake_block(tls, 4);
773 case HANDSHAKE_SERVER_HELLO_DONE: 780// }
781 if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) {
774 // 0e 000000 (len:0) 782 // 0e 000000 (len:0)
775 dbg("got SERVER_HELLO_DONE\n"); 783 dbg("got SERVER_HELLO_DONE\n");
776 send_client_key_exchange(tls); 784 send_client_key_exchange(tls);
777 len = xread_tls_block(tls); 785 send_change_cipher_spec(tls);
778 break; 786//we now should be able to send encrypted... as soon as we grok AES.
779 default: 787 } else {
780 tls_error_die(tls); 788 tls_error_die(tls);
781 } 789 }
782} 790}