aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-18 06:45:50 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-18 06:45:50 +0100
commitc8ba23bcec94ecbc8ee82053d1b7e299cc839184 (patch)
treec04686e84bc16f23c30fa1606e751c856853f1d9 /networking/tls.c
parent5d1662ea1c29f53b6ece93806c4cf218f9b9a5ae (diff)
downloadbusybox-w32-c8ba23bcec94ecbc8ee82053d1b7e299cc839184.tar.gz
busybox-w32-c8ba23bcec94ecbc8ee82053d1b7e299cc839184.tar.bz2
busybox-w32-c8ba23bcec94ecbc8ee82053d1b7e299cc839184.zip
tls: massage writing for encryption support; finer-grained debug
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c69
1 files changed, 38 insertions, 31 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 8bcaee9a6..9d1a0fca9 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -25,7 +25,9 @@
25 25
26#include "tls.h" 26#include "tls.h"
27 27
28#define TLS_DEBUG 2 28#define TLS_DEBUG 1
29#define TLS_DEBUG_HASH 0
30#define TLS_DEBUG_DER 0
29 31
30#if TLS_DEBUG 32#if TLS_DEBUG
31# define dbg(...) fprintf(stderr, __VA_ARGS__) 33# define dbg(...) fprintf(stderr, __VA_ARGS__)
@@ -33,6 +35,12 @@
33# define dbg(...) ((void)0) 35# define dbg(...) ((void)0)
34#endif 36#endif
35 37
38#if TLS_DEBUG_DER
39# define dbg_der(...) fprintf(stderr, __VA_ARGS__)
40#else
41# define dbg_der(...) ((void)0)
42#endif
43
36#define RECORD_TYPE_CHANGE_CIPHER_SPEC 20 44#define RECORD_TYPE_CHANGE_CIPHER_SPEC 20
37#define RECORD_TYPE_ALERT 21 45#define RECORD_TYPE_ALERT 21
38#define RECORD_TYPE_HANDSHAKE 22 46#define RECORD_TYPE_HANDSHAKE 22
@@ -269,7 +277,7 @@ static void sha256_peek(sha256_ctx_t *ctx, void *buffer)
269 sha256_end(&ctx_copy, buffer); 277 sha256_end(&ctx_copy, buffer);
270} 278}
271 279
272#if TLS_DEBUG >= 2 280#if TLS_DEBUG_HASH
273static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buffer, size_t len) 281static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buffer, size_t len)
274{ 282{
275 uint8_t h[SHA256_OUTSIZE]; 283 uint8_t h[SHA256_OUTSIZE];
@@ -283,7 +291,7 @@ static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buff
283#else 291#else
284# define sha256_hash_dbg(fmt, ctx, buffer, len) \ 292# define sha256_hash_dbg(fmt, ctx, buffer, len) \
285 sha256_hash(ctx, buffer, len) 293 sha256_hash(ctx, buffer, len)
286#endif /* not TLS_DEBUG >= 2 */ 294#endif
287 295
288// RFC 2104 296// RFC 2104
289// HMAC(key, text) based on a hash H (say, sha256) is: 297// HMAC(key, text) based on a hash H (say, sha256) is:
@@ -424,8 +432,7 @@ static void prf_hmac_sha256(
424#undef SEED 432#undef SEED
425} 433}
426 434
427static 435static tls_state_t *new_tls_state(void)
428tls_state_t *new_tls_state(void)
429{ 436{
430 tls_state_t *tls = xzalloc(sizeof(*tls)); 437 tls_state_t *tls = xzalloc(sizeof(*tls));
431 tls->fd = -1; 438 tls->fd = -1;
@@ -488,31 +495,31 @@ static void xwrite_and_hash(tls_state_t *tls, /*const*/ void *buf, unsigned size
488 uint8_t mac_hash[SHA256_OUTSIZE]; 495 uint8_t mac_hash[SHA256_OUTSIZE];
489 struct record_hdr *xhdr = buf; 496 struct record_hdr *xhdr = buf;
490 497
491 if (tls->encrypt_on_write) { 498 if (!tls->encrypt_on_write) {
499 xwrite(tls->fd, buf, size);
500 dbg("wrote %u bytes\n", size);
501 /* Handshake hash does not include record headers */
502 if (size > 5 && xhdr->type == RECORD_TYPE_HANDSHAKE) {
503 sha256_hash_dbg(">> sha256:%s", &tls->handshake_sha256_ctx, (uint8_t*)buf + 5, size - 5);
504 }
505 return;
506 }
507
492//TODO: convert hmac_sha256 to precomputed 508//TODO: convert hmac_sha256 to precomputed
493 hmac_sha256(mac_hash, 509 hmac_sha256(mac_hash,
494 tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key), 510 tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key),
495 &tls->write_seq64_be, sizeof(tls->write_seq64_be), 511 &tls->write_seq64_be, sizeof(tls->write_seq64_be),
496 buf, size, 512 buf, size,
497 NULL); 513 NULL);
498 tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be)); 514 tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be));
499 /* Temporarily change for writing */
500 xhdr->len16_lo += SHA256_OUTSIZE;
501 }
502 515
516 xhdr->len16_lo += SHA256_OUTSIZE;
503 xwrite(tls->fd, buf, size); 517 xwrite(tls->fd, buf, size);
518 xhdr->len16_lo -= SHA256_OUTSIZE;
504 dbg("wrote %u bytes\n", size); 519 dbg("wrote %u bytes\n", size);
505 520
506 if (tls->encrypt_on_write) { 521 xwrite(tls->fd, mac_hash, sizeof(mac_hash));
507 xwrite(tls->fd, mac_hash, sizeof(mac_hash)); 522 dbg("wrote %u bytes of hash\n", (int)sizeof(mac_hash));
508 dbg("wrote %u bytes of hash\n", (int)sizeof(mac_hash));
509 xhdr->len16_lo -= SHA256_OUTSIZE;
510 }
511
512 /* Handshake hash does not include record headers */
513 if (size > 5 && xhdr->type == RECORD_TYPE_HANDSHAKE) {
514 sha256_hash_dbg(">> sha256:%s", &tls->handshake_sha256_ctx, (uint8_t*)buf + 5, size - 5);
515 }
516} 523}
517 524
518static int xread_tls_block(tls_state_t *tls) 525static int xread_tls_block(tls_state_t *tls)
@@ -611,7 +618,7 @@ static uint8_t *enter_der_item(uint8_t *der, uint8_t **endp)
611{ 618{
612 uint8_t *new_der; 619 uint8_t *new_der;
613 unsigned len = get_der_len(&new_der, der, *endp); 620 unsigned len = get_der_len(&new_der, der, *endp);
614 dbg("entered der @%p:0x%02x len:%u inner_byte @%p:0x%02x\n", der, der[0], len, new_der, new_der[0]); 621 dbg_der("entered der @%p:0x%02x len:%u inner_byte @%p:0x%02x\n", der, der[0], len, new_der, new_der[0]);
615 /* Move "end" position to cover only this item */ 622 /* Move "end" position to cover only this item */
616 *endp = new_der + len; 623 *endp = new_der + len;
617 return new_der; 624 return new_der;
@@ -623,7 +630,7 @@ static uint8_t *skip_der_item(uint8_t *der, uint8_t *end)
623 unsigned len = get_der_len(&new_der, der, end); 630 unsigned len = get_der_len(&new_der, der, end);
624 /* Skip body */ 631 /* Skip body */
625 new_der += len; 632 new_der += len;
626 dbg("skipped der 0x%02x, next byte 0x%02x\n", der[0], new_der[0]); 633 dbg_der("skipped der 0x%02x, next byte 0x%02x\n", der[0], new_der[0]);
627 return new_der; 634 return new_der;
628} 635}
629 636
@@ -632,7 +639,7 @@ static void der_binary_to_pstm(pstm_int *pstm_n, uint8_t *der, uint8_t *end)
632 uint8_t *bin_ptr; 639 uint8_t *bin_ptr;
633 unsigned len = get_der_len(&bin_ptr, der, end); 640 unsigned len = get_der_len(&bin_ptr, der, end);
634 641
635 dbg("binary bytes:%u, first:0x%02x\n", len, bin_ptr[0]); 642 dbg_der("binary bytes:%u, first:0x%02x\n", len, bin_ptr[0]);
636 pstm_init_for_read_unsigned_bin(/*pool:*/ NULL, pstm_n, len); 643 pstm_init_for_read_unsigned_bin(/*pool:*/ NULL, pstm_n, len);
637 pstm_read_unsigned_bin(pstm_n, bin_ptr, len); 644 pstm_read_unsigned_bin(pstm_n, bin_ptr, len);
638 //return bin + len; 645 //return bin + len;
@@ -854,7 +861,7 @@ static void send_client_hello(tls_state_t *tls)
854 /* record.comprtypes[0] = 0; */ 861 /* record.comprtypes[0] = 0; */
855 862
856 //dbg (make it repeatable): memset(record.rand32, 0x11, sizeof(record.rand32)); 863 //dbg (make it repeatable): memset(record.rand32, 0x11, sizeof(record.rand32));
857 dbg(">> HANDSHAKE_CLIENT_HELLO\n"); 864 dbg(">> CLIENT_HELLO\n");
858 xwrite_and_hash(tls, &record, sizeof(record)); 865 xwrite_and_hash(tls, &record, sizeof(record));
859 memcpy(tls->client_and_server_rand32, record.rand32, sizeof(record.rand32)); 866 memcpy(tls->client_and_server_rand32, record.rand32, sizeof(record.rand32));
860} 867}
@@ -988,7 +995,7 @@ static void send_client_key_exchange(tls_state_t *tls)
988 record.xhdr.len16_hi = len >> 8; 995 record.xhdr.len16_hi = len >> 8;
989 record.xhdr.len16_lo = len & 0xff; 996 record.xhdr.len16_lo = len & 0xff;
990 997
991 dbg(">> HANDSHAKE_CLIENT_KEY_EXCHANGE\n"); 998 dbg(">> CLIENT_KEY_EXCHANGE\n");
992 xwrite_and_hash(tls, &record, sizeof(record.xhdr) + len); 999 xwrite_and_hash(tls, &record, sizeof(record.xhdr) + len);
993 1000
994 // RFC 5246 1001 // RFC 5246
@@ -1114,13 +1121,13 @@ static void send_change_cipher_spec(tls_state_t *tls)
1114// includes all existing cipher suites. 1121// includes all existing cipher suites.
1115static void send_client_finished(tls_state_t *tls) 1122static void send_client_finished(tls_state_t *tls)
1116{ 1123{
1117 struct client_finished { 1124 struct finished {
1118 struct record_hdr xhdr; 1125 struct record_hdr xhdr;
1119 uint8_t type; 1126 uint8_t type;
1120 uint8_t len24_hi, len24_mid, len24_lo; 1127 uint8_t len24_hi, len24_mid, len24_lo;
1121 uint8_t prf_result[12]; 1128 uint8_t prf_result[12];
1122 }; 1129 };
1123 struct client_finished record; 1130 struct finished record;
1124 uint8_t handshake_hash[SHA256_OUTSIZE]; 1131 uint8_t handshake_hash[SHA256_OUTSIZE];
1125 1132
1126 fill_handshake_record_hdr(&record.xhdr, sizeof(record)); 1133 fill_handshake_record_hdr(&record.xhdr, sizeof(record));
@@ -1134,13 +1141,13 @@ static void send_client_finished(tls_state_t *tls)
1134 ); 1141 );
1135 dump_hex("from secret: %s\n", tls->master_secret, sizeof(tls->master_secret)); 1142 dump_hex("from secret: %s\n", tls->master_secret, sizeof(tls->master_secret));
1136 dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1); 1143 dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1);
1137 dump_hex("%s\n", handshake_hash, sizeof(handshake_hash)); 1144 dump_hex("%s\n", handshake_hash, sizeof(handshake_hash));
1138 dump_hex("=> digest: %s\n", record.prf_result, sizeof(record.prf_result)); 1145 dump_hex("=> digest: %s\n", record.prf_result, sizeof(record.prf_result));
1139 1146
1140//(1) TODO: well, this should be encrypted on send, really. 1147//(1) TODO: well, this should be encrypted on send, really.
1141//(2) do we really need to also hash it? 1148//(2) do we really need to also hash it?
1142 1149
1143 dbg(">> HANDSHAKE_FINISHED\n"); 1150 dbg(">> FINISHED\n");
1144 xwrite_and_hash(tls, &record, sizeof(record)); 1151 xwrite_and_hash(tls, &record, sizeof(record));
1145} 1152}
1146 1153