aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-20 03:15:09 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-20 03:15:09 +0100
commitabbf17abccbf832365d9acf1c280369ba7d5f8b2 (patch)
tree8efda8ec7a3f95d2e4e5f90dc5af933d02b6b1f4
parentf7806f9d8fc889f1d6cd365b69d9d99a4a5a6e26 (diff)
downloadbusybox-w32-abbf17abccbf832365d9acf1c280369ba7d5f8b2.tar.gz
busybox-w32-abbf17abccbf832365d9acf1c280369ba7d5f8b2.tar.bz2
busybox-w32-abbf17abccbf832365d9acf1c280369ba7d5f8b2.zip
tls: add the i/o loop - largish rework of i/o buffering
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/tls.c274
1 files changed, 166 insertions, 108 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 092735884..71be2def8 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -23,9 +23,10 @@
23//usage:#define tls_full_usage "\n\n" 23//usage:#define tls_full_usage "\n\n"
24 24
25#include "tls.h" 25#include "tls.h"
26#include "common_bufsiz.h"
26 27
27#define TLS_DEBUG 1 28#define TLS_DEBUG 1
28#define TLS_DEBUG_HASH 0 29#define TLS_DEBUG_HASH 1
29#define TLS_DEBUG_DER 0 30#define TLS_DEBUG_DER 0
30 31
31#if TLS_DEBUG 32#if TLS_DEBUG
@@ -150,9 +151,8 @@
150// works against "openssl s_server -cipher NULL" 151// works against "openssl s_server -cipher NULL"
151// and against wolfssl-3.9.10-stable/examples/server/server.c: 152// and against wolfssl-3.9.10-stable/examples/server/server.c:
152//#define CIPHER_ID TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting) 153//#define CIPHER_ID TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting)
153// "works", meaning 154// works against wolfssl-3.9.10-stable/examples/server/server.c
154// "can send encrypted FINISHED to wolfssl-3.9.10-stable/examples/server/server.c", 155// (getting back and decrypt ok first application data message)
155// don't yet read its encrypted answers:
156#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE 156#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE
157 157
158enum { 158enum {
@@ -162,6 +162,11 @@ enum {
162 AES_BLOCKSIZE = 16, 162 AES_BLOCKSIZE = 16,
163 AES128_KEYSIZE = 16, 163 AES128_KEYSIZE = 16,
164 AES256_KEYSIZE = 32, 164 AES256_KEYSIZE = 32,
165
166 MAX_TLS_RECORD = (1 << 14),
167 OUTBUF_PFX = 8 + AES_BLOCKSIZE, /* header + IV */
168 OUTBUF_SFX = SHA256_OUTSIZE + AES_BLOCKSIZE, /* MAC + padding */
169 MAX_OTBUF = MAX_TLS_RECORD - OUTBUF_PFX - OUTBUF_SFX,
165}; 170};
166 171
167struct record_hdr { 172struct record_hdr {
@@ -195,6 +200,9 @@ typedef struct tls_state {
195// exceed 2^64-1. 200// exceed 2^64-1.
196 uint64_t write_seq64_be; 201 uint64_t write_seq64_be;
197 202
203 int outbuf_size;
204 uint8_t *outbuf;
205
198 // RFC 5246 206 // RFC 5246
199 // |6.2.1. Fragmentation 207 // |6.2.1. Fragmentation
200 // | The record layer fragments information blocks into TLSPlaintext 208 // | The record layer fragments information blocks into TLSPlaintext
@@ -225,7 +233,6 @@ typedef struct tls_state {
225//needed? 233//needed?
226 uint64_t align____; 234 uint64_t align____;
227 uint8_t inbuf[20*1024]; 235 uint8_t inbuf[20*1024];
228 uint8_t outbuf[20*1024];
229} tls_state_t; 236} tls_state_t;
230 237
231 238
@@ -462,6 +469,17 @@ static void tls_error_die(tls_state_t *tls)
462 xfunc_die(); 469 xfunc_die();
463} 470}
464 471
472static void *tls_get_outbuf(tls_state_t *tls, int len)
473{
474 if (len > MAX_OTBUF)
475 xfunc_die();
476 if (tls->outbuf_size < len + OUTBUF_PFX + OUTBUF_SFX) {
477 tls->outbuf_size = len + OUTBUF_PFX + OUTBUF_SFX;
478 tls->outbuf = xrealloc(tls->outbuf, tls->outbuf_size);
479 }
480 return tls->outbuf + OUTBUF_PFX;
481}
482
465// RFC 5246 483// RFC 5246
466// 6.2.3.1. Null or Standard Stream Cipher 484// 6.2.3.1. Null or Standard Stream Cipher
467// 485//
@@ -501,39 +519,41 @@ static void tls_error_die(tls_state_t *tls)
501// -------- ----------- ---------- -------------- 519// -------- ----------- ---------- --------------
502// SHA HMAC-SHA1 20 20 520// SHA HMAC-SHA1 20 20
503// SHA256 HMAC-SHA256 32 32 521// SHA256 HMAC-SHA256 32 32
504static void xwrite_and_hash(tls_state_t *tls, /*const*/ void *buf, unsigned size) 522static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
505{ 523{
506 uint8_t mac_hash[SHA256_OUTSIZE]; 524 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
507 struct record_hdr *xhdr = buf; 525 struct record_hdr *xhdr;
508 526
509 if (!tls->encrypt_on_write) { 527 xhdr = (void*)(buf - sizeof(*xhdr));
510 xwrite(tls->fd, buf, size); 528 if (CIPHER_ID != TLS_RSA_WITH_NULL_SHA256)
511 dbg("wrote %u bytes\n", size); 529 xhdr = (void*)(buf - sizeof(*xhdr) - AES_BLOCKSIZE); /* place for IV */
512 /* Handshake hash does not include record headers */ 530
513 if (size > 5 && xhdr->type == RECORD_TYPE_HANDSHAKE) { 531 xhdr->type = type;
514 sha256_hash_dbg(">> sha256:%s", &tls->handshake_sha256_ctx, (uint8_t*)buf + 5, size - 5); 532 xhdr->proto_maj = TLS_MAJ;
515 } 533 xhdr->proto_min = TLS_MIN;
516 return; 534 /* fake unencrypted record header len for MAC calculation */
517 } 535 xhdr->len16_hi = size >> 8;
536 xhdr->len16_lo = size & 0xff;
518 537
538 /* Calculate MAC signature */
519//TODO: convert hmac_sha256 to precomputed 539//TODO: convert hmac_sha256 to precomputed
520 hmac_sha256(mac_hash, 540 hmac_sha256(buf + size,
521 tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key), 541 tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key),
522 &tls->write_seq64_be, sizeof(tls->write_seq64_be), 542 &tls->write_seq64_be, sizeof(tls->write_seq64_be),
543 xhdr, sizeof(*xhdr),
523 buf, size, 544 buf, size,
524 NULL); 545 NULL);
525 tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be)); 546 tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be));
526 547
548 size += SHA256_OUTSIZE;
549
527 if (CIPHER_ID == TLS_RSA_WITH_NULL_SHA256) { 550 if (CIPHER_ID == TLS_RSA_WITH_NULL_SHA256) {
528 /* No encryption, only signing */ 551 /* No encryption, only signing */
529 xhdr->len16_lo += SHA256_OUTSIZE; 552 xhdr->len16_hi = size >> 8;
530//FIXME: overflow into len16_hi? 553 xhdr->len16_lo = size & 0xff;
531 xwrite(tls->fd, buf, size); 554 dump_hex(">> %s\n", xhdr, sizeof(*xhdr) + size);
532 xhdr->len16_lo -= SHA256_OUTSIZE; 555 xwrite(tls->fd, xhdr, sizeof(*xhdr) + size);
533 dbg("wrote %u bytes\n", size); 556 dbg("wrote %u bytes (NULL crypt, SHA256 hash)\n", size);
534
535 xwrite(tls->fd, mac_hash, sizeof(mac_hash));
536 dbg("wrote %u bytes of hash\n", (int)sizeof(mac_hash));
537 return; 557 return;
538 } 558 }
539 559
@@ -579,13 +599,8 @@ static void xwrite_and_hash(tls_state_t *tls, /*const*/ void *buf, unsigned size
579 uint8_t padding_length; 599 uint8_t padding_length;
580 600
581 /* Build IV+content+MAC+padding in outbuf */ 601 /* Build IV+content+MAC+padding in outbuf */
582 tls_get_random(tls->outbuf, AES_BLOCKSIZE); /* IV */ 602 tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */
583 p = tls->outbuf + AES_BLOCKSIZE; 603 dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", size, SHA256_OUTSIZE);
584 size -= sizeof(*xhdr);
585 dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", size, (int)sizeof(mac_hash));
586 p = mempcpy(p, buf + sizeof(*xhdr), size); /* content */
587 p = mempcpy(p, mac_hash, sizeof(mac_hash)); /* MAC */
588 size += sizeof(mac_hash);
589 // RFC is talking nonsense: 604 // RFC is talking nonsense:
590 // Padding that is added to force the length of the plaintext to be 605 // Padding that is added to force the length of the plaintext to be
591 // an integral multiple of the block cipher's block length. 606 // an integral multiple of the block cipher's block length.
@@ -601,6 +616,7 @@ static void xwrite_and_hash(tls_state_t *tls, /*const*/ void *buf, unsigned size
601 // If you need no bytes to reach BLOCKSIZE, you have to pad a full 616 // If you need no bytes to reach BLOCKSIZE, you have to pad a full
602 // BLOCKSIZE with bytes of value (BLOCKSIZE-1). 617 // BLOCKSIZE with bytes of value (BLOCKSIZE-1).
603 // It's ok to have more than minimum padding, but we do minimum. 618 // It's ok to have more than minimum padding, but we do minimum.
619 p = buf + size;
604 padding_length = (~size) & (AES_BLOCKSIZE - 1); 620 padding_length = (~size) & (AES_BLOCKSIZE - 1);
605 do { 621 do {
606 *p++ = padding_length; /* padding */ 622 *p++ = padding_length; /* padding */
@@ -608,12 +624,12 @@ static void xwrite_and_hash(tls_state_t *tls, /*const*/ void *buf, unsigned size
608 } while ((size & (AES_BLOCKSIZE - 1)) != 0); 624 } while ((size & (AES_BLOCKSIZE - 1)) != 0);
609 625
610 /* Encrypt content+MAC+padding in place */ 626 /* Encrypt content+MAC+padding in place */
611 psAesInit(&ctx, tls->outbuf, /* IV */ 627 psAesInit(&ctx, buf - AES_BLOCKSIZE, /* IV */
612 tls->client_write_key, sizeof(tls->client_write_key) 628 tls->client_write_key, sizeof(tls->client_write_key)
613 ); 629 );
614 psAesEncrypt(&ctx, 630 psAesEncrypt(&ctx,
615 tls->outbuf + AES_BLOCKSIZE, /* plaintext */ 631 buf, /* plaintext */
616 tls->outbuf + AES_BLOCKSIZE, /* ciphertext */ 632 buf, /* ciphertext */
617 size 633 size
618 ); 634 );
619 635
@@ -623,14 +639,33 @@ static void xwrite_and_hash(tls_state_t *tls, /*const*/ void *buf, unsigned size
623 size += AES_BLOCKSIZE; /* + IV */ 639 size += AES_BLOCKSIZE; /* + IV */
624 xhdr->len16_hi = size >> 8; 640 xhdr->len16_hi = size >> 8;
625 xhdr->len16_lo = size & 0xff; 641 xhdr->len16_lo = size & 0xff;
626 xwrite(tls->fd, xhdr, sizeof(*xhdr)); 642 dump_hex(">> %s\n", xhdr, sizeof(*xhdr) + size);
627 xwrite(tls->fd, tls->outbuf, size); 643 xwrite(tls->fd, xhdr, sizeof(*xhdr) + size);
628 dbg("wrote %u bytes\n", (int)sizeof(*xhdr) + size); 644 dbg("wrote %u bytes\n", (int)sizeof(*xhdr) + size);
629//restore xhdr->len16_hi = ;
630//restore xhdr->len16_lo = ;
631 } 645 }
632} 646}
633 647
648static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size)
649{
650 if (!tls->encrypt_on_write) {
651 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
652 struct record_hdr *xhdr = (void*)(buf - sizeof(*xhdr));
653
654 xhdr->type = RECORD_TYPE_HANDSHAKE;
655 xhdr->proto_maj = TLS_MAJ;
656 xhdr->proto_min = TLS_MIN;
657 xhdr->len16_hi = size >> 8;
658 xhdr->len16_lo = size & 0xff;
659 dump_hex(">> %s\n", xhdr, sizeof(*xhdr) + size);
660 xwrite(tls->fd, xhdr, sizeof(*xhdr) + size);
661 dbg("wrote %u bytes\n", (int)sizeof(*xhdr) + size);
662 /* Handshake hash does not include record headers */
663 sha256_hash_dbg(">> sha256:%s", &tls->handshake_sha256_ctx, buf, size);
664 return;
665 }
666 xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE);
667}
668
634static int xread_tls_block(tls_state_t *tls) 669static int xread_tls_block(tls_state_t *tls)
635{ 670{
636 struct record_hdr *xhdr; 671 struct record_hdr *xhdr;
@@ -668,7 +703,7 @@ static int xread_tls_block(tls_state_t *tls)
668 sz = target - sizeof(*xhdr); 703 sz = target - sizeof(*xhdr);
669 704
670 /* Needs to be decrypted? */ 705 /* Needs to be decrypted? */
671 if (tls->min_encrypted_len_on_read) { 706 if (tls->min_encrypted_len_on_read > SHA256_OUTSIZE) {
672 psCipherContext_t ctx; 707 psCipherContext_t ctx;
673 uint8_t *p = tls->inbuf + sizeof(*xhdr); 708 uint8_t *p = tls->inbuf + sizeof(*xhdr);
674 int padding_len; 709 int padding_len;
@@ -698,6 +733,10 @@ static int xread_tls_block(tls_state_t *tls)
698 /* Skip IV */ 733 /* Skip IV */
699 memmove(tls->inbuf + 5, tls->inbuf + 5 + AES_BLOCKSIZE, sz); 734 memmove(tls->inbuf + 5, tls->inbuf + 5 + AES_BLOCKSIZE, sz);
700 } 735 }
736 } else {
737 /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */
738 /* else: no encryption yet on input, subtract zero = NOP */
739 sz -= tls->min_encrypted_len_on_read;
701 } 740 }
702 741
703 /* RFC 5246 is not saying it explicitly, but sha256 hash 742 /* RFC 5246 is not saying it explicitly, but sha256 hash
@@ -943,39 +982,24 @@ static int xread_tls_handshake_block(tls_state_t *tls, int min_len)
943 return len; 982 return len;
944} 983}
945 984
946static void fill_handshake_record_hdr(struct record_hdr *xhdr, unsigned len) 985static ALWAYS_INLINE void fill_handshake_record_hdr(void *buf, unsigned type, unsigned len)
947{ 986{
948 struct handshake_hdr { 987 struct handshake_hdr {
949 struct record_hdr xhdr;
950 uint8_t type; 988 uint8_t type;
951 uint8_t len24_hi, len24_mid, len24_lo; 989 uint8_t len24_hi, len24_mid, len24_lo;
952 } *h = (void*)xhdr; 990 } *h = buf;
953
954 h->xhdr.type = RECORD_TYPE_HANDSHAKE;
955 h->xhdr.proto_maj = TLS_MAJ;
956 h->xhdr.proto_min = TLS_MIN;
957 len -= 5;
958 h->xhdr.len16_hi = len >> 8;
959 // can be optimized to do one store instead of four:
960 // uint32_t v = htonl(0x100*(RECORD_TYPE_HANDSHAKE + 0x100*(TLS_MAJ + 0x100*(TLS_MIN))))
961 // | ((len >> 8) << 24); // little-endian specific, don't use in this form
962 // *(uint32_t *)xhdr = v;
963
964 h->xhdr.len16_lo = len & 0xff;
965 991
966 len -= 4; 992 len -= 4;
993 h->type = type;
967 h->len24_hi = len >> 16; 994 h->len24_hi = len >> 16;
968 h->len24_mid = len >> 8; 995 h->len24_mid = len >> 8;
969 h->len24_lo = len & 0xff; 996 h->len24_lo = len & 0xff;
970
971 memset(h + 1, 0, len);
972} 997}
973 998
974//TODO: implement RFC 5746 (Renegotiation Indication Extension) - some servers will refuse to work with us otherwise 999//TODO: implement RFC 5746 (Renegotiation Indication Extension) - some servers will refuse to work with us otherwise
975static void send_client_hello(tls_state_t *tls) 1000static void send_client_hello(tls_state_t *tls)
976{ 1001{
977 struct client_hello { 1002 struct client_hello {
978 struct record_hdr xhdr;
979 uint8_t type; 1003 uint8_t type;
980 uint8_t len24_hi, len24_mid, len24_lo; 1004 uint8_t len24_hi, len24_mid, len24_lo;
981 uint8_t proto_maj, proto_min; 1005 uint8_t proto_maj, proto_min;
@@ -987,25 +1011,25 @@ static void send_client_hello(tls_state_t *tls)
987 uint8_t comprtypes_len; 1011 uint8_t comprtypes_len;
988 uint8_t comprtypes[1]; /* actually variable */ 1012 uint8_t comprtypes[1]; /* actually variable */
989 }; 1013 };
990 struct client_hello record; 1014 struct client_hello *record = tls_get_outbuf(tls, sizeof(*record));
991 1015
992 fill_handshake_record_hdr(&record.xhdr, sizeof(record)); 1016 fill_handshake_record_hdr(record, HANDSHAKE_CLIENT_HELLO, sizeof(*record));
993 record.type = HANDSHAKE_CLIENT_HELLO; 1017 record->proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */
994 record.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ 1018 record->proto_min = TLS_MIN; /* can be higher than one in record headers */
995 record.proto_min = TLS_MIN; /* can be higher than one in record headers */ 1019 tls_get_random(record->rand32, sizeof(record->rand32));
996 tls_get_random(record.rand32, sizeof(record.rand32)); 1020memset(record->rand32, 0x11, sizeof(record->rand32));
997 /* record.session_id_len = 0; - already is */ 1021 memcpy(tls->client_and_server_rand32, record->rand32, sizeof(record->rand32));
998 /* record.cipherid_len16_hi = 0; */ 1022 record->session_id_len = 0;
999 record.cipherid_len16_lo = 2 * 1; 1023 record->cipherid_len16_hi = 0;
1000 record.cipherid[0] = CIPHER_ID >> 8; 1024 record->cipherid_len16_lo = 2 * 1;
1001 record.cipherid[1] = CIPHER_ID & 0xff; 1025 record->cipherid[0] = CIPHER_ID >> 8;
1002 record.comprtypes_len = 1; 1026 record->cipherid[1] = CIPHER_ID & 0xff;
1003 /* record.comprtypes[0] = 0; */ 1027 record->comprtypes_len = 1;
1028 record->comprtypes[0] = 0;
1004 1029
1005 //dbg (make it repeatable): memset(record.rand32, 0x11, sizeof(record.rand32)); 1030 //dbg (make it repeatable): memset(record.rand32, 0x11, sizeof(record.rand32));
1006 dbg(">> CLIENT_HELLO\n"); 1031 dbg(">> CLIENT_HELLO\n");
1007 xwrite_and_hash(tls, &record, sizeof(record)); 1032 xwrite_and_update_handshake_hash(tls, sizeof(*record));
1008 memcpy(tls->client_and_server_rand32, record.rand32, sizeof(record.rand32));
1009} 1033}
1010 1034
1011static void get_server_hello(tls_state_t *tls) 1035static void get_server_hello(tls_state_t *tls)
@@ -1099,21 +1123,19 @@ static void get_server_cert(tls_state_t *tls)
1099static void send_client_key_exchange(tls_state_t *tls) 1123static void send_client_key_exchange(tls_state_t *tls)
1100{ 1124{
1101 struct client_key_exchange { 1125 struct client_key_exchange {
1102 struct record_hdr xhdr;
1103 uint8_t type; 1126 uint8_t type;
1104 uint8_t len24_hi, len24_mid, len24_lo; 1127 uint8_t len24_hi, len24_mid, len24_lo;
1105 /* keylen16 exists for RSA (in TLS, not in SSL), but not for some other key types */ 1128 /* keylen16 exists for RSA (in TLS, not in SSL), but not for some other key types */
1106 uint8_t keylen16_hi, keylen16_lo; 1129 uint8_t keylen16_hi, keylen16_lo;
1107 uint8_t key[4 * 1024]; // size?? 1130 uint8_t key[4 * 1024]; // size??
1108 }; 1131 };
1109 struct client_key_exchange record; 1132//FIXME: better size estimate
1133 struct client_key_exchange *record = tls_get_outbuf(tls, sizeof(*record));
1110 uint8_t rsa_premaster[SSL_HS_RSA_PREMASTER_SIZE]; 1134 uint8_t rsa_premaster[SSL_HS_RSA_PREMASTER_SIZE];
1111 int len; 1135 int len;
1112 1136
1113 fill_handshake_record_hdr(&record.xhdr, sizeof(record) - sizeof(record.key));
1114 record.type = HANDSHAKE_CLIENT_KEY_EXCHANGE;
1115
1116 tls_get_random(rsa_premaster, sizeof(rsa_premaster)); 1137 tls_get_random(rsa_premaster, sizeof(rsa_premaster));
1138memset(rsa_premaster, 0x44, sizeof(rsa_premaster));
1117 // RFC 5246 1139 // RFC 5246
1118 // "Note: The version number in the PreMasterSecret is the version 1140 // "Note: The version number in the PreMasterSecret is the version
1119 // offered by the client in the ClientHello.client_version, not the 1141 // offered by the client in the ClientHello.client_version, not the
@@ -1123,22 +1145,20 @@ static void send_client_key_exchange(tls_state_t *tls)
1123 len = psRsaEncryptPub(/*pool:*/ NULL, 1145 len = psRsaEncryptPub(/*pool:*/ NULL,
1124 /* psRsaKey_t* */ &tls->server_rsa_pub_key, 1146 /* psRsaKey_t* */ &tls->server_rsa_pub_key,
1125 rsa_premaster, /*inlen:*/ sizeof(rsa_premaster), 1147 rsa_premaster, /*inlen:*/ sizeof(rsa_premaster),
1126 record.key, sizeof(record.key), 1148 record->key, sizeof(record->key),
1127 data_param_ignored 1149 data_param_ignored
1128 ); 1150 );
1129 /* length fields need fixing */ 1151 record->keylen16_hi = len >> 8;
1130 record.keylen16_hi = len >> 8; 1152 record->keylen16_lo = len & 0xff;
1131 record.keylen16_lo = len & 0xff;
1132 len += 2; 1153 len += 2;
1133 /* record.len24_hi = 0; - already is */ 1154 record->type = HANDSHAKE_CLIENT_KEY_EXCHANGE;
1134 record.len24_mid = len >> 8; 1155 record->len24_hi = 0;
1135 record.len24_lo = len & 0xff; 1156 record->len24_mid = len >> 8;
1157 record->len24_lo = len & 0xff;
1136 len += 4; 1158 len += 4;
1137 record.xhdr.len16_hi = len >> 8;
1138 record.xhdr.len16_lo = len & 0xff;
1139 1159
1140 dbg(">> CLIENT_KEY_EXCHANGE\n"); 1160 dbg(">> CLIENT_KEY_EXCHANGE\n");
1141 xwrite_and_hash(tls, &record, sizeof(record.xhdr) + len); 1161 xwrite_and_update_handshake_hash(tls, len);
1142 1162
1143 // RFC 5246 1163 // RFC 5246
1144 // For all key exchange methods, the same algorithm is used to convert 1164 // For all key exchange methods, the same algorithm is used to convert
@@ -1224,7 +1244,6 @@ static const uint8_t rec_CHANGE_CIPHER_SPEC[] = {
1224 1244
1225static void send_change_cipher_spec(tls_state_t *tls) 1245static void send_change_cipher_spec(tls_state_t *tls)
1226{ 1246{
1227 /* Not "xwrite_and_hash": this is not a handshake message */
1228 dbg(">> CHANGE_CIPHER_SPEC\n"); 1247 dbg(">> CHANGE_CIPHER_SPEC\n");
1229 xwrite(tls->fd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC)); 1248 xwrite(tls->fd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC));
1230} 1249}
@@ -1269,19 +1288,17 @@ static void send_change_cipher_spec(tls_state_t *tls)
1269static void send_client_finished(tls_state_t *tls) 1288static void send_client_finished(tls_state_t *tls)
1270{ 1289{
1271 struct finished { 1290 struct finished {
1272 struct record_hdr xhdr;
1273 uint8_t type; 1291 uint8_t type;
1274 uint8_t len24_hi, len24_mid, len24_lo; 1292 uint8_t len24_hi, len24_mid, len24_lo;
1275 uint8_t prf_result[12]; 1293 uint8_t prf_result[12];
1276 }; 1294 };
1277 struct finished record; 1295 struct finished *record = tls_get_outbuf(tls, sizeof(*record));
1278 uint8_t handshake_hash[SHA256_OUTSIZE]; 1296 uint8_t handshake_hash[SHA256_OUTSIZE];
1279 1297
1280 fill_handshake_record_hdr(&record.xhdr, sizeof(record)); 1298 fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record));
1281 record.type = HANDSHAKE_FINISHED;
1282 1299
1283 sha256_peek(&tls->handshake_sha256_ctx, handshake_hash); 1300 sha256_peek(&tls->handshake_sha256_ctx, handshake_hash);
1284 prf_hmac_sha256(record.prf_result, sizeof(record.prf_result), 1301 prf_hmac_sha256(record->prf_result, sizeof(record->prf_result),
1285 tls->master_secret, sizeof(tls->master_secret), 1302 tls->master_secret, sizeof(tls->master_secret),
1286 "client finished", 1303 "client finished",
1287 handshake_hash, sizeof(handshake_hash) 1304 handshake_hash, sizeof(handshake_hash)
@@ -1289,13 +1306,10 @@ static void send_client_finished(tls_state_t *tls)
1289 dump_hex("from secret: %s\n", tls->master_secret, sizeof(tls->master_secret)); 1306 dump_hex("from secret: %s\n", tls->master_secret, sizeof(tls->master_secret));
1290 dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1); 1307 dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1);
1291 dump_hex("%s\n", handshake_hash, sizeof(handshake_hash)); 1308 dump_hex("%s\n", handshake_hash, sizeof(handshake_hash));
1292 dump_hex("=> digest: %s\n", record.prf_result, sizeof(record.prf_result)); 1309 dump_hex("=> digest: %s\n", record->prf_result, sizeof(record->prf_result));
1293
1294//(1) TODO: well, this should be encrypted on send, really.
1295//(2) do we really need to also hash it?
1296 1310
1297 dbg(">> FINISHED\n"); 1311 dbg(">> FINISHED\n");
1298 xwrite_and_hash(tls, &record, sizeof(record)); 1312 xwrite_encrypted(tls, sizeof(*record), RECORD_TYPE_HANDSHAKE);
1299} 1313}
1300 1314
1301static void tls_handshake(tls_state_t *tls) 1315static void tls_handshake(tls_state_t *tls)
@@ -1376,8 +1390,11 @@ static void tls_handshake(tls_state_t *tls)
1376 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) 1390 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
1377 tls_error_die(tls); 1391 tls_error_die(tls);
1378 dbg("<< CHANGE_CIPHER_SPEC\n"); 1392 dbg("<< CHANGE_CIPHER_SPEC\n");
1379 /* all incoming packets now should be encrypted and have IV + MAC + padding */ 1393 if (CIPHER_ID == TLS_RSA_WITH_NULL_SHA256)
1380 tls->min_encrypted_len_on_read = AES_BLOCKSIZE + SHA256_OUTSIZE + AES_BLOCKSIZE; 1394 tls->min_encrypted_len_on_read = SHA256_OUTSIZE;
1395 else
1396 /* all incoming packets now should be encrypted and have IV + MAC + padding */
1397 tls->min_encrypted_len_on_read = AES_BLOCKSIZE + SHA256_OUTSIZE + AES_BLOCKSIZE;
1381 1398
1382 /* Get (encrypted) FINISHED from the server */ 1399 /* Get (encrypted) FINISHED from the server */
1383 len = xread_tls_block(tls); 1400 len = xread_tls_block(tls);
@@ -1387,6 +1404,12 @@ static void tls_handshake(tls_state_t *tls)
1387 /* application data can be sent/received */ 1404 /* application data can be sent/received */
1388} 1405}
1389 1406
1407static void tls_xwrite(tls_state_t *tls, int len)
1408{
1409 dbg(">> DATA\n");
1410 xwrite_encrypted(tls, len, RECORD_TYPE_APPLICATION_DATA);
1411}
1412
1390// To run a test server using openssl: 1413// To run a test server using openssl:
1391// openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' 1414// openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost'
1392// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 1415// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1
@@ -1400,8 +1423,8 @@ int tls_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1400int tls_main(int argc UNUSED_PARAM, char **argv) 1423int tls_main(int argc UNUSED_PARAM, char **argv)
1401{ 1424{
1402 tls_state_t *tls; 1425 tls_state_t *tls;
1403 len_and_sockaddr *lsa; 1426 fd_set readfds, testfds;
1404 int fd; 1427 int cfd;
1405 1428
1406 // INIT_G(); 1429 // INIT_G();
1407 // getopt32(argv, "myopts") 1430 // getopt32(argv, "myopts")
@@ -1409,13 +1432,48 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1409 if (!argv[1]) 1432 if (!argv[1])
1410 bb_show_usage(); 1433 bb_show_usage();
1411 1434
1412 lsa = xhost2sockaddr(argv[1], 443); 1435 cfd = create_and_connect_stream_or_die(argv[1], 443);
1413 fd = xconnect_stream(lsa);
1414 1436
1415 tls = new_tls_state(); 1437 tls = new_tls_state();
1416 tls->fd = fd; 1438 tls->fd = cfd;
1417 tls_handshake(tls); 1439 tls_handshake(tls);
1418 1440
1441 /* Select loop copying stdin to cfd, and cfd to stdout */
1442 FD_ZERO(&readfds);
1443 FD_SET(cfd, &readfds);
1444 FD_SET(STDIN_FILENO, &readfds);
1445
1446#define iobuf bb_common_bufsiz1
1447 setup_common_bufsiz();
1448 for (;;) {
1449 int nread;
1450
1451 testfds = readfds;
1452
1453 if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0)
1454 bb_perror_msg_and_die("select");
1455
1456 if (FD_ISSET(STDIN_FILENO, &testfds)) {
1457 void *buf = tls_get_outbuf(tls, COMMON_BUFSIZE);
1458 nread = safe_read(STDIN_FILENO, buf, COMMON_BUFSIZE);
1459 if (nread < 1) {
1460//&& errno != EAGAIN
1461 /* Close outgoing half-connection so they get EOF,
1462 * but leave incoming alone so we can see response */
1463// shutdown(cfd, SHUT_WR);
1464 FD_CLR(STDIN_FILENO, &readfds);
1465 }
1466 tls_xwrite(tls, nread);
1467 }
1468 if (FD_ISSET(cfd, &testfds)) {
1469 nread = xread_tls_block(tls);
1470 if (nread < 1)
1471//if eof, just close stdout, but not exit!
1472 return EXIT_SUCCESS;
1473 xwrite(STDOUT_FILENO, tls->inbuf + 5, nread);
1474 }
1475 }
1476
1419 return EXIT_SUCCESS; 1477 return EXIT_SUCCESS;
1420} 1478}
1421/* Unencryped SHA256 example: 1479/* Unencryped SHA256 example: