aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h88
-rw-r--r--networking/ssl_client.c55
-rw-r--r--networking/tls.c151
-rw-r--r--networking/wget.c102
4 files changed, 221 insertions, 175 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 87f89c76d..ba3b1479e 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -355,6 +355,27 @@ extern char *skip_dev_pfx(const char *tty_name) FAST_FUNC;
355 355
356extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC; 356extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC;
357 357
358/* dmalloc will redefine these to it's own implementation. It is safe
359 * to have the prototypes here unconditionally. */
360void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC;
361void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
362void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
363void *xrealloc(void *old, size_t size) FAST_FUNC;
364/* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use
365 * at least v[idx] and v[idx+1], for all idx values.
366 * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...)
367 * when all elements are used up. New elements are zeroed out.
368 * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs -
369 * skipping an index is a bad bug - it may miss a realloc!
370 */
371#define xrealloc_vector(vector, shift, idx) \
372 xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx))
373void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC;
374char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC;
375char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC;
376void *xmemdup(const void *s, int n) FAST_FUNC RETURNS_MALLOC;
377
378
358//TODO: supply a pointer to char[11] buffer (avoid statics)? 379//TODO: supply a pointer to char[11] buffer (avoid statics)?
359extern const char *bb_mode_string(mode_t mode) FAST_FUNC; 380extern const char *bb_mode_string(mode_t mode) FAST_FUNC;
360extern int is_directory(const char *name, int followLinks) FAST_FUNC; 381extern int is_directory(const char *name, int followLinks) FAST_FUNC;
@@ -692,6 +713,52 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC;
692// Also mount.c and inetd.c are using gethostbyname(), 713// Also mount.c and inetd.c are using gethostbyname(),
693// + inet_common.c has additional IPv4-only stuff 714// + inet_common.c has additional IPv4-only stuff
694 715
716#define SHA256_INSIZE 64
717#define SHA256_OUTSIZE 32
718#define AES_BLOCKSIZE 16
719#define AES128_KEYSIZE 16
720#define AES256_KEYSIZE 32
721struct tls_handshake_data; /* opaque */
722typedef struct tls_state {
723 int ofd;
724 int ifd;
725
726 int min_encrypted_len_on_read;
727 uint8_t encrypt_on_write;
728
729 uint8_t *outbuf;
730 int outbuf_size;
731
732 int inbuf_size;
733 int ofs_to_buffered;
734 int buffered_size;
735 uint8_t *inbuf;
736
737 struct tls_handshake_data *hsd;
738
739 // RFC 5246
740 // sequence number
741 // Each connection state contains a sequence number, which is
742 // maintained separately for read and write states. The sequence
743 // number MUST be set to zero whenever a connection state is made the
744 // active state. Sequence numbers are of type uint64 and may not
745 // exceed 2^64-1.
746 /*uint64_t read_seq64_be;*/
747 uint64_t write_seq64_be;
748
749 uint8_t client_write_MAC_key[SHA256_OUTSIZE];
750 uint8_t server_write_MAC_key[SHA256_OUTSIZE];
751 uint8_t client_write_key[AES256_KEYSIZE];
752 uint8_t server_write_key[AES256_KEYSIZE];
753} tls_state_t;
754
755static inline tls_state_t *new_tls_state(void)
756{
757 tls_state_t *tls = xzalloc(sizeof(*tls));
758 return tls;
759}
760void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC;
761void tls_run_copy_loop(tls_state_t *tls) FAST_FUNC;
695 762
696void socket_want_pktinfo(int fd) FAST_FUNC; 763void socket_want_pktinfo(int fd) FAST_FUNC;
697ssize_t send_to_from(int fd, void *buf, size_t len, int flags, 764ssize_t send_to_from(int fd, void *buf, size_t len, int flags,
@@ -705,9 +772,6 @@ ssize_t recv_from_to(int fd, void *buf, size_t len, int flags,
705 772
706uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC; 773uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC;
707 774
708char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC;
709char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC;
710void *xmemdup(const void *s, int n) FAST_FUNC RETURNS_MALLOC;
711void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; 775void overlapping_strcpy(char *dst, const char *src) FAST_FUNC;
712char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; 776char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC;
713char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; 777char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC;
@@ -753,24 +817,6 @@ enum {
753}; 817};
754void visible(unsigned ch, char *buf, int flags) FAST_FUNC; 818void visible(unsigned ch, char *buf, int flags) FAST_FUNC;
755 819
756/* dmalloc will redefine these to it's own implementation. It is safe
757 * to have the prototypes here unconditionally. */
758void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC;
759void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
760void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC;
761void *xrealloc(void *old, size_t size) FAST_FUNC;
762/* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use
763 * at least v[idx] and v[idx+1], for all idx values.
764 * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...)
765 * when all elements are used up. New elements are zeroed out.
766 * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs -
767 * skipping an index is a bad bug - it may miss a realloc!
768 */
769#define xrealloc_vector(vector, shift, idx) \
770 xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx))
771void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC;
772
773
774extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC; 820extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC;
775extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count) FAST_FUNC; 821extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count) FAST_FUNC;
776// NB: will return short read on error, not -1, 822// NB: will return short read on error, not -1,
diff --git a/networking/ssl_client.c b/networking/ssl_client.c
new file mode 100644
index 000000000..cfeae1587
--- /dev/null
+++ b/networking/ssl_client.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2017 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6//config:config SSL_CLIENT
7//config: bool "ssl_client"
8//config: default y
9//config: select TLS
10//config: help
11//config: This tool pipes data to/from a socket, TLS-encrypting it.
12
13//applet:IF_SSL_CLIENT(APPLET(ssl_client, BB_DIR_USR_BIN, BB_SUID_DROP))
14
15//kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o
16
17//usage:#define ssl_client_trivial_usage
18//usage: "-s FD [-r FD] [-n SNI]"
19//usage:#define ssl_client_full_usage ""
20
21#include "libbb.h"
22
23int ssl_client_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
24int ssl_client_main(int argc UNUSED_PARAM, char **argv)
25{
26 tls_state_t *tls;
27 const char *sni = NULL;
28 int opt;
29
30 // INIT_G();
31
32 tls = new_tls_state();
33 opt = getopt32(argv, "s:#r:#n:", &tls->ofd, &tls->ifd, &sni);
34 if (!(opt & 2)) {
35 /* -r N defaults to -s N */
36 tls->ifd = tls->ofd;
37 }
38
39 if (!(opt & 3)) {
40 if (!argv[1])
41 bb_show_usage();
42 /* Undocumented debug feature: without -s and -r, takes HOST arg and connects to it */
43 //
44 // Talk to kernel.org:
45 // printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | ./busybox ssl_client kernel.org
46 if (!sni)
47 sni = argv[1];
48 tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443);
49 }
50
51 tls_handshake(tls, sni);
52 tls_run_copy_loop(tls);
53
54 return EXIT_SUCCESS;
55}
diff --git a/networking/tls.c b/networking/tls.c
index b111e4bb4..29cc5b9f3 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -4,11 +4,9 @@
4 * Licensed under GPLv2, see file LICENSE in this source tree. 4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */ 5 */
6//config:config TLS 6//config:config TLS
7//config: bool "tls (debugging)" 7//config: bool #No description makes it a hidden option
8//config: default n 8//config: default n
9 9
10//applet:IF_TLS(APPLET(tls, BB_DIR_USR_BIN, BB_SUID_DROP))
11
12//kbuild:lib-$(CONFIG_TLS) += tls.o 10//kbuild:lib-$(CONFIG_TLS) += tls.o
13//kbuild:lib-$(CONFIG_TLS) += tls_pstm.o 11//kbuild:lib-$(CONFIG_TLS) += tls_pstm.o
14//kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o 12//kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o
@@ -18,12 +16,7 @@
18//kbuild:lib-$(CONFIG_TLS) += tls_aes.o 16//kbuild:lib-$(CONFIG_TLS) += tls_aes.o
19////kbuild:lib-$(CONFIG_TLS) += tls_aes_gcm.o 17////kbuild:lib-$(CONFIG_TLS) += tls_aes_gcm.o
20 18
21//usage:#define tls_trivial_usage
22//usage: "HOST[:PORT]"
23//usage:#define tls_full_usage "\n\n"
24
25#include "tls.h" 19#include "tls.h"
26//#include "common_bufsiz.h"
27 20
28#define TLS_DEBUG 1 21#define TLS_DEBUG 1
29#define TLS_DEBUG_HASH 0 22#define TLS_DEBUG_HASH 0
@@ -165,13 +158,6 @@
165#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE 158#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE
166 159
167enum { 160enum {
168 SHA256_INSIZE = 64,
169 SHA256_OUTSIZE = 32,
170
171 AES_BLOCKSIZE = 16,
172 AES128_KEYSIZE = 16,
173 AES256_KEYSIZE = 32,
174
175 RSA_PREMASTER_SIZE = 48, 161 RSA_PREMASTER_SIZE = 48,
176 162
177 RECHDR_LEN = 5, 163 RECHDR_LEN = 5,
@@ -225,20 +211,7 @@ struct record_hdr {
225 uint8_t len16_hi, len16_lo; 211 uint8_t len16_hi, len16_lo;
226}; 212};
227 213
228typedef struct tls_state { 214struct tls_handshake_data {
229 int fd;
230
231 int min_encrypted_len_on_read;
232 uint8_t encrypt_on_write;
233
234 uint8_t *outbuf;
235 int outbuf_size;
236
237 int inbuf_size;
238 int ofs_to_buffered;
239 int buffered_size;
240 uint8_t *inbuf;
241
242//TODO: store just the DER key here, parse/use/delete it when sending client key 215//TODO: store just the DER key here, parse/use/delete it when sending client key
243//this way it will stay key type agnostic here. 216//this way it will stay key type agnostic here.
244 psRsaKey_t server_rsa_pub_key; 217 psRsaKey_t server_rsa_pub_key;
@@ -247,22 +220,7 @@ typedef struct tls_state {
247// these two are unused after finished messages are exchanged: 220// these two are unused after finished messages are exchanged:
248 sha256_ctx_t handshake_sha256_ctx; 221 sha256_ctx_t handshake_sha256_ctx;
249 uint8_t master_secret[48]; 222 uint8_t master_secret[48];
250 223};
251 // RFC 5246
252 // sequence number
253 // Each connection state contains a sequence number, which is
254 // maintained separately for read and write states. The sequence
255 // number MUST be set to zero whenever a connection state is made the
256 // active state. Sequence numbers are of type uint64 and may not
257 // exceed 2^64-1.
258 /*uint64_t read_seq64_be;*/
259 uint64_t write_seq64_be;
260
261 uint8_t client_write_MAC_key[SHA256_OUTSIZE];
262 uint8_t server_write_MAC_key[SHA256_OUTSIZE];
263 uint8_t client_write_key[AES256_KEYSIZE];
264 uint8_t server_write_key[AES256_KEYSIZE];
265} tls_state_t;
266 224
267 225
268static unsigned get24be(const uint8_t *p) 226static unsigned get24be(const uint8_t *p)
@@ -487,14 +445,6 @@ static void prf_hmac_sha256(
487#undef SEED 445#undef SEED
488} 446}
489 447
490static tls_state_t *new_tls_state(void)
491{
492 tls_state_t *tls = xzalloc(sizeof(*tls));
493 tls->fd = -1;
494 sha256_begin(&tls->handshake_sha256_ctx);
495 return tls;
496}
497
498static void tls_error_die(tls_state_t *tls) 448static void tls_error_die(tls_state_t *tls)
499{ 449{
500 dump_tls_record(tls->inbuf, tls->ofs_to_buffered + tls->buffered_size); 450 dump_tls_record(tls->inbuf, tls->ofs_to_buffered + tls->buffered_size);
@@ -597,7 +547,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
597 xhdr->len16_hi = size >> 8; 547 xhdr->len16_hi = size >> 8;
598 xhdr->len16_lo = size & 0xff; 548 xhdr->len16_lo = size & 0xff;
599 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); 549 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
600 xwrite(tls->fd, xhdr, RECHDR_LEN + size); 550 xwrite(tls->ofd, xhdr, RECHDR_LEN + size);
601 dbg("wrote %u bytes (NULL crypt, SHA256 hash)\n", size); 551 dbg("wrote %u bytes (NULL crypt, SHA256 hash)\n", size);
602 return; 552 return;
603 } 553 }
@@ -681,7 +631,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
681 xhdr->len16_hi = size >> 8; 631 xhdr->len16_hi = size >> 8;
682 xhdr->len16_lo = size & 0xff; 632 xhdr->len16_lo = size & 0xff;
683 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); 633 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
684 xwrite(tls->fd, xhdr, RECHDR_LEN + size); 634 xwrite(tls->ofd, xhdr, RECHDR_LEN + size);
685 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); 635 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size);
686} 636}
687 637
@@ -697,10 +647,10 @@ static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size)
697 xhdr->len16_hi = size >> 8; 647 xhdr->len16_hi = size >> 8;
698 xhdr->len16_lo = size & 0xff; 648 xhdr->len16_lo = size & 0xff;
699 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); 649 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
700 xwrite(tls->fd, xhdr, RECHDR_LEN + size); 650 xwrite(tls->ofd, xhdr, RECHDR_LEN + size);
701 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); 651 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size);
702 /* Handshake hash does not include record headers */ 652 /* Handshake hash does not include record headers */
703 sha256_hash_dbg(">> sha256:%s", &tls->handshake_sha256_ctx, buf, size); 653 sha256_hash_dbg(">> sha256:%s", &tls->hsd->handshake_sha256_ctx, buf, size);
704 return; 654 return;
705 } 655 }
706 xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE); 656 xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE);
@@ -769,7 +719,7 @@ static int tls_xread_record(tls_state_t *tls)
769 rem = tls->inbuf_size - total; 719 rem = tls->inbuf_size - total;
770 tls->inbuf = xrealloc(tls->inbuf, tls->inbuf_size); 720 tls->inbuf = xrealloc(tls->inbuf, tls->inbuf_size);
771 } 721 }
772 sz = safe_read(tls->fd, tls->inbuf + total, rem); 722 sz = safe_read(tls->ifd, tls->inbuf + total, rem);
773 if (sz <= 0) { 723 if (sz <= 0) {
774 if (sz == 0 && total == 0) { 724 if (sz == 0 && total == 0) {
775 /* "Abrupt" EOF, no TLS shutdown (seen from kernel.org) */ 725 /* "Abrupt" EOF, no TLS shutdown (seen from kernel.org) */
@@ -848,7 +798,7 @@ static int tls_xread_record(tls_state_t *tls)
848 * in our FINISHED record must include data of incoming packets too! 798 * in our FINISHED record must include data of incoming packets too!
849 */ 799 */
850 if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE) { 800 if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE) {
851 sha256_hash_dbg("<< sha256:%s", &tls->handshake_sha256_ctx, tls->inbuf + RECHDR_LEN, sz); 801 sha256_hash_dbg("<< sha256:%s", &tls->hsd->handshake_sha256_ctx, tls->inbuf + RECHDR_LEN, sz);
852 } 802 }
853 end: 803 end:
854 dbg("got block len:%u\n", sz); 804 dbg("got block len:%u\n", sz);
@@ -1059,12 +1009,12 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
1059 xfunc_die(); 1009 xfunc_die();
1060 der++; 1010 der++;
1061 der = enter_der_item(der, &end); /* enter SEQ */ 1011 der = enter_der_item(der, &end); /* enter SEQ */
1062 /* memset(tls->server_rsa_pub_key, 0, sizeof(tls->server_rsa_pub_key)); - already is */ 1012 /* memset(tls->hsd->server_rsa_pub_key, 0, sizeof(tls->hsd->server_rsa_pub_key)); - already is */
1063 der_binary_to_pstm(&tls->server_rsa_pub_key.N, der, end); /* modulus */ 1013 der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.N, der, end); /* modulus */
1064 der = skip_der_item(der, end); 1014 der = skip_der_item(der, end);
1065 der_binary_to_pstm(&tls->server_rsa_pub_key.e, der, end); /* exponent */ 1015 der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.e, der, end); /* exponent */
1066 tls->server_rsa_pub_key.size = pstm_unsigned_bin_size(&tls->server_rsa_pub_key.N); 1016 tls->hsd->server_rsa_pub_key.size = pstm_unsigned_bin_size(&tls->hsd->server_rsa_pub_key.N);
1067 dbg("server_rsa_pub_key.size:%d\n", tls->server_rsa_pub_key.size); 1017 dbg("server_rsa_pub_key.size:%d\n", tls->hsd->server_rsa_pub_key.size);
1068} 1018}
1069 1019
1070/* 1020/*
@@ -1140,7 +1090,7 @@ static void send_client_hello(tls_state_t *tls, const char *sni)
1140 tls_get_random(record->rand32, sizeof(record->rand32)); 1090 tls_get_random(record->rand32, sizeof(record->rand32));
1141 if (TLS_DEBUG_FIXED_SECRETS) 1091 if (TLS_DEBUG_FIXED_SECRETS)
1142 memset(record->rand32, 0x11, sizeof(record->rand32)); 1092 memset(record->rand32, 0x11, sizeof(record->rand32));
1143 memcpy(tls->client_and_server_rand32, record->rand32, sizeof(record->rand32)); 1093 memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32));
1144 /* record->session_id_len = 0; - already is */ 1094 /* record->session_id_len = 0; - already is */
1145 /* record->cipherid_len16_hi = 0; */ 1095 /* record->cipherid_len16_hi = 0; */
1146 record->cipherid_len16_lo = 2 * 1; 1096 record->cipherid_len16_lo = 2 * 1;
@@ -1225,7 +1175,7 @@ static void get_server_hello(tls_state_t *tls)
1225 } 1175 }
1226 1176
1227 dbg("<< SERVER_HELLO\n"); 1177 dbg("<< SERVER_HELLO\n");
1228 memcpy(tls->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32)); 1178 memcpy(tls->hsd->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32));
1229} 1179}
1230 1180
1231static void get_server_cert(tls_state_t *tls) 1181static void get_server_cert(tls_state_t *tls)
@@ -1282,7 +1232,7 @@ static void send_client_key_exchange(tls_state_t *tls)
1282 rsa_premaster[0] = TLS_MAJ; 1232 rsa_premaster[0] = TLS_MAJ;
1283 rsa_premaster[1] = TLS_MIN; 1233 rsa_premaster[1] = TLS_MIN;
1284 len = psRsaEncryptPub(/*pool:*/ NULL, 1234 len = psRsaEncryptPub(/*pool:*/ NULL,
1285 /* psRsaKey_t* */ &tls->server_rsa_pub_key, 1235 /* psRsaKey_t* */ &tls->hsd->server_rsa_pub_key,
1286 rsa_premaster, /*inlen:*/ sizeof(rsa_premaster), 1236 rsa_premaster, /*inlen:*/ sizeof(rsa_premaster),
1287 record->key, sizeof(record->key), 1237 record->key, sizeof(record->key),
1288 data_param_ignored 1238 data_param_ignored
@@ -1310,12 +1260,12 @@ static void send_client_key_exchange(tls_state_t *tls)
1310 // The master secret is always exactly 48 bytes in length. The length 1260 // The master secret is always exactly 48 bytes in length. The length
1311 // of the premaster secret will vary depending on key exchange method. 1261 // of the premaster secret will vary depending on key exchange method.
1312 prf_hmac_sha256( 1262 prf_hmac_sha256(
1313 tls->master_secret, sizeof(tls->master_secret), 1263 tls->hsd->master_secret, sizeof(tls->hsd->master_secret),
1314 rsa_premaster, sizeof(rsa_premaster), 1264 rsa_premaster, sizeof(rsa_premaster),
1315 "master secret", 1265 "master secret",
1316 tls->client_and_server_rand32, sizeof(tls->client_and_server_rand32) 1266 tls->hsd->client_and_server_rand32, sizeof(tls->hsd->client_and_server_rand32)
1317 ); 1267 );
1318 dump_hex("master secret:%s\n", tls->master_secret, sizeof(tls->master_secret)); 1268 dump_hex("master secret:%s\n", tls->hsd->master_secret, sizeof(tls->hsd->master_secret));
1319 1269
1320 // RFC 5246 1270 // RFC 5246
1321 // 6.3. Key Calculation 1271 // 6.3. Key Calculation
@@ -1354,8 +1304,8 @@ static void send_client_key_exchange(tls_state_t *tls)
1354 uint8_t tmp64[64]; 1304 uint8_t tmp64[64];
1355 1305
1356 /* make "server_rand32 + client_rand32" */ 1306 /* make "server_rand32 + client_rand32" */
1357 memcpy(&tmp64[0] , &tls->client_and_server_rand32[32], 32); 1307 memcpy(&tmp64[0] , &tls->hsd->client_and_server_rand32[32], 32);
1358 memcpy(&tmp64[32], &tls->client_and_server_rand32[0] , 32); 1308 memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32);
1359 1309
1360 prf_hmac_sha256( 1310 prf_hmac_sha256(
1361 tls->client_write_MAC_key, 2 * (SHA256_OUTSIZE + AES256_KEYSIZE), 1311 tls->client_write_MAC_key, 2 * (SHA256_OUTSIZE + AES256_KEYSIZE),
@@ -1363,7 +1313,7 @@ static void send_client_key_exchange(tls_state_t *tls)
1363 // server_write_MAC_key[SHA256_OUTSIZE] 1313 // server_write_MAC_key[SHA256_OUTSIZE]
1364 // client_write_key[AES256_KEYSIZE] 1314 // client_write_key[AES256_KEYSIZE]
1365 // server_write_key[AES256_KEYSIZE] 1315 // server_write_key[AES256_KEYSIZE]
1366 tls->master_secret, sizeof(tls->master_secret), 1316 tls->hsd->master_secret, sizeof(tls->hsd->master_secret),
1367 "key expansion", 1317 "key expansion",
1368 tmp64, 64 1318 tmp64, 64
1369 ); 1319 );
@@ -1384,7 +1334,7 @@ static const uint8_t rec_CHANGE_CIPHER_SPEC[] = {
1384static void send_change_cipher_spec(tls_state_t *tls) 1334static void send_change_cipher_spec(tls_state_t *tls)
1385{ 1335{
1386 dbg(">> CHANGE_CIPHER_SPEC\n"); 1336 dbg(">> CHANGE_CIPHER_SPEC\n");
1387 xwrite(tls->fd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC)); 1337 xwrite(tls->ofd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC));
1388} 1338}
1389 1339
1390// 7.4.9. Finished 1340// 7.4.9. Finished
@@ -1436,13 +1386,13 @@ static void send_client_finished(tls_state_t *tls)
1436 1386
1437 fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record)); 1387 fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record));
1438 1388
1439 sha256_peek(&tls->handshake_sha256_ctx, handshake_hash); 1389 sha256_peek(&tls->hsd->handshake_sha256_ctx, handshake_hash);
1440 prf_hmac_sha256(record->prf_result, sizeof(record->prf_result), 1390 prf_hmac_sha256(record->prf_result, sizeof(record->prf_result),
1441 tls->master_secret, sizeof(tls->master_secret), 1391 tls->hsd->master_secret, sizeof(tls->hsd->master_secret),
1442 "client finished", 1392 "client finished",
1443 handshake_hash, sizeof(handshake_hash) 1393 handshake_hash, sizeof(handshake_hash)
1444 ); 1394 );
1445 dump_hex("from secret: %s\n", tls->master_secret, sizeof(tls->master_secret)); 1395 dump_hex("from secret: %s\n", tls->hsd->master_secret, sizeof(tls->hsd->master_secret));
1446 dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1); 1396 dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1);
1447 dump_hex("%s\n", handshake_hash, sizeof(handshake_hash)); 1397 dump_hex("%s\n", handshake_hash, sizeof(handshake_hash));
1448 dump_hex("=> digest: %s\n", record->prf_result, sizeof(record->prf_result)); 1398 dump_hex("=> digest: %s\n", record->prf_result, sizeof(record->prf_result));
@@ -1451,7 +1401,7 @@ static void send_client_finished(tls_state_t *tls)
1451 xwrite_encrypted(tls, sizeof(*record), RECORD_TYPE_HANDSHAKE); 1401 xwrite_encrypted(tls, sizeof(*record), RECORD_TYPE_HANDSHAKE);
1452} 1402}
1453 1403
1454static void tls_handshake(tls_state_t *tls, const char *sni) 1404void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni)
1455{ 1405{
1456 // Client RFC 5246 Server 1406 // Client RFC 5246 Server
1457 // (*) - optional messages, not always sent 1407 // (*) - optional messages, not always sent
@@ -1472,6 +1422,9 @@ static void tls_handshake(tls_state_t *tls, const char *sni)
1472 // Application Data <------> Application Data 1422 // Application Data <------> Application Data
1473 int len; 1423 int len;
1474 1424
1425 tls->hsd = xzalloc(sizeof(*tls->hsd));
1426 sha256_begin(&tls->hsd->handshake_sha256_ctx);
1427
1475 send_client_hello(tls, sni); 1428 send_client_hello(tls, sni);
1476 get_server_hello(tls); 1429 get_server_hello(tls);
1477 1430
@@ -1541,6 +1494,12 @@ static void tls_handshake(tls_state_t *tls, const char *sni)
1541 tls_error_die(tls); 1494 tls_error_die(tls);
1542 dbg("<< FINISHED\n"); 1495 dbg("<< FINISHED\n");
1543 /* application data can be sent/received */ 1496 /* application data can be sent/received */
1497
1498 /* free handshake data */
1499// if (PARANOIA)
1500// memset(tls->hsd, 0, sizeof(*tls->hsd));
1501 free(tls->hsd);
1502 tls->hsd = NULL;
1544} 1503}
1545 1504
1546static void tls_xwrite(tls_state_t *tls, int len) 1505static void tls_xwrite(tls_state_t *tls, int len)
@@ -1557,35 +1516,17 @@ static void tls_xwrite(tls_state_t *tls, int len)
1557// openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' 1516// openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost'
1558// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL 1517// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL
1559// openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256 1518// openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256
1560//
1561// Talk to kernel.org:
1562// printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | ./busybox tls kernel.org
1563 1519
1564int tls_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1520void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
1565int tls_main(int argc UNUSED_PARAM, char **argv)
1566{ 1521{
1567 tls_state_t *tls;
1568 fd_set readfds; 1522 fd_set readfds;
1569 int inbuf_size; 1523 int inbuf_size;
1570 const int INBUF_STEP = 4 * 1024; 1524 const int INBUF_STEP = 4 * 1024;
1571 int cfd;
1572
1573 1525
1574 // INIT_G(); 1526//TODO: convert to poll
1575 // getopt32(argv, "myopts") 1527 /* Select loop copying stdin to ofd, and ifd to stdout */
1576
1577 if (!argv[1])
1578 bb_show_usage();
1579
1580 cfd = create_and_connect_stream_or_die(argv[1], 443);
1581
1582 tls = new_tls_state();
1583 tls->fd = cfd;
1584 tls_handshake(tls, argv[1]);
1585
1586 /* Select loop copying stdin to cfd, and cfd to stdout */
1587 FD_ZERO(&readfds); 1528 FD_ZERO(&readfds);
1588 FD_SET(cfd, &readfds); 1529 FD_SET(tls->ifd, &readfds);
1589 FD_SET(STDIN_FILENO, &readfds); 1530 FD_SET(STDIN_FILENO, &readfds);
1590 1531
1591 inbuf_size = INBUF_STEP; 1532 inbuf_size = INBUF_STEP;
@@ -1594,7 +1535,7 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1594 int nread; 1535 int nread;
1595 1536
1596 testfds = readfds; 1537 testfds = readfds;
1597 if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0) 1538 if (select(tls->ifd + 1, &testfds, NULL, NULL, NULL) < 0)
1598 bb_perror_msg_and_die("select"); 1539 bb_perror_msg_and_die("select");
1599 1540
1600 if (FD_ISSET(STDIN_FILENO, &testfds)) { 1541 if (FD_ISSET(STDIN_FILENO, &testfds)) {
@@ -1608,7 +1549,7 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1608 /* Close outgoing half-connection so they get EOF, 1549 /* Close outgoing half-connection so they get EOF,
1609 * but leave incoming alone so we can see response 1550 * but leave incoming alone so we can see response
1610 */ 1551 */
1611 //shutdown(cfd, SHUT_WR); 1552 //shutdown(tls->ofd, SHUT_WR);
1612 /* But TLS has no way to encode this, 1553 /* But TLS has no way to encode this,
1613 * doubt it's ok to do it "raw" 1554 * doubt it's ok to do it "raw"
1614 */ 1555 */
@@ -1626,7 +1567,7 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1626 tls_xwrite(tls, nread); 1567 tls_xwrite(tls, nread);
1627 } 1568 }
1628 } 1569 }
1629 if (FD_ISSET(cfd, &testfds)) { 1570 if (FD_ISSET(tls->ifd, &testfds)) {
1630 dbg("NETWORK HAS DATA\n"); 1571 dbg("NETWORK HAS DATA\n");
1631 read_record: 1572 read_record:
1632 nread = tls_xread_record(tls); 1573 nread = tls_xread_record(tls);
@@ -1634,7 +1575,7 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1634 /* TLS protocol has no real concept of one-sided shutdowns: 1575 /* TLS protocol has no real concept of one-sided shutdowns:
1635 * if we get "TLS EOF" from the peer, writes will fail too 1576 * if we get "TLS EOF" from the peer, writes will fail too
1636 */ 1577 */
1637 //FD_CLR(cfd, &readfds); 1578 //FD_CLR(tls->ifd, &readfds);
1638 //close(STDOUT_FILENO); 1579 //close(STDOUT_FILENO);
1639 //tls_free_inbuf(tls); /* mem usage optimization */ 1580 //tls_free_inbuf(tls); /* mem usage optimization */
1640 //continue; 1581 //continue;
@@ -1650,6 +1591,4 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1650 goto read_record; 1591 goto read_record;
1651 } 1592 }
1652 } 1593 }
1653
1654 return EXIT_SUCCESS;
1655} 1594}
diff --git a/networking/wget.c b/networking/wget.c
index 58ead4c96..a448acdae 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -47,18 +47,26 @@
47//config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option 47//config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option
48//config: will work in addition to -T. 48//config: will work in addition to -T.
49//config: 49//config:
50//config:config FEATURE_WGET_HTTPS
51//config: bool "Support HTTPS using internal TLS code"
52//config: default y
53//config: depends on WGET
54//config: select TLS
55//config: help
56//config: wget will use internal TLS code to connect to https:// URLs.
57//config: Note:
58//config: On NOMMU machines, ssl_helper applet should be available
59//config: in the $PATH for this to work. Make sure to select that applet.
60//config:
50//config:config FEATURE_WGET_OPENSSL 61//config:config FEATURE_WGET_OPENSSL
51//config: bool "Try to connect to HTTPS using openssl" 62//config: bool "Try to connect to HTTPS using openssl"
52//config: default y 63//config: default y
53//config: depends on WGET 64//config: depends on WGET
54//config: help 65//config: help
55//config: Choose how wget establishes SSL connection for https:// URLs. 66//config: Try to use openssl to handle HTTPS.
56//config:
57//config: Busybox itself contains no SSL code. wget will spawn
58//config: a helper program to talk over HTTPS.
59//config: 67//config:
60//config: OpenSSL has a simple SSL client for debug purposes. 68//config: OpenSSL has a simple SSL client for debug purposes.
61//config: If you select "openssl" helper, wget will effectively run: 69//config: If you select this option, wget will effectively run:
62//config: "openssl s_client -quiet -connect hostname:443 70//config: "openssl s_client -quiet -connect hostname:443
63//config: -servername hostname 2>/dev/null" and pipe its data 71//config: -servername hostname 2>/dev/null" and pipe its data
64//config: through it. -servername is not used if hostname is numeric. 72//config: through it. -servername is not used if hostname is numeric.
@@ -71,24 +79,9 @@
71//config: openssl is also a big binary, often dynamically linked 79//config: openssl is also a big binary, often dynamically linked
72//config: against ~15 libraries. 80//config: against ~15 libraries.
73//config: 81//config:
74//config:config FEATURE_WGET_SSL_HELPER 82//config: If openssl can't be executed, internal TLS code will be used
75//config: bool "Try to connect to HTTPS using ssl_helper" 83//config: (if you enabled it); if openssl can be executed but fails later,
76//config: default y 84//config: wget can't detect this, and download will fail.
77//config: depends on WGET
78//config: help
79//config: Choose how wget establishes SSL connection for https:// URLs.
80//config:
81//config: Busybox itself contains no SSL code. wget will spawn
82//config: a helper program to talk over HTTPS.
83//config:
84//config: ssl_helper is a tool which can be built statically
85//config: from busybox sources against a small embedded SSL library.
86//config: Please see networking/ssl_helper/README.
87//config: It does not require double host resolution and emits
88//config: error messages to stderr.
89//config:
90//config: Precompiled static binary may be available at
91//config: http://busybox.net/downloads/binaries/
92 85
93//applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) 86//applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP))
94 87
@@ -137,7 +130,7 @@
137#endif 130#endif
138 131
139 132
140#define SSL_SUPPORTED (ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER) 133#define SSL_SUPPORTED (ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_HTTPS)
141 134
142struct host_info { 135struct host_info {
143 char *allocated; 136 char *allocated;
@@ -657,7 +650,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
657 char *servername; 650 char *servername;
658 int sp[2]; 651 int sp[2];
659 int pid; 652 int pid;
660 IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) 653 IF_FEATURE_WGET_HTTPS(volatile int child_failed = 0;)
661 654
662 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 655 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0)
663 /* Kernel can have AF_UNIX support disabled */ 656 /* Kernel can have AF_UNIX support disabled */
@@ -702,7 +695,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
702 695
703 BB_EXECVP(argv[0], argv); 696 BB_EXECVP(argv[0], argv);
704 xmove_fd(3, 2); 697 xmove_fd(3, 2);
705# if ENABLE_FEATURE_WGET_SSL_HELPER 698# if ENABLE_FEATURE_WGET_HTTPS
706 child_failed = 1; 699 child_failed = 1;
707 xfunc_die(); 700 xfunc_die();
708# else 701# else
@@ -715,7 +708,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
715 free(servername); 708 free(servername);
716 free(allocated); 709 free(allocated);
717 close(sp[1]); 710 close(sp[1]);
718# if ENABLE_FEATURE_WGET_SSL_HELPER 711# if ENABLE_FEATURE_WGET_HTTPS
719 if (child_failed) { 712 if (child_failed) {
720 close(sp[0]); 713 close(sp[0]);
721 return -1; 714 return -1;
@@ -725,38 +718,51 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
725} 718}
726#endif 719#endif
727 720
728/* See networking/ssl_helper/README how to build one */ 721#if ENABLE_FEATURE_WGET_HTTPS
729#if ENABLE_FEATURE_WGET_SSL_HELPER 722static void spawn_ssl_client(const char *host, int network_fd)
730static void spawn_https_helper_small(int network_fd)
731{ 723{
732 int sp[2]; 724 int sp[2];
733 int pid; 725 int pid;
726 char *servername, *p;
727
728 servername = xstrdup(host);
729 p = strrchr(servername, ':');
730 if (p) *p = '\0';
734 731
735 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 732 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0)
736 /* Kernel can have AF_UNIX support disabled */ 733 /* Kernel can have AF_UNIX support disabled */
737 bb_perror_msg_and_die("socketpair"); 734 bb_perror_msg_and_die("socketpair");
738 735
736 fflush_all();
739 pid = BB_MMU ? xfork() : xvfork(); 737 pid = BB_MMU ? xfork() : xvfork();
740 if (pid == 0) { 738 if (pid == 0) {
741 /* Child */ 739 /* Child */
742 char *argv[3];
743
744 close(sp[0]); 740 close(sp[0]);
745 xmove_fd(sp[1], 0); 741 xmove_fd(sp[1], 0);
746 xdup2(0, 1); 742 xdup2(0, 1);
747 xmove_fd(network_fd, 3); 743 if (BB_MMU) {
748 /* 744 tls_state_t *tls = new_tls_state();
749 * A simple ssl/tls helper 745 tls->ifd = tls->ofd = network_fd;
750 */ 746 tls_handshake(tls, servername);
751 argv[0] = (char*)"ssl_helper"; 747 tls_run_copy_loop(tls);
752 argv[1] = (char*)"-d3"; 748 exit(0);
753 argv[2] = NULL; 749 } else {
754 BB_EXECVP(argv[0], argv); 750 char *argv[5];
755 bb_perror_msg_and_die("can't execute '%s'", argv[0]); 751 xmove_fd(network_fd, 3);
752 argv[0] = (char*)"ssl_client";
753 argv[1] = (char*)"-s3";
754 //TODO: if (!is_ip_address(servername))...
755 argv[2] = (char*)"-n";
756 argv[3] = servername;
757 argv[4] = NULL;
758 BB_EXECVP(argv[0], argv);
759 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
760 }
756 /* notreached */ 761 /* notreached */
757 } 762 }
758 763
759 /* Parent */ 764 /* Parent */
765 free(servername);
760 close(sp[1]); 766 close(sp[1]);
761 xmove_fd(sp[0], network_fd); 767 xmove_fd(sp[0], network_fd);
762} 768}
@@ -1005,16 +1011,16 @@ static void download_one_url(const char *url)
1005 1011
1006 /* Open socket to http(s) server */ 1012 /* Open socket to http(s) server */
1007#if ENABLE_FEATURE_WGET_OPENSSL 1013#if ENABLE_FEATURE_WGET_OPENSSL
1008 /* openssl (and maybe ssl_helper) support is configured */ 1014 /* openssl (and maybe internal TLS) support is configured */
1009 if (target.protocol == P_HTTPS) { 1015 if (target.protocol == P_HTTPS) {
1010 /* openssl-based helper 1016 /* openssl-based helper
1011 * Inconvenient API since we can't give it an open fd 1017 * Inconvenient API since we can't give it an open fd
1012 */ 1018 */
1013 int fd = spawn_https_helper_openssl(server.host, server.port); 1019 int fd = spawn_https_helper_openssl(server.host, server.port);
1014# if ENABLE_FEATURE_WGET_SSL_HELPER 1020# if ENABLE_FEATURE_WGET_HTTPS
1015 if (fd < 0) { /* no openssl? try ssl_helper */ 1021 if (fd < 0) { /* no openssl? try internal */
1016 sfp = open_socket(lsa); 1022 sfp = open_socket(lsa);
1017 spawn_https_helper_small(fileno(sfp)); 1023 spawn_ssl_client(server.host, fileno(sfp));
1018 goto socket_opened; 1024 goto socket_opened;
1019 } 1025 }
1020# else 1026# else
@@ -1027,11 +1033,11 @@ static void download_one_url(const char *url)
1027 } 1033 }
1028 sfp = open_socket(lsa); 1034 sfp = open_socket(lsa);
1029 socket_opened: 1035 socket_opened:
1030#elif ENABLE_FEATURE_WGET_SSL_HELPER 1036#elif ENABLE_FEATURE_WGET_HTTPS
1031 /* Only ssl_helper support is configured */ 1037 /* Only internal TLS support is configured */
1032 sfp = open_socket(lsa); 1038 sfp = open_socket(lsa);
1033 if (target.protocol == P_HTTPS) 1039 if (target.protocol == P_HTTPS)
1034 spawn_https_helper_small(fileno(sfp)); 1040 spawn_ssl_client(server.host, fileno(sfp));
1035#else 1041#else
1036 /* ssl (https) support is not configured */ 1042 /* ssl (https) support is not configured */
1037 sfp = open_socket(lsa); 1043 sfp = open_socket(lsa);