aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.src30
-rw-r--r--networking/hostname.c4
-rw-r--r--networking/libiproute/iproute.c16
-rw-r--r--networking/ntpd.c2
-rw-r--r--networking/tls.c570
-rw-r--r--networking/tls.h2
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
75choice
76 prompt "TLS implementation"
77 default FEATURE_TLS_INTERNAL
78
79config FEATURE_TLS_INTERNAL
80 bool "Internal"
81 depends on TLS
82 help
83 Use the BusyBox default internal TLS implementation.
84
85config 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
92endchoice
93
75config FEATURE_TLS_SHA1 94config 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
105config 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
86INSERT 114INSERT
87 115
88source networking/udhcp/Config.in 116source 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
2578static 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
2589static 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
2774static 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
2827static 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
2903void 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
3070void 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(
120void curve_P256_compute_pubkey_and_premaster_NEW( 121void 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