diff options
Diffstat (limited to 'networking')
-rw-r--r-- | networking/Config.src | 30 | ||||
-rw-r--r-- | networking/hostname.c | 4 | ||||
-rw-r--r-- | networking/libiproute/iproute.c | 16 | ||||
-rw-r--r-- | networking/ntpd.c | 2 | ||||
-rw-r--r-- | networking/tls.c | 570 | ||||
-rw-r--r-- | networking/tls.h | 2 |
6 files changed, 601 insertions, 23 deletions
diff --git a/networking/Config.src b/networking/Config.src index 0942645c3..aa0806a18 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -72,9 +72,28 @@ config FEATURE_HWIB | |||
72 | help | 72 | help |
73 | Support for printing infiniband addresses in network applets. | 73 | Support for printing infiniband addresses in network applets. |
74 | 74 | ||
75 | choice | ||
76 | prompt "TLS implementation" | ||
77 | default FEATURE_TLS_INTERNAL | ||
78 | |||
79 | config FEATURE_TLS_INTERNAL | ||
80 | bool "Internal" | ||
81 | depends on TLS | ||
82 | help | ||
83 | Use the BusyBox default internal TLS implementation. | ||
84 | |||
85 | config FEATURE_TLS_SCHANNEL | ||
86 | bool "Schannel SSP" | ||
87 | depends on TLS && PLATFORM_MINGW32 | ||
88 | help | ||
89 | Use the Schannel SSP to provide TLS support. | ||
90 | Reduces code size and enables certificate checking. | ||
91 | |||
92 | endchoice | ||
93 | |||
75 | config FEATURE_TLS_SHA1 | 94 | config FEATURE_TLS_SHA1 |
76 | bool "In TLS code, support ciphers which use deprecated SHA1" | 95 | bool "In TLS code, support ciphers which use deprecated SHA1" |
77 | depends on TLS | 96 | depends on FEATURE_TLS_INTERNAL |
78 | default n | 97 | default n |
79 | help | 98 | help |
80 | Selecting this option increases interoperability with very old | 99 | Selecting this option increases interoperability with very old |
@@ -83,6 +102,15 @@ config FEATURE_TLS_SHA1 | |||
83 | Most TLS servers support SHA256 today (2018), since SHA1 is | 102 | Most TLS servers support SHA256 today (2018), since SHA1 is |
84 | considered possibly insecure (although not yet definitely broken). | 103 | considered possibly insecure (although not yet definitely broken). |
85 | 104 | ||
105 | config FEATURE_TLS_SCHANNEL_1_3 | ||
106 | bool "Enable TLS 1.3 support for Schannel" | ||
107 | depends on FEATURE_TLS_SCHANNEL | ||
108 | default n | ||
109 | help | ||
110 | Enable TLS 1.3 support for Schannel. | ||
111 | This only works on Windows 11/Server 2022 | ||
112 | and up. | ||
113 | |||
86 | INSERT | 114 | INSERT |
87 | 115 | ||
88 | source networking/udhcp/Config.in | 116 | source networking/udhcp/Config.in |
diff --git a/networking/hostname.c b/networking/hostname.c index 36cb70866..101b89e77 100644 --- a/networking/hostname.c +++ b/networking/hostname.c | |||
@@ -25,8 +25,8 @@ | |||
25 | //applet:IF_DNSDOMAINNAME(APPLET_NOEXEC(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) | 25 | //applet:IF_DNSDOMAINNAME(APPLET_NOEXEC(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) |
26 | //applet:IF_HOSTNAME( APPLET_NOEXEC(hostname, hostname, BB_DIR_BIN, BB_SUID_DROP, hostname )) | 26 | //applet:IF_HOSTNAME( APPLET_NOEXEC(hostname, hostname, BB_DIR_BIN, BB_SUID_DROP, hostname )) |
27 | 27 | ||
28 | //kbuild: lib-$(CONFIG_HOSTNAME) += hostname.o | 28 | //kbuild:lib-$(CONFIG_HOSTNAME) += hostname.o |
29 | //kbuild: lib-$(CONFIG_DNSDOMAINNAME) += hostname.o | 29 | //kbuild:lib-$(CONFIG_DNSDOMAINNAME) += hostname.o |
30 | 30 | ||
31 | //usage:#define hostname_trivial_usage | 31 | //usage:#define hostname_trivial_usage |
32 | //usage: "[-sidf] [HOSTNAME | -F FILE]" | 32 | //usage: "[-sidf] [HOSTNAME | -F FILE]" |
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index cd77f642f..a30f070eb 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -302,24 +302,22 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
302 | printf("notify "); | 302 | printf("notify "); |
303 | } | 303 | } |
304 | 304 | ||
305 | if (r->rtm_family == AF_INET6) { | 305 | if (r->rtm_family == AF_INET || r->rtm_family == AF_INET6) { |
306 | struct rta_cacheinfo *ci = NULL; | 306 | if (r->rtm_family == AF_INET) { |
307 | if (tb[RTA_CACHEINFO]) { | ||
308 | ci = RTA_DATA(tb[RTA_CACHEINFO]); | ||
309 | } | ||
310 | if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { | ||
311 | if (r->rtm_flags & RTM_F_CLONED) { | 307 | if (r->rtm_flags & RTM_F_CLONED) { |
312 | printf("%c cache ", _SL_); | 308 | printf("%c cache ", _SL_); |
309 | /* upstream: print_cache_flags() prints more here */ | ||
313 | } | 310 | } |
311 | } | ||
312 | if (tb[RTA_CACHEINFO]) { | ||
313 | struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]); | ||
314 | if (ci->rta_expires) { | 314 | if (ci->rta_expires) { |
315 | printf(" expires %dsec", ci->rta_expires / get_hz()); | 315 | printf(" expires %dsec", ci->rta_expires / get_hz()); |
316 | } | 316 | } |
317 | if (ci->rta_error != 0) { | 317 | if (ci->rta_error != 0) { |
318 | printf(" error %d", ci->rta_error); | 318 | printf(" error %d", ci->rta_error); |
319 | } | 319 | } |
320 | } else if (ci) { | 320 | /* upstream: print_rta_cacheinfo() prints more here */ |
321 | if (ci->rta_error != 0) | ||
322 | printf(" error %d", ci->rta_error); | ||
323 | } | 321 | } |
324 | } | 322 | } |
325 | if (tb[RTA_IIF] && G_filter.iif == 0) { | 323 | if (tb[RTA_IIF] && G_filter.iif == 0) { |
diff --git a/networking/ntpd.c b/networking/ntpd.c index dcbdb8e60..4c4842cb2 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -205,7 +205,7 @@ | |||
205 | #define MINDISP 0.01 /* minimum dispersion (sec) */ | 205 | #define MINDISP 0.01 /* minimum dispersion (sec) */ |
206 | #define MAXDISP 16 /* maximum dispersion (sec) */ | 206 | #define MAXDISP 16 /* maximum dispersion (sec) */ |
207 | #define MAXSTRAT 16 /* maximum stratum (infinity metric) */ | 207 | #define MAXSTRAT 16 /* maximum stratum (infinity metric) */ |
208 | #define MAXDIST 1 /* distance threshold (sec) */ | 208 | #define MAXDIST 3 /* distance threshold (sec): do not use peers who are farther away */ |
209 | #define MIN_SELECTED 1 /* minimum intersection survivors */ | 209 | #define MIN_SELECTED 1 /* minimum intersection survivors */ |
210 | #define MIN_CLUSTERED 3 /* minimum cluster survivors */ | 210 | #define MIN_CLUSTERED 3 /* minimum cluster survivors */ |
211 | 211 | ||
diff --git a/networking/tls.c b/networking/tls.c index 736bce323..89726fee0 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -10,20 +10,24 @@ | |||
10 | //Config.src also defines FEATURE_TLS_SHA1 option | 10 | //Config.src also defines FEATURE_TLS_SHA1 option |
11 | 11 | ||
12 | //kbuild:lib-$(CONFIG_TLS) += tls.o | 12 | //kbuild:lib-$(CONFIG_TLS) += tls.o |
13 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm.o | 13 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm.o |
14 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o | 14 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm_montgomery_reduce.o |
15 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o | 15 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm_mul_comba.o |
16 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o | 16 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm_sqr_comba.o |
17 | //kbuild:lib-$(CONFIG_TLS) += tls_aes.o | 17 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_aes.o |
18 | //kbuild:lib-$(CONFIG_TLS) += tls_aesgcm.o | 18 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_aesgcm.o |
19 | //kbuild:lib-$(CONFIG_TLS) += tls_rsa.o | 19 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_rsa.o |
20 | //kbuild:lib-$(CONFIG_TLS) += tls_fe.o | 20 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_fe.o |
21 | //kbuild:lib-$(CONFIG_TLS) += tls_sp_c32.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_sp_c32.o |
22 | 22 | ||
23 | #include "tls.h" | 23 | #include "tls.h" |
24 | 24 | ||
25 | #if ENABLE_FEATURE_TLS_SCHANNEL || ENABLE_FEATURE_USE_CNG_API | ||
26 | #include <windows.h> | ||
27 | #endif | ||
28 | |||
29 | #if !ENABLE_FEATURE_TLS_SCHANNEL | ||
25 | #if ENABLE_FEATURE_USE_CNG_API | 30 | #if ENABLE_FEATURE_USE_CNG_API |
26 | # include <windows.h> | ||
27 | # include <bcrypt.h> | 31 | # include <bcrypt.h> |
28 | 32 | ||
29 | // these work on Windows >= 10 | 33 | // these work on Windows >= 10 |
@@ -2555,3 +2559,549 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags) | |||
2555 | } | 2559 | } |
2556 | } | 2560 | } |
2557 | } | 2561 | } |
2562 | #else | ||
2563 | |||
2564 | #if ENABLE_FEATURE_TLS_SCHANNEL_1_3 | ||
2565 | #include <subauth.h> | ||
2566 | #endif | ||
2567 | |||
2568 | #define SCHANNEL_USE_BLACKLISTS | ||
2569 | |||
2570 | #include <security.h> | ||
2571 | #include <schannel.h> | ||
2572 | |||
2573 | |||
2574 | #define BB_SCHANNEL_ISC_FLAGS \ | ||
2575 | (ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | \ | ||
2576 | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS) | ||
2577 | |||
2578 | static char *hresult_to_error_string(HRESULT result) { | ||
2579 | char *output = NULL; | ||
2580 | |||
2581 | FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | ||
2582 | | FORMAT_MESSAGE_IGNORE_INSERTS | | ||
2583 | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, result, | ||
2584 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
2585 | (char *) &output, 0, NULL); | ||
2586 | return output; | ||
2587 | } | ||
2588 | |||
2589 | static ssize_t tls_read(struct tls_state *state, char *buf, ssize_t len) { | ||
2590 | ssize_t amount_read = 0; | ||
2591 | |||
2592 | if (state->closed) { | ||
2593 | return 0; | ||
2594 | } | ||
2595 | |||
2596 | while (len > 0) { | ||
2597 | if (state->out_buffer && (state->out_buffer_size > 0)) { | ||
2598 | unsigned long copy_amount = | ||
2599 | min(len, (ssize_t) state->out_buffer_size); | ||
2600 | memcpy(buf, state->out_buffer, copy_amount); | ||
2601 | |||
2602 | amount_read += copy_amount; | ||
2603 | buf += copy_amount; | ||
2604 | len -= copy_amount; | ||
2605 | |||
2606 | if (copy_amount == state->out_buffer_size) { | ||
2607 | // We've used all the decrypted data | ||
2608 | // Move extra data to the front | ||
2609 | memmove(state->in_buffer, | ||
2610 | state->in_buffer + state->out_buffer_used, | ||
2611 | state->in_buffer_size - state->out_buffer_used); | ||
2612 | state->in_buffer_size -= state->out_buffer_used; | ||
2613 | |||
2614 | state->out_buffer = NULL; | ||
2615 | state->out_buffer_used = 0; | ||
2616 | state->out_buffer_size = 0; | ||
2617 | } else { | ||
2618 | state->out_buffer_size -= copy_amount; | ||
2619 | state->out_buffer += copy_amount; | ||
2620 | } | ||
2621 | } else { | ||
2622 | SECURITY_STATUS status; | ||
2623 | |||
2624 | int received; | ||
2625 | |||
2626 | SecBuffer buffers[4]; | ||
2627 | |||
2628 | SecBufferDesc desc; | ||
2629 | |||
2630 | buffers[0].BufferType = SECBUFFER_DATA; | ||
2631 | buffers[0].pvBuffer = state->in_buffer; | ||
2632 | buffers[0].cbBuffer = state->in_buffer_size; | ||
2633 | |||
2634 | buffers[1].BufferType = SECBUFFER_EMPTY; | ||
2635 | buffers[1].pvBuffer = NULL; | ||
2636 | buffers[1].cbBuffer = 0; | ||
2637 | |||
2638 | buffers[2].BufferType = SECBUFFER_EMPTY; | ||
2639 | buffers[2].pvBuffer = NULL; | ||
2640 | buffers[2].cbBuffer = 0; | ||
2641 | |||
2642 | buffers[3].BufferType = SECBUFFER_EMPTY; | ||
2643 | buffers[3].pvBuffer = NULL; | ||
2644 | buffers[3].cbBuffer = 0; | ||
2645 | |||
2646 | desc.ulVersion = SECBUFFER_VERSION; | ||
2647 | desc.pBuffers = buffers; | ||
2648 | desc.cBuffers = _countof(buffers); | ||
2649 | |||
2650 | status = DecryptMessage(&state->ctx_handle, &desc, 0, NULL); | ||
2651 | |||
2652 | switch (status) { | ||
2653 | case SEC_E_OK:{ | ||
2654 | state->out_buffer = buffers[1].pvBuffer; | ||
2655 | state->out_buffer_size = buffers[1].cbBuffer; | ||
2656 | |||
2657 | state->out_buffer_used = state->in_buffer_size; | ||
2658 | if (buffers[3].BufferType == SECBUFFER_EXTRA) { | ||
2659 | state->out_buffer_used -= buffers[3].cbBuffer; | ||
2660 | } | ||
2661 | |||
2662 | continue; | ||
2663 | } | ||
2664 | case SEC_I_CONTEXT_EXPIRED:{ | ||
2665 | state->closed = 1; | ||
2666 | goto Success; | ||
2667 | } | ||
2668 | case SEC_I_RENEGOTIATE:{ | ||
2669 | // Renegotiate the TLS connection. | ||
2670 | // Microsoft repurposed this flag | ||
2671 | // for TLS 1.3 support. | ||
2672 | int i; | ||
2673 | |||
2674 | DWORD flags; | ||
2675 | |||
2676 | SecBuffer in_buffers[2]; | ||
2677 | |||
2678 | SecBuffer out_buffers[2]; | ||
2679 | |||
2680 | SecBufferDesc in_desc; | ||
2681 | |||
2682 | SecBufferDesc out_desc; | ||
2683 | |||
2684 | |||
2685 | for (i = 0; i < 4; i++) { | ||
2686 | if (buffers[i].BufferType == SECBUFFER_EXTRA) | ||
2687 | break; | ||
2688 | } | ||
2689 | |||
2690 | flags = BB_SCHANNEL_ISC_FLAGS; | ||
2691 | |||
2692 | in_buffers[0].BufferType = SECBUFFER_TOKEN; | ||
2693 | in_buffers[0].pvBuffer = buffers[i].pvBuffer; | ||
2694 | in_buffers[0].cbBuffer = buffers[i].cbBuffer; | ||
2695 | |||
2696 | in_buffers[1].BufferType = SECBUFFER_EMPTY; | ||
2697 | in_buffers[1].pvBuffer = NULL; | ||
2698 | in_buffers[1].cbBuffer = 0; | ||
2699 | |||
2700 | out_buffers[0].BufferType = SECBUFFER_TOKEN; | ||
2701 | out_buffers[0].pvBuffer = NULL; | ||
2702 | out_buffers[0].cbBuffer = 0; | ||
2703 | |||
2704 | out_buffers[1].BufferType = SECBUFFER_ALERT; | ||
2705 | out_buffers[1].pvBuffer = NULL; | ||
2706 | out_buffers[1].cbBuffer = 0; | ||
2707 | |||
2708 | in_desc.ulVersion = SECBUFFER_VERSION; | ||
2709 | in_desc.pBuffers = in_buffers; | ||
2710 | in_desc.cBuffers = _countof(in_buffers); | ||
2711 | |||
2712 | out_desc.ulVersion = SECBUFFER_VERSION; | ||
2713 | out_desc.pBuffers = out_buffers; | ||
2714 | out_desc.cBuffers = _countof(out_buffers); | ||
2715 | |||
2716 | status = InitializeSecurityContext(&state->cred_handle, | ||
2717 | state->initialized ? | ||
2718 | &state->ctx_handle : NULL, | ||
2719 | state->initialized ? NULL : | ||
2720 | state->hostname, flags, 0, | ||
2721 | 0, | ||
2722 | state->initialized ? | ||
2723 | &in_desc : NULL, 0, | ||
2724 | state->initialized ? NULL : | ||
2725 | &state->ctx_handle, | ||
2726 | &out_desc, &flags, 0); | ||
2727 | |||
2728 | if (status != SEC_E_OK) { | ||
2729 | bb_error_msg_and_die("schannel: renegotiate failed: (0x%08lx): %s", | ||
2730 | status, hresult_to_error_string(status)); | ||
2731 | } | ||
2732 | |||
2733 | if (in_buffers[1].BufferType == SECBUFFER_EXTRA) { | ||
2734 | memmove(state->in_buffer, | ||
2735 | state->in_buffer + (state->in_buffer_size - | ||
2736 | in_buffers[1].cbBuffer), | ||
2737 | in_buffers[1].cbBuffer); | ||
2738 | } | ||
2739 | |||
2740 | state->out_buffer_used = | ||
2741 | state->in_buffer_size - in_buffers[1].cbBuffer; | ||
2742 | state->in_buffer_size = in_buffers[1].cbBuffer; | ||
2743 | |||
2744 | continue; | ||
2745 | } | ||
2746 | case SEC_E_INCOMPLETE_MESSAGE:{ | ||
2747 | break; | ||
2748 | } | ||
2749 | default:{ | ||
2750 | bb_error_msg_and_die("schannel: DecryptMessage failed: (0x%08lx): %s", status, | ||
2751 | hresult_to_error_string(status)); | ||
2752 | } | ||
2753 | } | ||
2754 | |||
2755 | received = | ||
2756 | safe_read(state->ifd, | ||
2757 | state->in_buffer + state->in_buffer_size, | ||
2758 | sizeof(state->in_buffer) - state->in_buffer_size); | ||
2759 | if (received == 0) { | ||
2760 | state->closed = 1; | ||
2761 | goto Success; | ||
2762 | } else if (received < 0) { | ||
2763 | bb_error_msg_and_die("schannel: read() failed"); | ||
2764 | } | ||
2765 | |||
2766 | state->in_buffer_size += received; | ||
2767 | } | ||
2768 | } | ||
2769 | |||
2770 | Success: | ||
2771 | return amount_read; | ||
2772 | } | ||
2773 | |||
2774 | static void tls_write(struct tls_state *state, char *buf, size_t len) { | ||
2775 | if (state->closed) { | ||
2776 | bb_error_msg_and_die("schannel: attempted to write to a closed connection"); | ||
2777 | } | ||
2778 | |||
2779 | while (len > 0) { | ||
2780 | unsigned long copy_amount = | ||
2781 | min(len, (size_t) state->stream_sizes.cbMaximumMessage); | ||
2782 | char *write_buffer = _alloca(sizeof(state->in_buffer)); | ||
2783 | |||
2784 | SECURITY_STATUS status; | ||
2785 | |||
2786 | SecBuffer buffers[4]; | ||
2787 | |||
2788 | SecBufferDesc desc; | ||
2789 | |||
2790 | buffers[0].BufferType = SECBUFFER_STREAM_HEADER; | ||
2791 | buffers[0].pvBuffer = write_buffer; | ||
2792 | buffers[0].cbBuffer = state->stream_sizes.cbHeader; | ||
2793 | |||
2794 | buffers[1].BufferType = SECBUFFER_DATA; | ||
2795 | buffers[1].pvBuffer = write_buffer + state->stream_sizes.cbHeader; | ||
2796 | buffers[1].cbBuffer = copy_amount; | ||
2797 | |||
2798 | buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; | ||
2799 | buffers[2].pvBuffer = | ||
2800 | write_buffer + state->stream_sizes.cbHeader + copy_amount; | ||
2801 | buffers[2].cbBuffer = state->stream_sizes.cbTrailer; | ||
2802 | |||
2803 | buffers[3].BufferType = SECBUFFER_EMPTY; | ||
2804 | buffers[3].pvBuffer = NULL; | ||
2805 | buffers[3].cbBuffer = 0; | ||
2806 | |||
2807 | memcpy(buffers[1].pvBuffer, buf, copy_amount); | ||
2808 | |||
2809 | desc.ulVersion = SECBUFFER_VERSION; | ||
2810 | desc.pBuffers = buffers; | ||
2811 | desc.cBuffers = _countof(buffers); | ||
2812 | |||
2813 | status = EncryptMessage(&state->ctx_handle, 0, &desc, 0); | ||
2814 | if (status != SEC_E_OK) { | ||
2815 | bb_error_msg_and_die("schannel: EncryptMessage failed: (0x%08lx): %s", status, | ||
2816 | hresult_to_error_string(status)); | ||
2817 | } | ||
2818 | |||
2819 | xwrite(state->ofd, write_buffer, | ||
2820 | buffers[0].cbBuffer + buffers[1].cbBuffer + | ||
2821 | buffers[2].cbBuffer); | ||
2822 | |||
2823 | len -= copy_amount; | ||
2824 | } | ||
2825 | } | ||
2826 | |||
2827 | static void tls_disconnect(tls_state_t * state) { | ||
2828 | SECURITY_STATUS status; | ||
2829 | DWORD token = SCHANNEL_SHUTDOWN; | ||
2830 | DWORD flags = BB_SCHANNEL_ISC_FLAGS; | ||
2831 | |||
2832 | SecBuffer buf_token; | ||
2833 | |||
2834 | SecBufferDesc buf_token_desc; | ||
2835 | |||
2836 | SecBuffer in_buffers[2]; | ||
2837 | SecBuffer out_buffers[2]; | ||
2838 | |||
2839 | SecBufferDesc in_desc; | ||
2840 | SecBufferDesc out_desc; | ||
2841 | |||
2842 | buf_token.BufferType = SECBUFFER_TOKEN; | ||
2843 | buf_token.pvBuffer = &token; | ||
2844 | buf_token.cbBuffer = sizeof(token); | ||
2845 | |||
2846 | buf_token_desc.ulVersion = SECBUFFER_VERSION; | ||
2847 | buf_token_desc.pBuffers = &buf_token; | ||
2848 | buf_token_desc.cBuffers = 1; | ||
2849 | |||
2850 | ApplyControlToken(&state->ctx_handle, &buf_token_desc); | ||
2851 | |||
2852 | // attempt to send any final data | ||
2853 | |||
2854 | in_buffers[0].BufferType = SECBUFFER_TOKEN; | ||
2855 | in_buffers[0].pvBuffer = state->in_buffer; | ||
2856 | in_buffers[0].cbBuffer = state->in_buffer_size; | ||
2857 | |||
2858 | in_buffers[1].BufferType = SECBUFFER_EMPTY; | ||
2859 | in_buffers[1].pvBuffer = NULL; | ||
2860 | in_buffers[1].cbBuffer = 0; | ||
2861 | |||
2862 | out_buffers[0].BufferType = SECBUFFER_TOKEN; | ||
2863 | out_buffers[0].pvBuffer = NULL; | ||
2864 | out_buffers[0].cbBuffer = 0; | ||
2865 | |||
2866 | out_buffers[1].BufferType = SECBUFFER_ALERT; | ||
2867 | out_buffers[1].pvBuffer = NULL; | ||
2868 | out_buffers[1].cbBuffer = 0; | ||
2869 | |||
2870 | in_desc.ulVersion = SECBUFFER_VERSION; | ||
2871 | in_desc.pBuffers = in_buffers; | ||
2872 | in_desc.cBuffers = _countof(in_buffers); | ||
2873 | |||
2874 | out_desc.ulVersion = SECBUFFER_VERSION; | ||
2875 | out_desc.pBuffers = out_buffers; | ||
2876 | out_desc.cBuffers = _countof(out_buffers); | ||
2877 | |||
2878 | status = InitializeSecurityContext(&state->cred_handle, | ||
2879 | state-> | ||
2880 | initialized ? &state->ctx_handle : | ||
2881 | NULL, | ||
2882 | state-> | ||
2883 | initialized ? NULL : state->hostname, | ||
2884 | flags, 0, 0, | ||
2885 | state->initialized ? &in_desc : NULL, | ||
2886 | 0, | ||
2887 | state-> | ||
2888 | initialized ? NULL : | ||
2889 | &state->ctx_handle, &out_desc, &flags, | ||
2890 | 0); | ||
2891 | |||
2892 | if (status == SEC_E_OK) { | ||
2893 | // attempt to write any extra data | ||
2894 | write(state->ofd, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer); | ||
2895 | } | ||
2896 | |||
2897 | DeleteSecurityContext(&state->ctx_handle); | ||
2898 | FreeCredentialsHandle(&state->cred_handle); | ||
2899 | free(state->hostname); | ||
2900 | } | ||
2901 | |||
2902 | |||
2903 | void FAST_FUNC tls_handshake(tls_state_t * state, const char *hostname) { | ||
2904 | SECURITY_STATUS status; | ||
2905 | int received; | ||
2906 | |||
2907 | #if ENABLE_FEATURE_TLS_SCHANNEL_1_3 | ||
2908 | SCH_CREDENTIALS credential = {.dwVersion = SCH_CREDENTIALS_VERSION, | ||
2909 | .dwCredFormat = 0, | ||
2910 | .cCreds = 0, | ||
2911 | .paCred = NULL, | ||
2912 | .hRootStore = NULL, | ||
2913 | .cMappers = 0, | ||
2914 | .aphMappers = NULL, | ||
2915 | .dwSessionLifespan = 0, | ||
2916 | .dwFlags = | ||
2917 | SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS | | ||
2918 | SCH_USE_STRONG_CRYPTO, | ||
2919 | .cTlsParameters = 0, | ||
2920 | .pTlsParameters = NULL | ||
2921 | }; | ||
2922 | #else | ||
2923 | SCHANNEL_CRED credential = {.dwVersion = SCHANNEL_CRED_VERSION, | ||
2924 | .cCreds = 0, | ||
2925 | .paCred = NULL, | ||
2926 | .hRootStore = NULL, | ||
2927 | .cMappers = 0, | ||
2928 | .aphMappers = NULL, | ||
2929 | .cSupportedAlgs = 0, | ||
2930 | .palgSupportedAlgs = NULL, | ||
2931 | .grbitEnabledProtocols = | ||
2932 | SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_1_CLIENT | | ||
2933 | SP_PROT_TLS1_2_CLIENT, | ||
2934 | .dwMinimumCipherStrength = 0, | ||
2935 | .dwMaximumCipherStrength = 0, | ||
2936 | .dwSessionLifespan = 0, | ||
2937 | .dwFlags = | ||
2938 | SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS | | ||
2939 | SCH_USE_STRONG_CRYPTO, | ||
2940 | .dwCredFormat = 0 | ||
2941 | }; | ||
2942 | #endif | ||
2943 | |||
2944 | if ((status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *) UNISP_NAME_A, | ||
2945 | SECPKG_CRED_OUTBOUND, NULL, | ||
2946 | &credential, | ||
2947 | NULL, NULL, &state->cred_handle, | ||
2948 | NULL)) != SEC_E_OK) { | ||
2949 | bb_error_msg_and_die("schannel: AcquireCredentialsHandleA failed: (0x%08lx): %s", | ||
2950 | status, hresult_to_error_string(status)); | ||
2951 | } | ||
2952 | |||
2953 | state->in_buffer_size = 0; | ||
2954 | state->out_buffer_size = 0; | ||
2955 | state->out_buffer_used = 0; | ||
2956 | |||
2957 | state->out_buffer = NULL; | ||
2958 | |||
2959 | state->hostname = strdup(hostname); | ||
2960 | |||
2961 | state->initialized = 0; | ||
2962 | state->closed = 0; | ||
2963 | |||
2964 | while (1) { | ||
2965 | DWORD flags = BB_SCHANNEL_ISC_FLAGS; | ||
2966 | |||
2967 | SecBuffer in_buffers[2]; | ||
2968 | SecBuffer out_buffers[2]; | ||
2969 | |||
2970 | SecBufferDesc in_desc; | ||
2971 | SecBufferDesc out_desc; | ||
2972 | |||
2973 | in_buffers[0].BufferType = SECBUFFER_TOKEN; | ||
2974 | in_buffers[0].pvBuffer = state->in_buffer; | ||
2975 | in_buffers[0].cbBuffer = state->in_buffer_size; | ||
2976 | |||
2977 | in_buffers[1].BufferType = SECBUFFER_EMPTY; | ||
2978 | in_buffers[1].pvBuffer = NULL; | ||
2979 | in_buffers[1].cbBuffer = 0; | ||
2980 | |||
2981 | out_buffers[0].BufferType = SECBUFFER_TOKEN; | ||
2982 | out_buffers[0].pvBuffer = NULL; | ||
2983 | out_buffers[0].cbBuffer = 0; | ||
2984 | |||
2985 | out_buffers[1].BufferType = SECBUFFER_ALERT; | ||
2986 | out_buffers[1].pvBuffer = NULL; | ||
2987 | out_buffers[1].cbBuffer = 0; | ||
2988 | |||
2989 | in_desc.ulVersion = SECBUFFER_VERSION; | ||
2990 | in_desc.pBuffers = in_buffers; | ||
2991 | in_desc.cBuffers = _countof(in_buffers); | ||
2992 | |||
2993 | out_desc.ulVersion = SECBUFFER_VERSION; | ||
2994 | out_desc.pBuffers = out_buffers; | ||
2995 | out_desc.cBuffers = _countof(out_buffers); | ||
2996 | |||
2997 | status = InitializeSecurityContext(&state->cred_handle, | ||
2998 | state-> | ||
2999 | initialized ? &state->ctx_handle : | ||
3000 | NULL, | ||
3001 | state-> | ||
3002 | initialized ? NULL : | ||
3003 | state->hostname, flags, 0, 0, | ||
3004 | state->initialized ? &in_desc : | ||
3005 | NULL, 0, | ||
3006 | state->initialized ? NULL : | ||
3007 | &state->ctx_handle, &out_desc, | ||
3008 | &flags, 0); | ||
3009 | |||
3010 | state->initialized = 1; | ||
3011 | |||
3012 | if (in_buffers[1].BufferType == SECBUFFER_EXTRA) { | ||
3013 | memmove(state->in_buffer, | ||
3014 | state->in_buffer + (state->in_buffer_size - | ||
3015 | in_buffers[1].cbBuffer), | ||
3016 | in_buffers[1].cbBuffer); | ||
3017 | state->in_buffer_size = in_buffers[1].cbBuffer; | ||
3018 | } else if (status != SEC_E_INCOMPLETE_MESSAGE) { | ||
3019 | state->in_buffer_size = 0; | ||
3020 | } | ||
3021 | |||
3022 | switch (status) { | ||
3023 | case SEC_E_OK:{ | ||
3024 | if (out_buffers[0].cbBuffer > 0) { | ||
3025 | xwrite(state->ofd, out_buffers[0].pvBuffer, | ||
3026 | out_buffers[0].cbBuffer); | ||
3027 | FreeContextBuffer(out_buffers[0].pvBuffer); | ||
3028 | } | ||
3029 | goto Success; | ||
3030 | } | ||
3031 | case SEC_I_CONTINUE_NEEDED:{ | ||
3032 | xwrite(state->ofd, out_buffers[0].pvBuffer, | ||
3033 | out_buffers[0].cbBuffer); | ||
3034 | FreeContextBuffer(out_buffers[0].pvBuffer); | ||
3035 | break; | ||
3036 | } | ||
3037 | case SEC_I_INCOMPLETE_CREDENTIALS:{ | ||
3038 | // we don't support this | ||
3039 | bb_error_msg_and_die("schannel: client certificates not supported"); | ||
3040 | } | ||
3041 | case SEC_E_INCOMPLETE_MESSAGE:{ | ||
3042 | break; | ||
3043 | } | ||
3044 | default:{ | ||
3045 | bb_error_msg_and_die("schannel: handshake failed: (0x%08lx): %s", | ||
3046 | status, hresult_to_error_string(status)); | ||
3047 | } | ||
3048 | } | ||
3049 | |||
3050 | received = | ||
3051 | safe_read(state->ifd, state->in_buffer + state->in_buffer_size, | ||
3052 | sizeof(state->in_buffer) - state->in_buffer_size); | ||
3053 | if (received <= 0) { | ||
3054 | bb_error_msg_and_die("schannel: handshake read() failed"); | ||
3055 | } | ||
3056 | state->in_buffer_size += received; | ||
3057 | } | ||
3058 | |||
3059 | Success: | ||
3060 | QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_STREAM_SIZES, | ||
3061 | &state->stream_sizes); | ||
3062 | |||
3063 | //SecPkgContext_ConnectionInfo info; | ||
3064 | //QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_CONNECTION_INFO, | ||
3065 | // &info); | ||
3066 | // | ||
3067 | //fprintf(stderr, "TLS 1.%d\n", (((uint32_t)(8 * sizeof(unsigned long long) - __builtin_clzll((info.dwProtocol)) - 1)) - 7)/2); | ||
3068 | } | ||
3069 | |||
3070 | void FAST_FUNC tls_run_copy_loop(tls_state_t * tls, unsigned flags) { | ||
3071 | char buffer[65536]; | ||
3072 | |||
3073 | struct pollfd pfds[2]; | ||
3074 | |||
3075 | pfds[0].fd = STDIN_FILENO; | ||
3076 | pfds[0].events = POLLIN; | ||
3077 | pfds[1].fd = tls->ifd; | ||
3078 | pfds[1].events = POLLIN; | ||
3079 | |||
3080 | for (;;) { | ||
3081 | int nread; | ||
3082 | |||
3083 | if (safe_poll(pfds, 2, -1) < 0) | ||
3084 | bb_simple_perror_msg_and_die("poll"); | ||
3085 | |||
3086 | if (pfds[0].revents) { | ||
3087 | nread = safe_read(STDIN_FILENO, buffer, sizeof(buffer)); | ||
3088 | if (nread < 1) { | ||
3089 | pfds[0].fd = -1; | ||
3090 | tls_disconnect(tls); | ||
3091 | if (flags & TLSLOOP_EXIT_ON_LOCAL_EOF) | ||
3092 | break; | ||
3093 | } else { | ||
3094 | tls_write(tls, buffer, nread); | ||
3095 | } | ||
3096 | } | ||
3097 | if (pfds[1].revents) { | ||
3098 | nread = tls_read(tls, buffer, sizeof(buffer)); | ||
3099 | if (nread < 1) { | ||
3100 | tls_disconnect(tls); | ||
3101 | break; | ||
3102 | } | ||
3103 | xwrite(STDOUT_FILENO, buffer, nread); | ||
3104 | } | ||
3105 | } | ||
3106 | } | ||
3107 | #endif | ||
diff --git a/networking/tls.h b/networking/tls.h index 0173b87b2..4fac23993 100644 --- a/networking/tls.h +++ b/networking/tls.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include "libbb.h" | 11 | #include "libbb.h" |
12 | 12 | ||
13 | 13 | ||
14 | #if !ENABLE_FEATURE_TLS_SCHANNEL | ||
14 | /* Config tweaks */ | 15 | /* Config tweaks */ |
15 | #define HAVE_NATIVE_INT64 | 16 | #define HAVE_NATIVE_INT64 |
16 | #undef USE_1024_KEY_SPEED_OPTIMIZATIONS | 17 | #undef USE_1024_KEY_SPEED_OPTIMIZATIONS |
@@ -120,3 +121,4 @@ void curve_P256_compute_pubkey_and_premaster( | |||
120 | void curve_P256_compute_pubkey_and_premaster_NEW( | 121 | void curve_P256_compute_pubkey_and_premaster_NEW( |
121 | uint8_t *pubkey2x32, uint8_t *premaster32, | 122 | uint8_t *pubkey2x32, uint8_t *premaster32, |
122 | const uint8_t *peerkey2x32) FAST_FUNC; | 123 | const uint8_t *peerkey2x32) FAST_FUNC; |
124 | #endif | ||