diff --git a/buildwin.sh b/buildwin.sh index 5e1165c..fea1b51 100644 --- a/buildwin.sh +++ b/buildwin.sh @@ -1,16 +1,16 @@ # msys2 windows build script -echo "Build docs..." -make -C docs - echo "Build proxytunnel..." -make -f Makefile -strip -s proxytunnel.exe +make + +echo "Build docs..." +make docs + +echo "Copy msys/openssl dll to build dir..." +cp /usr/bin/msys-2.0.dll /usr/bin/msys-crypto-3.dll /usr/bin/msys-ssl-3.dll /usr/bin/msys-z.dll . echo "Generate proxytunnel.zip with docs, exe and msys/openssl dll..." -zip proxytunnel.zip proxytunnel.exe docs/proxytunnel.1 docs/proxytunnel.1.html docs/proxytunnel-paper.html -DLLS="$(ldd proxytunnel.exe | grep msys.*\.dll | awk '{print $3}' | xargs) /usr/lib/ossl-modules/legacy.dll" -zip proxytunnel.zip -j $DLLS +zip proxytunnel.zip proxytunnel.exe *.dll docs/proxytunnel.1 docs/proxytunnel.1.html docs/proxytunnel-paper.html if [ ! -z "${TRAVIS_TAG}" ]; then echo "Deploy proxytunnel.zip to github release tag:${TRAVIS_TAG}..." diff --git a/cmdline.c b/cmdline.c index 7e5db30..25d966b 100644 --- a/cmdline.c +++ b/cmdline.c @@ -69,8 +69,7 @@ void cmdline_parser_print_help (void) { " setups)\n" " -B, --buggy-encrypt-proxy Equivalent to -E -W, provided for backwards\n" " compatibility\n" -/*" -L, --tlsenforce Enforce TLSv1 connection (legacy)\n" -" -T, --no-ssl3 Do not connect using SSLv3 (legacy)\n"*/ +//" -L, --tlsenforce Enforce TLSv1 connection (legacy)\n" " -z, --no-check-certificate Don't verify server SSL certificate\n" " -C, --cacert=STRING Path to trusted CA certificate or directory\n" #endif @@ -81,7 +80,8 @@ void cmdline_parser_print_help (void) { " -R, --remproxyauth=STRING Remote proxy auth credentials user:pass combination\n" #ifdef USE_SSL " -c, --cert=FILENAME client SSL certificate (chain)\n" -" -k, --key=FILENAME client SSL key\n" +" -k, --key=FILENAME client SSL key (PEM format)\n" +" -T, --tpmkey=FILENAME client TPM SSL key (TSS2 format)\n" #endif // " -u, --user=STRING Username for proxy authentication\n" // " -s, --pass=STRING Password for proxy authentication\n" @@ -159,6 +159,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar args_info->encryptremproxy_given = 0; args_info->clientcert_given = 0; args_info->clientkey_given = 0; + args_info->tpmkey_given = 0; args_info->wa_bug_29744_given = 0; args_info->proctitle_given = 0; /* args_info->enforcetls1_given = 0; */ @@ -193,8 +194,8 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar args_info->encryptremproxy_flag = 0; \ args_info->clientcert_arg = NULL; \ args_info->clientkey_arg = NULL; \ + args_info->tpmkey_arg = NULL; \ args_info->wa_bug_29744_flag = 0; \ - /* args_info->no_ssl3_flag = 0; */\ args_info->proctitle_arg = NULL; \ /* args_info->enforcetls1_flag = 0; */\ args_info->host_arg = NULL; \ @@ -245,7 +246,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar { "key", 1, NULL, 'k' }, { "wa-bug-29744", 0, NULL, 'W' }, { "buggy-encrypt-proxy", 0, NULL, 'B' }, - { "no-ssl3", 0, NULL, 'T' }, + { "tpmkey", 1, NULL, 'T' }, { "no-check-certificate",0,NULL,'z' }, { "cacert", 1, NULL, 'C' }, { "ipv4", 0, NULL, '4' }, @@ -296,6 +297,11 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar clear_args (); exit(1); } + if (args_info->tpmkey_given) { + fprintf (stderr, "'--key' ('-k') and '--tpmkey' ('-T') are mutually exclusive\n"); + clear_args(); + exit(1); + } args_info->clientkey_given = 1; args_info->clientkey_arg = gengetopt_strdup (optarg); break; @@ -345,8 +351,10 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar case 'x': args_info->proctitle_given = 1; - message( "Proctitle override enabled\n" ); args_info->proctitle_arg = gengetopt_strdup (optarg); + if( args_info->verbose_flag ) { + message( "Proctitle override enabled: %s\n", args_info->proctitle_arg); + } break; case 'L': @@ -447,11 +455,21 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar message("SSL local to remote proxy enabled\n"); break; - case 'T': /* Turn off SSLv3 */ - /* args_info->no_ssl3_flag = !(args_info->no_ssl3_flag); - if( args_info->verbose_flag ) - message("SSLv3 disabled\n"); */ - message ("Option -T/--no-ssl3 is deprecated and without effect\n"); + case 'T': /* Use TPM provided key */ + if (args_info->tpmkey_given) { + fprintf (stderr, "%s: '--tpmkey' ('-T') option given more than once\n", PACKAGE); + clear_args (); + exit(1); + } + if (args_info->clientkey_given) { + fprintf (stderr, "'--tpmkey' ('-T') and '--key' ('-k') are mutually exclusive\n"); + clear_args(); + exit(1); + } + args_info->tpmkey_given = 1; + args_info->tpmkey_arg = gengetopt_strdup (optarg); + if( args_info->verbose_flag ) + message("Using TPM-backed private key\n"); break; case 'd': /* Destination host to built the tunnel to. */ @@ -603,11 +621,13 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar exit(1); } - if ( args_info->clientcert_given ^ args_info->clientkey_given ) { - clear_args (); - message( "Both of '--cert' ('-c') and '--key' ('-k') must be specified\n" ); - exit(1); - } + /*if ( args_info->clientcert_given ^ args_info->clientkey_given ) { + if (!args_info->tpmkey_given) { + clear_args (); + message( "Both of '--cert' ('-c') and '--key' ('-k') or '--tpmkey' ('-T') must be specified\n" ); + exit(1); + } + }*/ /* Parse -p/--proxy information */ if (args_info->proxy_given ) { diff --git a/cmdline.h b/cmdline.h index 93cf460..6d60a1b 100644 --- a/cmdline.h +++ b/cmdline.h @@ -52,6 +52,7 @@ struct gengetopt_args_info { int encryptremproxy_flag; /* Turn on local to remote proxy SSL encryption (def=off).*/ char *clientcert_arg; /* client SSL certificate */ char *clientkey_arg; /* client SSL key */ + char *tpmkey_arg; /* client TPM 2.0 SSL key */ int wa_bug_29744_flag; /* Use SSL encryption only until CONNECT, if at all (def=off).*/ /* int no_ssl3_flag; Turn off SSLv3 (default=on) */ char *proctitle_arg; /* Override process title (default=off). */ @@ -93,6 +94,7 @@ struct gengetopt_args_info { /* int enforcetls1_given; Wheter to enforce TLSv1 */ int host_given; /* Wheter we override the Host Header */ int cacert_given; /* Whether cacert was given */ + int tpmkey_given; /* Whether tpmkey was given */ }; int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *args_info ); diff --git a/io.c b/io.c index 56d516e..0bb1491 100644 --- a/io.c +++ b/io.c @@ -1,4 +1,4 @@ -/* Proxytunnel - (C) 2001-2008 Jos Visser / Mark Janssen */ + /* Proxytunnel - (C) 2001-2008 Jos Visser / Mark Janssen */ /* Contact: josv@osp.nl / maniac@maniac.nl */ /* @@ -57,7 +57,7 @@ int readline(PTSTREAM *pts) { if( args_info.verbose_flag ) { /* Copy line of data into dstr without trailing newline */ - char *dstr = calloc(1, strlen(buf) + 1); + char *dstr = malloc(strlen(buf) + 1); strncpy( dstr, buf, strlen(buf)); if (strcmp(dstr, "")) message( " <- %s\n", dstr ); @@ -89,10 +89,13 @@ void cpio(PTSTREAM *stream1, PTSTREAM *stream2) { select_timeout.tv_sec = 30; /* should be fine */ select_timeout.tv_usec = 0; - if( args_info.verbose_flag ) + if( args_info.verbose_flag ) { message( "\nTunnel established.\n" ); - - int stream_status = ACTIVE; + } + if( args_info.proctitle_given ) { + message( "%s tunnel active\n", args_info.proctitle_arg ); + } + int stream_status = ACTIVE; while( stream_status == ACTIVE ) { /* Clear the interesting socket sets */ FD_ZERO( &readfds ); diff --git a/proxytunnel.c b/proxytunnel.c index a847223..adff142 100644 --- a/proxytunnel.c +++ b/proxytunnel.c @@ -132,7 +132,7 @@ int tunnel_connect() { message( "Connected to %s (local proxy)\n", args_info.proxy_arg ); } } - + /* Return the socket */ return sd; } diff --git a/ptstream.c b/ptstream.c index d7c6424..f52a465 100644 --- a/ptstream.c +++ b/ptstream.c @@ -20,7 +20,6 @@ /* ptstream.c */ #include -#include #include #include #include @@ -256,9 +255,14 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) { const SSL_METHOD *meth; SSL *ssl; SSL_CTX *ctx; + OSSL_LIB_CTX *tpm2_libctx = NULL; + tpm2_libctx = OSSL_LIB_CTX_new(); + OSSL_PROVIDER *prov = NULL; + EVP_PKEY *TPMpkey = NULL; + OSSL_STORE_INFO *info = NULL; + OSSL_STORE_CTX *storeCtx; long res = 1; long ssl_options = 0; - X509* cert = NULL; int status; struct stat st_buf; @@ -277,6 +281,13 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) { size_t peer_arg_len; char peer_arg_fmt[32]; char *peer_host = NULL; + + if ((prov = OSSL_PROVIDER_load(tpm2_libctx, "default")) == NULL) + { + message("Error loading OpenSSL default provider\n"); + goto fail; + } + message("Loaded OpenSSL default provider\n", prov); /* Initialise the connection */ SSLeay_add_ssl_algorithms(); @@ -311,16 +322,70 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) { } /* If given, load client certificate (chain) and key */ - if ( args_info.clientcert_given && args_info.clientkey_given ) { + if ( args_info.clientcert_given ) { if ( 1 != SSL_CTX_use_certificate_chain_file(ctx, args_info.clientcert_arg) ) { message("Error loading client certificate (chain) from %s\n", args_info.clientcert_arg); goto fail; } - if ( 1 != SSL_CTX_use_PrivateKey_file(ctx, args_info.clientkey_arg, SSL_FILETYPE_PEM) ) { - message("Error loading client key from %s, or key does not match certificate\n", args_info.clientkey_arg); - goto fail; - } - } + + /* -T was used - this is a TSS2 private key */ + if ( args_info.tpmkey_given ) { + if ((prov = OSSL_PROVIDER_load(tpm2_libctx, "tpm2")) == NULL) + { + message("Error loading OpenSSL TPM 2.0 provider (tpm2)\n"); + goto fail; + } + message("Loaded OpenSSL tpm2 provider\n"); + char TPMUri[256] = "file:"; // TSS2 key file uses the file: URI format + char uri[sizeof(args_info.tpmkey_arg)]; + strcpy(uri, args_info.tpmkey_arg); + strncat(TPMUri, uri, 250); + if ( args_info.verbose_flag ) { + message("Using TPM 2.0 provider-backed private key from %s\n", TPMUri); + } + storeCtx = OSSL_STORE_open_ex(TPMUri, tpm2_libctx, "?provider=tpm2", NULL, ctx, NULL, NULL, NULL); + if (storeCtx == NULL) { + message("Error loading client key from TPM via %s\n", TPMUri); + goto fail; + } + while (!OSSL_STORE_eof(storeCtx) && (info = OSSL_STORE_load(storeCtx)) != NULL) { + int type = OSSL_STORE_INFO_get_type(info); + if (type == OSSL_STORE_INFO_PKEY) { + TPMpkey = OSSL_STORE_INFO_get1_PKEY(info); + OSSL_STORE_INFO_free(info); + if (TPMpkey) { + if ( args_info.verbose_flag ) { + message("OpenSSL TPM 2.0 provider initialization successful\n"); + } + break; + } + } + else { + OSSL_STORE_INFO_free(info); + } + } + if (TPMpkey == NULL) { + message("Error loading TPM 2.0 provider-backed private key from %s\n", TPMUri); + goto fail; + } + OSSL_STORE_close(storeCtx); + if ( 1 != SSL_CTX_use_PrivateKey(ctx, TPMpkey) ) { + message("Error loading TPM 2.0 client key from %s, or key does not match certificate\n", TPMUri); + goto fail; + } + } + + /* -k was used - this is a PEM format private key */ + if ( args_info.clientkey_given ) { + if ( 1 != SSL_CTX_use_PrivateKey_file(ctx, args_info.clientkey_arg, SSL_FILETYPE_PEM) ) { + message("Error loading client key from %s, or key does not match certificate\n", args_info.clientkey_arg); + goto fail; + } + if ( args_info.verbose_flag ) { + message("Loaded private key from %s\n", args_info.clientkey_arg); + } + } + } ssl = SSL_new (ctx); if ( ssl == NULL ) { diff --git a/ptstream.h b/ptstream.h index ccfd717..1614b5d 100644 --- a/ptstream.h +++ b/ptstream.h @@ -24,8 +24,11 @@ #include #include #include +#include #include +#include #include +#include #endif typedef struct ptstream {