From 66ed24b1624606593a23c9fe78d459718d26409c Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 11 Jan 2017 00:13:59 +0100 Subject: [PATCH] Add a test "uitest" It tests both the use of UI_METHOD (through the apps/apps.h API) and wrapping an older style PEM password callback in a UI_METHOD. Replace the earlier UI test with a run of this test program Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2204) --- test/build.info | 6 +- test/recipes/03-test_ui.t | 21 +------ test/uitest.c | 117 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 20 deletions(-) create mode 100644 test/uitest.c diff --git a/test/build.info b/test/build.info index 62949a5109..eed8aa5fa7 100644 --- a/test/build.info +++ b/test/build.info @@ -25,7 +25,7 @@ IF[{- !$disabled{tests} -}] dtlsv1listentest ct_test threadstest afalgtest d2i_test \ ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \ - pkey_meth_test + pkey_meth_test uitest SOURCE[aborttest]=aborttest.c INCLUDE[aborttest]=../include @@ -316,6 +316,10 @@ IF[{- !$disabled{tests} -}] DEPEND[cipher_overhead_test]=../libcrypto ../libssl ENDIF + SOURCE[uitest]=uitest.c testutil.c test_main_custom.c ../apps/apps.c ../apps/opt.c + INCLUDE[uitest]=.. ../include + DEPEND[uitest]=../libcrypto ../libssl + # Internal test programs. These are essentially a collection of internal # test routines. Some of them need to reach internal symbols that aren't # available through the shared library (at least on Linux, Solaris, Windows diff --git a/test/recipes/03-test_ui.t b/test/recipes/03-test_ui.t index b1065d1bdb..cf2f5acdd4 100644 --- a/test/recipes/03-test_ui.t +++ b/test/recipes/03-test_ui.t @@ -8,23 +8,6 @@ use strict; use warnings; -use OpenSSL::Test; +use OpenSSL::Test::Simple; -setup("test_ui"); - -plan tests => 1; - -note <<"EOF"; -The best way to test the UI interface is currently by using an openssl -command that uses password_callback. The only one that does this is -'genrsa'. -Since password_callback uses a UI method derived from UI_OpenSSL(), it -ensures that one gets tested well enough as well. -EOF - -my $outfile = "rsa_$$.pem"; -ok(run(app(["openssl", "genrsa", "-passout", "pass:password", "-aes128", - "-out", $outfile])), - "Checking that genrsa with a password works properly"); - -unlink $outfile; +simple_test("test_ui", "uitest", "ui"); diff --git a/test/uitest.c b/test/uitest.c new file mode 100644 index 0000000000..84fe71b22d --- /dev/null +++ b/test/uitest.c @@ -0,0 +1,117 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "../apps/apps.h" + +#include "testutil.h" +#include "test_main_custom.h" + +/* apps/apps.c depend on these */ +char *default_config_file = NULL; +BIO *bio_err = NULL; + +/* Old style PEM password callback */ +static int test_pem_password_cb(char *buf, int size, int rwflag, void *userdata) +{ + OPENSSL_strlcpy(buf, (char *)userdata, (size_t)size); + return 1; +} + +/* + * Test wrapping old style PEM password callback in a UI method through the + * use of UI utility functions + */ +static int test_old() +{ + UI_METHOD *ui_method = NULL; + UI *ui = NULL; + char defpass[] = "password"; + char pass[16]; + int ok = 0; + + if ((ui_method = + UI_UTIL_wrap_read_pem_callback(test_pem_password_cb, 0)) == NULL + || (ui = UI_new_method(ui_method)) == NULL) + goto err; + + /* The wrapper passes the UI userdata as the callback userdata param */ + UI_add_user_data(ui, defpass); + + if (!UI_add_input_string(ui, "prompt", UI_INPUT_FLAG_DEFAULT_PWD, + pass, 0, sizeof(pass) - 1)) + goto err; + + switch (UI_process(ui)) { + case -2: + BIO_printf(bio_err, "test_old: UI process interrupted or cancelled\n"); + /* fall through */ + case -1: + goto err; + default: + break; + } + + if (strcmp(pass, defpass) == 0) + ok = 1; + else + BIO_printf(bio_err, "test_old: password failure\n"); + + err: + if (!ok) + ERR_print_errors_fp(stderr); + UI_free(ui); + UI_destroy_method(ui_method); + + return ok; +} + +/* Test of UI. This uses the UI method defined in apps/apps.c */ +static int test_new_ui() +{ + PW_CB_DATA cb_data = { + "password", + "prompt" + }; + char pass[16]; + int ok = 0; + + setup_ui_method(); + if (password_callback(pass, sizeof(pass), 0, &cb_data) > 0 + && strcmp(pass, cb_data.password) == 0) + ok = 1; + else + BIO_printf(bio_err, "test_new: password failure\n"); + + if (!ok) + ERR_print_errors_fp(stderr); + + destroy_ui_method(); + return ok; +} + +int test_main(int argc, char *argv[]) +{ + int ret; + + bio_err = dup_bio_err(FORMAT_TEXT); + + ADD_TEST(test_old); + ADD_TEST(test_new_ui); + + ret = run_tests(argv[0]); + + (void)BIO_flush(bio_err); + BIO_free(bio_err); + + return ret; +} -- 2.34.1