Index: autogen.sh ================================================================== --- autogen.sh +++ autogen.sh @@ -11,10 +11,11 @@ urls=( http://chiselapp.com/user/rkeene/repository/autoconf/doc/trunk/tcl.m4 http://chiselapp.com/user/rkeene/repository/autoconf/doc/trunk/shobj.m4 http://chiselapp.com/user/rkeene/repository/autoconf/doc/trunk/versionscript.m4 + 'http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_check_compile_flag.m4' ) localFiles=( aclocal/tcltls_openssl.m4 ) Index: configure.in ================================================================== --- configure.in +++ configure.in @@ -106,10 +106,13 @@ tcltls_debug='true' fi ]) if test "$tcltls_debug" = 'true'; then AC_DEFINE(TCLEXT_TCLTLS_DEBUG, [1], [Enable debugging build]) + AX_CHECK_COMPILE_FLAG([-fcheck-pointer-bounds], [CFLAGS="$CFLAGS -fcheck-pointer-bounds"]) + AX_CHECK_COMPILE_FLAG([-fsanitize=address], [CFLAGS="$CFLAGS -fsanitize=address"]) + AX_CHECK_COMPILE_FLAG([-fsanitize=undefined], [CFLAGS="$CFLAGS -fsanitize=undefined"]) fi dnl Find "xxd" so we can build the tls.tcl.h file AC_CHECK_PROG([XXD], [xxd], [xxd], [__xxd__not__found]) @@ -134,10 +137,15 @@ if test "$enableval" = 'yes'; then TCLEXT_TLS_STATIC_SSL='yes' fi ]) +dnl Enable hardening +AX_CHECK_COMPILE_FLAG([-fstack-protector-all], [CFLAGS="$CFLAGS -fstack-protector-all"]) +AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CFLAGS="$CFLAGS -fno-strict-overflow"]) +AC_DEFINE([_FORTIFY_SOURCE], [2], [Enable fortification]) + dnl XXX:TODO: Automatically determine the SSL library to use dnl defaulting to OpenSSL for compatibility reasons if test "$tcltls_ssl_lib" = 'auto'; then tcltls_ssl_lib='openssl' fi Index: gen_dh_params ================================================================== --- gen_dh_params +++ gen_dh_params @@ -100,10 +100,14 @@ gen_dh_params_fallback && exit 0 exit 1 fi +echo "*****************************" +echo "** Generating DH Primes. **" +echo "** This will take a while. **" +echo "*****************************" gen_dh_params_openssl && exit 0 gen_dh_params_remote && exit 0 gen_dh_params_fallback && exit 0 exit 1 Index: tls.c ================================================================== --- tls.c +++ tls.c @@ -63,11 +63,11 @@ static SSL_CTX *CTX_Init(State *statePtr, int proto, char *key, char *cert, char *CAdir, char *CAfile, char *ciphers, char *DHparams); -static int TlsLibInit(void); +static int TlsLibInit(int uninitialize); #define TLS_PROTO_SSL2 0x01 #define TLS_PROTO_SSL3 0x02 #define TLS_PROTO_TLS1 0x04 #define TLS_PROTO_TLS1_1 0x08 @@ -115,33 +115,26 @@ /* * Threaded operation requires locking callbacks * Based from /crypto/cryptlib.c of OpenSSL and NSOpenSSL. */ -#ifndef CRYPTO_NUM_LOCKS -#define CRYPTO_NUM_LOCKS 128 -#endif -static Tcl_Mutex locks[CRYPTO_NUM_LOCKS]; +static Tcl_Mutex *locks = NULL; static Tcl_Mutex init_mx; -static void CryptoThreadLockCallback (int mode, int n, const char *file, int line); -static unsigned long CryptoThreadIdCallback (void); - -static void -CryptoThreadLockCallback(int mode, int n, const char *file, int line) -{ - if (mode & CRYPTO_LOCK) { - Tcl_MutexLock(&locks[n]); - } else { - Tcl_MutexUnlock(&locks[n]); - } -} - -static unsigned long -CryptoThreadIdCallback(void) -{ - return (unsigned long) Tcl_GetCurrentThread(); +static void CryptoThreadLockCallback(int mode, int n, const char *file, int line); +static unsigned long CryptoThreadIdCallback(void); + +static void CryptoThreadLockCallback(int mode, int n, const char *file, int line) { + if (mode & CRYPTO_LOCK) { + Tcl_MutexLock(&locks[n]); + } else { + Tcl_MutexUnlock(&locks[n]); + } +} + +static unsigned long CryptoThreadIdCallback(void) { + return (unsigned long) Tcl_GetCurrentThread(); } #endif /* OPENSSL_THREADS */ #endif /* TCL_THREADS */ @@ -1656,11 +1649,11 @@ #endif == NULL) { return TCL_ERROR; } - if (TlsLibInit() != TCL_OK) { + if (TlsLibInit(0) != TCL_OK) { Tcl_AppendResult(interp, "could not initialize SSL library", NULL); return TCL_ERROR; } Tcl_CreateObjCommand(interp, "tls::ciphers", CiphersObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); @@ -1717,13 +1710,44 @@ * Result: * none * *------------------------------------------------------* */ -static int TlsLibInit(void) { +static int TlsLibInit(int uninitialize) { static int initialized = 0; int status = TCL_OK; +#if defined(OPENSSL_THREADS) && defined(TCL_THREADS) + size_t num_locks; +#endif + + if (uninitialize) { + if (!initialized) { + dprintf("Asked to uninitialize, but we are not initialized"); + + return(TCL_OK); + } + + dprintf("Asked to uninitialize"); +#if defined(OPENSSL_THREADS) && defined(TCL_THREADS) + Tcl_MutexLock(&init_mx); + + CRYPTO_set_locking_callback(NULL); + CRYPTO_set_id_callback(NULL); + + if (locks) { + free(locks); + locks = NULL; + } +#endif + initialized = 0; + +#if defined(OPENSSL_THREADS) && defined(TCL_THREADS) + Tcl_MutexUnlock(&init_mx); +#endif + + return(TCL_OK); + } if (initialized) { dprintf("Called, but using cached value"); return(status); } @@ -1731,22 +1755,14 @@ dprintf("Called"); initialized = 1; #if defined(OPENSSL_THREADS) && defined(TCL_THREADS) - size_t num_locks; - Tcl_MutexLock(&init_mx); -#endif -#if defined(OPENSSL_THREADS) && defined(TCL_THREADS) - /* should we consider allocating mutexes? */ num_locks = CRYPTO_num_locks(); - if (num_locks > CRYPTO_NUM_LOCKS) { - status = TCL_ERROR; - goto done; - } + locks = malloc(sizeof(*locks) * num_locks); CRYPTO_set_locking_callback(CryptoThreadLockCallback); CRYPTO_set_id_callback(CryptoThreadIdCallback); #endif