From af3a5ff01379c0d0784eb993b06fa4418f3a23a2 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Thu, 24 Jun 2021 21:07:17 +0200 Subject: [PATCH] Build fixes for Linux platform + added a simple password entry dialog. --- .gitattributes | 2 + .gitignore | 3 + Makefile | 40 ++-- deps/build-openssl-linux.sh | 51 +++++ ...uild-openssl.sh => build-openssl-mingw.sh} | 0 src/codesign_keygen.c | 13 +- src/codesign_sign.c | 51 +++-- src/codesign_verify.c | 46 ++--- src/common.c | 150 ++++++++++---- src/common.h | 16 +- src/platform.h | 29 +++ utilities/PasswordDialog/App.config | 6 + utilities/PasswordDialog/App.xaml | 9 + utilities/PasswordDialog/App.xaml.cs | 22 +++ utilities/PasswordDialog/MainWindow.xaml | 19 ++ utilities/PasswordDialog/MainWindow.xaml.cs | 116 +++++++++++ .../PasswordDialog/PasswordDialog.csproj | 115 +++++++++++ utilities/PasswordDialog/PasswordDialog.sln | 22 +++ .../PasswordDialog/Properties/AssemblyInfo.cs | 53 +++++ .../Properties/Resources.Designer.cs | 63 ++++++ .../PasswordDialog/Properties/Resources.resx | 117 +++++++++++ .../Properties/Settings.Designer.cs | 26 +++ .../Properties/Settings.settings | 7 + utilities/PasswordDialog/Resources/Icon.ico | Bin 0 -> 43302 bytes utilities/PasswordDialog/SecureWrapper.cs | 186 ++++++++++++++++++ 25 files changed, 1045 insertions(+), 117 deletions(-) create mode 100644 .gitattributes create mode 100644 deps/build-openssl-linux.sh rename deps/{build-openssl.sh => build-openssl-mingw.sh} (100%) create mode 100644 src/platform.h create mode 100644 utilities/PasswordDialog/App.config create mode 100644 utilities/PasswordDialog/App.xaml create mode 100644 utilities/PasswordDialog/App.xaml.cs create mode 100644 utilities/PasswordDialog/MainWindow.xaml create mode 100644 utilities/PasswordDialog/MainWindow.xaml.cs create mode 100644 utilities/PasswordDialog/PasswordDialog.csproj create mode 100644 utilities/PasswordDialog/PasswordDialog.sln create mode 100644 utilities/PasswordDialog/Properties/AssemblyInfo.cs create mode 100644 utilities/PasswordDialog/Properties/Resources.Designer.cs create mode 100644 utilities/PasswordDialog/Properties/Resources.resx create mode 100644 utilities/PasswordDialog/Properties/Settings.Designer.cs create mode 100644 utilities/PasswordDialog/Properties/Settings.settings create mode 100644 utilities/PasswordDialog/Resources/Icon.ico create mode 100644 utilities/PasswordDialog/SecureWrapper.cs diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6bd1aae --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +Makefile text eol=lf +*.sh text eol=lf diff --git a/.gitignore b/.gitignore index 28ad3d6..f290326 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ /deps/**/* /obj /src/.magic.h +/utilities/PasswordDialog/.vs +/utilities/PasswordDialog/bin +/utilities/PasswordDialog/obj diff --git a/Makefile b/Makefile index e193634..0af502e 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +SHELL := bash + # --------------------------------------------------------------------------- # FLAGS # --------------------------------------------------------------------------- @@ -13,10 +15,15 @@ else MTUNE := intel endif -CFLAGS = -municode -march=$(MARCH) -mtune=$(MTUNE) -Os -DNDEBUG -Wall -flto -Ideps/$(MYCPU)/include -LDFLAGS = -static -Ldeps/$(MYCPU)/lib -Wl,--strip-all +CFLAGS = -march=$(MARCH) -mtune=$(MTUNE) -Os -DNDEBUG -Wall -flto -Ideps/$(MYCPU)/include +LDFLAGS = -Ldeps/$(MYCPU)/lib -static -Wl,--strip-all LIBS = -lcrypto +ifeq ($(MACHINE),$(filter %-mingw32,$(MACHINE))) + SUFFIX = .exe + LDFLAGS += -municode +endif + ifneq ($(XCFLAGS),) CFLAGS += $(XCFLAGS) endif @@ -35,19 +42,15 @@ endif all: keygen sign verify -keygen: subdirs src/.magic.h - windres -DAPP="Key Generator ($(MYCPU))" -DNAME=keygen -o obj/version_keygen.o res/version.rc - gcc $(CFLAGS) $(LDFLAGS) -o bin/codesign_keygen.exe src/codesign_keygen.c src/common.c obj/version_keygen.o $(LIBS) +keygen: subdirs src/.magic.h rsrc + gcc $(CFLAGS) $(LDFLAGS) -o bin/codesign_keygen$(SUFFIX) src/codesign_keygen.c src/common.c obj/version_keygen.o $(LIBS) sign: subdirs src/.magic.h - windres -DAPP="Signer ($(MYCPU))" -DNAME=sign -o obj/version_sign.o res/version.rc - gcc $(CFLAGS) $(LDFLAGS) -o bin/codesign_sign.exe src/codesign_sign.c src/common.c obj/version_sign.o $(LIBS) + gcc $(CFLAGS) $(LDFLAGS) -o bin/codesign_sign$(SUFFIX) src/codesign_sign.c src/common.c obj/version_sign.o $(LIBS) -verify: subdirs src/.magic.h - windres -DAPP="Verifier ($(MYCPU))" -DNAME=verify -o obj/version_verify.o res/version.rc - windres -DAPP="Verifier ($(MYCPU))" -DNAME=verifz -o obj/version_verifz.o res/version.rc - gcc $(CFLAGS) -UEMBED_PUBKEY $(LDFLAGS) -o bin/codesign_verify.exe src/codesign_verify.c src/common.c obj/version_verify.o $(LIBS) - gcc $(CFLAGS) -DEMBED_PUBKEY $(LDFLAGS) -o bin/codesign_verifz.exe src/codesign_verify.c src/common.c obj/version_verifz.o $(LIBS) +verify: subdirs src/.magic.h rsrc + gcc $(CFLAGS) -UEMBED_PUBKEY $(LDFLAGS) -o bin/codesign_verify$(SUFFIX) src/codesign_verify.c src/common.c obj/version_verify.o $(LIBS) + gcc $(CFLAGS) -DEMBED_PUBKEY $(LDFLAGS) -o bin/codesign_verifz$(SUFFIX) src/codesign_verify.c src/common.c obj/version_verify.o $(LIBS) src/.magic.h: str=$$(tr -dc '0-9A-F' < /dev/urandom | head -c 26); \ @@ -58,7 +61,18 @@ src/.magic.h: done >> $@; \ printf ' };\n' >> $@ -subdirs: +rsrc: subdirs +ifeq ($(MACHINE),$(filter %-mingw32,$(MACHINE))) + windres -DAPP="Key Generator ($(MYCPU))" -DNAME=keygen -o obj/version_keygen.o res/version.rc + windres -DAPP="Signer ($(MYCPU))" -DNAME=sign -o obj/version_sign.o res/version.rc + windres -DAPP="Verifier ($(MYCPU))" -DNAME=verify -o obj/version_verify.o res/version.rc +else + gcc -o obj/version_keygen.o -xc -c - < /dev/null + gcc -o obj/version_sign.o -xc -c - < /dev/null + gcc -o obj/version_verify.o -xc -c - < /dev/null +endif + +subdirs: deps/$(MYCPU)/lib/libcrypto.a deps/$(MYCPU)/lib/libssl.a @mkdir -p bin obj clean: diff --git a/deps/build-openssl-linux.sh b/deps/build-openssl-linux.sh new file mode 100644 index 0000000..85bdb9e --- /dev/null +++ b/deps/build-openssl-linux.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -e +trap 'read -p "Press any key..." x' EXIT + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Set up compiler +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +case "$(cc -dumpmachine)" in + i686-*) + readonly MY_CPU=x86 + readonly MY_MARCH=i486 + readonly MY_MTUNE=intel + ;; + x86_64-*) + readonly MY_CPU=x64 + readonly MY_MARCH=x86-64 + readonly MY_MTUNE=corei7 + ;; + *) + echo "Unknown compiler detected!"; + exit 1 + ;; +esac + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Initialize paths +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +readonly BASE_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +readonly LIBS_DIR="${BASE_DIR}/${MY_CPU}" +readonly OSSL_DIR="${LIBS_DIR}/.build/openssl" +find "${BASE_DIR}" -maxdepth 1 -type d -name "*-${MY_CPU}" -exec rm -rf "{}" \; +rm -rf "${LIBS_DIR}" && mkdir -p "${LIBS_DIR}/bin" "${LIBS_DIR}/include" "${LIBS_DIR}/lib/pkgconfig" "${LIBS_DIR}/share" "${OSSL_DIR}" + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Fetch sources +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +wget -4 -O "${LIBS_DIR}/openssl.tar.gz" https://www.openssl.org/source/openssl-1.1.1k.tar.gz +tar -xvf "${LIBS_DIR}/openssl.tar.gz" --strip-components=1 -C "${OSSL_DIR}" + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Build +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[[ "${MY_CPU}" == "x64" ]] && readonly ossl_flag="no-sse2" || readonly ossl_flag="386" +[[ "${MY_CPU}" == "x64" ]] && readonly ossl_linux="linux-x86_64" || readonly ossl_linux="linux-x86" +pushd "${OSSL_DIR}" +./Configure no-afalgeng no-aria no-asan no-asm no-async no-autoerrinit no-autoload-config no-bf no-blake2 no-buildtest-c++ no-camellia no-capieng no-cast no-chacha no-cmac no-cms no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-ct no-deprecated no-des no-devcryptoeng no-dgram no-dh no-dsa no-dso no-dtls no-dynamic-engine no-ec no-ec2m no-ecdh no-ecdsa no-ec_nistp_64_gcc_128 no-egd no-engine no-err no-external-tests no-filenames no-fuzz-libfuzzer no-fuzz-afl no-gost no-heartbeats no-hw no-idea no-makedepend no-md2 no-md4 no-mdc2 no-msan no-multiblock no-nextprotoneg no-pinshared no-ocb no-ocsp no-pic no-poly1305 no-posix-io no-psk no-rc2 no-rc4 no-rc5 no-rdrand no-rfc3779 no-rmd160 no-scrypt no-sctp no-seed no-shared no-siphash no-sm2 no-sm3 no-sm4 no-sock no-srp no-srtp no-ssl no-ssl-trace no-static-engine no-tests no-threads no-tls no-ts no-ubsan no-ui-console no-unit-test no-whirlpool no-weak-ssl-ciphers no-zlib no-zlib-dynamic ${ossl_flag} -static -march=${MY_MARCH} -mtune=${MY_MTUNE} -Os -flto -D_WIN32_WINNT=0x0501 -I"${LIBS_DIR}/include" -L"${LIBS_DIR}/lib" --prefix="${LIBS_DIR}" ${ossl_linux} +make build_libs && make install_dev +popd + +printf "\nCompleted.\n\n" diff --git a/deps/build-openssl.sh b/deps/build-openssl-mingw.sh similarity index 100% rename from deps/build-openssl.sh rename to deps/build-openssl-mingw.sh diff --git a/src/codesign_keygen.c b/src/codesign_keygen.c index eb076f6..d8c2a51 100644 --- a/src/codesign_keygen.c +++ b/src/codesign_keygen.c @@ -4,7 +4,6 @@ /******************************************************************************/ #include "common.h" -#include #include #include @@ -15,7 +14,7 @@ #define RSA_EXPONENT 0x10001 #define RSA_KEY_SIZE 8192 -int wmain(int argc, wchar_t *argv[]) +int MAIN(int argc, CHAR_T *argv[]) { int exit_code = EXIT_FAILURE; BIGNUM *exp = NULL; @@ -28,7 +27,7 @@ int wmain(int argc, wchar_t *argv[]) /* Check arguments */ /*-------------------------------------------------------*/ - print_logo("Sign Tool"); + print_logo("Key Generator"); if ((argc < 4) || (!argv[1][0]) || (!argv[2][0]) || (!argv[3][0])) { @@ -42,14 +41,14 @@ int wmain(int argc, wchar_t *argv[]) /* Open output files */ /*-------------------------------------------------------*/ - file_pubkey = _wfsopen(argv[2], L"wb", _SH_DENYRW); + file_pubkey = FOPEN(argv[2], T("wb")); if (!file_pubkey) { fputs("Error: Failed to open output file for public key!\n\n", stderr); goto clean_up; } - file_privkey = _wfsopen(argv[3], L"wb", _SH_DENYRW); + file_privkey = FOPEN(argv[3], T("wb")); if (!file_privkey) { fputs("Error: Failed to open output file for private key!\n\n", stderr); @@ -71,7 +70,7 @@ int wmain(int argc, wchar_t *argv[]) } else { - passwd = convert_wchar_to_UTF8(argv[1]); + passwd = convert_CHAR_to_UTF8(argv[1]); if (!passwd) { fputs("Error: Failed to convert password to UTF-8 format!\n\n", stderr); @@ -167,7 +166,7 @@ clean_up: if (passwd) { - zero_memory(passwd, _msize(passwd)); + OPENSSL_cleanse(passwd, strlen(passwd)); free(passwd); } diff --git a/src/codesign_sign.c b/src/codesign_sign.c index a8b1c41..c7e0a93 100644 --- a/src/codesign_sign.c +++ b/src/codesign_sign.c @@ -6,7 +6,6 @@ #include "common.h" #include ".magic.h" -#include #include #include @@ -15,21 +14,22 @@ #define BUFFSIZE 4096 -int wmain(int argc, wchar_t *argv[]) +int MAIN(int argc, CHAR_T *argv[]) { int exit_code = EXIT_FAILURE; RSA *rsa = NULL; SHA512_CTX sha512 = { }; FILE *file_privkey = NULL, *file_data = NULL, *file_signature = NULL; char *passwd = NULL, *base64 = NULL; - unsigned char buffer[BUFFSIZE], digest[SHA512_DIGEST_LENGTH], timestamp[sizeof(UI64_T)], *output = NULL; + uint64_t timestamp = 0ULL; + unsigned char buffer[BUFFSIZE], digest[SHA512_DIGEST_LENGTH], ts_buffer[sizeof(uint64_t)], *output = NULL; unsigned int signature_length = 0U, output_length = 0U, base64_length = 0U; /*-------------------------------------------------------*/ /* Check arguments */ /*-------------------------------------------------------*/ - print_logo("Signer"); + print_logo("File Signer"); if ((argc < 5) || (!argv[1][0]) || (!argv[2][0]) || (!argv[3][0]) || (!argv[4][0])) { @@ -43,21 +43,21 @@ int wmain(int argc, wchar_t *argv[]) /* Open input/output files */ /*-------------------------------------------------------*/ - file_privkey = _wfsopen(argv[2], L"rb", _SH_DENYWR); + file_privkey = FOPEN(argv[2], T("rb")); if (!file_privkey) { fputs("Error: Failed to open private key file!\n\n", stderr); goto clean_up; } - file_data = _wfsopen(argv[3], L"rb", _SH_DENYWR); + file_data = FOPEN(argv[3], T("rb")); if (!file_data) { fputs("Error: Failed to open input file to be signed!\n\n", stderr); goto clean_up; } - file_signature = _wfsopen(argv[4], L"wb", _SH_DENYRW); + file_signature = FOPEN(argv[4], T("wb")); if (!file_signature) { fputs("Error: Failed to open output file for signature!\n\n", stderr); @@ -79,7 +79,7 @@ int wmain(int argc, wchar_t *argv[]) } else { - passwd = convert_wchar_to_UTF8(argv[1]); + passwd = convert_CHAR_to_UTF8(argv[1]); if (!passwd) { fputs("Error: Failed to convert password to UTF-8 format!\n\n", stderr); @@ -103,7 +103,18 @@ int wmain(int argc, wchar_t *argv[]) goto clean_up; } - store_uint64(timestamp, get_current_time()); + /*-------------------------------------------------------*/ + /* Get current time */ + /*-------------------------------------------------------*/ + + timestamp = get_current_time_usec(); + if (!(timestamp > 0ULL)) + { + fputs("Error: Failed to get the current system time!\n\n", stderr); + goto clean_up; + } + + store_uint64(ts_buffer, timestamp); /*-------------------------------------------------------*/ /* Compute file digest */ @@ -118,7 +129,7 @@ int wmain(int argc, wchar_t *argv[]) fputs("Generating the RSA signature, please wait...\n", stderr); fflush(stderr); - if (SHA512_Update(&sha512, timestamp, sizeof(timestamp)) != 1) + if (SHA512_Update(&sha512, ts_buffer, sizeof(ts_buffer)) != 1) { fputs("Failed!\n\nError: Failed to update SHA-512 digest!\n\n", stderr); goto clean_up; @@ -159,16 +170,16 @@ int wmain(int argc, wchar_t *argv[]) /* Compute the RSA signature */ /*-------------------------------------------------------*/ - output = (unsigned char*) malloc(RSA_size(rsa) + sizeof(timestamp)); + output = (unsigned char*) malloc(RSA_size(rsa) + sizeof(ts_buffer)); if (!output) { fputs("Failed!\n\nError: Failed to allocate output buffer!\n\n", stderr); goto clean_up; } - memcpy(output, timestamp, sizeof(timestamp)); + memcpy(output, ts_buffer, sizeof(ts_buffer)); - if (RSA_sign(NID_sha512, digest, SHA512_DIGEST_LENGTH, output + sizeof(timestamp), &signature_length, rsa) != 1) + if (RSA_sign(NID_sha512, digest, SHA512_DIGEST_LENGTH, output + sizeof(ts_buffer), &signature_length, rsa) != 1) { fputs("Failed!\n\nError: Failed to compute signature!\n\n", stderr); goto clean_up; @@ -181,7 +192,7 @@ int wmain(int argc, wchar_t *argv[]) /* Write signature the output file */ /*-------------------------------------------------------*/ - base64 = (char*) malloc(1U + (base64_length = 4U * (((output_length = signature_length + sizeof(timestamp)) + 2U) / 3U))); + base64 = (char*) malloc(1U + (base64_length = 4U * (((output_length = signature_length + sizeof(ts_buffer)) + 2U) / 3U))); if (!base64) { fputs("Error: Failed to allocate hex-string buffer!\n\n", stderr); @@ -217,19 +228,19 @@ clean_up: if (passwd) { - zero_memory(passwd, strlen(passwd)); + OPENSSL_cleanse(passwd, strlen(passwd)); free(passwd); } if (base64) { - zero_memory(base64, strlen(base64)); + OPENSSL_cleanse(base64, strlen(base64)); free(base64); } if (output) { - zero_memory(output, _msize(output)); + OPENSSL_cleanse(output, MSIZE(output)); free(output); } @@ -253,8 +264,10 @@ clean_up: RSA_free(rsa); } - zero_memory(timestamp, sizeof(timestamp)); - zero_memory(&sha512, sizeof(SHA512_CTX)); + + OPENSSL_cleanse(ts_buffer, sizeof(ts_buffer)); + OPENSSL_cleanse(&sha512, sizeof(SHA512_CTX)); + OPENSSL_cleanse(×tamp, sizeof(uint64_t)); return exit_code; } diff --git a/src/codesign_verify.c b/src/codesign_verify.c index c07c735..19ddc4b 100644 --- a/src/codesign_verify.c +++ b/src/codesign_verify.c @@ -6,7 +6,6 @@ #include "common.h" #include ".magic.h" -#include #include #include @@ -24,7 +23,7 @@ #define BUFFSIZE 4096 -int wmain(int argc, wchar_t *argv[]) +int MAIN(int argc, CHAR_T *argv[]) { int exit_code = EXIT_FAILURE; BIO *bio_pubkey = NULL; @@ -32,7 +31,6 @@ int wmain(int argc, wchar_t *argv[]) SHA512_CTX sha512 = { }; char *base64 = NULL; FILE *file_pubkey = NULL, *file_data = NULL, *file_signature = NULL; - UI64_T timestamp = 0U, current_time = 0U; unsigned char buffer[BUFFSIZE], digest[SHA512_DIGEST_LENGTH], *input = NULL; unsigned int input_length = 0U, base64_length = 0U; #ifdef EMBED_PUBKEY @@ -44,7 +42,7 @@ int wmain(int argc, wchar_t *argv[]) /* Check arguments */ /*-------------------------------------------------------*/ - print_logo("Verifier"); + print_logo("File Verifier"); #ifdef EMBED_PUBKEY @@ -74,14 +72,14 @@ int wmain(int argc, wchar_t *argv[]) #ifdef EMBED_PUBKEY - public_key = load_resource_data(L"RSA_PUBLIC_KEY", &pubkey_length); + public_key = load_resource_data(T("RSA_PUBLIC_KEY"), &pubkey_length); if (!public_key) { fputs("Error: Failed to load public key data from resources!\n\n", stderr); goto clean_up; } - checksum_pubkey = load_resource_data(L"CHECKSUM_SHA512", &checksum_length); + checksum_pubkey = load_resource_data(T("CHECKSUM_SHA512"), &checksum_length); if ((!checksum_pubkey) || (checksum_length < SHA512_DIGEST_LENGTH)) { fputs("Error: Failed to load public key checksum from resources!\n\n", stderr); @@ -115,7 +113,7 @@ int wmain(int argc, wchar_t *argv[]) #else - file_pubkey = _wfsopen(argv[1], L"rb", _SH_DENYWR); + file_pubkey = FOPEN(argv[1], T("rb")); if (!file_pubkey) { fputs("Error: Failed to open public key input file!\n\n", stderr); @@ -134,14 +132,14 @@ int wmain(int argc, wchar_t *argv[]) /* Open input files */ /*-------------------------------------------------------*/ - file_data = _wfsopen(ARGV_INPUTFILE, L"rb", _SH_DENYWR); + file_data = FOPEN(ARGV_INPUTFILE, T("rb")); if (!file_data) { fputs("Error: Failed to open the input file!\n\n", stderr); goto clean_up; } - file_signature = _wfsopen(ARGV_SIGNATURE, L"rb", _SH_DENYWR); + file_signature = FOPEN(ARGV_SIGNATURE, T("rb")); if (!file_signature) { fputs("Error: Failed to open the signature file!\n\n", stderr); @@ -179,7 +177,7 @@ int wmain(int argc, wchar_t *argv[]) goto clean_up; } - if (input_length <= 2U + sizeof(UI64_T)) + if (input_length <= 2U + sizeof(uint64_t)) { fputs("Error: Signature binary data appears to be truncated!\n\n", stderr); goto clean_up; @@ -190,24 +188,6 @@ int wmain(int argc, wchar_t *argv[]) input_length -= (base64[base64_length - 2U] == '=') ? 2U : 1U; /*remove padding!*/ } - /*-------------------------------------------------------*/ - /* Check the time-stamp */ - /*-------------------------------------------------------*/ - - timestamp = load_uint64(input); - - if (timestamp > (current_time = get_current_time())) - { - fputs("Error: Signature time-stamp appears to be from the future!\n\n", stderr); - goto clean_up; - } - - if (current_time - timestamp > 94670856000000ULL) - { - fputs("Error: Signature time-stamp is more than 3 years old!\n\n", stderr); - goto clean_up; - } - /*-------------------------------------------------------*/ /* Compute file digest */ /*-------------------------------------------------------*/ @@ -221,7 +201,7 @@ int wmain(int argc, wchar_t *argv[]) fputs("Verifying the RSA signature, please wait...\n", stderr); fflush(stderr); - if (SHA512_Update(&sha512, input, sizeof(UI64_T)) != 1) + if (SHA512_Update(&sha512, input, sizeof(uint64_t)) != 1) { fputs("Failed!\n\nError: Failed to update SHA-512 digest!\n\n", stderr); goto clean_up; @@ -262,7 +242,7 @@ int wmain(int argc, wchar_t *argv[]) /* Validate the RSA signature */ /*-------------------------------------------------------*/ - if (RSA_verify(NID_sha512, digest, SHA512_DIGEST_LENGTH, input + sizeof(UI64_T), input_length - sizeof(UI64_T), rsa) != 1) + if (RSA_verify(NID_sha512, digest, SHA512_DIGEST_LENGTH, input + sizeof(uint64_t), input_length - sizeof(uint64_t), rsa) != 1) { fputs("Failed!\n\nInvalid signature or corrupted file :-(\n\n", stderr); goto clean_up; @@ -279,13 +259,13 @@ clean_up: if (input) { - zero_memory(input, _msize(input)); + OPENSSL_cleanse(input, MSIZE(input)); free(input); } if (base64) { - zero_memory(base64, strlen(base64)); + OPENSSL_cleanse(base64, strlen(base64)); free(base64); } @@ -314,7 +294,7 @@ clean_up: RSA_free(rsa); } - zero_memory(&sha512, sizeof(SHA512_CTX)); + OPENSSL_cleanse(&sha512, sizeof(SHA512_CTX)); return exit_code; } diff --git a/src/common.c b/src/common.c index 0e6fc44..4e711ea 100644 --- a/src/common.c +++ b/src/common.c @@ -4,19 +4,31 @@ /******************************************************************************/ #include "common.h" -#include -#include -#include +#include +#include +#ifdef _WIN32 #define WIN32_LEAN_AND_MEAN 1 #include +#include +#include +#else +#include +#include +#endif #include +/*-------------------------------------------------------*/ +/* print_logo() / print_license() */ +/*-------------------------------------------------------*/ + void print_logo(const char *const app_name) { +#ifdef _WIN32 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); _setmode(_fileno(stdin), _O_BINARY); +#endif fprintf(stderr, "CodeSign - %s [" __DATE__ "], by LoRd_MuldeR \n", app_name); fprintf(stderr, "using %.15s\n\n", OpenSSL_version(OPENSSL_VERSION)); fflush(stderr); @@ -28,18 +40,23 @@ void print_license(void) fputs("Please see http://www.muldersoft.com for additional information.\n\n", stderr); } -char *convert_wchar_to_UTF8(const wchar_t *str_w) +/*-------------------------------------------------------*/ +/* convert_wchar_to_UTF8() */ +/*-------------------------------------------------------*/ + +char *convert_CHAR_to_UTF8(const CHAR_T *str) { char *str_utf8 = NULL; - if (str_w) +#ifdef _WIN32 + if (str) { - int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL, 0, NULL, NULL); + int bytes = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); if (bytes > 0) { str_utf8 = malloc(bytes); if(str_utf8) { - if (WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes, NULL, NULL) == 0) + if (WideCharToMultiByte(CP_UTF8, 0, str, -1, str_utf8, bytes, NULL, NULL) == 0) { free(str_utf8); return NULL; @@ -47,9 +64,16 @@ char *convert_wchar_to_UTF8(const wchar_t *str_w) } } } +#else + str_utf8 = strdup(str); +#endif return str_utf8; } +/*-------------------------------------------------------*/ +/* read_line_from_file() */ +/*-------------------------------------------------------*/ + char *read_line_from_file(FILE *const file, const int trim) { char buffer[4096], *line; @@ -94,44 +118,94 @@ char *read_line_from_file(FILE *const file, const int trim) return NULL; } -UI64_T get_current_time(void) +/*-------------------------------------------------------*/ +/* get_current_time() */ +/*-------------------------------------------------------*/ + +#define FILETIME_1970 116444736000000000ULL + +#ifdef _WIN32 + +static inline uint64_t filetime_to_ui64(const FILETIME *const file_time) { - struct timeval t; + ULARGE_INTEGER result; + result.HighPart = file_time->dwHighDateTime; + result. LowPart = file_time-> dwLowDateTime; + return result.QuadPart; +} + +static uint64_t get_system_time(void) +{ + FILETIME system_time; + GetSystemTimeAsFileTime(&system_time); + return filetime_to_ui64(&system_time); +} + +uint64_t get_current_time_usec(void) +{ + /* struct timeval t; if(gettimeofday(&t, NULL) == 0) { - return (((UI64_T)t.tv_sec) * 1000000ULL) + ((UI64_T)t.tv_usec); + return (((uint64_t)t.tv_sec) * 1000000ULL) + ((uint64_t)t.tv_usec); + } */ + const uint64_t system_time = get_system_time(); + if (system_time >= FILETIME_1970) + { + return (system_time - FILETIME_1970) / 10ULL; } return 0ULL; } -void store_uint64(unsigned char *const buffer, const UI64_T value) +#else + +uint64_t get_current_time_usec(void) { - buffer[0U] = (BYTE)(value >> 56); - buffer[1U] = (BYTE)(value >> 48); - buffer[2U] = (BYTE)(value >> 40); - buffer[3U] = (BYTE)(value >> 32); - buffer[4U] = (BYTE)(value >> 24); - buffer[5U] = (BYTE)(value >> 16); - buffer[6U] = (BYTE)(value >> 8); - buffer[7U] = (BYTE)(value >> 0); + struct timeval t; + if(gettimeofday(&t, NULL) == 0) + { + return (((uint64_t)t.tv_sec) * 1000000ULL) + ((uint64_t)t.tv_usec); + } + return 0ULL; } -UI64_T load_uint64(const unsigned char *const buffer) +#endif + +/*-------------------------------------------------------*/ +/* store_uint64() / load_uint64() */ +/*-------------------------------------------------------*/ + +void store_uint64(unsigned char *const buffer, const uint64_t value) { - UI64_T value = 0U; - value |= ((UI64_T)buffer[0U]) << 56; - value |= ((UI64_T)buffer[1U]) << 48; - value |= ((UI64_T)buffer[2U]) << 40; - value |= ((UI64_T)buffer[3U]) << 32; - value |= ((UI64_T)buffer[4U]) << 24; - value |= ((UI64_T)buffer[5U]) << 16; - value |= ((UI64_T)buffer[6U]) << 8; - value |= ((UI64_T)buffer[7U]) << 0; - return value; + buffer[0U] = (uint8_t)(value >> 56); + buffer[1U] = (uint8_t)(value >> 48); + buffer[2U] = (uint8_t)(value >> 40); + buffer[3U] = (uint8_t)(value >> 32); + buffer[4U] = (uint8_t)(value >> 24); + buffer[5U] = (uint8_t)(value >> 16); + buffer[6U] = (uint8_t)(value >> 8); + buffer[7U] = (uint8_t)(value); } -const unsigned char* load_resource_data(const wchar_t *const name, unsigned int *const length) +uint64_t load_uint64(const unsigned char *const buffer) { + return + (((uint64_t)buffer[0U]) << 56) | + (((uint64_t)buffer[1U]) << 48) | + (((uint64_t)buffer[2U]) << 40) | + (((uint64_t)buffer[3U]) << 32) | + (((uint64_t)buffer[4U]) << 24) | + (((uint64_t)buffer[5U]) << 16) | + (((uint64_t)buffer[6U]) << 8) | + (((uint64_t)buffer[7U])); +} + +/*-------------------------------------------------------*/ +/* load_resource_data() */ +/*-------------------------------------------------------*/ + +const unsigned char* load_resource_data(const CHAR_T *const name, unsigned int *const length) +{ +#ifdef _WIN32 HRSRC resource = FindResourceW(NULL, name, RT_RCDATA); if (resource) { @@ -145,18 +219,22 @@ const unsigned char* load_resource_data(const wchar_t *const name, unsigned int } } } +#endif *length = 0U; return NULL; } +/*-------------------------------------------------------*/ +/* force_flush() */ +/*-------------------------------------------------------*/ + int force_flush(FILE *const file) { const int result = fflush(file); +#ifdef _WIN32 FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(file))); +#else + fsync(fileno(file)); +#endif return (result == 0); } - -void zero_memory(void *const ptr, const size_t size) -{ - SecureZeroMemory(ptr, size); -} diff --git a/src/common.h b/src/common.h index b5c4e17..0613c6c 100644 --- a/src/common.h +++ b/src/common.h @@ -6,21 +6,19 @@ #ifndef _COMMON_H #define _COMMON_H -#include -#include +#include "platform.h" +#include #define PASSWD_MINLEN 8 -typedef unsigned long long UI64_T; void print_logo(const char *const app_name); void print_license(void); -char *convert_wchar_to_UTF8(const wchar_t *str_w); +char *convert_CHAR_to_UTF8(const CHAR_T *str); char *read_line_from_file(FILE *const file, const int trim); -UI64_T get_current_time(void); -void store_uint64(unsigned char *const buffer, const UI64_T value); -UI64_T load_uint64(const unsigned char *const buffer); -const unsigned char* load_resource_data(const wchar_t *const name, unsigned int *const length); +uint64_t get_current_time_usec(void); +void store_uint64(unsigned char *const buffer, const uint64_t value); +uint64_t load_uint64(const unsigned char *const buffer); +const unsigned char* load_resource_data(const CHAR_T *const name, unsigned int *const length); int force_flush(FILE *const file); -void zero_memory(void *const ptr, const size_t size); #endif /*_COMMON_H*/ diff --git a/src/platform.h b/src/platform.h new file mode 100644 index 0000000..bbbbd1d --- /dev/null +++ b/src/platform.h @@ -0,0 +1,29 @@ +#ifndef _PLATFORM_H +#define _PLATFORM_H + +#include "platform.h" +#include +#include +#include + +#ifdef _WIN32 +#include + +#define CHAR_T wchar_t +#define MAIN wmain +#define FOPEN(X,Y) _wfsopen((X),(Y),_SH_SECURE) +#define MSIZE(X) _msize((X)) +#define _T(X) L##X +#define T(X) _T(X) + +#else + +#define CHAR_T char +#define MAIN main +#define FOPEN(X,Y) fopen((X),(Y)) +#define MSIZE(X) malloc_usable_size((X)) +#define T(X) X + +#endif + +#endif /*_PLATFORM_H*/ diff --git a/utilities/PasswordDialog/App.config b/utilities/PasswordDialog/App.config new file mode 100644 index 0000000..8e15646 --- /dev/null +++ b/utilities/PasswordDialog/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/utilities/PasswordDialog/App.xaml b/utilities/PasswordDialog/App.xaml new file mode 100644 index 0000000..b71b3a7 --- /dev/null +++ b/utilities/PasswordDialog/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/utilities/PasswordDialog/App.xaml.cs b/utilities/PasswordDialog/App.xaml.cs new file mode 100644 index 0000000..cbcc064 --- /dev/null +++ b/utilities/PasswordDialog/App.xaml.cs @@ -0,0 +1,22 @@ +/******************************************************************************/ +/* CodeSign, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace PasswordDialog +{ + /// + /// Interaktionslogik für "App.xaml" + /// + public partial class App : Application + { + } +} diff --git a/utilities/PasswordDialog/MainWindow.xaml b/utilities/PasswordDialog/MainWindow.xaml new file mode 100644 index 0000000..acc6ef5 --- /dev/null +++ b/utilities/PasswordDialog/MainWindow.xaml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/utilities/PasswordDialog/MainWindow.xaml.cs b/utilities/PasswordDialog/MainWindow.xaml.cs new file mode 100644 index 0000000..1a72309 --- /dev/null +++ b/utilities/PasswordDialog/MainWindow.xaml.cs @@ -0,0 +1,116 @@ +/******************************************************************************/ +/* CodeSign, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Interop; +using System.Windows.Threading; + +namespace PasswordDialog +{ + /// + /// Interaktionslogik für MainWindow.xaml + /// + public partial class MainWindow : Window + { + private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); + private const UInt32 SWP_NOSIZE = 0x0001; + private const UInt32 SWP_NOMOVE = 0x0002; + private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE; + + private readonly DispatcherTimer dispatcherTimer; + private readonly WindowInteropHelper interopHelper; + + public MainWindow() + { + InitializeComponent(); + dispatcherTimer = new DispatcherTimer(DispatcherPriority.Background); + interopHelper = new WindowInteropHelper(this); + } + + //------------------------------------------------------------------- + // Event Handlers + //------------------------------------------------------------------- + + protected override void OnContentRendered(EventArgs e) + { + IntPtr handle = interopHelper.Handle; + SetForegroundWindow(handle); + SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); + + PasswordBox.Focus(); + + dispatcherTimer.Tick += OnTimerTick; + dispatcherTimer.Interval = TimeSpan.FromMinutes(3); + dispatcherTimer.Start(); + } + + private void Button_OK_Click(object sender, RoutedEventArgs e) + { + if (Button_OK.IsEnabled) + { + using (SecureWrapper wrapper = new SecureWrapper(PasswordBox.SecurePassword)) + { + byte[] buffer = wrapper.ByteBuffer; + using (Stream stdout = Console.OpenStandardOutput()) + { + stdout.Write(buffer, 0, buffer.Length); + stdout.Flush(); + } + } + Close(); /*password was entered, now exit!*/ + } + } + + private void Button_Close_Click(object sender, RoutedEventArgs e) + { + Close(); /*aborted*/ + } + + private void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) + { + if (e.Key == System.Windows.Input.Key.Escape) + { + e.Handled = true; + Close(); + } + } + + private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) + { + Button_OK.IsEnabled = (PasswordBox.SecurePassword.Length > 0); + } + + private void PasswordBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) + { + if (e.Key == System.Windows.Input.Key.Enter) + { + e.Handled = true; + Dispatcher.InvokeAsync(() => Button_OK_Click(sender, e)); + } + } + + private void OnTimerTick(object sender, EventArgs e) + { + dispatcherTimer.Stop(); + Close(); + } + + //------------------------------------------------------------------- + // Native Methods + //------------------------------------------------------------------- + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool SetForegroundWindow(IntPtr hWnd); + } +} diff --git a/utilities/PasswordDialog/PasswordDialog.csproj b/utilities/PasswordDialog/PasswordDialog.csproj new file mode 100644 index 0000000..8102052 --- /dev/null +++ b/utilities/PasswordDialog/PasswordDialog.csproj @@ -0,0 +1,115 @@ + + + + + Debug + AnyCPU + {833EC8FB-054C-42FF-9F76-33A8DBCAF967} + Exe + Properties + PasswordDialog + passentry + v4.5 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + + + prompt + 4 + Off + + + PasswordDialog.App + + + Resources\Icon.ico + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + + + \ No newline at end of file diff --git a/utilities/PasswordDialog/PasswordDialog.sln b/utilities/PasswordDialog/PasswordDialog.sln new file mode 100644 index 0000000..c2323bf --- /dev/null +++ b/utilities/PasswordDialog/PasswordDialog.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PasswordDialog", "PasswordDialog.csproj", "{833EC8FB-054C-42FF-9F76-33A8DBCAF967}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {833EC8FB-054C-42FF-9F76-33A8DBCAF967}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {833EC8FB-054C-42FF-9F76-33A8DBCAF967}.Debug|Any CPU.Build.0 = Debug|Any CPU + {833EC8FB-054C-42FF-9F76-33A8DBCAF967}.Release|Any CPU.ActiveCfg = Release|Any CPU + {833EC8FB-054C-42FF-9F76-33A8DBCAF967}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/utilities/PasswordDialog/Properties/AssemblyInfo.cs b/utilities/PasswordDialog/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ef72ccb --- /dev/null +++ b/utilities/PasswordDialog/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die einer Assembly zugeordnet sind. +[assembly: AssemblyTitle("CodeSign - PasswordDialog")] +[assembly: AssemblyDescription("CodeSign - PasswordDialog")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Muldersoft")] +[assembly: AssemblyProduct("CodeSign")] +[assembly: AssemblyCopyright("Created by LoRd_MuldeR ")] +[assembly: AssemblyTrademark("Muldersoft")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. +[assembly: ComVisible(false)] + +//Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie +//ImCodeVerwendeteKultur in der .csproj-Datei +//in einer fest. Wenn Sie in den Quelldateien beispielsweise Deutsch +//(Deutschland) verwenden, legen Sie auf \"de-DE\" fest. Heben Sie dann die Auskommentierung +//des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile, +//sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher + //(wird verwendet, wenn eine Ressource auf der Seite + // oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.) + ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs + //(wird verwendet, wenn eine Ressource auf der Seite, in der Anwendung oder einem + // designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.) +)] + + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/utilities/PasswordDialog/Properties/Resources.Designer.cs b/utilities/PasswordDialog/Properties/Resources.Designer.cs new file mode 100644 index 0000000..ef40d2d --- /dev/null +++ b/utilities/PasswordDialog/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace PasswordDialog.Properties { + using System; + + + /// + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PasswordDialog.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/utilities/PasswordDialog/Properties/Resources.resx b/utilities/PasswordDialog/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/utilities/PasswordDialog/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/utilities/PasswordDialog/Properties/Settings.Designer.cs b/utilities/PasswordDialog/Properties/Settings.Designer.cs new file mode 100644 index 0000000..54b5b5c --- /dev/null +++ b/utilities/PasswordDialog/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace PasswordDialog.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/utilities/PasswordDialog/Properties/Settings.settings b/utilities/PasswordDialog/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/utilities/PasswordDialog/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/utilities/PasswordDialog/Resources/Icon.ico b/utilities/PasswordDialog/Resources/Icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c10c8f8017e933c3883af23ccf2592110b0742cb GIT binary patch literal 43302 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 literal 0 HcmV?d00001 diff --git a/utilities/PasswordDialog/SecureWrapper.cs b/utilities/PasswordDialog/SecureWrapper.cs new file mode 100644 index 0000000..2550675 --- /dev/null +++ b/utilities/PasswordDialog/SecureWrapper.cs @@ -0,0 +1,186 @@ +/******************************************************************************/ +/* CodeSign, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +using System; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace PasswordDialog +{ + public class SecureWrapper : IDisposable + { + private static readonly char[] EMPTY_CHARS = new char[0]; + private static readonly byte[] EMPTY_BYTES = new byte[0]; + + private readonly SecureString m_string; + private readonly Object m_lock = new Object(); + + private GCHandle m_charBuffer; + private GCHandle m_byteBuffer; + + private volatile bool m_disposed = false; + + //------------------------------------------------------------------- + // Constructor + //------------------------------------------------------------------- + + public SecureWrapper(SecureString secureString) + { + if(ReferenceEquals(m_string = secureString, null)) + { + throw new ArgumentNullException("SecureString must not be null!"); + } + } + + ~SecureWrapper() + { + Dispose(); + } + + //------------------------------------------------------------------- + // Public Interface + //------------------------------------------------------------------- + + public char[] CharBuffer + { + get + { + lock(m_lock) + { + if(m_disposed) + { + throw new ObjectDisposedException("Already disposed!"); + } + if(m_string.Length > 0) + { + if (!m_charBuffer.IsAllocated) + { + m_charBuffer = AllocateBuffer(m_string.Length); + try + { + CopyToBuffer((char[])m_charBuffer.Target, m_string); + } + catch + { + ClearBuffer(m_charBuffer); + throw; /*re-throw after clean-up!*/ + } + } + return (char[])m_charBuffer.Target; + } + return EMPTY_CHARS; + } + } + } + + public byte[] ByteBuffer + { + get + { + lock (m_lock) + { + if(m_disposed) + { + throw new ObjectDisposedException("Already disposed!"); + } + if (m_string.Length > 0) + { + if (!m_byteBuffer.IsAllocated) + { + UTF8Encoding encoding = new UTF8Encoding(false); + char[] chars = CharBuffer; + m_byteBuffer = AllocateBuffer(encoding.GetByteCount(chars)); + try + { + encoding.GetBytes(chars, 0, chars.Length, (byte[])m_byteBuffer.Target, 0); + } + catch + { + ClearBuffer(m_byteBuffer); + throw; /*re-throw after clean-up!*/ + } + } + return (byte[])m_byteBuffer.Target; + } + return EMPTY_BYTES; + } + } + } + + public void Dispose() + { + lock (m_lock) + { + if (!m_disposed) + { + m_disposed = true; + try + { + ClearBuffer(m_byteBuffer); + } + catch { } + try + { + ClearBuffer(m_charBuffer); + } + catch { } + } + } + } + + //------------------------------------------------------------------- + // Internal Methods + //------------------------------------------------------------------- + + private static GCHandle AllocateBuffer(int length) + { + T[] buffer = new T[length]; + return GCHandle.Alloc(buffer, GCHandleType.Pinned); + } + + private static void CopyToBuffer(char[] buffer, SecureString secStr) + { + IntPtr valuePtr = IntPtr.Zero; + try + { + valuePtr = Marshal.SecureStringToGlobalAllocUnicode(secStr); + Marshal.Copy(valuePtr, buffer, 0, Math.Min(secStr.Length, buffer.Length)); + } + finally + { + Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); + } + } + + private static void ClearBuffer(GCHandle handle) + { + if(handle.IsAllocated) + { + try + { + if(handle.Target is Array) + { + Array array = (Array)handle.Target; + Array.Clear(array, 0, array.Length); + } + else if(handle.Target is String) + { + char[] zeros = new char[((String)handle.Target).Length]; + Marshal.Copy(zeros, 0, handle.AddrOfPinnedObject(), zeros.Length); + } + else + { + throw new ArgumentException("Unsupported buffer type!"); + } + } + finally + { + handle.Free(); + } + } + } + } +}