]> git.ipfire.org Git - thirdparty/openssl.git/blobdiff - crypto/encode_decode/encoder_meth.c
crypto: rename error flags in internal structures
[thirdparty/openssl.git] / crypto / encode_decode / encoder_meth.c
index 93929b5360d52266285e48a349db65ae40437671..490eeb2e0aa666fa9a3334849a6b9dab5af1b63b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -69,24 +69,26 @@ static void encoder_store_free(void *vstore)
     ossl_method_store_free(vstore);
 }
 
-static void *encoder_store_new(OPENSSL_CTX *ctx)
+static void *encoder_store_new(OSSL_LIB_CTX *ctx)
 {
     return ossl_method_store_new(ctx);
 }
 
 
-static const OPENSSL_CTX_METHOD encoder_store_method = {
+static const OSSL_LIB_CTX_METHOD encoder_store_method = {
     encoder_store_new,
     encoder_store_free,
 };
 
 /* Data to be passed through ossl_method_construct() */
 struct encoder_data_st {
-    OPENSSL_CTX *libctx;
+    OSSL_LIB_CTX *libctx;
     OSSL_METHOD_CONSTRUCT_METHOD *mcm;
     int id;                      /* For get_encoder_from_store() */
     const char *names;           /* For get_encoder_from_store() */
     const char *propquery;       /* For get_encoder_from_store() */
+
+    unsigned int flag_construct_error_occurred : 1;
 };
 
 /*
@@ -95,7 +97,7 @@ struct encoder_data_st {
  */
 
 /* Temporary encoder method store, constructor and destructor */
-static void *alloc_tmp_encoder_store(OPENSSL_CTX *ctx)
+static void *alloc_tmp_encoder_store(OSSL_LIB_CTX *ctx)
 {
     return ossl_method_store_new(ctx);
 }
@@ -107,14 +109,14 @@ static void dealloc_tmp_encoder_store(void *store)
 }
 
 /* Get the permanent encoder store */
-static OSSL_METHOD_STORE *get_encoder_store(OPENSSL_CTX *libctx)
+static OSSL_METHOD_STORE *get_encoder_store(OSSL_LIB_CTX *libctx)
 {
-    return openssl_ctx_get_data(libctx, OPENSSL_CTX_ENCODER_STORE_INDEX,
-                                &encoder_store_method);
+    return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_ENCODER_STORE_INDEX,
+                                 &encoder_store_method);
 }
 
 /* Get encoder methods from a store, or put one in */
-static void *get_encoder_from_store(OPENSSL_CTX *libctx, void *store,
+static void *get_encoder_from_store(OSSL_LIB_CTX *libctx, void *store,
                                     void *data)
 {
     struct encoder_data_st *methdata = data;
@@ -136,7 +138,7 @@ static void *get_encoder_from_store(OPENSSL_CTX *libctx, void *store,
     return method;
 }
 
-static int put_encoder_in_store(OPENSSL_CTX *libctx, void *store,
+static int put_encoder_in_store(OSSL_LIB_CTX *libctx, void *store,
                                 void *method, const OSSL_PROVIDER *prov,
                                 int operation_id, const char *names,
                                 const char *propdef, void *unused)
@@ -200,6 +202,11 @@ static void *encoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
                 encoder->settable_ctx_params =
                     OSSL_FUNC_encoder_settable_ctx_params(fns);
             break;
+        case OSSL_FUNC_ENCODER_DOES_SELECTION:
+            if (encoder->does_selection == NULL)
+                encoder->does_selection =
+                    OSSL_FUNC_encoder_does_selection(fns);
+            break;
         case OSSL_FUNC_ENCODER_ENCODE:
             if (encoder->encode == NULL)
                 encoder->encode = OSSL_FUNC_encoder_encode(fns);
@@ -249,7 +256,7 @@ static void *encoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
  * then call encoder_from_dispatch() with that identity number.
  */
 static void *construct_encoder(const OSSL_ALGORITHM *algodef,
-                               OSSL_PROVIDER *prov, void *unused)
+                               OSSL_PROVIDER *prov, void *data)
 {
     /*
      * This function is only called if get_encoder_from_store() returned
@@ -257,7 +264,8 @@ static void *construct_encoder(const OSSL_ALGORITHM *algodef,
      * namemap entry, this is it.  Should the name already exist there, we
      * know that ossl_namemap_add() will return its corresponding number.
      */
-    OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
+    struct encoder_data_st *methdata = data;
+    OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
     const char *names = algodef->algorithm_names;
     int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
@@ -266,6 +274,14 @@ static void *construct_encoder(const OSSL_ALGORITHM *algodef,
     if (id != 0)
         method = encoder_from_dispatch(id, algodef, prov);
 
+    /*
+     * Flag to indicate that there was actual construction errors.  This
+     * helps inner_evp_generic_fetch() determine what error it should
+     * record on inaccessible algorithms.
+     */
+    if (method == NULL)
+        methdata->flag_construct_error_occurred = 1;
+
     return method;
 }
 
@@ -286,27 +302,39 @@ static void free_encoder(void *method)
 }
 
 /* Fetching support.  Can fetch by numeric identity or by name */
-static OSSL_ENCODER *inner_ossl_encoder_fetch(OPENSSL_CTX *libctx,
+static OSSL_ENCODER *inner_ossl_encoder_fetch(OSSL_LIB_CTX *libctx,
                                               int id, const char *name,
                                               const char *properties)
 {
     OSSL_METHOD_STORE *store = get_encoder_store(libctx);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
     void *method = NULL;
+    int unsupported = 0;
 
-    if (store == NULL || namemap == NULL)
+    if (store == NULL || namemap == NULL) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT);
         return NULL;
+    }
 
     /*
      * If we have been passed neither a name_id or a name, we have an
      * internal programming error.
      */
-    if (!ossl_assert(id != 0 || name != NULL))
+    if (!ossl_assert(id != 0 || name != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR);
         return NULL;
+    }
 
     if (id == 0)
         id = ossl_namemap_name2num(namemap, name);
 
+    /*
+     * If we haven't found the name yet, chances are that the algorithm to
+     * be fetched is unsupported.
+     */
+    if (id == 0)
+        unsupported = 1;
+
     if (id == 0
         || !ossl_method_store_cache_get(store, id, properties, &method)) {
         OSSL_METHOD_CONSTRUCT_METHOD mcm = {
@@ -324,6 +352,7 @@ static OSSL_ENCODER *inner_ossl_encoder_fetch(OPENSSL_CTX *libctx,
         mcmdata.id = id;
         mcmdata.names = name;
         mcmdata.propquery = properties;
+        mcmdata.flag_construct_error_occurred = 0;
         if ((method = ossl_method_construct(libctx, OSSL_OP_ENCODER,
                                             0 /* !force_cache */,
                                             &mcm, &mcmdata)) != NULL) {
@@ -338,18 +367,36 @@ static OSSL_ENCODER *inner_ossl_encoder_fetch(OPENSSL_CTX *libctx,
             ossl_method_store_cache_set(store, id, properties, method,
                                         up_ref_encoder, free_encoder);
         }
+
+        /*
+         * If we never were in the constructor, the algorithm to be fetched
+         * is unsupported.
+         */
+        unsupported = !mcmdata.flag_construct_error_occurred;
+    }
+
+    if (method == NULL) {
+        int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED;
+
+        if (name == NULL)
+            name = ossl_namemap_num2name(namemap, id, 0);
+        ERR_raise_data(ERR_LIB_OSSL_ENCODER, code,
+                       "%s, Name (%s : %d), Properties (%s)",
+                       ossl_lib_ctx_get_descriptor(libctx),
+                       name = NULL ? "<null>" : name, id,
+                       properties == NULL ? "<null>" : properties);
     }
 
     return method;
 }
 
-OSSL_ENCODER *OSSL_ENCODER_fetch(OPENSSL_CTX *libctx, const char *name,
+OSSL_ENCODER *OSSL_ENCODER_fetch(OSSL_LIB_CTX *libctx, const char *name,
                                  const char *properties)
 {
     return inner_ossl_encoder_fetch(libctx, 0, name, properties);
 }
 
-OSSL_ENCODER *ossl_encoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+OSSL_ENCODER *ossl_encoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id,
                                            const char *properties)
 {
     return inner_ossl_encoder_fetch(libctx, id, NULL, properties);
@@ -392,7 +439,7 @@ int OSSL_ENCODER_number(const OSSL_ENCODER *encoder)
 int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name)
 {
     if (encoder->base.prov != NULL) {
-        OPENSSL_CTX *libctx = ossl_provider_library_context(encoder->base.prov);
+        OSSL_LIB_CTX *libctx = ossl_provider_libctx(encoder->base.prov);
         OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
 
         return ossl_namemap_name2num(namemap, name) == encoder->base.id;
@@ -410,7 +457,7 @@ static void encoder_do_one(OSSL_PROVIDER *provider,
                            int no_store, void *vdata)
 {
     struct encoder_do_all_data_st *data = vdata;
-    OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
+    OSSL_LIB_CTX *libctx = ossl_provider_libctx(provider);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
     const char *names = algodef->algorithm_names;
     int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
@@ -426,7 +473,7 @@ static void encoder_do_one(OSSL_PROVIDER *provider,
     }
 }
 
-void OSSL_ENCODER_do_all_provided(OPENSSL_CTX *libctx,
+void OSSL_ENCODER_do_all_provided(OSSL_LIB_CTX *libctx,
                                   void (*fn)(OSSL_ENCODER *encoder, void *arg),
                                   void *arg)
 {
@@ -443,19 +490,21 @@ void OSSL_ENCODER_do_all_provided(OPENSSL_CTX *libctx,
                           encoder_do_one, NULL, &data);
 }
 
-void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder,
-                               void (*fn)(const char *name, void *data),
-                               void *data)
+int OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder,
+                              void (*fn)(const char *name, void *data),
+                              void *data)
 {
     if (encoder == NULL)
-        return;
+        return 0;
 
     if (encoder->base.prov != NULL) {
-        OPENSSL_CTX *libctx = ossl_provider_library_context(encoder->base.prov);
+        OSSL_LIB_CTX *libctx = ossl_provider_libctx(encoder->base.prov);
         OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
 
-        ossl_namemap_doall_names(namemap, encoder->base.id, fn, data);
+        return ossl_namemap_doall_names(namemap, encoder->base.id, fn, data);
     }
+
+    return 1;
 }
 
 const OSSL_PARAM *
@@ -503,6 +552,7 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(void)
 int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx,
                                 const OSSL_PARAM params[])
 {
+    int ok = 1;
     size_t i;
     size_t l;
 
@@ -524,9 +574,9 @@ int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx,
         if (encoderctx == NULL || encoder->set_ctx_params == NULL)
             continue;
         if (!encoder->set_ctx_params(encoderctx, params))
-            return 0;
+            ok = 0;
     }
-    return 1;
+    return ok;
 }
 
 void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx)