#endif
#if HAVE_OPENSSL_ENGINE
+#include <openssl/ui.h>
#include <openssl/engine.h>
static bool engine_initialized = false; /* GLOBAL */
{
return CRYPTO_memcmp(a, b, size);
}
+
+#if HAVE_OPENSSL_ENGINE
+static int
+ui_reader(UI *ui, UI_STRING *uis)
+{
+ SSL_CTX *ctx = UI_get0_user_data(ui);
+
+ if (UI_get_string_type(uis) == UIT_PROMPT) {
+ pem_password_cb *cb = SSL_CTX_get_default_passwd_cb(ctx);
+ void *d = SSL_CTX_get_default_passwd_cb_userdata(ctx);
+ char password[64];
+
+ cb(password, sizeof(password), 0, d);
+ UI_set_result(ui, uis, password);
+
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+EVP_PKEY *
+engine_load_key(const char *file, SSL_CTX *ctx)
+{
+#if HAVE_OPENSSL_ENGINE
+ UI_METHOD *ui;
+ EVP_PKEY *pkey;
+
+ if (!engine_persist)
+ return NULL;
+
+ /* this will print out the error from BIO_read */
+ crypto_msg(M_INFO, "PEM_read_bio failed, now trying engine method to load private key");
+
+ ui = UI_create_method("openvpn");
+ if (!ui) {
+ crypto_msg(M_FATAL, "Engine UI creation failed");
+ return NULL;
+ }
+
+ UI_method_set_reader(ui, ui_reader);
+
+ ENGINE_init(engine_persist);
+ pkey = ENGINE_load_private_key(engine_persist, file, ui, ctx);
+ ENGINE_finish(engine_persist);
+ if (!pkey)
+ crypto_msg(M_FATAL, "Engine could not load key file");
+
+ UI_destroy_method(ui);
+ return pkey;
+#else
+ return NULL;
+#endif
+}
+
#endif /* ENABLE_CRYPTO_OPENSSL */
return EVP_CIPHER_flags(cipher) & EVP_CIPH_VARIABLE_LENGTH;
}
+/**
+ * Load a key file from an engine
+ *
+ * @param file The engine file to load
+ * @param ui The UI method for the password prompt
+ * @param data The data to pass to the UI method
+ *
+ * @return The private key if successful or NULL if not
+ */
+EVP_PKEY *
+engine_load_key(const char *file, SSL_CTX *ctx);
+
#endif /* CRYPTO_OPENSSL_H_ */
pkey = PEM_read_bio_PrivateKey(in, NULL,
SSL_CTX_get_default_passwd_cb(ctx->ctx),
SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx));
+ if (!pkey)
+ {
+ pkey = engine_load_key(priv_key_file, ctx->ctx);
+ }
+
if (!pkey || !SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
{
#ifdef ENABLE_MANAGEMENT