From c35b388e8494489b3af07bc53c87c6a329b90abc Mon Sep 17 00:00:00 2001 From: Susan Hinrichs Date: Thu, 11 Mar 2021 17:35:25 +0000 Subject: [PATCH 1/3] Use return values to fix ubuntu release build error --- tests/tools/plugins/async_engine.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/tools/plugins/async_engine.c b/tests/tools/plugins/async_engine.c index 76149be1ffd..db09f560104 100644 --- a/tests/tools/plugins/async_engine.c +++ b/tests/tools/plugins/async_engine.c @@ -227,8 +227,11 @@ delay_method(void *arg) int signal_fd = (intptr_t)arg; sleep(2); char buf = DUMMY_CHAR; - write(signal_fd, &buf, sizeof(buf)); - fprintf(stderr, "Send signal to %d\n", signal_fd); + if (write(signal_fd, &buf, sizeof(buf)) < 0) { + fprintf(stderr, "Failed to send signal to %d, errno=%d\n", signal_fd, errno); + } else { + fprintf(stderr, "Send signal to %d\n", signal_fd); + } return NULL; } @@ -251,7 +254,9 @@ spawn_delay_thread() OSSL_ASYNC_FD signal_fd; OSSL_ASYNC_FD pipefds[2] = {0, 0}; OSSL_ASYNC_FD *writefd = OPENSSL_malloc(sizeof(*writefd)); - pipe(pipefds); + if (pipe(pipefds) < 0) { + fprintf(stderr, "Spawn, failed to create pipe errno=%d\n", errno); + } signal_fd = *writefd = pipefds[1]; ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_id, pipefds[0], writefd, wait_cleanup); fprintf(stderr, "Spawn, create wait_ctx %d %d\n", pipefds[0], pipefds[1]); From 3b04b3f4a1f4bc9119d7b5d1e32a5e1e02109fd6 Mon Sep 17 00:00:00 2001 From: Susan Hinrichs Date: Thu, 11 Mar 2021 17:37:52 +0000 Subject: [PATCH 2/3] Actually return in the error case --- tests/tools/plugins/async_engine.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tools/plugins/async_engine.c b/tests/tools/plugins/async_engine.c index db09f560104..eac65cd1d27 100644 --- a/tests/tools/plugins/async_engine.c +++ b/tests/tools/plugins/async_engine.c @@ -256,6 +256,7 @@ spawn_delay_thread() OSSL_ASYNC_FD *writefd = OPENSSL_malloc(sizeof(*writefd)); if (pipe(pipefds) < 0) { fprintf(stderr, "Spawn, failed to create pipe errno=%d\n", errno); + return; } signal_fd = *writefd = pipefds[1]; ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_id, pipefds[0], writefd, wait_cleanup); From 05f535e4c3919d1c611526b9c8764df0afcfb52a Mon Sep 17 00:00:00 2001 From: Susan Hinrichs Date: Fri, 12 Mar 2021 17:31:09 +0000 Subject: [PATCH 3/3] Fix the async_engine to actually pause even if the sync event is already there --- contrib/openssl/async_engine.c | 328 ++++++++++++------------ tests/gold_tests/tls/tls_engine.test.py | 2 +- tests/tools/plugins/async_engine.c | 8 +- 3 files changed, 172 insertions(+), 166 deletions(-) diff --git a/contrib/openssl/async_engine.c b/contrib/openssl/async_engine.c index 7c3604d606a..b596b418050 100644 --- a/contrib/openssl/async_engine.c +++ b/contrib/openssl/async_engine.c @@ -27,6 +27,11 @@ * operations spawns a thread to sleep for 5 seconds before resuming * the asynchronous job */ + +/* TLS_USE_TLS_ASYNC defined in ink_config.h */ +#include "tscore/ink_config.h" +#if TS_USE_TLS_ASYNC + #include #include @@ -39,189 +44,182 @@ #include #include - /* Engine Id and Name */ -static const char *engine_id = "async-test"; +static const char *engine_id = "async-test"; static const char *engine_name = "Asynchronous test engine"; - /* Engine Lifetime functions */ static int async_destroy(ENGINE *e); static int engine_async_init(ENGINE *e); static int async_finish(ENGINE *e); void engine_load_async_int(void); - static void async_pause_job(void); /* RSA */ -static int async_pub_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int async_pub_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int async_rsa_priv_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int async_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int async_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); +static int async_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +static int async_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +static int async_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +static int async_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); +static int async_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); static int async_rsa_init(RSA *rsa); static int async_rsa_finish(RSA *rsa); static RSA_METHOD *async_rsa_method = NULL; -EVP_PKEY *async_load_privkey(ENGINE *e, const char *s_key_id, UI_METHOD *ui_method, void *callback_data) +EVP_PKEY * +async_load_privkey(ENGINE *e, const char *s_key_id, UI_METHOD *ui_method, void *callback_data) { - printf("Loading key %s\n", s_key_id); - FILE *f = fopen(s_key_id, "r"); + fprintf(stderr, "Loading key %s\n", s_key_id); + FILE *f = fopen(s_key_id, "r"); EVP_PKEY *key = PEM_read_PrivateKey(f, NULL, NULL, NULL); fclose(f); return key; } -static int bind_async(ENGINE *e) +static int +bind_async(ENGINE *e) { - /* Setup RSA_METHOD */ - if ((async_rsa_method = RSA_meth_new("Async RSA method", 0)) == NULL - || RSA_meth_set_pub_enc(async_rsa_method, async_pub_enc) == 0 - || RSA_meth_set_pub_dec(async_rsa_method, async_pub_dec) == 0 - || RSA_meth_set_priv_enc(async_rsa_method, async_rsa_priv_enc) == 0 - || RSA_meth_set_priv_dec(async_rsa_method, async_rsa_priv_dec) == 0 - || RSA_meth_set_mod_exp(async_rsa_method, async_rsa_mod_exp) == 0 - || RSA_meth_set_bn_mod_exp(async_rsa_method, BN_mod_exp_mont) == 0 - || RSA_meth_set_init(async_rsa_method, async_rsa_init) == 0 - || RSA_meth_set_finish(async_rsa_method, async_rsa_finish) == 0) { - fprintf(stderr, "Failed to initialize rsa method\n"); - return 0; - } + /* Setup RSA_METHOD */ + if ((async_rsa_method = RSA_meth_new("Async RSA method", 0)) == NULL || + RSA_meth_set_pub_enc(async_rsa_method, async_pub_enc) == 0 || RSA_meth_set_pub_dec(async_rsa_method, async_pub_dec) == 0 || + RSA_meth_set_priv_enc(async_rsa_method, async_rsa_priv_enc) == 0 || + RSA_meth_set_priv_dec(async_rsa_method, async_rsa_priv_dec) == 0 || + RSA_meth_set_mod_exp(async_rsa_method, async_rsa_mod_exp) == 0 || + RSA_meth_set_bn_mod_exp(async_rsa_method, BN_mod_exp_mont) == 0 || RSA_meth_set_init(async_rsa_method, async_rsa_init) == 0 || + RSA_meth_set_finish(async_rsa_method, async_rsa_finish) == 0) { + fprintf(stderr, "Failed to initialize rsa method\n"); + return 0; + } - /* Ensure the dasync error handling is set up */ - ERR_load_ASYNC_strings(); - - if (!ENGINE_set_id(e, engine_id) - || !ENGINE_set_name(e, engine_name) - || !ENGINE_set_RSA(e, async_rsa_method) - || !ENGINE_set_destroy_function(e, async_destroy) - || !ENGINE_set_init_function(e, engine_async_init) - || !ENGINE_set_finish_function(e, async_finish) - || !ENGINE_set_load_privkey_function(e, async_load_privkey)) { - fprintf(stderr, "Failed to initialize\n"); - return 0; - } + /* Ensure the dasync error handling is set up */ + ERR_load_ASYNC_strings(); + + if (!ENGINE_set_id(e, engine_id) || !ENGINE_set_name(e, engine_name) || !ENGINE_set_RSA(e, async_rsa_method) || + !ENGINE_set_destroy_function(e, async_destroy) || !ENGINE_set_init_function(e, engine_async_init) || + !ENGINE_set_finish_function(e, async_finish) || !ENGINE_set_load_privkey_function(e, async_load_privkey)) { + fprintf(stderr, "Failed to initialize\n"); + return 0; + } - return 1; + return 1; } -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_helper(ENGINE *e, const char *id) +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int +bind_helper(ENGINE *e, const char *id) { - if (id && (strcmp(id, engine_id) != 0)) - return 0; - if (!bind_async(e)) - return 0; - return 1; + if (id && (strcmp(id, engine_id) != 0)) + return 0; + if (!bind_async(e)) + return 0; + return 1; } IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) -# endif +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) +#endif -static ENGINE *engine_async(void) +static ENGINE * +engine_async(void) { - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_async(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_async(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; } -void engine_load_async_int(void) +void +engine_load_async_int(void) { - ENGINE *toadd = engine_async(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); + ENGINE *toadd = engine_async(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); } -static int engine_async_init(ENGINE *e) +static int +engine_async_init(ENGINE *e) { - return 1; + return 1; } - -static int async_finish(ENGINE *e) +static int +async_finish(ENGINE *e) { - return 1; + return 1; } - -static int async_destroy(ENGINE *e) +static int +async_destroy(ENGINE *e) { - RSA_meth_free(async_rsa_method); - return 1; + RSA_meth_free(async_rsa_method); + return 1; } -static void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, - OSSL_ASYNC_FD readfd, void *pvwritefd) +static void +wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, OSSL_ASYNC_FD readfd, void *pvwritefd) { - OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd; - close(readfd); - close(*pwritefd); - OPENSSL_free(pwritefd); + OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd; + close(readfd); + close(*((OSSL_ASYNC_FD *)pwritefd)); + OPENSSL_free(pwritefd); + fprintf(stderr, "Cleanup %d and %d\n", readfd, *pwritefd); } #define DUMMY_CHAR 'X' -static void async_pause_job(void) { - ASYNC_JOB *job; - ASYNC_WAIT_CTX *waitctx; - OSSL_ASYNC_FD pipefds[2] = {0, 0}; - OSSL_ASYNC_FD *writefd; - char buf = DUMMY_CHAR; +static void +async_pause_job(void) +{ + ASYNC_JOB *job; + ASYNC_WAIT_CTX *waitctx; + OSSL_ASYNC_FD pipefds[2] = {0, 0}; + OSSL_ASYNC_FD *writefd; + char buf = DUMMY_CHAR; + + if ((job = ASYNC_get_current_job()) == NULL) { + fprintf(stderr, "No job\n"); + return; + } + + waitctx = ASYNC_get_wait_ctx(job); - if ((job = ASYNC_get_current_job()) == NULL) { - printf("No job\n"); - return; + if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_id, &pipefds[0], (void **)&writefd)) { + fprintf(stderr, "Existing wait ctx %d\n", *writefd); + } else { + writefd = (OSSL_ASYNC_FD *)OPENSSL_malloc(sizeof(*writefd)); + if (writefd == NULL) + return; + if (pipe(pipefds) != 0) { + OPENSSL_free(writefd); + return; } + *writefd = pipefds[1]; + + fprintf(stderr, "New wait ctx %d %d\n", pipefds[0], pipefds[1]); - waitctx = ASYNC_get_wait_ctx(job); - - if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_id, &pipefds[0], - (void **)&writefd)) { - printf("Existing wait ctx\n"); - return; - } else { - writefd = (OSSL_ASYNC_FD *)OPENSSL_malloc(sizeof(*writefd)); - if (writefd == NULL) - return; - if (pipe(pipefds) != 0) { - OPENSSL_free(writefd); - return; - } - *writefd = pipefds[1]; - - printf("New wait ctx %d %d\n", pipefds[0], pipefds[1]); - - if(!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_id, pipefds[0], - writefd, wait_cleanup)) { - wait_cleanup(waitctx, engine_id, pipefds[0], writefd); - return; - } + if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_id, pipefds[0], writefd, wait_cleanup)) { + fprintf(stderr, "set_wait_fd failed\n"); + wait_cleanup(waitctx, engine_id, pipefds[0], writefd); + return; } + } - /* Ignore errors - we carry on anyway */ - ASYNC_pause_job(); + /* Ignore errors - we carry on anyway */ + ASYNC_pause_job(); - /* Clear the wake signal */ - if (read(pipefds[0], &buf, 1) < 0) - return; + /* Clear the wake signal */ + if (read(pipefds[0], &buf, 1) < 0) + return; } void * @@ -230,87 +228,93 @@ delay_method(void *arg) int signal_fd = (intptr_t)arg; sleep(2); char buf = DUMMY_CHAR; - write(signal_fd, &buf, sizeof(buf)); - printf("Send signal to %d\n", signal_fd); + if (write(signal_fd, &buf, sizeof(buf)) < 0) { + fprintf(stderr, "Failed to send signal to %d, errno=%d\n", signal_fd, errno); + } else { + fprintf(stderr, "Send signal to %d\n", signal_fd); + } return NULL; } - void spawn_delay_thread() { pthread_t thread_id; ASYNC_JOB *job; if ((job = ASYNC_get_current_job()) == NULL) { - printf("Spawn no job\n"); - return; + fprintf(stderr, "Spawn no job\n"); + return; } ASYNC_WAIT_CTX *waitctx = ASYNC_get_wait_ctx(job); size_t numfds; if (ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds) && numfds > 0) { - printf("Spawn, wait_ctx exists. Go away, something else is using this job\n"); + fprintf(stderr, "Spawn, wait_ctx exists. Go away, something else is using this job\n"); } else { OSSL_ASYNC_FD signal_fd; - OSSL_ASYNC_FD pipefds[2] = {0,0}; - OSSL_ASYNC_FD *writefd = OPENSSL_malloc(sizeof(*writefd)); - pipe(pipefds); + OSSL_ASYNC_FD pipefds[2] = {0, 0}; + OSSL_ASYNC_FD *writefd = OPENSSL_malloc(sizeof(*writefd)); + if (pipe(pipefds) < 0) { + fprintf(stderr, "Spawn, failed to create pipe errno=%d\n", errno); + return; + } signal_fd = *writefd = pipefds[1]; ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_id, pipefds[0], writefd, wait_cleanup); - printf("Spawn, create wait_ctx %d %d\n", pipefds[0], pipefds[1]); + fprintf(stderr, "Spawn, create wait_ctx %d %d\n", pipefds[0], pipefds[1]); pthread_create(&thread_id, NULL, delay_method, (void *)((intptr_t)signal_fd)); } } - /* * RSA implementation */ -static int async_pub_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) { - return RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL()) - (flen, from, to, rsa, padding); +static int +async_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); } -static int async_pub_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) { - return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL()) - (flen, from, to, rsa, padding); +static int +async_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) +{ + return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); } -static int async_rsa_priv_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) +static int +async_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - printf("async_priv_enc\n"); - spawn_delay_thread(); - async_pause_job(); - return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL()) - (flen, from, to, rsa, padding); + fprintf(stderr, "async_priv_enc\n"); + spawn_delay_thread(); + async_pause_job(); + fprintf(stderr, "async_priv_enc resume\n"); + return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); } -static int async_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) +static int +async_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - printf("async_priv_dec\n"); - spawn_delay_thread(); - async_pause_job(); - return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL()) - (flen, from, to, rsa, padding); + fprintf(stderr, "async_priv_dec\n"); + spawn_delay_thread(); + async_pause_job(); + return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); } -static int async_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +static int +async_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { - return RSA_meth_get_mod_exp(RSA_PKCS1_OpenSSL())(r0, I, rsa, ctx); + return RSA_meth_get_mod_exp(RSA_PKCS1_OpenSSL())(r0, I, rsa, ctx); } -static int async_rsa_init(RSA *rsa) +static int +async_rsa_init(RSA *rsa) { - return RSA_meth_get_init(RSA_PKCS1_OpenSSL())(rsa); + return RSA_meth_get_init(RSA_PKCS1_OpenSSL())(rsa); } -static int async_rsa_finish(RSA *rsa) +static int +async_rsa_finish(RSA *rsa) { - return RSA_meth_get_finish(RSA_PKCS1_OpenSSL())(rsa); + return RSA_meth_get_finish(RSA_PKCS1_OpenSSL())(rsa); } - +#endif /* TS_USE_TLS_ASYNC */ diff --git a/tests/gold_tests/tls/tls_engine.test.py b/tests/gold_tests/tls/tls_engine.test.py index a1966f174ba..cb2f16825b7 100644 --- a/tests/gold_tests/tls/tls_engine.test.py +++ b/tests/gold_tests/tls/tls_engine.test.py @@ -64,7 +64,7 @@ 'proxy.config.ssl.engine.conf_file': '{0}/ts/config/load_engine.cnf'.format(Test.RunDirectory), 'proxy.config.ssl.async.handshake.enabled': 1, 'proxy.config.diags.debug.enabled': 0, - 'proxy.config.diags.debug.tags': 'ssl' + 'proxy.config.diags.debug.tags': 'ssl|http' }) ts.Disk.MakeConfigFile('load_engine.cnf').AddLines([ diff --git a/tests/tools/plugins/async_engine.c b/tests/tools/plugins/async_engine.c index eac65cd1d27..b596b418050 100644 --- a/tests/tools/plugins/async_engine.c +++ b/tests/tools/plugins/async_engine.c @@ -170,8 +170,9 @@ wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, OSSL_ASYNC_FD readfd, void *p { OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd; close(readfd); - close(*pwritefd); + close(*((OSSL_ASYNC_FD *)pwritefd)); OPENSSL_free(pwritefd); + fprintf(stderr, "Cleanup %d and %d\n", readfd, *pwritefd); } #define DUMMY_CHAR 'X' @@ -193,8 +194,7 @@ async_pause_job(void) waitctx = ASYNC_get_wait_ctx(job); if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_id, &pipefds[0], (void **)&writefd)) { - fprintf(stderr, "Existing wait ctx\n"); - return; + fprintf(stderr, "Existing wait ctx %d\n", *writefd); } else { writefd = (OSSL_ASYNC_FD *)OPENSSL_malloc(sizeof(*writefd)); if (writefd == NULL) @@ -208,6 +208,7 @@ async_pause_job(void) fprintf(stderr, "New wait ctx %d %d\n", pipefds[0], pipefds[1]); if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_id, pipefds[0], writefd, wait_cleanup)) { + fprintf(stderr, "set_wait_fd failed\n"); wait_cleanup(waitctx, engine_id, pipefds[0], writefd); return; } @@ -287,6 +288,7 @@ async_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA * fprintf(stderr, "async_priv_enc\n"); spawn_delay_thread(); async_pause_job(); + fprintf(stderr, "async_priv_enc resume\n"); return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); }