eng_dyn: Avoid spurious errors when checking for 1.1.x engine
authorTomas Mraz <tomas@openssl.org>
Wed, 16 Mar 2022 11:14:16 +0000 (12:14 +0100)
committerTomas Mraz <tomas@openssl.org>
Fri, 18 Mar 2022 11:21:58 +0000 (12:21 +0100)
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17901)

(cherry picked from commit bd5c91c82cdc4b6ffe4a2970f9512fc5ec7d2d06)

crypto/engine/eng_dyn.c

index 3c0f960fc525a8861efedf170068b74b9364e383..6d402927c546477dbe848e2ba25c0c4c0656e675 100644 (file)
@@ -401,6 +401,26 @@ static int int_load(dynamic_data_ctx *ctx)
     return 0;
 }
 
+/*
+ * Unfortunately the version checker does not distinguish between
+ * engines built for openssl 1.1.x and openssl 3.x, but loading
+ * an engine that is built for openssl 1.1.x will cause a fatal
+ * error.  Detect such engines, since EVP_PKEY_base_id is exported
+ * as a function in openssl 1.1.x, while it is named EVP_PKEY_get_base_id
+ * in openssl 3.x.  Therefore we take the presence of that symbol
+ * as an indication that the engine will be incompatible.
+ */
+static int using_libcrypto_11(dynamic_data_ctx *ctx)
+{
+    int ret;
+
+    ERR_set_mark();
+    ret = DSO_bind_func(ctx->dynamic_dso, "EVP_PKEY_base_id") != NULL;
+    ERR_pop_to_mark();
+
+    return ret;
+}
+
 static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
 {
     ENGINE cpy;
@@ -450,18 +470,9 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
         /*
          * We fail if the version checker veto'd the load *or* if it is
          * deferring to us (by returning its version) and we think it is too
-         * old.
-         * Unfortunately the version checker does not distinguish between
-         * engines built for openssl 1.1.x and openssl 3.x, but loading
-         * an engine that is built for openssl 1.1.x will cause a fatal
-         * error.  Detect such engines, since EVP_PKEY_base_id is exported
-         * as a function in openssl 1.1.x, while it is a macro in openssl 3.x,
-         * and therefore only the symbol EVP_PKEY_get_base_id is available
-         * in openssl 3.x.
+         * old. Also fail if this is engine for openssl 1.1.x.
          */
-        if (vcheck_res < OSSL_DYNAMIC_OLDEST
-                || DSO_bind_func(ctx->dynamic_dso,
-                                 "EVP_PKEY_base_id") != NULL) {
+        if (vcheck_res < OSSL_DYNAMIC_OLDEST || using_libcrypto_11(ctx)) {
             /* Fail */
             ctx->bind_engine = NULL;
             ctx->v_check = NULL;