From 58fcd3c39c73d83eb9782a8ef935498b18b5ae73 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Thu, 20 Nov 2014 00:26:55 -0600 Subject: Add conditional compilation for windows and posix functions. This adds a Windows-specific versions of several symbols from libcrypto and openssl(1). --- apps/apps_win.c | 29 ++++ crypto/compat/b_win.c | 54 ++++++ crypto/compat/ui_openssl_win.c | 367 +++++++++++++++++++++++++++++++++++++++++ update.sh | 49 +++++- 4 files changed, 492 insertions(+), 7 deletions(-) create mode 100644 apps/apps_win.c create mode 100644 crypto/compat/b_win.c create mode 100644 crypto/compat/ui_openssl_win.c diff --git a/apps/apps_win.c b/apps/apps_win.c new file mode 100644 index 0000000..496ac03 --- /dev/null +++ b/apps/apps_win.c @@ -0,0 +1,29 @@ +/* + * Public domain + * + * Dongsheng Song + * Brent Cook + */ + +#include + +#include "apps.h" + +double +app_tminterval(int stop, int usertime) +{ + static unsigned __int64 tmstart; + union { + unsigned __int64 u64; + FILETIME ft; + } ct, et, kt, ut; + + GetProcessTimes(GetCurrentProcess(), &ct.ft, &et.ft, &kt.ft, &ut.ft); + + if (stop == TM_START) { + tmstart = ut.u64 + kt.u64; + } else { + return (ut.u64 + kt.u64 - tmstart) / (double) 10000000; + } + return 0; +} diff --git a/crypto/compat/b_win.c b/crypto/compat/b_win.c new file mode 100644 index 0000000..b8d01ae --- /dev/null +++ b/crypto/compat/b_win.c @@ -0,0 +1,54 @@ +/* + * Public domain + * + * Dongsheng Song + * Brent Cook + */ + +#include + +#include +#include + +int +BIO_sock_init(void) +{ + /* + * WSAStartup loads the winsock .dll and initializes the networking + * stack on Windows, or simply increases the reference count. + */ + static struct WSAData wsa_state = {0}; + WORD version_requested = MAKEWORD(2, 2); + static int wsa_init_done = 0; + if (!wsa_init_done) { + if (WSAStartup(version_requested, &wsa_state) != 0) { + int err = WSAGetLastError(); + SYSerr(SYS_F_WSASTARTUP, err); + BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); + return (-1); + } + wsa_init_done = 1; + } + return (1); +} + +void +BIO_sock_cleanup(void) +{ + /* + * We could call WSACleanup here, but it is easy to get it wrong. Since + * this API provides no way to even tell if it failed, there is no safe + * way to expose that functionality here. + * + * The cost of leaving the networking DLLs loaded may have been large + * during the Windows 3.1/win32s era, but it is small in modern + * contexts, so don't bother. + */ +} + +int +BIO_socket_nbio(int s, int mode) +{ + u_long value = mode; + return ioctlsocket(s, FIONBIO, &value) != SOCKET_ERROR; +} diff --git a/crypto/compat/ui_openssl_win.c b/crypto/compat/ui_openssl_win.c new file mode 100644 index 0000000..ecf7376 --- /dev/null +++ b/crypto/compat/ui_openssl_win.c @@ -0,0 +1,367 @@ +/* $OpenBSD: ui_openssl.c,v 1.22 2014/07/11 08:44:49 jsing Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) and others + * for the OpenSSL project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* The lowest level part of this file was previously in crypto/des/read_pwd.c, + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "ui_locl.h" + +#ifndef NX509_SIG +#define NX509_SIG 32 +#endif + +/* Define globals. They are protected by a lock */ +static void (*savsig[NX509_SIG])(int ); + +static FILE *tty_in, *tty_out; +static int is_a_tty; + +/* Declare static functions */ +static int read_till_nl(FILE *); +static void recsig(int); +static void pushsig(void); +static void popsig(void); +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); + +static int read_string(UI *ui, UI_STRING *uis); +static int write_string(UI *ui, UI_STRING *uis); + +static int open_console(UI *ui); +static int echo_console(UI *ui); +static int noecho_console(UI *ui); +static int close_console(UI *ui); + +static UI_METHOD ui_openssl = { + .name = "OpenSSL default user interface", + .ui_open_session = open_console, + .ui_write_string = write_string, + .ui_read_string = read_string, + .ui_close_session = close_console, +}; + +/* The method with all the built-in thingies */ +UI_METHOD * +UI_OpenSSL(void) +{ + return &ui_openssl; +} + +/* The following function makes sure that info and error strings are printed + before any prompt. */ +static int +write_string(UI *ui, UI_STRING *uis) +{ + switch (UI_get_string_type(uis)) { + case UIT_ERROR: + case UIT_INFO: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + break; + default: + break; + } + return 1; +} + +static int +read_string(UI *ui, UI_STRING *uis) +{ + int ok = 0; + + switch (UI_get_string_type(uis)) { + case UIT_BOOLEAN: + fputs(UI_get0_output_string(uis), tty_out); + fputs(UI_get0_action_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0); + case UIT_PROMPT: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1); + case UIT_VERIFY: + fprintf(tty_out, "Verifying - %s", + UI_get0_output_string(uis)); + fflush(tty_out); + if ((ok = read_string_inner(ui, uis, UI_get_input_flags(uis) & + UI_INPUT_FLAG_ECHO, 1)) <= 0) + return ok; + if (strcmp(UI_get0_result_string(uis), + UI_get0_test_string(uis)) != 0) { + fprintf(tty_out, "Verify failure\n"); + fflush(tty_out); + return 0; + } + break; + default: + break; + } + return 1; +} + + +/* Internal functions to read a string without echoing */ +static int +read_till_nl(FILE *in) +{ +#define SIZE 4 + char buf[SIZE + 1]; + + do { + if (!fgets(buf, SIZE, in)) + return 0; + } while (strchr(buf, '\n') == NULL); + return 1; +} + +static volatile sig_atomic_t intr_signal; + +static int +read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) +{ + static int ps; + int ok; + char result[BUFSIZ]; + int maxsize = BUFSIZ - 1; + char *p; + + intr_signal = 0; + ok = 0; + ps = 0; + + pushsig(); + + ps = 1; + + if (!echo && !noecho_console(ui)) + goto error; + ps = 2; + + result[0] = '\0'; + p = fgets(result, maxsize, tty_in); + if (!p) + goto error; + if (feof(tty_in)) + goto error; + if (ferror(tty_in)) + goto error; + if ((p = strchr(result, '\n')) != NULL) { + if (strip_nl) + *p = '\0'; + } else if (!read_till_nl(tty_in)) + goto error; + if (UI_set_result(ui, uis, result) >= 0) + ok = 1; + +error: + if (intr_signal == SIGINT) + ok = -1; + if (!echo) + fprintf(tty_out, "\n"); + if (ps >= 2 && !echo && !echo_console(ui)) + ok = 0; + + if (ps >= 1) + popsig(); + + OPENSSL_cleanse(result, BUFSIZ); + return ok; +} + + +/* Internal functions to open, handle and close a channel to the console. */ +static int +open_console(UI *ui) +{ + CRYPTO_w_lock(CRYPTO_LOCK_UI); + is_a_tty = 1; + + tty_in = stdin; + tty_out = stderr; + + return 1; +} + +static int +noecho_console(UI *ui) +{ + DWORD mode = 0; + HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); + if (handle != INVALID_HANDLE_VALUE && handle != handle) { + return GetConsoleMode(handle, &mode) && SetConsoleMode(handle, mode & (~ENABLE_ECHO_INPUT)); + } + return 0; +} + +static int +echo_console(UI *ui) +{ + DWORD mode = 0; + HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); + if (handle != INVALID_HANDLE_VALUE && handle != handle) { + return GetConsoleMode(handle, &mode) && SetConsoleMode(handle, mode | ENABLE_ECHO_INPUT); + } + return 0; +} + +static int +close_console(UI *ui) +{ + if (tty_in != stdin) + fclose(tty_in); + if (tty_out != stderr) + fclose(tty_out); + CRYPTO_w_unlock(CRYPTO_LOCK_UI); + + return 1; +} + +/* Internal functions to handle signals and act on them */ +static void +pushsig(void) +{ + savsig[SIGABRT] = signal(SIGABRT, recsig); + savsig[SIGFPE] = signal(SIGFPE, recsig); + savsig[SIGILL] = signal(SIGILL, recsig); + savsig[SIGINT] = signal(SIGINT, recsig); + savsig[SIGSEGV] = signal(SIGSEGV, recsig); + savsig[SIGTERM] = signal(SIGTERM, recsig); +} + +static void +popsig(void) +{ + signal(SIGABRT, savsig[SIGABRT]); + signal(SIGFPE, savsig[SIGFPE]); + signal(SIGILL, savsig[SIGILL]); + signal(SIGINT, savsig[SIGINT]); + signal(SIGSEGV, savsig[SIGSEGV]); + signal(SIGTERM, savsig[SIGTERM]); +} + +static void +recsig(int i) +{ + intr_signal = i; +} diff --git a/update.sh b/update.sh index 3a0edbb..80842cf 100755 --- a/update.sh +++ b/update.sh @@ -38,7 +38,11 @@ copy_src() { mkdir -p $1 rm -f $1/*.c for file in $3; do - $CP $2/src/$1/$file $1 + if [ -e $2/src/$1/$file ]; then + $CP $2/src/$1/$file $1 + else + $CP crypto/compat/$file $1 + fi done } @@ -128,7 +132,8 @@ copy_crypto bf "bf_skey.c bf_ecb.c bf_enc.c bf_cfb64.c bf_ofb64.c bf_locl.h bf_p copy_crypto bio "bio_lib.c bio_cb.c bio_err.c bss_mem.c bss_null.c bss_fd.c bss_file.c bss_sock.c bss_conn.c bf_null.c bf_buff.c b_dump.c - b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c bss_dgram.c b_print.c" + b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c bss_dgram.c b_print.c + b_posix.c b_win.c" copy_crypto bn "bn_add.c bn_asm.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c bn_kron.c @@ -262,7 +267,7 @@ copy_crypto ts "ts_err.c ts_req_utils.c ts_req_print.c ts_rsp_utils.c copy_crypto txt_db "txt_db.c" -copy_crypto ui "ui_err.c ui_lib.c ui_openssl.c ui_util.c ui_locl.h" +copy_crypto ui "ui_err.c ui_lib.c ui_openssl.c ui_openssl_win.c ui_util.c ui_locl.h" copy_crypto whrlpool "wp_block.c wp_dgst.c wp_locl.h" @@ -373,6 +378,14 @@ crypto_excludes=( chacha/chacha-merged.c poly1305/poly1305-donna.c ) +crypto_posix_only=( + bio/b_posix.c + ui/ui_openssl.c + ) +crypto_win32_only=( + bio/b_win.c + ui/ui_openssl_win.c + ) (cd crypto sed -e "s/libcrypto-version/${libcrypto_version}/" Makefile.am.tpl > Makefile.am for i in `ls -1 *.c|sort`; do @@ -385,10 +398,18 @@ crypto_excludes=( echo >> Makefile.am echo "# ${subdir}" >> Makefile.am for i in `ls -1 $subdir/*.c|sort`; do - if ! [[ ${crypto_excludes[*]} =~ $i ]]; then - echo "libcrypto_la_SOURCES += $i" >> Makefile.am - else + if [[ ${crypto_excludes[*]} =~ $i ]]; then echo "EXTRA_libcrypto_la_SOURCES += $i" >> Makefile.am + elif [[ ${crypto_posix_only[*]} =~ $i ]]; then + echo "if !HOST_WIN" >> Makefile.am + echo "libcrypto_la_SOURCES += ${i}" >> Makefile.am + echo "endif" >> Makefile.am + elif [[ ${crypto_win32_only[*]} =~ $i ]]; then + echo "if HOST_WIN" >> Makefile.am + echo "libcrypto_la_SOURCES += ${i}" >> Makefile.am + echo "endif" >> Makefile.am + else + echo "libcrypto_la_SOURCES += $i" >> Makefile.am fi done headers=`ls -1 $subdir/*.h 2>/dev/null |sort` @@ -405,10 +426,24 @@ $CP $libc_src/stdlib/strtonum.c apps/ apps_excludes=( strtonum.c ) +apps_posix_only=( + apps_posix.c + ) +apps_win32_only=( + apps_win.c + ) (cd apps $CP Makefile.am.tpl Makefile.am for i in `ls -1 *.c|sort`; do - if ! [[ ${apps_excludes[*]} =~ $i ]]; then + if [[ ${apps_posix_only[*]} =~ $i ]]; then + echo "if !HOST_WIN" >> Makefile.am + echo "openssl_SOURCES += ${i}" >> Makefile.am + echo "endif" >> Makefile.am + elif [[ ${apps_win32_only[*]} =~ $i ]]; then + echo "if HOST_WIN" >> Makefile.am + echo "openssl_SOURCES += ${i}" >> Makefile.am + echo "endif" >> Makefile.am + elif ! [[ ${apps_excludes[*]} =~ $i ]]; then echo "openssl_SOURCES += $i" >> Makefile.am fi done -- cgit v1.2.3-55-g6feb