aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-15 14:16:51 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-15 14:16:51 +0100
commit3f8ecd933a610c6f3b5d02e184c7faf205ad95d3 (patch)
treeae7a778a4a8dbbfc255b9a9f527179bfa9cc865c /networking/tls.c
parentc5540d61f6b411967fc3e30f1eb1e8af5077c2e5 (diff)
downloadbusybox-w32-3f8ecd933a610c6f3b5d02e184c7faf205ad95d3.tar.gz
busybox-w32-3f8ecd933a610c6f3b5d02e184c7faf205ad95d3.tar.bz2
busybox-w32-3f8ecd933a610c6f3b5d02e184c7faf205ad95d3.zip
tls: rearrange code, add/improve comments, fix whitespace, no real changes here
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c362
1 files changed, 202 insertions, 160 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 71e5ac3a5..44c9da195 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -286,85 +286,6 @@ static int xread_tls_handshake_block(tls_state_t *tls, int min_len)
286 return len; 286 return len;
287} 287}
288 288
289static void send_client_hello(tls_state_t *tls)
290{
291 struct client_hello {
292 struct record_hdr xhdr;
293 uint8_t type;
294 uint8_t len24_hi, len24_mid, len24_lo;
295 uint8_t proto_maj, proto_min;
296 uint8_t rand32[32];
297 uint8_t session_id_len;
298 /* uint8_t session_id[]; */
299 uint8_t cipherid_len16_hi, cipherid_len16_lo;
300 uint8_t cipherid[2 * 1]; /* actually variable */
301 uint8_t comprtypes_len;
302 uint8_t comprtypes[1]; /* actually variable */
303 };
304 struct client_hello hello;
305
306 memset(&hello, 0, sizeof(hello));
307 hello.xhdr.type = RECORD_TYPE_HANDSHAKE;
308 hello.xhdr.proto_maj = TLS_MAJ;
309 hello.xhdr.proto_min = TLS_MIN;
310 //zero: hello.xhdr.len16_hi = (sizeof(hello) - sizeof(hello.xhdr)) >> 8;
311 hello.xhdr.len16_lo = (sizeof(hello) - sizeof(hello.xhdr));
312 hello.type = HANDSHAKE_CLIENT_HELLO;
313 //hello.len24_hi = 0;
314 //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8;
315 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4);
316 hello.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */
317 hello.proto_min = TLS_MIN; /* can be higher than one in record headers */
318 tls_get_random(hello.rand32, sizeof(hello.rand32));
319 //hello.session_id_len = 0;
320 //hello.cipherid_len16_hi = 0;
321 hello.cipherid_len16_lo = 2 * 1;
322 hello.cipherid[0] = CIPHER_ID >> 8;
323 hello.cipherid[1] = CIPHER_ID & 0xff;
324 hello.comprtypes_len = 1;
325 //hello.comprtypes[0] = 0;
326
327 xwrite(tls->fd, &hello, sizeof(hello));
328}
329
330static void get_server_hello_or_die(tls_state_t *tls)
331{
332 struct server_hello {
333 struct record_hdr xhdr;
334 uint8_t type;
335 uint8_t len24_hi, len24_mid, len24_lo;
336 uint8_t proto_maj, proto_min;
337 uint8_t rand32[32]; /* first 4 bytes are unix time in BE format */
338 uint8_t session_id_len;
339 uint8_t session_id[32];
340 uint8_t cipherid_hi, cipherid_lo;
341 uint8_t comprtype;
342 /* extensions may follow, but only those which client offered in its Hello */
343 };
344 struct server_hello *hp;
345
346 xread_tls_handshake_block(tls, 74);
347
348 hp = (void*)tls->inbuf;
349 // 74 bytes:
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|
351 //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel
352 if (hp->type != HANDSHAKE_SERVER_HELLO
353 || hp->len24_hi != 0
354 || hp->len24_mid != 0
355 || hp->len24_lo != 70
356 || hp->proto_maj != TLS_MAJ
357 || hp->proto_min != TLS_MIN
358 || hp->session_id_len != 32
359 || hp->cipherid_hi != (CIPHER_ID >> 8)
360 || hp->cipherid_lo != (CIPHER_ID & 0xff)
361 || hp->comprtype != 0
362 ) {
363 tls_error_die(tls);
364 }
365 dbg("got SERVER_HELLO\n");
366}
367
368static unsigned get_der_len(uint8_t **bodyp, uint8_t *der, uint8_t *end) 289static unsigned get_der_len(uint8_t **bodyp, uint8_t *der, uint8_t *end)
369{ 290{
370 unsigned len, len1; 291 unsigned len, len1;
@@ -573,7 +494,104 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
573 dbg("server_rsa_pub_key.size:%d\n", tls->server_rsa_pub_key.size); 494 dbg("server_rsa_pub_key.size:%d\n", tls->server_rsa_pub_key.size);
574} 495}
575 496
576static void get_server_cert_or_die(tls_state_t *tls) 497/*
498 * TLS Handshake routines
499 */
500static void send_client_hello(tls_state_t *tls)
501{
502 struct client_hello {
503 struct record_hdr xhdr;
504 uint8_t type;
505 uint8_t len24_hi, len24_mid, len24_lo;
506 uint8_t proto_maj, proto_min;
507 uint8_t rand32[32];
508 uint8_t session_id_len;
509 /* uint8_t session_id[]; */
510 uint8_t cipherid_len16_hi, cipherid_len16_lo;
511 uint8_t cipherid[2 * 1]; /* actually variable */
512 uint8_t comprtypes_len;
513 uint8_t comprtypes[1]; /* actually variable */
514 };
515 struct client_hello hello;
516
517 memset(&hello, 0, sizeof(hello));
518 hello.xhdr.type = RECORD_TYPE_HANDSHAKE;
519 hello.xhdr.proto_maj = TLS_MAJ;
520 hello.xhdr.proto_min = TLS_MIN;
521 //zero: hello.xhdr.len16_hi = (sizeof(hello) - sizeof(hello.xhdr)) >> 8;
522 hello.xhdr.len16_lo = (sizeof(hello) - sizeof(hello.xhdr));
523 hello.type = HANDSHAKE_CLIENT_HELLO;
524 //hello.len24_hi = 0;
525 //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8;
526 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4);
527 hello.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */
528 hello.proto_min = TLS_MIN; /* can be higher than one in record headers */
529 tls_get_random(hello.rand32, sizeof(hello.rand32));
530 //hello.session_id_len = 0;
531 //hello.cipherid_len16_hi = 0;
532 hello.cipherid_len16_lo = 2 * 1;
533 hello.cipherid[0] = CIPHER_ID >> 8;
534 hello.cipherid[1] = CIPHER_ID & 0xff;
535 hello.comprtypes_len = 1;
536 //hello.comprtypes[0] = 0;
537
538 xwrite(tls->fd, &hello, sizeof(hello));
539#if 0 /* dump */
540 for (;;) {
541 uint8_t buf[16*1024];
542 sleep(2);
543 len = recv(tls->fd, buf, sizeof(buf), 0); //MSG_DONTWAIT);
544 if (len < 0) {
545 if (errno == EAGAIN)
546 continue;
547 bb_perror_msg_and_die("recv");
548 }
549 if (len == 0)
550 break;
551 dump(buf, len);
552 }
553#endif
554}
555
556static void get_server_hello(tls_state_t *tls)
557{
558 struct server_hello {
559 struct record_hdr xhdr;
560 uint8_t type;
561 uint8_t len24_hi, len24_mid, len24_lo;
562 uint8_t proto_maj, proto_min;
563 uint8_t rand32[32]; /* first 4 bytes are unix time in BE format */
564 uint8_t session_id_len;
565 uint8_t session_id[32];
566 uint8_t cipherid_hi, cipherid_lo;
567 uint8_t comprtype;
568 /* extensions may follow, but only those which client offered in its Hello */
569 };
570 struct server_hello *hp;
571
572 xread_tls_handshake_block(tls, 74);
573
574 hp = (void*)tls->inbuf;
575 // 74 bytes:
576 // 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|
577 //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel
578 if (hp->type != HANDSHAKE_SERVER_HELLO
579 || hp->len24_hi != 0
580 || hp->len24_mid != 0
581 || hp->len24_lo != 70
582 || hp->proto_maj != TLS_MAJ
583 || hp->proto_min != TLS_MIN
584 || hp->session_id_len != 32
585 || hp->cipherid_hi != (CIPHER_ID >> 8)
586 || hp->cipherid_lo != (CIPHER_ID & 0xff)
587 || hp->comprtype != 0
588 ) {
589 tls_error_die(tls);
590 }
591 dbg("got SERVER_HELLO\n");
592}
593
594static void get_server_cert(tls_state_t *tls)
577{ 595{
578 struct record_hdr *xhdr; 596 struct record_hdr *xhdr;
579 uint8_t *certbuf; 597 uint8_t *certbuf;
@@ -605,63 +623,6 @@ static void get_server_cert_or_die(tls_state_t *tls)
605 623
606static void send_client_key_exchange(tls_state_t *tls) 624static void send_client_key_exchange(tls_state_t *tls)
607{ 625{
608#if 0 //matrixssl code snippets:
609 int32 csRsaEncryptPub(psPool_t *pool, psPubKey_t *key,
610 unsigned char *in, uint32 inlen, unsigned char *out, uint32 outlen,
611 void *data)
612 {
613 psAssert(key->type == PS_RSA);
614 return psRsaEncryptPub(pool, (psRsaKey_t*)key->key, in, inlen, out, outlen,
615 data);
616 }
617...
618 /* pkaAfter.user is buffer len */
619 if ((rc = csRsaEncryptPub(pka->pool, &ssl->sec.cert->publicKey,
620 ssl->sec.premaster, ssl->sec.premasterSize, pka->outbuf,
621 pka->user, pka->data)) < 0) {
622 if (rc == PS_PENDING) {
623 /* For these ClientKeyExchange paths, we do want to come
624 back through nowDoCkePka for a double pass so each
625 case can manage its own pkaAfter and to make sure
626 psX509FreeCert and sslCreateKeys() are hit below. */
627 return rc;
628 }
629 psTraceIntInfo("csRsaEncryptPub in CKE failed %d\n", rc);
630 return MATRIXSSL_ERROR;
631 }
632 /* RSA closed the pool on second pass */
633 pka->pool = NULL;
634 clearPkaAfter(ssl);
635...
636#ifdef USE_RSA_CIPHER_SUITE
637/*
638 Standard RSA suite
639*/
640 ssl->sec.premasterSize = SSL_HS_RSA_PREMASTER_SIZE;
641 ssl->sec.premaster = psMalloc(ssl->hsPool,
642 SSL_HS_RSA_PREMASTER_SIZE);
643 if (ssl->sec.premaster == NULL) {
644 return SSL_MEM_ERROR;
645 }
646
647 ssl->sec.premaster[0] = ssl->reqMajVer;
648 ssl->sec.premaster[1] = ssl->reqMinVer;
649 if (matrixCryptoGetPrngData(ssl->sec.premaster + 2,
650 SSL_HS_RSA_PREMASTER_SIZE - 2, ssl->userPtr) < 0) {
651 return MATRIXSSL_ERROR;
652 }
653
654 /* Shedule RSA encryption. Put tmp pool under control of After */
655 pkaAfter->type = PKA_AFTER_RSA_ENCRYPT;
656 pkaAfter->outbuf = c;
657 pkaAfter->data = pkiData;
658 pkaAfter->pool = pkiPool;
659 pkaAfter->user = (uint32)(end - c); /* Available space */
660
661 c += keyLen;
662#endif
663#endif // 0
664
665 struct client_key_exchange { 626 struct client_key_exchange {
666 struct record_hdr xhdr; 627 struct record_hdr xhdr;
667 uint8_t type; 628 uint8_t type;
@@ -675,7 +636,7 @@ static void send_client_key_exchange(tls_state_t *tls)
675 uint8_t key[384]; // size?? 636 uint8_t key[384]; // size??
676 }; 637 };
677 struct client_key_exchange record; 638 struct client_key_exchange record;
678 uint8_t premaster[SSL_HS_RSA_PREMASTER_SIZE]; 639 uint8_t rsa_premaster[SSL_HS_RSA_PREMASTER_SIZE];
679 640
680 memset(&record, 0, sizeof(record)); 641 memset(&record, 0, sizeof(record));
681 record.xhdr.type = RECORD_TYPE_HANDSHAKE; 642 record.xhdr.type = RECORD_TYPE_HANDSHAKE;
@@ -690,12 +651,16 @@ static void send_client_key_exchange(tls_state_t *tls)
690 record.keylen16_hi = (sizeof(record) - sizeof(record.xhdr) - 6) >> 8; 651 record.keylen16_hi = (sizeof(record) - sizeof(record.xhdr) - 6) >> 8;
691 record.keylen16_lo = (sizeof(record) - sizeof(record.xhdr) - 6) & 0xff; 652 record.keylen16_lo = (sizeof(record) - sizeof(record.xhdr) - 6) & 0xff;
692 653
693 tls_get_random(premaster, sizeof(premaster)); 654 tls_get_random(rsa_premaster, sizeof(rsa_premaster));
694 premaster[0] = TLS_MAJ; 655// RFC 5246
695 premaster[1] = TLS_MIN; 656// "Note: The version number in the PreMasterSecret is the version
657// offered by the client in the ClientHello.client_version, not the
658// version negotiated for the connection."
659 rsa_premaster[0] = TLS_MAJ;
660 rsa_premaster[1] = TLS_MIN;
696 psRsaEncryptPub(/*pool:*/ NULL, 661 psRsaEncryptPub(/*pool:*/ NULL,
697 /* psRsaKey_t* */ &tls->server_rsa_pub_key, 662 /* psRsaKey_t* */ &tls->server_rsa_pub_key,
698 premaster, /*inlen:*/ sizeof(premaster), 663 rsa_premaster, /*inlen:*/ sizeof(rsa_premaster),
699 record.key, sizeof(record.key), 664 record.key, sizeof(record.key),
700 data_param_ignored 665 data_param_ignored
701 ); 666 );
@@ -712,6 +677,88 @@ static void send_change_cipher_spec(tls_state_t *tls)
712 xwrite(tls->fd, rec, sizeof(rec)); 677 xwrite(tls->fd, rec, sizeof(rec));
713} 678}
714 679
680static void send_client_finished(tls_state_t *tls)
681{
682// RFC 5246 on pseudorandom function (PRF):
683//
684// 5. HMAC and the Pseudorandom Function
685//...
686// In this section, we define one PRF, based on HMAC. This PRF with the
687// SHA-256 hash function is used for all cipher suites defined in this
688// document and in TLS documents published prior to this document when
689// TLS 1.2 is negotiated.
690//...
691// P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
692// HMAC_hash(secret, A(2) + seed) +
693// HMAC_hash(secret, A(3) + seed) + ...
694// where + indicates concatenation.
695// A() is defined as:
696// A(0) = seed
697// A(i) = HMAC_hash(secret, A(i-1))
698// P_hash can be iterated as many times as necessary to produce the
699// required quantity of data. For example, if P_SHA256 is being used to
700// create 80 bytes of data, it will have to be iterated three times
701// (through A(3)), creating 96 bytes of output data; the last 16 bytes
702// of the final iteration will then be discarded, leaving 80 bytes of
703// output data.
704//
705// TLS's PRF is created by applying P_hash to the secret as:
706//
707// PRF(secret, label, seed) = P_<hash>(secret, label + seed)
708//
709// The label is an ASCII string.
710
711 tls->fd = 0;
712
713// 7.4.9. Finished
714// A Finished message is always sent immediately after a change
715// cipher spec message to verify that the key exchange and
716// authentication processes were successful. It is essential that a
717// change cipher spec message be received between the other handshake
718// messages and the Finished message.
719//...
720// The Finished message is the first one protected with the just
721// negotiated algorithms, keys, and secrets. Recipients of Finished
722// messages MUST verify that the contents are correct. Once a side
723// has sent its Finished message and received and validated the
724// Finished message from its peer, it may begin to send and receive
725// application data over the connection.
726//...
727// struct {
728// opaque verify_data[verify_data_length];
729// } Finished;
730//
731// verify_data
732// PRF(master_secret, finished_label, Hash(handshake_messages))
733// [0..verify_data_length-1];
734//
735// finished_label
736// For Finished messages sent by the client, the string
737// "client finished". For Finished messages sent by the server,
738// the string "server finished".
739//
740// Hash denotes a Hash of the handshake messages. For the PRF
741// defined in Section 5, the Hash MUST be the Hash used as the basis
742// for the PRF. Any cipher suite which defines a different PRF MUST
743// also define the Hash to use in the Finished computation.
744//
745// In previous versions of TLS, the verify_data was always 12 octets
746// long. In the current version of TLS, it depends on the cipher
747// suite. Any cipher suite which does not explicitly specify
748// verify_data_length has a verify_data_length equal to 12. This
749// includes all existing cipher suites.
750}
751
752static void get_change_cipher_spec(tls_state_t *tls)
753{
754 tls->fd = 0;
755}
756
757static void get_server_finished(tls_state_t *tls)
758{
759 tls->fd = 0;
760}
761
715static void tls_handshake(tls_state_t *tls) 762static void tls_handshake(tls_state_t *tls)
716{ 763{
717 // Client RFC 5246 Server 764 // Client RFC 5246 Server
@@ -734,23 +781,7 @@ static void tls_handshake(tls_state_t *tls)
734 int len; 781 int len;
735 782
736 send_client_hello(tls); 783 send_client_hello(tls);
737#if 0 /* dump */ 784 get_server_hello(tls);
738 for (;;) {
739 uint8_t buf[16*1024];
740 sleep(2);
741 len = recv(tls->fd, buf, sizeof(buf), 0); //MSG_DONTWAIT);
742 if (len < 0) {
743 if (errno == EAGAIN)
744 continue;
745 bb_perror_msg_and_die("recv");
746 }
747 if (len == 0)
748 break;
749 dump(buf, len);
750 }
751#endif
752
753 get_server_hello_or_die(tls);
754 785
755 //RFC 5246 786 //RFC 5246
756 // The server MUST send a Certificate message whenever the agreed- 787 // The server MUST send a Certificate message whenever the agreed-
@@ -761,7 +792,7 @@ static void tls_handshake(tls_state_t *tls)
761 // 792 //
762 // IOW: in practice, Certificate *always* follows. 793 // IOW: in practice, Certificate *always* follows.
763 // (for example, kernel.org does not even accept DH_anon cipher id) 794 // (for example, kernel.org does not even accept DH_anon cipher id)
764 get_server_cert_or_die(tls); 795 get_server_cert(tls);
765 796
766 len = xread_tls_handshake_block(tls, 4); 797 len = xread_tls_handshake_block(tls, 4);
767 if (tls->inbuf[5] == HANDSHAKE_SERVER_KEY_EXCHANGE) { 798 if (tls->inbuf[5] == HANDSHAKE_SERVER_KEY_EXCHANGE) {
@@ -776,6 +807,13 @@ static void tls_handshake(tls_state_t *tls)
776 } 807 }
777// if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) { 808// if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) {
778// dbg("got CERTIFICATE_REQUEST\n"); 809// dbg("got CERTIFICATE_REQUEST\n");
810//RFC 5246: (in response to this,) "If no suitable certificate is available,
811// the client MUST send a certificate message containing no
812// certificates. That is, the certificate_list structure has a
813// length of zero. ...
814// Client certificates are sent using the Certificate structure
815// defined in Section 7.4.2."
816// (i.e. the same format as server certs)
779// xread_tls_handshake_block(tls, 4); 817// xread_tls_handshake_block(tls, 4);
780// } 818// }
781 if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) { 819 if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) {
@@ -784,6 +822,10 @@ static void tls_handshake(tls_state_t *tls)
784 send_client_key_exchange(tls); 822 send_client_key_exchange(tls);
785 send_change_cipher_spec(tls); 823 send_change_cipher_spec(tls);
786//we now should be able to send encrypted... as soon as we grok AES. 824//we now should be able to send encrypted... as soon as we grok AES.
825 send_client_finished(tls);
826 get_change_cipher_spec(tls);
827 get_server_finished(tls);
828//we now should receive encrypted, and application data can be sent/received
787 } else { 829 } else {
788 tls_error_die(tls); 830 tls_error_die(tls);
789 } 831 }