Add a test "uitest"
authorRichard Levitte <levitte@openssl.org>
Tue, 10 Jan 2017 23:13:59 +0000 (00:13 +0100)
committerRichard Levitte <levitte@openssl.org>
Wed, 11 Jan 2017 17:27:27 +0000 (18:27 +0100)
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 <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2204)

test/build.info
test/recipes/03-test_ui.t
test/uitest.c [new file with mode: 0644]

index 62949a51096fe3a2d3c9496f13c74c9ed147e759..eed8aa5fa79bfc9b60c69e82f96c2f4ddd31abcb 100644 (file)
@@ -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
index b1065d1bdbbc4799e9089af2b4ef2db3c5cf7b0b..cf2f5acdd41a3b2935f7356bd20f8b335ebd0508 100644 (file)
@@ -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 (file)
index 0000000..84fe71b
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/ui.h>
+#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;
+}