Call ENGINE_init() before trying to use keys from engine
authorDavid Woodhouse <David.Woodhouse@intel.com>
Wed, 28 Sep 2016 12:08:45 +0000 (13:08 +0100)
committerRich Salz <rsalz@openssl.org>
Wed, 28 Sep 2016 16:15:17 +0000 (12:15 -0400)
When I said before that s_client "used to work in 1.0.2" that was only
partly true. It worked for engines which provided a default generic
method for some key type, because it called ENGINE_set_default() and
that ended up being an implicit initialisation and functional refcount.

But an engine which doesn't provide generic methods doesn't get initialised,
and then when you try to use it you get an error:

cannot load client certificate private key file from engine
140688147056384:error:26096075:engine routines:ENGINE_load_private_key:not initialised:crypto/engine/eng_pkey.c:66:
unable to load client certificate private key file

cf. https://github.com/OpenSC/libp11/issues/107 (in which we discover
that engine_pkcs11 *used* to provide generic methods that OpenSSL would
try to use for ephemeral DH keys when negotiating ECDHE cipher suites in
TLS, and that didn't work out very well.)

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1639)

apps/apps.c

index b2877480a0b7199d46e98ac7978bf662449875e5..9a58f17b671aa4963bd92b9ab00d3b726b906378 100644 (file)
@@ -1269,7 +1269,7 @@ ENGINE *setup_engine(const char *engine, int debug)
             ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
         }
         ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
             ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
         }
         ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
-        if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+        if (!ENGINE_init(e) || !ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
             BIO_printf(bio_err, "can't use that engine\n");
             ERR_print_errors(bio_err);
             ENGINE_free(e);
             BIO_printf(bio_err, "can't use that engine\n");
             ERR_print_errors(bio_err);
             ENGINE_free(e);