diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-15 02:17:03 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-15 02:17:03 +0100 |
commit | c5540d61f6b411967fc3e30f1eb1e8af5077c2e5 (patch) | |
tree | a3f99e304812d378a5ab4671773b58a33a505442 /networking/tls.c | |
parent | f78ad0938b76112aed0317d2e7d1ecbf469c3731 (diff) | |
download | busybox-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.c | 82 |
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 | ||
272 | static 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 | |||
272 | static void send_client_hello(tls_state_t *tls) | 289 | static 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 | ||
706 | static 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 | |||
706 | static void tls_handshake(tls_state_t *tls) | 715 | static 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 | } |