[openssl-commits] [openssl] master update

Richard Levitte levitte at openssl.org
Wed Jan 11 17:27:37 UTC 2017


The branch master has been updated
       via  66ed24b1624606593a23c9fe78d459718d26409c (commit)
       via  78b19e90b4aade1ffdf8d918277910b01dac1d76 (commit)
       via  cc10f2275594eac2bcdaa218c1d6f672c2b891b7 (commit)
       via  3ab3c8cb274aca1b5c0fbf83af96e49baf422708 (commit)
       via  0fe1fc858a0519c3866c0d2e88513e677b674926 (commit)
       via  18cfc668eae2c296e9bc90ffc989d9bbe61cc82f (commit)
       via  a223ffe6d35209c59ed498ee89d1bac6e82e2ac2 (commit)
       via  264b2d92511572a247ecb673d61ff385deb9eb8d (commit)
      from  5eeb6c6e562937dcfdd4b79619a699a118deadba (commit)


- Log -----------------------------------------------------------------
commit 66ed24b1624606593a23c9fe78d459718d26409c
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jan 11 00:13:59 2017 +0100

    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 <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

commit 78b19e90b4aade1ffdf8d918277910b01dac1d76
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jan 11 00:12:01 2017 +0100

    Add a few documentation lines about UI_OpenSSL()
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

commit cc10f2275594eac2bcdaa218c1d6f672c2b891b7
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jan 10 09:02:40 2017 +0100

    Document the UI utility functions
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

commit 3ab3c8cb274aca1b5c0fbf83af96e49baf422708
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Jan 9 14:26:55 2017 +0100

    make update
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

commit 0fe1fc858a0519c3866c0d2e88513e677b674926
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Dec 6 14:36:43 2016 +0100

    Add a UI utility function with which to wrap pem_callback_cb in a UI_METHOD
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

commit 18cfc668eae2c296e9bc90ffc989d9bbe61cc82f
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Dec 6 14:36:04 2016 +0100

    Add an application data field in the UI_METHOD
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

commit a223ffe6d35209c59ed498ee89d1bac6e82e2ac2
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Dec 6 14:34:52 2016 +0100

    Constify the input parameter to UI_method_get_*
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

commit 264b2d92511572a247ecb673d61ff385deb9eb8d
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Dec 6 04:17:18 2016 +0100

    Enable apps to get a UI_METHOD for the default prompter
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2204)

-----------------------------------------------------------------------

Summary of changes:
 apps/apps.c                          |   5 ++
 apps/apps.h                          |   1 +
 crypto/ui/ui_lib.c                   |  49 ++++++++++-----
 crypto/ui/ui_locl.h                  |   4 ++
 crypto/ui/ui_util.c                  | 111 +++++++++++++++++++++++++++++++++
 doc/man3/CRYPTO_get_ex_new_index.pod |   1 +
 doc/man3/UI_UTIL_read_pw.pod         |  47 ++++++++++++++
 doc/man3/UI_new.pod                  |   3 +
 include/openssl/crypto.h             |   3 +-
 include/openssl/ui.h                 |  19 +++---
 test/build.info                      |   6 +-
 test/recipes/03-test_ui.t            |  21 +------
 test/uitest.c                        | 117 +++++++++++++++++++++++++++++++++++
 util/libcrypto.num                   |   3 +
 14 files changed, 344 insertions(+), 46 deletions(-)
 create mode 100644 doc/man3/UI_UTIL_read_pw.pod
 create mode 100644 test/uitest.c

diff --git a/apps/apps.c b/apps/apps.c
index d911c0f..969b6b8 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -245,6 +245,11 @@ void destroy_ui_method(void)
         ui_method = NULL;
     }
 }
+
+const UI_METHOD *get_ui_method(void)
+{
+    return ui_method;
+}
 #endif
 
 int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
diff --git a/apps/apps.h b/apps/apps.h
index d9f7c08..7cdf711 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -389,6 +389,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data);
 
 int setup_ui_method(void);
 void destroy_ui_method(void);
+const UI_METHOD *get_ui_method(void);
 
 int chopup_args(ARGS *arg, char *buf);
 # ifdef HEADER_X509_H
diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c
index ffe5513..ceda7e9 100644
--- a/crypto/ui/ui_lib.c
+++ b/crypto/ui/ui_lib.c
@@ -561,15 +561,17 @@ const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
 
 UI_METHOD *UI_create_method(const char *name)
 {
-    UI_METHOD *ui_method = OPENSSL_zalloc(sizeof(*ui_method));
-
-    if (ui_method != NULL) {
-        ui_method->name = OPENSSL_strdup(name);
-        if (ui_method->name == NULL) {
-            OPENSSL_free(ui_method);
-            UIerr(UI_F_UI_CREATE_METHOD, ERR_R_MALLOC_FAILURE);
-            return NULL;
-        }
+    UI_METHOD *ui_method = NULL;
+
+    if ((ui_method = OPENSSL_zalloc(sizeof(*ui_method))) == NULL
+        || (ui_method->name = OPENSSL_strdup(name)) == NULL
+        || !CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI_METHOD, ui_method,
+                               &ui_method->ex_data)) {
+        if (ui_method)
+            OPENSSL_free(ui_method->name);
+        OPENSSL_free(ui_method);
+        UIerr(UI_F_UI_CREATE_METHOD, ERR_R_MALLOC_FAILURE);
+        return NULL;
     }
     return ui_method;
 }
@@ -581,6 +583,10 @@ UI_METHOD *UI_create_method(const char *name)
  */
 void UI_destroy_method(UI_METHOD *ui_method)
 {
+    if (ui_method == NULL)
+        return;
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI_METHOD, ui_method,
+                        &ui_method->ex_data);
     OPENSSL_free(ui_method->name);
     ui_method->name = NULL;
     OPENSSL_free(ui_method);
@@ -647,50 +653,59 @@ int UI_method_set_prompt_constructor(UI_METHOD *method,
     return -1;
 }
 
-int (*UI_method_get_opener(UI_METHOD *method)) (UI *)
+int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data)
+{
+    return CRYPTO_set_ex_data(&method->ex_data, idx, data);
+}
+
+int (*UI_method_get_opener(const UI_METHOD *method)) (UI *)
 {
     if (method != NULL)
         return method->ui_open_session;
     return NULL;
 }
 
-int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *)
+int (*UI_method_get_writer(const UI_METHOD *method)) (UI *, UI_STRING *)
 {
     if (method != NULL)
         return method->ui_write_string;
     return NULL;
 }
 
-int (*UI_method_get_flusher(UI_METHOD *method)) (UI *)
+int (*UI_method_get_flusher(const UI_METHOD *method)) (UI *)
 {
     if (method != NULL)
         return method->ui_flush;
     return NULL;
 }
 
-int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *)
+int (*UI_method_get_reader(const UI_METHOD *method)) (UI *, UI_STRING *)
 {
     if (method != NULL)
         return method->ui_read_string;
     return NULL;
 }
 
-int (*UI_method_get_closer(UI_METHOD *method)) (UI *)
+int (*UI_method_get_closer(const UI_METHOD *method)) (UI *)
 {
     if (method != NULL)
         return method->ui_close_session;
     return NULL;
 }
 
-char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
-                                                              const char *,
-                                                              const char *)
+char *(*UI_method_get_prompt_constructor(const UI_METHOD *method))
+    (UI *, const char *, const char *)
 {
     if (method != NULL)
         return method->ui_construct_prompt;
     return NULL;
 }
 
+const void *UI_method_get_ex_data(const UI_METHOD *method, int idx)
+{
+    return CRYPTO_get_ex_data(&method->ex_data, idx);
+}
+
 enum UI_string_types UI_get_string_type(UI_STRING *uis)
 {
     return uis->type;
diff --git a/crypto/ui/ui_locl.h b/crypto/ui/ui_locl.h
index 2953739..94a9e35 100644
--- a/crypto/ui/ui_locl.h
+++ b/crypto/ui/ui_locl.h
@@ -46,6 +46,10 @@ struct ui_method_st {
      */
     char *(*ui_construct_prompt) (UI *ui, const char *object_desc,
                                   const char *object_name);
+    /*
+     * UI_METHOD specific application data.
+     */
+    CRYPTO_EX_DATA ex_data;
 };
 
 struct ui_string_st {
diff --git a/crypto/ui/ui_util.c b/crypto/ui/ui_util.c
index 3b51db9..70202a6 100644
--- a/crypto/ui/ui_util.c
+++ b/crypto/ui/ui_util.c
@@ -49,3 +49,114 @@ int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
         ok = 0;
     return (ok);
 }
+
+/*
+ * Wrapper around pem_password_cb, a method to help older APIs use newer
+ * ones.
+ */
+struct pem_password_cb_data {
+    pem_password_cb *cb;
+    int rwflag;
+};
+
+static void ui_new_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                               int idx, long argl, void *argp)
+{
+    /*
+     * Do nothing, the data is allocated externally and assigned later with
+     * CRYPTO_set_ex_data()
+     */
+}
+
+static int ui_dup_method_data(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+                              void *from_d, int idx, long argl, void *argp)
+{
+    void **pptr = (void **)from_d;
+    if (*pptr != NULL)
+        *pptr = OPENSSL_memdup(*pptr, sizeof(struct pem_password_cb_data));
+    return 1;
+}
+
+static void ui_free_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                                int idx, long argl, void *argp)
+{
+    OPENSSL_free(ptr);
+}
+
+static int ui_method_data_index()
+{
+    static int idx = -1;
+
+    if (idx == -1)
+        idx = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI_METHOD,
+                                      0, NULL,
+                                      ui_new_method_data,
+                                      ui_dup_method_data,
+                                      ui_free_method_data);
+
+    return idx;
+}
+
+static int ui_open(UI *ui)
+{
+    return 1;
+}
+static int ui_read(UI *ui, UI_STRING *uis)
+{
+    switch (UI_get_string_type(uis)) {
+    case UIT_PROMPT:
+        {
+            char result[PEM_BUFSIZE];
+            const struct pem_password_cb_data *data =
+                UI_method_get_ex_data(UI_get_method(ui),
+                                      ui_method_data_index());
+            int maxsize = UI_get_result_maxsize(uis);
+            int len = data->cb(result,
+                               maxsize > PEM_BUFSIZE ? PEM_BUFSIZE : maxsize,
+                               data->rwflag, UI_get0_user_data(ui));
+
+            if (len <= 0)
+                return len;
+            if (UI_set_result(ui, uis, result) >= 0)
+                return 1;
+            return 0;
+        }
+    case UIT_VERIFY:
+    case UIT_NONE:
+    case UIT_BOOLEAN:
+    case UIT_INFO:
+    case UIT_ERROR:
+        break;
+    }
+    return 1;
+}
+static int ui_write(UI *ui, UI_STRING *uis)
+{
+    return 1;
+}
+static int ui_close(UI *ui)
+{
+    return 1;
+}
+
+UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag)
+{
+    struct pem_password_cb_data *data = NULL;
+    UI_METHOD *ui_method = NULL;
+
+    if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL
+        || (ui_method = UI_create_method("PEM password callback wrapper")) == NULL
+        || UI_method_set_opener(ui_method, ui_open) < 0
+        || UI_method_set_reader(ui_method, ui_read) < 0
+        || UI_method_set_writer(ui_method, ui_write) < 0
+        || UI_method_set_closer(ui_method, ui_close) < 0
+        || UI_method_set_ex_data(ui_method, ui_method_data_index(), data) < 0) {
+        UI_destroy_method(ui_method);
+        OPENSSL_free(data);
+        return NULL;
+    }
+    data->rwflag = rwflag;
+    data->cb = cb;
+
+    return ui_method;
+}
diff --git a/doc/man3/CRYPTO_get_ex_new_index.pod b/doc/man3/CRYPTO_get_ex_new_index.pod
index 98085f5..ed32bb2 100644
--- a/doc/man3/CRYPTO_get_ex_new_index.pod
+++ b/doc/man3/CRYPTO_get_ex_new_index.pod
@@ -52,6 +52,7 @@ The specific structures are:
     RSA
     ENGINE
     UI
+    UI_METHOD
     BIO
 
 Each is identified by an B<CRYPTO_EX_INDEX_xxx> define in the B<crypto.h>
diff --git a/doc/man3/UI_UTIL_read_pw.pod b/doc/man3/UI_UTIL_read_pw.pod
new file mode 100644
index 0000000..f0b4a69
--- /dev/null
+++ b/doc/man3/UI_UTIL_read_pw.pod
@@ -0,0 +1,47 @@
+=pod
+
+=head1 NAME
+
+UI_UTIL_read_pw_string, UI_UTIL_read_pw,
+*UI_UTIL_wrap_read_pem_callback - user interface utilities
+
+=head1 SYNOPSIS
+
+ #include <openssl/ui.h>
+
+ int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
+                            int verify);
+ int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
+                     int verify);
+ UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int
+ rwflag);
+
+=head1 DESCRIPTION
+
+UI_UTIL_read_pw_string() asks for a passphrase, using B<prompt> as a
+prompt, and stores it in B<buf>.
+The maximum allowed size is given with B<length>, including the
+terminating NUL byte.
+If B<verify> is non-zero, the password will be verified as well.
+
+UI_UTIL_read_pw() does the same as UI_UTIL_read_pw_string(), the
+difference is that you can give it an external buffer B<buff> for the
+verification passphrase.
+
+UI_UTIL_wrap_read_pem_callback() can be used to create a temporary
+B<UI_METHOD> that wraps a given PEM password callback B<cb>.
+B<rwflag> is used to specify if this method will be used for
+passphrase entry without (0) or with (1) verification.
+When not used any more, the returned method should be freed with
+UI_destroy_method().
+
+=head1 COPYRIGHT
+
+Copyright 2001-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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/UI_new.pod b/doc/man3/UI_new.pod
index 9abb697..dedf4dc 100644
--- a/doc/man3/UI_new.pod
+++ b/doc/man3/UI_new.pod
@@ -174,6 +174,9 @@ UI_get_method() returns the UI method associated with a given UI.
 
 UI_set_method() changes the UI method associated with a given UI.
 
+UI_OpenSSL() is the default OpenSSL UI method for prompting
+passphrases on the command line.
+
 =head1 COPYRIGHT
 
 Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h
index bd0b140..8ee3e8a 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/crypto.h
@@ -110,7 +110,8 @@ DEFINE_STACK_OF(void)
 # define CRYPTO_EX_INDEX_UI              11
 # define CRYPTO_EX_INDEX_BIO             12
 # define CRYPTO_EX_INDEX_APP             13
-# define CRYPTO_EX_INDEX__COUNT          14
+# define CRYPTO_EX_INDEX_UI_METHOD       14
+# define CRYPTO_EX_INDEX__COUNT          15
 
 /*
  * This is the default callbacks, but we can have others as well: this is
diff --git a/include/openssl/ui.h b/include/openssl/ui.h
index 49e763d..c5718d2 100644
--- a/include/openssl/ui.h
+++ b/include/openssl/ui.h
@@ -18,6 +18,7 @@
 #   include <openssl/crypto.h>
 #  endif
 #  include <openssl/safestack.h>
+#  include <openssl/pem.h>
 #  include <openssl/ossl_typ.h>
 
 #ifdef  __cplusplus
@@ -284,14 +285,15 @@ int UI_method_set_prompt_constructor(UI_METHOD *method,
                                                                   *object_desc,
                                                                   const char
                                                                   *object_name));
-int (*UI_method_get_opener(UI_METHOD *method)) (UI *);
-int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *);
-int (*UI_method_get_flusher(UI_METHOD *method)) (UI *);
-int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *);
-int (*UI_method_get_closer(UI_METHOD *method)) (UI *);
-char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
-                                                              const char *,
-                                                              const char *);
+int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data);
+int (*UI_method_get_opener(const UI_METHOD *method)) (UI *);
+int (*UI_method_get_writer(const UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_flusher(const UI_METHOD *method)) (UI *);
+int (*UI_method_get_reader(const UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_closer(const UI_METHOD *method)) (UI *);
+char *(*UI_method_get_prompt_constructor(const UI_METHOD *method))
+    (UI *, const char *, const char *);
+const void *UI_method_get_ex_data(const UI_METHOD *method, int idx);
 
 /*
  * The following functions are helpers for method writers to access relevant
@@ -327,6 +329,7 @@ int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
                            int verify);
 int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
                     int verify);
+    UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag);
 
 /* BEGIN ERROR CODES */
 /*
diff --git a/test/build.info b/test/build.info
index 62949a5..eed8aa5 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 b1065d1..cf2f5ac 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 0000000..84fe71b
--- /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 <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;
+}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index ffd03b5..1c81545 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4224,3 +4224,6 @@ X509_VERIFY_PARAM_set_inh_flags         4174	1_1_0d	EXIST::FUNCTION:
 X509_VERIFY_PARAM_get_inh_flags         4175	1_1_0d	EXIST::FUNCTION:
 EVP_PKEY_CTX_md                         4176	1_1_1	EXIST::FUNCTION:
 RSA_pkey_ctx_ctrl                       4177	1_1_1	EXIST::FUNCTION:RSA
+UI_method_set_ex_data                   4178	1_1_1	EXIST::FUNCTION:UI
+UI_method_get_ex_data                   4179	1_1_1	EXIST::FUNCTION:UI
+UI_UTIL_wrap_read_pem_callback          4180	1_1_1	EXIST::FUNCTION:UI


More information about the openssl-commits mailing list