Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -10,11 +10,11 @@ pkgIndex.tcl tcltls.so tcltls.a tcltls.a.linkadd tls.o -tlsBIO.o +tls_openssl_bio.o tlsIO.o tlsX509.o tls.tcl.h build/work dh_params.h Index: Makefile.in ================================================================== --- Makefile.in +++ Makefile.in @@ -12,22 +12,22 @@ VPATH = @srcdir@ all: @EXTENSION_TARGET@ # The shared object target -tcltls.@SHOBJEXT@: tls.o tlsBIO.o tlsIO.o tlsX509.o Makefile - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o tcltls.@SHOBJEXT@ tls.o tlsBIO.o tlsIO.o tlsX509.o $(LIBS) +tcltls.@SHOBJEXT@: tls.o tls_@TCLTLS_SSL_LIB@_bio.o tlsIO.o tlsX509.o Makefile + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o tcltls.@SHOBJEXT@ tls.o tls_@TCLTLS_SSL_LIB@_bio.o tlsIO.o tlsX509.o $(LIBS) # The static target -tcltls.@AREXT@: tls.o tlsBIO.o tlsIO.o tlsX509.o Makefile - $(AR) rcu tcltls.a.new tls.o tlsBIO.o tlsIO.o tlsX509.o +tcltls.@AREXT@: tls.o tls_@TCLTLS_SSL_LIB@_bio.o tlsIO.o tlsX509.o Makefile + $(AR) rcu tcltls.a.new tls.o tls_@TCLTLS_SSL_LIB@_bio.o tlsIO.o tlsX509.o $(RANLIB) tcltls.a.new mv tcltls.a.new tcltls.a # Dependencies for all our targets tls.o: @srcdir@/tls.c @srcdir@/tlsInt.h @srcdir@/tclOpts.h @srcdir@/tls.tcl.h dh_params.h Makefile -tlsBIO.o: @srcdir@/tlsBIO.c @srcdir@/tlsInt.h Makefile +tls_openssl_bio.o: @srcdir@/tls_openssl_bio.c @srcdir@/tlsInt.h Makefile tlsIO.o: @srcdir@/tlsIO.c @srcdir@/tlsInt.h Makefile tlsX509.o: @srcdir@/tlsX509.c @srcdir@/tlsInt.h Makefile # Create a C-source-ified version of the script resources # for TclTLS so that we only need a single file to enable @@ -51,11 +51,11 @@ $(INSTALL) -d '$(DESTDIR)$(PACKAGE_INSTALL_DIR)' $(INSTALL) -t '$(DESTDIR)$(PACKAGE_INSTALL_DIR)' @EXTENSION_TARGET@ pkgIndex.tcl # Clean the local build directory for rebuild against the same configuration clean: - rm -f tls.o tlsBIO.o tlsIO.o tlsX509.o + rm -f tls.o tls_openssl_bio.o tlsIO.o tlsX509.o rm -f tcltls.@SHOBJEXT@ rm -f tcltls.a.new tcltls.a # Clean the local build directory back to what it was after unpacking the # distribution tarball Index: configure.in ================================================================== --- configure.in +++ configure.in @@ -129,10 +129,12 @@ if test "$tcltls_ssl_lib" = 'auto'; then tcltls_ssl_lib='openssl' fi AC_MSG_CHECKING([which TLS library to use]) +TCLTLS_SSL_LIB="${tcltls_ssl_lib}" +AC_SUBST(TCLTLS_SSL_LIB) AC_MSG_RESULT([$tcltls_ssl_lib]) dnl Manually rewrite libressl to OpenSSL since we use the dnl compatibility interface if test "$tcltls_ssl_lib" = "libressl"; then @@ -140,10 +142,11 @@ fi AS_CASE([$tcltls_ssl_lib], [openssl], [ TCLTLS_SSL_OPENSSL + AC_DEFINE([TCLTLS_SSL_OPENSSL], [1], [Define if the backend being used is OpenSSL (or the LibreSSL OpenSSL compatibility interface)]) ], [nss], [ TCLTLS_SSL_LIBS="" TCLTLS_SSL_CFLAGS="" TCLTLS_SSL_CPPFLAGS="" DELETED tlsBIO.c Index: tlsBIO.c ================================================================== --- tlsBIO.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 1997-2000 Matt Newman - * - * Provides BIO layer to interface openssl to Tcl. - */ - -#include "tlsInt.h" - -#ifdef TCLTLS_OPENSSL_PRE_1_1_API -#define BIO_get_data(bio) ((bio)->ptr) -#define BIO_get_init(bio) ((bio)->init) -#define BIO_get_shutdown(bio) ((bio)->shutdown) -#define BIO_set_data(bio, val) (bio)->ptr = (val) -#define BIO_set_init(bio, val) (bio)->init = (val) -#define BIO_set_shutdown(bio, val) (bio)->shutdown = (val) - -/* XXX: This assumes the variable being assigned to is BioMethods */ -#define BIO_meth_new(type_, name_) (BIO_METHOD *)Tcl_Alloc(sizeof(BIO_METHOD)); \ - memset(BioMethods, 0, sizeof(BIO_METHOD)); \ - BioMethods->type = type_; \ - BioMethods->name = name_; -#define BIO_meth_set_write(bio, val) (bio)->bwrite = val; -#define BIO_meth_set_read(bio, val) (bio)->bread = val; -#define BIO_meth_set_puts(bio, val) (bio)->bputs = val; -#define BIO_meth_set_ctrl(bio, val) (bio)->ctrl = val; -#define BIO_meth_set_create(bio, val) (bio)->create = val; -#define BIO_meth_set_destroy(bio, val) (bio)->destroy = val; -#endif - -/* - * Forward declarations - */ - -static int BioWrite _ANSI_ARGS_((BIO *h, CONST char *buf, int num)); -static int BioRead _ANSI_ARGS_((BIO *h, char *buf, int num)); -static int BioPuts _ANSI_ARGS_((BIO *h, CONST char *str)); -static long BioCtrl _ANSI_ARGS_((BIO *h, int cmd, long arg1, void *ptr)); -static int BioNew _ANSI_ARGS_((BIO *h)); -static int BioFree _ANSI_ARGS_((BIO *h)); - -BIO *BIO_new_tcl(State *statePtr, int flags) { - BIO *bio; - static BIO_METHOD *BioMethods = NULL; - - dprintf("BIO_new_tcl() called"); - - if (BioMethods == NULL) { - BioMethods = BIO_meth_new(BIO_TYPE_TCL, "tcl"); - BIO_meth_set_write(BioMethods, BioWrite); - BIO_meth_set_read(BioMethods, BioRead); - BIO_meth_set_puts(BioMethods, BioPuts); - BIO_meth_set_ctrl(BioMethods, BioCtrl); - BIO_meth_set_create(BioMethods, BioNew); - BIO_meth_set_destroy(BioMethods, BioFree); - } - - bio = BIO_new(BioMethods); - - BIO_set_data(bio, statePtr); - BIO_set_init(bio, 1); - BIO_set_shutdown(bio, flags); - - return(bio); -} - -static int BioWrite(BIO *bio, CONST char *buf, int bufLen) { - Tcl_Channel chan; - int ret; - - chan = Tls_GetParent((State *) BIO_get_data(bio)); - - dprintf("BioWrite(%p, , %d) [%p]", (void *) bio, bufLen, (void *) chan); - - ret = Tcl_WriteRaw(chan, buf, bufLen); - - dprintf("[%p] BioWrite(%d) -> %d [%d.%d]", (void *) chan, bufLen, ret, Tcl_Eof(chan), Tcl_GetErrno()); - - BIO_clear_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); - - if (ret == 0) { - if (!Tcl_Eof(chan)) { - BIO_set_retry_write(bio); - ret = -1; - } - } - - if (BIO_should_read(bio)) { - BIO_set_retry_read(bio); - } - - return(ret); -} - -static int BioRead(BIO *bio, char *buf, int bufLen) { - Tcl_Channel chan; - int ret = 0; - int tclEofChan; - - chan = Tls_GetParent((State *) BIO_get_data(bio)); - - dprintf("BioRead(%p, , %d) [%p]", (void *) bio, bufLen, (void *) chan); - - if (buf == NULL) { - return 0; - } - - ret = Tcl_ReadRaw(chan, buf, bufLen); - - tclEofChan = Tcl_Eof(chan); - - dprintf("[%p] BioRead(%d) -> %d [tclEof=%d; tclErrno=%d]", (void *) chan, bufLen, ret, tclEofChan, Tcl_GetErrno()); - - BIO_clear_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); - - if (ret == 0) { - if (!tclEofChan) { - dprintf("Got 0 from Tcl_Read or Tcl_ReadRaw, and EOF is not set -- ret == -1 now"); - BIO_set_retry_read(bio); - ret = -1; - } else { - dprintf("Got 0 from Tcl_Read or Tcl_ReadRaw, and EOF is set"); - } - } else { - dprintf("Got non-zero from Tcl_Read or Tcl_ReadRaw; ret == %i", ret); - } - - if (BIO_should_write(bio)) { - BIO_set_retry_write(bio); - } - - dprintf("BioRead(%p, , %d) [%p] returning %i", (void *) bio, bufLen, (void *) chan, ret); - - return(ret); -} - -static int BioPuts(BIO *bio, CONST char *str) { - dprintf("BioPuts(%p, ) called", bio, str); - - return BioWrite(bio, str, (int) strlen(str)); -} - -static long BioCtrl(BIO *bio, int cmd, long num, void *ptr) { - Tcl_Channel chan; - long ret = 1; - - chan = Tls_GetParent((State *) BIO_get_data(bio)); - - dprintf("BioCtrl(%p, 0x%x, 0x%x, %p)", (void *) bio, (unsigned int) cmd, (unsigned int) num, (void *) ptr); - - switch (cmd) { - case BIO_CTRL_RESET: - dprintf("Got BIO_CTRL_RESET"); - num = 0; - case BIO_C_FILE_SEEK: - dprintf("Got BIO_C_FILE_SEEK"); - case BIO_C_FILE_TELL: - dprintf("Got BIO_C_FILE_TELL"); - ret = 0; - break; - case BIO_CTRL_INFO: - dprintf("Got BIO_CTRL_INFO"); - ret = 1; - break; - case BIO_C_SET_FD: - dprintf("Unsupported call: BIO_C_SET_FD"); - ret = -1; - break; - case BIO_C_GET_FD: - dprintf("Unsupported call: BIO_C_GET_FD"); - ret = -1; - break; - case BIO_CTRL_GET_CLOSE: - dprintf("Got BIO_CTRL_CLOSE"); - ret = BIO_get_shutdown(bio); - break; - case BIO_CTRL_SET_CLOSE: - dprintf("Got BIO_SET_CLOSE"); - BIO_set_shutdown(bio, num); - break; - case BIO_CTRL_EOF: - dprintf("Got BIO_CTRL_EOF"); - ret = Tcl_Eof(chan); - break; - case BIO_CTRL_PENDING: - dprintf("Got BIO_CTRL_PENDING"); - ret = ((chan) ? 1 : 0); - dprintf("BIO_CTRL_PENDING(%d)", (int) ret); - break; - case BIO_CTRL_WPENDING: - dprintf("Got BIO_CTRL_WPENDING"); - ret = 0; - break; - case BIO_CTRL_DUP: - dprintf("Got BIO_CTRL_DUP"); - break; - case BIO_CTRL_FLUSH: - dprintf("Got BIO_CTRL_FLUSH"); - ret = ((Tcl_WriteRaw(chan, "", 0) >= 0) ? 1 : -1); - dprintf("BIO_CTRL_FLUSH returning value %li", ret); - break; - default: - dprintf("Got unknown control command (%i)", cmd); - ret = 0; - break; - } - - return(ret); -} - -static int BioNew(BIO *bio) { - dprintf("BioNew(%p) called", bio); - - BIO_set_init(bio, 0); - BIO_set_data(bio, NULL); - BIO_clear_flags(bio, -1); - - return(1); -} - -static int BioFree(BIO *bio) { - if (bio == NULL) { - return(0); - } - - dprintf("BioFree(%p) called", bio); - - if (BIO_get_shutdown(bio)) { - if (BIO_get_init(bio)) { - /*shutdown(bio->num, 2) */ - /*closesocket(bio->num) */ - } - - BIO_set_init(bio, 0); - BIO_clear_flags(bio, -1); - } - - return(1); -} ADDED tls_openssl_bio.c Index: tls_openssl_bio.c ================================================================== --- /dev/null +++ tls_openssl_bio.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 1997-2000 Matt Newman + * + * Provides BIO layer to interface openssl to Tcl. + */ + +#include "tlsInt.h" + +#ifdef TCLTLS_OPENSSL_PRE_1_1_API +#define BIO_get_data(bio) ((bio)->ptr) +#define BIO_get_init(bio) ((bio)->init) +#define BIO_get_shutdown(bio) ((bio)->shutdown) +#define BIO_set_data(bio, val) (bio)->ptr = (val) +#define BIO_set_init(bio, val) (bio)->init = (val) +#define BIO_set_shutdown(bio, val) (bio)->shutdown = (val) + +/* XXX: This assumes the variable being assigned to is BioMethods */ +#define BIO_meth_new(type_, name_) (BIO_METHOD *)Tcl_Alloc(sizeof(BIO_METHOD)); \ + memset(BioMethods, 0, sizeof(BIO_METHOD)); \ + BioMethods->type = type_; \ + BioMethods->name = name_; +#define BIO_meth_set_write(bio, val) (bio)->bwrite = val; +#define BIO_meth_set_read(bio, val) (bio)->bread = val; +#define BIO_meth_set_puts(bio, val) (bio)->bputs = val; +#define BIO_meth_set_ctrl(bio, val) (bio)->ctrl = val; +#define BIO_meth_set_create(bio, val) (bio)->create = val; +#define BIO_meth_set_destroy(bio, val) (bio)->destroy = val; +#endif + +/* + * Forward declarations + */ + +static int BioWrite _ANSI_ARGS_((BIO *h, CONST char *buf, int num)); +static int BioRead _ANSI_ARGS_((BIO *h, char *buf, int num)); +static int BioPuts _ANSI_ARGS_((BIO *h, CONST char *str)); +static long BioCtrl _ANSI_ARGS_((BIO *h, int cmd, long arg1, void *ptr)); +static int BioNew _ANSI_ARGS_((BIO *h)); +static int BioFree _ANSI_ARGS_((BIO *h)); + +BIO *BIO_new_tcl(State *statePtr, int flags) { + BIO *bio; + static BIO_METHOD *BioMethods = NULL; + + dprintf("BIO_new_tcl() called"); + + if (BioMethods == NULL) { + BioMethods = BIO_meth_new(BIO_TYPE_TCL, "tcl"); + BIO_meth_set_write(BioMethods, BioWrite); + BIO_meth_set_read(BioMethods, BioRead); + BIO_meth_set_puts(BioMethods, BioPuts); + BIO_meth_set_ctrl(BioMethods, BioCtrl); + BIO_meth_set_create(BioMethods, BioNew); + BIO_meth_set_destroy(BioMethods, BioFree); + } + + bio = BIO_new(BioMethods); + + BIO_set_data(bio, statePtr); + BIO_set_init(bio, 1); + BIO_set_shutdown(bio, flags); + + return(bio); +} + +static int BioWrite(BIO *bio, CONST char *buf, int bufLen) { + Tcl_Channel chan; + int ret; + + chan = Tls_GetParent((State *) BIO_get_data(bio)); + + dprintf("BioWrite(%p, , %d) [%p]", (void *) bio, bufLen, (void *) chan); + + ret = Tcl_WriteRaw(chan, buf, bufLen); + + dprintf("[%p] BioWrite(%d) -> %d [%d.%d]", (void *) chan, bufLen, ret, Tcl_Eof(chan), Tcl_GetErrno()); + + BIO_clear_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); + + if (ret == 0) { + if (!Tcl_Eof(chan)) { + BIO_set_retry_write(bio); + ret = -1; + } + } + + if (BIO_should_read(bio)) { + BIO_set_retry_read(bio); + } + + return(ret); +} + +static int BioRead(BIO *bio, char *buf, int bufLen) { + Tcl_Channel chan; + int ret = 0; + int tclEofChan; + + chan = Tls_GetParent((State *) BIO_get_data(bio)); + + dprintf("BioRead(%p, , %d) [%p]", (void *) bio, bufLen, (void *) chan); + + if (buf == NULL) { + return 0; + } + + ret = Tcl_ReadRaw(chan, buf, bufLen); + + tclEofChan = Tcl_Eof(chan); + + dprintf("[%p] BioRead(%d) -> %d [tclEof=%d; tclErrno=%d]", (void *) chan, bufLen, ret, tclEofChan, Tcl_GetErrno()); + + BIO_clear_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); + + if (ret == 0) { + if (!tclEofChan) { + dprintf("Got 0 from Tcl_Read or Tcl_ReadRaw, and EOF is not set -- ret == -1 now"); + BIO_set_retry_read(bio); + ret = -1; + } else { + dprintf("Got 0 from Tcl_Read or Tcl_ReadRaw, and EOF is set"); + } + } else { + dprintf("Got non-zero from Tcl_Read or Tcl_ReadRaw; ret == %i", ret); + } + + if (BIO_should_write(bio)) { + BIO_set_retry_write(bio); + } + + dprintf("BioRead(%p, , %d) [%p] returning %i", (void *) bio, bufLen, (void *) chan, ret); + + return(ret); +} + +static int BioPuts(BIO *bio, CONST char *str) { + dprintf("BioPuts(%p, ) called", bio, str); + + return BioWrite(bio, str, (int) strlen(str)); +} + +static long BioCtrl(BIO *bio, int cmd, long num, void *ptr) { + Tcl_Channel chan; + long ret = 1; + + chan = Tls_GetParent((State *) BIO_get_data(bio)); + + dprintf("BioCtrl(%p, 0x%x, 0x%x, %p)", (void *) bio, (unsigned int) cmd, (unsigned int) num, (void *) ptr); + + switch (cmd) { + case BIO_CTRL_RESET: + dprintf("Got BIO_CTRL_RESET"); + num = 0; + case BIO_C_FILE_SEEK: + dprintf("Got BIO_C_FILE_SEEK"); + case BIO_C_FILE_TELL: + dprintf("Got BIO_C_FILE_TELL"); + ret = 0; + break; + case BIO_CTRL_INFO: + dprintf("Got BIO_CTRL_INFO"); + ret = 1; + break; + case BIO_C_SET_FD: + dprintf("Unsupported call: BIO_C_SET_FD"); + ret = -1; + break; + case BIO_C_GET_FD: + dprintf("Unsupported call: BIO_C_GET_FD"); + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + dprintf("Got BIO_CTRL_CLOSE"); + ret = BIO_get_shutdown(bio); + break; + case BIO_CTRL_SET_CLOSE: + dprintf("Got BIO_SET_CLOSE"); + BIO_set_shutdown(bio, num); + break; + case BIO_CTRL_EOF: + dprintf("Got BIO_CTRL_EOF"); + ret = Tcl_Eof(chan); + break; + case BIO_CTRL_PENDING: + dprintf("Got BIO_CTRL_PENDING"); + ret = ((chan) ? 1 : 0); + dprintf("BIO_CTRL_PENDING(%d)", (int) ret); + break; + case BIO_CTRL_WPENDING: + dprintf("Got BIO_CTRL_WPENDING"); + ret = 0; + break; + case BIO_CTRL_DUP: + dprintf("Got BIO_CTRL_DUP"); + break; + case BIO_CTRL_FLUSH: + dprintf("Got BIO_CTRL_FLUSH"); + ret = ((Tcl_WriteRaw(chan, "", 0) >= 0) ? 1 : -1); + dprintf("BIO_CTRL_FLUSH returning value %li", ret); + break; + default: + dprintf("Got unknown control command (%i)", cmd); + ret = 0; + break; + } + + return(ret); +} + +static int BioNew(BIO *bio) { + dprintf("BioNew(%p) called", bio); + + BIO_set_init(bio, 0); + BIO_set_data(bio, NULL); + BIO_clear_flags(bio, -1); + + return(1); +} + +static int BioFree(BIO *bio) { + if (bio == NULL) { + return(0); + } + + dprintf("BioFree(%p) called", bio); + + if (BIO_get_shutdown(bio)) { + if (BIO_get_init(bio)) { + /*shutdown(bio->num, 2) */ + /*closesocket(bio->num) */ + } + + BIO_set_init(bio, 0); + BIO_clear_flags(bio, -1); + } + + return(1); +}