diff options
Diffstat (limited to 'crypto/encode_decode/decoder_lib.c')
-rw-r--r-- | crypto/encode_decode/decoder_lib.c | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index 17dca0fc22..9eeff20f7c 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -12,6 +12,7 @@ #include <openssl/params.h> #include <openssl/provider.h> #include "internal/passphrase.h" +#include "crypto/decoder.h" #include "encoder_local.h" #include "e_os.h" @@ -89,14 +90,13 @@ int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, return 1; } -int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) +OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, + void *decoderctx) { OSSL_DECODER_INSTANCE *decoder_inst = NULL; - const OSSL_PROVIDER *prov = NULL; OSSL_PARAM params[2]; - void *provctx = NULL; - if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) { + if (!ossl_assert(decoder != NULL)) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -107,12 +107,6 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) return 0; } - if (ctx->decoder_insts == NULL - && (ctx->decoder_insts = - sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); - return 0; - } if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); return 0; @@ -121,10 +115,6 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); goto err; } - decoder_inst->decoder = decoder; - - prov = OSSL_DECODER_provider(decoder_inst->decoder); - provctx = OSSL_PROVIDER_get0_provider_ctx(prov); /* Cache the input type for this encoder */ params[0] = @@ -132,25 +122,74 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) (char **)&decoder_inst->input_type, 0); params[1] = OSSL_PARAM_construct_end(); - if (!decoder_inst->decoder->get_params(params) + if (!decoder->get_params(params) || !OSSL_PARAM_modified(¶ms[0])) goto err; - if ((decoder_inst->decoderctx = decoder_inst->decoder->newctx(provctx)) - == NULL) - goto err; - - if (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, decoder_inst) <= 0) - goto err; - - return 1; + decoder_inst->decoder = decoder; + decoder_inst->decoderctx = decoderctx; + return decoder_inst; err: + ossl_decoder_instance_free(decoder_inst); + return NULL; +} + +void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst) +{ if (decoder_inst != NULL) { if (decoder_inst->decoder != NULL) decoder_inst->decoder->freectx(decoder_inst->decoderctx); + decoder_inst->decoderctx = NULL; OSSL_DECODER_free(decoder_inst->decoder); + decoder_inst->decoder = NULL; OPENSSL_free(decoder_inst); } +} + +int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_INSTANCE *di) +{ + if (ctx->decoder_insts == NULL + && (ctx->decoder_insts = + sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + return (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, di) > 0); +} + +int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, + OSSL_DECODER *decoder) +{ + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + const OSSL_PROVIDER *prov = NULL; + void *decoderctx = NULL; + void *provctx = NULL; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + prov = OSSL_DECODER_provider(decoder); + provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if ((decoderctx = decoder->newctx(provctx)) == NULL + || (decoder_inst = + ossl_decoder_instance_new(decoder, decoderctx)) == NULL) + goto err; + /* Avoid double free of decoderctx on further errors */ + decoderctx = NULL; + + if (!ossl_decoder_ctx_add_decoder_inst(ctx, decoder_inst)) + goto err; + + return 1; + err: + ossl_decoder_instance_free(decoder_inst); + if (decoderctx != NULL) + decoder->freectx(decoderctx); return 0; } |