X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=crypto%2Fencode_decode%2Fencoder_meth.c;h=f1a6e89b83e3777514289cec4541545cf4991509;hb=4333b89f504e7a8de9c42a0d27f68530b5301848;hp=bee54bf63ac3b71db25cebcfa8e25fa009ba436f;hpb=a829b735b645516041b55746e013692babd8cd31;p=thirdparty%2Fopenssl.git diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c index bee54bf63a..f1a6e89b83 100644 --- a/crypto/encode_decode/encoder_meth.c +++ b/crypto/encode_decode/encoder_meth.c @@ -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 @@ -87,6 +87,8 @@ struct encoder_data_st { 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_occured : 1; }; /* @@ -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,6 +264,7 @@ 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. */ + 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; @@ -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_occured = 1; + return method; } @@ -293,20 +309,32 @@ static OSSL_ENCODER *inner_ossl_encoder_fetch(OSSL_LIB_CTX *libctx, 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(OSSL_LIB_CTX *libctx, mcmdata.id = id; mcmdata.names = name; mcmdata.propquery = properties; + mcmdata.flag_construct_error_occured = 0; if ((method = ossl_method_construct(libctx, OSSL_OP_ENCODER, 0 /* !force_cache */, &mcm, &mcmdata)) != NULL) { @@ -338,6 +367,24 @@ static OSSL_ENCODER *inner_ossl_encoder_fetch(OSSL_LIB_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_occured; + } + + 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 ? "" : name, id, + properties == NULL ? "" : properties); } return method; @@ -503,6 +550,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 +572,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)