Put an error on the stack in the event of a fetch failure
authorMatt Caswell <matt@openssl.org>
Wed, 25 Mar 2020 12:12:59 +0000 (12:12 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 27 Mar 2020 11:12:27 +0000 (11:12 +0000)
Fetch failures are a common problem and it is useful to have detailed
information about what was requested in the event of a failure.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11405)

crypto/context.c
crypto/evp/evp_fetch.c
crypto/evp/pkey_mac.c
include/internal/cryptlib.h

index dcf960b..3553017 100644 (file)
@@ -172,6 +172,15 @@ OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx)
     return ctx;
 }
 
+int openssl_ctx_is_default(OPENSSL_CTX *ctx)
+{
+#ifndef FIPS_MODE
+    if (ctx == NULL || ctx == default_context)
+        return 1;
+#endif
+    return 0;
+}
+
 static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
                                     CRYPTO_EX_DATA *ad, int index,
                                     long argl_ign, void *argp)
index da7f33e..e808bf8 100644 (file)
@@ -294,9 +294,26 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
                         int (*up_ref_method)(void *),
                         void (*free_method)(void *))
 {
-    return inner_evp_generic_fetch(libctx,
-                                   operation_id, 0, name, properties,
-                                   new_method, up_ref_method, free_method);
+    void *ret = inner_evp_generic_fetch(libctx,
+                                        operation_id, 0, name, properties,
+                                        new_method, up_ref_method, free_method);
+
+    if (ret == NULL) {
+        int code = EVP_R_FETCH_FAILED;
+
+#ifdef FIPS_MODE
+        ERR_raise(ERR_LIB_EVP, code);
+#else
+        ERR_raise_data(ERR_LIB_EVP, code,
+                       "%s, Algorithm (%s), Properties (%s)",
+                       (openssl_ctx_is_default(libctx)
+                        ? "Default library context"
+                        : "Non-default library context"),
+                       name = NULL ? "<null>" : name,
+                       properties == NULL ? "<null>" : properties);
+#endif
+    }
+    return ret;
 }
 
 /*
@@ -314,9 +331,34 @@ void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id,
                                   int (*up_ref_method)(void *),
                                   void (*free_method)(void *))
 {
-    return inner_evp_generic_fetch(libctx,
-                                   operation_id, name_id, NULL, properties,
-                                   new_method, up_ref_method, free_method);
+    void *ret = inner_evp_generic_fetch(libctx,
+                                        operation_id, name_id, NULL,
+                                        properties, new_method, up_ref_method,
+                                        free_method);
+
+    if (ret == NULL) {
+        int code = EVP_R_FETCH_FAILED;
+
+#ifdef FIPS_MODE
+        ERR_raise(ERR_LIB_EVP, code);
+#else
+        {
+            OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+            const char *name = (namemap == NULL)
+                               ? NULL
+                               : ossl_namemap_num2name(namemap, name_id, 0);
+
+            ERR_raise_data(ERR_LIB_EVP, code,
+                           "%s, Algorithm (%s), Properties (%s)",
+                           (openssl_ctx_is_default(libctx)
+                            ? "Default library context"
+                            : "Non-default library context"),
+                           name = NULL ? "<null>" : name,
+                           properties == NULL ? "<null>" : properties);
+        }
+#endif
+    }
+    return ret;
 }
 
 int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq)
index 7430b62..7452e03 100644 (file)
@@ -51,7 +51,11 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
     MAC_PKEY_CTX *hctx;
     /* We're being smart and using the same base NIDs for PKEY and for MAC */
     int nid = ctx->pmeth->pkey_id;
-    EVP_MAC *mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
+    EVP_MAC *mac;
+
+    ERR_set_mark();
+    mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
+    ERR_pop_to_mark();
 
     /*
      * mac == NULL may actually be ok in some situations. In an
index 19e2c97..9a60f41 100644 (file)
@@ -165,6 +165,7 @@ typedef struct openssl_ctx_method {
 } OPENSSL_CTX_METHOD;
 
 OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx);
+int openssl_ctx_is_default(OPENSSL_CTX *ctx);
 
 /* Functions to retrieve pointers to data by index */
 void *openssl_ctx_get_data(OPENSSL_CTX *, int /* index */,