From 48b62fb33aa0c5bce52b939fcd94780736491a5d Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 14 Sep 2020 11:35:07 +0200 Subject: [PATCH] DECODER: Some cleanups, and aligning with OSSL_ENCODER Mostly source nits, but also removing a couple of OSSL_DECODER_PARAM macros that are never used or even make sense. Also, some function names weren't quite consistent. They were made a bit more consistent in the OSSL_ENCODER API, now we bring that back to OSSL_DECODER. Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/12873) --- crypto/encode_decode/decoder_lib.c | 60 +++-- crypto/encode_decode/decoder_meth.c | 32 +-- crypto/encode_decode/decoder_pkey.c | 24 +- doc/man3/OSSL_DECODER_CTX.pod | 207 ++++++++++++++++-- doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod | 85 ++++--- doc/man3/OSSL_DECODER_from_bio.pod | 187 +--------------- include/openssl/core_names.h | 2 - include/openssl/decoder.h | 25 ++- util/libcrypto.num | 7 +- util/other.syms | 1 - 10 files changed, 307 insertions(+), 323 deletions(-) diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index 9eeff20f7c..0bc772e43b 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -159,8 +159,7 @@ int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, return (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, di) > 0); } -int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, - OSSL_DECODER *decoder) +int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) { OSSL_DECODER_INSTANCE *decoder_inst = NULL; const OSSL_PROVIDER *prov = NULL; @@ -246,7 +245,8 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, for (i = w_prev_start; i < w_prev_end; i++) { OSSL_DECODER_INSTANCE *decoder_inst = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); - const char *name = decoder_inst->input_type; + const char *input_type = + OSSL_DECODER_INSTANCE_get_input_type(decoder_inst); OSSL_DECODER *decoder = NULL; /* @@ -256,12 +256,11 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, * on top of this one, so we don't. */ if (ctx->start_input_type != NULL - && strcasecmp(ctx->start_input_type, - decoder_inst->input_type) != 0) + && strcasecmp(ctx->start_input_type, input_type) != 0) continue; ERR_set_mark(); - decoder = OSSL_DECODER_fetch(libctx, name, propq); + decoder = OSSL_DECODER_fetch(libctx, input_type, propq); ERR_pop_to_mark(); if (decoder != NULL) { @@ -308,7 +307,7 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, return 1; } -int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx) +int OSSL_DECODER_CTX_get_num_decoders(OSSL_DECODER_CTX *ctx) { if (ctx == NULL || ctx->decoder_insts == NULL) return 0; @@ -375,6 +374,9 @@ int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst, void *reference, size_t reference_sz, OSSL_CALLBACK *export_cb, void *export_cbarg) { + OSSL_DECODER *decoder = NULL; + void *decoderctx = NULL; + if (!(ossl_assert(decoder_inst != NULL) && ossl_assert(reference != NULL) && ossl_assert(export_cb != NULL) @@ -383,25 +385,36 @@ int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst, return 0; } - return decoder_inst->decoder->export_object(decoder_inst->decoderctx, - reference, reference_sz, - export_cb, export_cbarg); + decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); + return decoder->export_object(decoderctx, reference, reference_sz, + export_cb, export_cbarg); } -OSSL_DECODER *OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst) +OSSL_DECODER * +OSSL_DECODER_INSTANCE_get_decoder(OSSL_DECODER_INSTANCE *decoder_inst) { if (decoder_inst == NULL) return NULL; return decoder_inst->decoder; } -void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst) +void * +OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst) { if (decoder_inst == NULL) return NULL; return decoder_inst->decoderctx; } +const char * +OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst == NULL) + return NULL; + return decoder_inst->input_type; +} + static int decoder_process(const OSSL_PARAM params[], void *arg) { struct decoder_process_data_st *data = arg; @@ -422,7 +435,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg) /* First iteration, where we prepare for what is to come */ data->current_decoder_inst_index = - OSSL_DECODER_CTX_num_decoders(ctx); + OSSL_DECODER_CTX_get_num_decoders(ctx); bio = data->bio; } else { @@ -431,7 +444,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg) decoder_inst = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, data->current_decoder_inst_index); - decoder = OSSL_DECODER_INSTANCE_decoder(decoder_inst); + decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); if (ctx->construct != NULL && ctx->construct(decoder_inst, params, ctx->construct_data)) { @@ -473,7 +486,11 @@ static int decoder_process(const OSSL_PARAM params[], void *arg) OSSL_DECODER_INSTANCE *new_decoder_inst = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); OSSL_DECODER *new_decoder = - OSSL_DECODER_INSTANCE_decoder(new_decoder_inst); + OSSL_DECODER_INSTANCE_get_decoder(new_decoder_inst); + void *new_decoderctx = + OSSL_DECODER_INSTANCE_get_decoder_ctx(new_decoder_inst); + const char *new_input_type = + OSSL_DECODER_INSTANCE_get_input_type(new_decoder_inst); /* * If |decoder| is NULL, it means we've just started, and the caller @@ -481,18 +498,16 @@ static int decoder_process(const OSSL_PARAM params[], void *arg) * that's the case, we do this extra check. */ if (decoder == NULL && ctx->start_input_type != NULL - && strcasecmp(ctx->start_input_type, - new_decoder_inst->input_type) != 0) + && strcasecmp(ctx->start_input_type, new_input_type) != 0) continue; /* * If we have a previous decoder, we check that the input type * of the next to be used matches the type of this previous one. - * decoder_inst->input_type is a cache of the parameter "input-type" - * value for that decoder. + * input_type is a cache of the parameter "input-type" value for + * that decoder. */ - if (decoder != NULL - && !OSSL_DECODER_is_a(decoder, new_decoder_inst->input_type)) + if (decoder != NULL && !OSSL_DECODER_is_a(decoder, new_input_type)) continue; /* @@ -511,8 +526,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg) /* Recurse */ new_data.current_decoder_inst_index = i; - ok = new_decoder->decode(new_decoder_inst->decoderctx, - (OSSL_CORE_BIO *)bio, + ok = new_decoder->decode(new_decoderctx, (OSSL_CORE_BIO *)bio, decoder_process, &new_data, ossl_pw_passphrase_callback_dec, &new_data.ctx->pwdata); diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c index 41406df90f..37c6ab2b57 100644 --- a/crypto/encode_decode/decoder_meth.c +++ b/crypto/encode_decode/decoder_meth.c @@ -484,10 +484,8 @@ OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void) { OSSL_DECODER_CTX *ctx; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); - return NULL; - } return ctx; } @@ -506,42 +504,30 @@ int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx, if (ctx->decoder_insts == NULL) return 1; - l = (size_t)sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); + l = OSSL_DECODER_CTX_get_num_decoders(ctx); for (i = 0; i < l; i++) { OSSL_DECODER_INSTANCE *decoder_inst = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + OSSL_DECODER *decoder = + OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + OSSL_DECODER *decoderctx = + OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); - if (decoder_inst->decoderctx == NULL - || decoder_inst->decoder->set_ctx_params == NULL) + if (decoderctx == NULL || decoder->set_ctx_params == NULL) continue; - if (!decoder_inst->decoder->set_ctx_params(decoder_inst->decoderctx, - params)) + if (!decoder->set_ctx_params(decoderctx, params)) return 0; } return 1; } -static void -OSSL_DECODER_INSTANCE_free(OSSL_DECODER_INSTANCE *decoder_inst) -{ - if (decoder_inst != NULL) { - if (decoder_inst->decoder->freectx != 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); - decoder_inst = NULL; - } -} - void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx) { if (ctx != NULL) { if (ctx->cleanup != NULL) ctx->cleanup(ctx->construct_data); sk_OSSL_DECODER_INSTANCE_pop_free(ctx->decoder_insts, - OSSL_DECODER_INSTANCE_free); + ossl_decoder_instance_free); ossl_pw_clear_passphrase_data(&ctx->pwdata); OPENSSL_free(ctx); } diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c index dfc7cccab1..2e07d0d7cc 100644 --- a/crypto/encode_decode/decoder_pkey.c +++ b/crypto/encode_decode/decoder_pkey.c @@ -62,9 +62,8 @@ static int decoder_construct_EVP_PKEY(OSSL_DECODER_INSTANCE *decoder_inst, void *construct_data) { struct decoder_EVP_PKEY_data_st *data = construct_data; - OSSL_DECODER *decoder = - OSSL_DECODER_INSTANCE_decoder(decoder_inst); - void *decoderctx = OSSL_DECODER_INSTANCE_decoder_ctx(decoder_inst); + OSSL_DECODER *decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + void *decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); size_t i, end_i; /* * |object_ref| points to a provider reference to an object, its exact @@ -207,7 +206,7 @@ static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) if (!EVP_KEYMGMT_up_ref(keymgmt) /* ref++ */) return; if (sk_EVP_KEYMGMT_push(data->process_data->keymgmts, keymgmt) <= 0) { - EVP_KEYMGMT_free(keymgmt); /* ref-- */ + EVP_KEYMGMT_free(keymgmt); /* ref-- */ return; } @@ -301,17 +300,16 @@ int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, if (data->error_occured) goto err; - /* If we found no decoders to match the keymgmts, we err */ - if (OSSL_DECODER_CTX_num_decoders(ctx) == 0) - goto err; + if (OSSL_DECODER_CTX_get_num_decoders(ctx) != 0) { + if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_EVP_PKEY) + || !OSSL_DECODER_CTX_set_construct_data(ctx, data->process_data) + || !OSSL_DECODER_CTX_set_cleanup(ctx, + decoder_clean_EVP_PKEY_construct_arg)) + goto err; - if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_EVP_PKEY) - || !OSSL_DECODER_CTX_set_construct_data(ctx, data->process_data) - || !OSSL_DECODER_CTX_set_cleanup(ctx, - decoder_clean_EVP_PKEY_construct_arg)) - goto err; + data->process_data = NULL; /* Avoid it being freed */ + } - data->process_data = NULL; ok = 1; err: if (data != NULL) { diff --git a/doc/man3/OSSL_DECODER_CTX.pod b/doc/man3/OSSL_DECODER_CTX.pod index 7dbd7550df..bb8875ea4f 100644 --- a/doc/man3/OSSL_DECODER_CTX.pod +++ b/doc/man3/OSSL_DECODER_CTX.pod @@ -6,8 +6,25 @@ OSSL_DECODER_CTX, OSSL_DECODER_CTX_new, OSSL_DECODER_settable_ctx_params, OSSL_DECODER_CTX_set_params, -OSSL_DECODER_CTX_free -- Encoder context routines +OSSL_DECODER_CTX_free, +OSSL_DECODER_CTX_set_input_type, +OSSL_DECODER_CTX_add_decoder, +OSSL_DECODER_CTX_add_extra, +OSSL_DECODER_CTX_get_num_decoders, +OSSL_DECODER_INSTANCE, +OSSL_DECODER_CONSTRUCT, +OSSL_DECODER_CLEANUP, +OSSL_DECODER_CTX_set_construct, +OSSL_DECODER_CTX_set_construct_data, +OSSL_DECODER_CTX_set_cleanup, +OSSL_DECODER_CTX_get_construct, +OSSL_DECODER_CTX_get_construct_data, +OSSL_DECODER_CTX_get_cleanup, +OSSL_DECODER_export, +OSSL_DECODER_INSTANCE_get_decoder, +OSSL_DECODER_INSTANCE_get_decoder_ctx, +OSSL_DECODER_INSTANCE_get_input_type +- Decoder context routines =head1 SYNOPSIS @@ -21,38 +38,186 @@ OSSL_DECODER_CTX_free const OSSL_PARAM params[]); void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx); + int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, + const char *input_type); + int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder); + int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx); + int OSSL_DECODER_CTX_get_num_decoders(OSSL_DECODER_CTX *ctx); + + typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE; + OSSL_DECODER * + OSSL_DECODER_INSTANCE_get_decoder(OSSL_DECODER_INSTANCE *decoder_inst); + void * + OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst); + const char * + OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst); + + typedef int OSSL_DECODER_CONSTRUCT(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *object, + void *construct_data); + typedef void OSSL_DECODER_CLEANUP(void *construct_data); + + int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CONSTRUCT *construct); + int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx, + void *construct_data); + int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CLEANUP *cleanup); + OSSL_DECODER_CONSTRUCT *OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx); + void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx); + OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx); + + int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst, + void *reference, size_t reference_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg); + =head1 DESCRIPTION -B is a context with which B -operations are performed. The context typically holds values, both -internal and supplied by the application, which are useful for the -implementations supplied by providers. +The B holds data about multiple decoders, as needed to +figure out what the input data is and to attempt to unpack it into one of +several possible related results. This also includes chaining decoders, so +the output from one can become the input for another. This allows having +generic format decoders such as PEM to DER, as well as more specialized +decoders like DER to RSA. + +The chains may be limited by specifying an input type, which is considered a +starting point. This is both considered by OSSL_DECODER_CTX_add_extra(), +which will stop adding one more decoder implementations when it has already +added those that take the specified input type, and functions like +L, which will only start the decoding process with +the decoder implementations that take that input type. For example, if the +input type is set to C, a PEM to DER decoder will be ignored. + +The input type can also be NULL, which means that the caller doesn't know +what type of input they have. In this case, OSSL_DECODER_from_bio() will +simply try with one decoder implementation after the other, and thereby +discover what kind of input the caller gave it. + +For every decoding done, even an intermediary one, a constructor provided by +the caller is called to attempt to construct an appropriate type / structure +that the caller knows how to handle from the current decoding result. +The constructor is set with OSSL_DECODER_CTX_set_construct(). + +B is an opaque structure that contains data about the +decoder that was just used, and that may be useful for the constructor. +There are some functions to extract data from this type, described further +down. + +=head2 Functions OSSL_DECODER_CTX_new() creates a new empty B. -OSSL_DECODER_settable_ctx_params() returns an L -array of parameter descriptors. +OSSL_DECODER_settable_ctx_params() returns an L array of +parameter descriptors. -OSSL_DECODER_CTX_set_params() attempts to set parameters specified -with an L array I. These parameters are passed -to all decoders that have been added to the I so far. -Parameters that an implementation doesn't recognise should be ignored -by it. +OSSL_DECODER_CTX_set_params() attempts to set parameters specified with an +L array I. These parameters are passed to all +decoders that have been added to the I so far. Parameters that an +implementation doesn't recognise should be ignored by it. OSSL_DECODER_CTX_free() frees the given context I. +OSSL_DECODER_CTX_add_decoder() populates the B I with +a decoder, to be used to attempt to decode some encoded input. + +OSSL_DECODER_CTX_add_extra() finds decoders that generate input for already +added decoders, and adds them as well. This is used to build decoder +chains. + +OSSL_DECODER_CTX_set_input_type() sets the starting input type. This limits +the decoder chains to be considered, as explained in the general description +above. + +OSSL_DECODER_CTX_get_num_decoders() gets the number of decoders currently +added to the context I. + +OSSL_DECODER_CTX_set_construct() sets the constructor I. + +OSSL_DECODER_CTX_set_construct_data() sets the constructor data that is +passed to the constructor every time it's called. + +OSSL_DECODER_CTX_set_cleanup() sets the constructor data I +function. This is called by L. + +OSSL_DECODER_CTX_get_construct(), OSSL_DECODER_CTX_get_construct_data() and +OSSL_DECODER_CTX_get_cleanup() return the values that have been set by +OSSL_DECODER_CTX_set_construct(), OSSL_DECODER_CTX_set_construct_data() and +OSSL_DECODER_CTX_set_cleanup() respectively. + +OSSL_DECODER_export() is a fallback function for constructors that cannot +use the data they get directly for diverse reasons. It takes the same +decode instance I that the constructor got and an object +I, unpacks the object which it refers to, and exports it by +creating an L array that it then passes to I, +along with I. + +=head2 Constructor + +A B gets the following arguments: + +=over 4 + +=item I + +The B for the decoder from which the constructor gets +its data. + +=item I + +A provider-native object abstraction produced by the decoder. Further +information on the provider-native object abstraction can be found in +L. + +=item I + +The pointer that was set with OSSL_DECODE_CTX_set_construct_data(). + +=back + +The constructor is expected to return 1 when the data it receives can be +constructed, otherwise 0. + +These utility functions may be used by a constructor: + +OSSL_DECODER_INSTANCE_get_decoder() can be used to get the decoder method +from a decoder instance I. + +OSSL_DECODER_INSTANCE_get_decoder_ctx() can be used to get the decoder +method's provider context from a decoder instance I. + +OSSL_DECODER_INSTANCE_get_input_type() can be used to get the decoder +method's input type from a decoder instance I. + =head1 RETURN VALUES -OSSL_DECODER_CTX_new() returns a pointer to a -B, or NULL if the context structure couldn't be -allocated. +OSSL_DECODER_CTX_new() returns a pointer to a B, or NULL +if the context structure couldn't be allocated. + +OSSL_DECODER_settable_ctx_params() returns an L array, or +NULL if none is available. + +OSSL_DECODER_CTX_set_params() returns 1 if all recognised parameters were +valid, or 0 if one of them was invalid or caused some other failure in the +implementation. + +OSSL_DECODER_CTX_add_decoder(), OSSL_DECODER_CTX_add_extra(), +OSSL_DECODER_CTX_set_construct(), OSSL_DECODER_CTX_set_construct_data() and +OSSL_DECODER_CTX_set_cleanup() return 1 on success, or 0 on failure. + +OSSL_DECODER_CTX_get_construct(), OSSL_DECODER_CTX_get_construct_data() and +OSSL_DECODER_CTX_get_cleanup() return the current pointers to the +constructor, the constructor data and the cleanup functions, respectively. + +OSSL_DECODER_CTX_num_decoders() returns the current number of decoders. It +returns 0 if I is NULL. + +OSSL_DECODER_export() returns 1 on success, or 0 on failure. -OSSL_DECODER_settable_ctx_params() returns an L -array, or NULL if none is available. +OSSL_DECODER_INSTANCE_decoder() returns an B pointer on +success, or NULL on failure. -OSSL_DECODER_CTX_set_params() returns 1 if all recognised -parameters were valid, or 0 if one of them was invalid or caused some -other failure in the implementation. +OSSL_DECODER_INSTANCE_decoder_ctx() returns a provider context pointer on +success, or NULL on failure. =head1 SEE ALSO diff --git a/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod index 620688e322..4190c4232b 100644 --- a/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod +++ b/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod @@ -32,63 +32,60 @@ OSSL_DECODER_CTX_set_passphrase_cb =head1 DESCRIPTION -OSSL_DECODER_CTX_new_by_EVP_PKEY() is a utility function that -creates a B, finds all applicable decoder -implementations and sets them up, so all the caller has to do next is -call functions like OSSL_DECODE_from_bio(). - -Internally OSSL_DECODER_CTX_new_by_EVP_PKEY() searches for all -available L implementations, and then builds a list of all -potential decoder implementations that may be able to process the -encoded input into data suitable for Bs. All these -implementations are implicitly fetched using I and I. - -The search of decoder implementations can be limited with -I, which specifies a starting input type. This is further -explained in L. - -If no suitable decoder was found, OSSL_DECODER_CTX_new_by_EVP_PKEY() -still creates a B, but with no associated -decoder (L returns -zero). This helps the caller distinguish between an error when -creating the B, and the lack the decoder -support and act accordingly. - -OSSL_DECODER_CTX_set_passphrase() gives the implementation a -pass phrase to use when decrypting the encoded private key. -Alternatively, a pass phrase callback may be specified with the -following functions. - -OSSL_DECODER_CTX_set_pem_password_cb(), -OSSL_DECODER_CTX_set_passphrase_ui() and -OSSL_DECODER_CTX_set_passphrase_cb() set up a callback method that -the implementation can use to prompt for a pass phrase, giving the caller -the choice of prefered pass phrase callback form. These are called -indirectly, through an internal B function. - -The internal B function caches the pass phrase, -to be re-used in all decodings that are performed in the same decoding run -(for example, within one L call). +OSSL_DECODER_CTX_new_by_EVP_PKEY() is a utility function that creates a +B, finds all applicable decoder implementations and sets +them up, so all the caller has to do next is call functions like +OSSL_DECODE_from_bio(). + +Internally OSSL_DECODER_CTX_new_by_EVP_PKEY() searches for all available +L implementations, and then builds a list of all potential +decoder implementations that may be able to process the encoded input into +data suitable for Bs. All these implementations are implicitly +fetched using I and I. + +The search of decoder implementations can be limited with I, +which specifies a starting input type. This is further explained in +L. + +If no suitable decoder implementation is found, +OSSL_DECODER_CTX_new_by_EVP_PKEY() still creates a B, but +with no associated decoder (L returns +zero). This helps the caller to distinguish between an error when creating +the B and missing encoder implementation, and allows it to +act accordingly. + +OSSL_DECODER_CTX_set_passphrase() gives the implementation a pass phrase to +use when decrypting the encoded private key. Alternatively, a pass phrase +callback may be specified with the following functions. + +OSSL_DECODER_CTX_set_pem_password_cb(), OSSL_DECODER_CTX_set_passphrase_ui() +and OSSL_DECODER_CTX_set_passphrase_cb() set up a callback method that the +implementation can use to prompt for a pass phrase, giving the caller the +choice of prefered pass phrase callback form. These are called indirectly, +through an internal B function. + +The internal B function caches the pass phrase, to +be re-used in all decodings that are performed in the same decoding run (for +example, within one L call). =head1 RETURN VALUES OSSL_DECODER_CTX_new_by_EVP_PKEY() returns a pointer to a B, or NULL if it couldn't be created. -OSSL_DECODER_CTX_set_passphrase(), -OSSL_DECODER_CTX_set_pem_password_cb(), +OSSL_DECODER_CTX_set_passphrase(), OSSL_DECODER_CTX_set_pem_password_cb(), OSSL_DECODER_CTX_set_passphrase_ui() and -OSSL_DECODER_CTX_set_passphrase_cb() -all return 1 on success, or 0 on failure. +OSSL_DECODER_CTX_set_passphrase_cb() all return 1 on success, or 0 on +failure. =head1 NOTES Parts of the function names are made to match already existing OpenSSL names. -B in OSSL_DECODER_CTX_new_by_EVP_PKEY() matches the type -name, thus making for the naming pattern -B>() when new types are handled. +B in OSSL_DECODER_CTX_new_by_EVP_PKEY() matches the type name, +thus making for the naming pattern B>() when +new types are handled. =head1 SEE ALSO diff --git a/doc/man3/OSSL_DECODER_from_bio.pod b/doc/man3/OSSL_DECODER_from_bio.pod index 560231fe23..7de550746e 100644 --- a/doc/man3/OSSL_DECODER_from_bio.pod +++ b/doc/man3/OSSL_DECODER_from_bio.pod @@ -3,23 +3,7 @@ =head1 NAME OSSL_DECODER_from_bio, -OSSL_DECODER_from_fp, -OSSL_DECODER_CTX_set_input_type, -OSSL_DECODER_CTX_add_decoder, -OSSL_DECODER_CTX_add_extra, -OSSL_DECODER_CTX_num_decoders, -OSSL_DECODER_INSTANCE, -OSSL_DECODER_CONSTRUCT, -OSSL_DECODER_CLEANUP, -OSSL_DECODER_CTX_set_construct, -OSSL_DECODER_CTX_set_construct_data, -OSSL_DECODER_CTX_set_cleanup, -OSSL_DECODER_CTX_get_construct, -OSSL_DECODER_CTX_get_construct_data, -OSSL_DECODER_CTX_get_cleanup, -OSSL_DECODER_export, -OSSL_DECODER_INSTANCE_decoder, -OSSL_DECODER_INSTANCE_decoder_ctx +OSSL_DECODER_from_fp - Routines to perform a decoding =head1 SYNOPSIS @@ -29,36 +13,6 @@ OSSL_DECODER_INSTANCE_decoder_ctx int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in); int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp); - int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, - const char *input_type); - int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder); - int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx); - int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx); - - typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE; - OSSL_DECODER * - OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst); - void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst); - - typedef int (OSSL_DECODER_CONSTRUCT)(OSSL_DECODER_INSTANCE *decoder_inst, - const OSSL_PARAM *object, - void *construct_data); - typedef void (OSSL_DECODER_CLEANUP)(void *construct_data); - - int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx, - OSSL_DECODER_CONSTRUCT *construct); - int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx, - void *construct_data); - int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx, - OSSL_DECODER_CLEANUP *cleanup); - OSSL_DECODER_CONSTRUCT *OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx); - void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx); - OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx); - - int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst, - void *reference, size_t reference_sz, - OSSL_CALLBACK *export_cb, void *export_cbarg); - Feature availability macros: =over 4 @@ -70,146 +24,17 @@ is undefined. =head1 DESCRIPTION -The B holds data about multiple decoders, as -needed to figure out what the input data is and to attempt to unpack it into -one of several possible related results. This also includes chaining -decoders, so the output from one can become the input for another. -This allows having generic format decoders such as PEM to DER, as well -as more specialized decoders like DER to RSA. - -The chains may be limited by specifying an input type, which is considered a -starting point. -This is both considered by OSSL_DECODER_CTX_add_extra(), which will -stop adding on more decoder implementations when it has already added -those that take the specified input type, and OSSL_DECODER_from_bio(), -which will only start the decoding process with the decoder -implementations that take that input type. For example, if the input type -is set to C, a PEM to DER decoder will be ignored. - -The input type can also be NULL, which means that the caller doesn't know -what type of input they have. In this case, OSSL_DECODER_from_bio() -will simply try with one decoder implementation after the other, and -thereby discover what kind of input the caller gave it. - -For every decoding done, even an intermediary one, a constructor -provided by the caller is called to attempt to construct an appropriate type -/ structure that the caller knows how to handle from the current -decoding result. -The constructor is set with OSSL_DECODER_CTX_set_construct(). - -B is an opaque structure that contains -data about the decoder that was just used, and that may be -useful for the constructor. There are some functions to extract data -from this type, described further down. - -=head2 Functions - -OSSL_DECODER_from_bio() runs the decoding process for the -context I, with the input coming from the B I. Should -it make a difference, it's recommended to have the BIO set in binary -mode rather than text mode. +OSSL_DECODER_from_bio() runs the decoding process for the context I, +with the input coming from the B I. Should it make a difference, +it's recommended to have the BIO set in binary mode rather than text mode. OSSL_DECODER_from_fp() does the same thing as OSSL_DECODER_from_bio(), except that the input is coming from the B I. -OSSL_DECODER_CTX_add_decoder() populates the B -I with a decoder, to be used to attempt to decode some -encoded input. - -OSSL_DECODER_CTX_add_extra() finds decoders that generate -input for already added decoders, and adds them as well. This is -used to build decoder chains. - -OSSL_DECODER_CTX_set_input_type() sets the starting input type. This -limits the decoder chains to be considered, as explained in the general -description above. - -OSSL_DECODER_CTX_num_decoders() gets the number of -decoders currently added to the context I. - -OSSL_DECODER_CTX_set_construct() sets the constructor I. - -OSSL_DECODER_CTX_set_construct_data() sets the constructor data that is -passed to the constructor every time it's called. - -OSSL_DECODER_CTX_set_cleanup() sets the constructor data I -function. This is called by L. - -OSSL_DECODER_CTX_get_construct(), -OSSL_DECODER_CTX_get_construct_data() and -OSSL_DECODER_CTX_get_cleanup() -return the values that have been set by -OSSL_DECODER_CTX_set_construct(), -OSSL_DECODER_CTX_set_construct_data() and -OSSL_DECODER_CTX_set_cleanup() respectively. - -OSSL_DECODER_export() is a fallback function for constructors that -cannot use the data they get directly for diverse reasons. It takes the same -decode instance I that the constructor got and an object -I, unpacks the object which it refers to, and exports it by creating -an L array that it then passes to I, along with -I. - -OSSL_DECODER_INSTANCE_decoder() can be used to get the -decoder method from a decoder instance I. - -OSSL_DECODER_INSTANCE_decoder-ctx() can be used to get the -decoder method's provider context from a decoder instance -I. - -=head2 Constructor - -A B gets the following arguments: - -=over 4 - -=item I - -The B for the decoder from which -the constructor gets its data. - -=item I - -A provider-native object abstraction produced by the decoder. Further -information on the provider-native object abstraction can be found in -L. - -=item I - -The pointer that was set with OSSL_DECODE_CTX_set_construct_data(). - -=back - -The constructor is expected to return 1 when the data it receives can -be constructed, otherwise 0. - =head1 RETURN VALUES -OSSL_DECODER_from_bio() and OSSL_DECODER_from_fp() return 1 on -success, or 0 on failure. - -OSSL_DECODER_CTX_add_decoder(), -OSSL_DECODER_CTX_add_extra(), -OSSL_DECODER_CTX_set_construct(), -OSSL_DECODER_CTX_set_construct_data() and -OSSL_DECODER_CTX_set_cleanup() return 1 on success, or 0 on -failure. - -OSSL_DECODER_CTX_get_construct(), -OSSL_DECODER_CTX_get_construct_data() and -OSSL_DECODER_CTX_get_cleanup() return the current pointers to the -cosntructor, the constructor data and the cleanup functions, respectively. - -OSSL_DECODER_CTX_num_decoders() returns the current -number of decoders. It returns 0 if I is NULL. - -OSSL_DECODER_export() returns 1 on success, or 0 on failure. - -OSSL_DECODER_INSTANCE_decoder() returns an -B pointer on success, or NULL on failure. - -OSSL_DECODER_INSTANCE_decoder_ctx() returns a provider -context pointer on success, or NULL on failure.> +OSSL_DECODER_from_bio() and OSSL_DECODER_from_fp() return 1 on success, or 0 +on failure. =begin comment TODO(3.0) Add examples! diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index e3d3d27a7f..d17ab49700 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -450,9 +450,7 @@ extern "C" { #define OSSL_ENCODER_PARAM_INPUT_TYPE "input-type" #define OSSL_ENCODER_PARAM_OUTPUT_TYPE "output-type" -#define OSSL_DECODER_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER #define OSSL_DECODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES -#define OSSL_DECODER_PARAM_PASS "passphrase" #define OSSL_DECODER_PARAM_INPUT_TYPE "input-type" /* Passphrase callback parameters */ diff --git a/include/openssl/decoder.h b/include/openssl/decoder.h index 91dfca4a09..3da4577437 100644 --- a/include/openssl/decoder.h +++ b/include/openssl/decoder.h @@ -53,11 +53,9 @@ void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx); /* Utilities that help set specific parameters */ int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, - const unsigned char *kstr, - size_t klen); + const unsigned char *kstr, size_t klen); int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx, - pem_password_cb *cb, - void *cbarg); + pem_password_cb *cb, void *cbarg); int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX *ctx, OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg); @@ -75,17 +73,20 @@ int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder); int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, OPENSSL_CTX *libctx, const char *propq); -int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx); +int OSSL_DECODER_CTX_get_num_decoders(OSSL_DECODER_CTX *ctx); typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE; OSSL_DECODER * -OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst); -void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst); - -typedef int (OSSL_DECODER_CONSTRUCT)(OSSL_DECODER_INSTANCE *decoder_inst, - const OSSL_PARAM *params, - void *construct_data); -typedef void (OSSL_DECODER_CLEANUP)(void *construct_data); +OSSL_DECODER_INSTANCE_get_decoder(OSSL_DECODER_INSTANCE *decoder_inst); +void * +OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst); +const char * +OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst); + +typedef int OSSL_DECODER_CONSTRUCT(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *params, + void *construct_data); +typedef void OSSL_DECODER_CLEANUP(void *construct_data); int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx, OSSL_DECODER_CONSTRUCT *construct); diff --git a/util/libcrypto.num b/util/libcrypto.num index fd6fe59b53..e414a6443b 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5154,11 +5154,11 @@ OSSL_DECODER_from_bio ? 3_0_0 EXIST::FUNCTION: OSSL_DECODER_from_fp ? 3_0_0 EXIST::FUNCTION:STDIO OSSL_DECODER_CTX_add_decoder ? 3_0_0 EXIST::FUNCTION: OSSL_DECODER_CTX_add_extra ? 3_0_0 EXIST::FUNCTION: -OSSL_DECODER_CTX_num_decoders ? 3_0_0 EXIST::FUNCTION: +OSSL_DECODER_CTX_get_num_decoders ? 3_0_0 EXIST::FUNCTION: OSSL_DECODER_CTX_set_input_type ? 3_0_0 EXIST::FUNCTION: OSSL_DECODER_export ? 3_0_0 EXIST::FUNCTION: -OSSL_DECODER_INSTANCE_decoder ? 3_0_0 EXIST::FUNCTION: -OSSL_DECODER_INSTANCE_decoder_ctx ? 3_0_0 EXIST::FUNCTION: +OSSL_DECODER_INSTANCE_get_decoder ? 3_0_0 EXIST::FUNCTION: +OSSL_DECODER_INSTANCE_get_decoder_ctx ? 3_0_0 EXIST::FUNCTION: ERR_load_OSSL_DECODER_strings ? 3_0_0 EXIST::FUNCTION: OSSL_DECODER_gettable_params ? 3_0_0 EXIST::FUNCTION: OSSL_DECODER_get_params ? 3_0_0 EXIST::FUNCTION: @@ -5312,3 +5312,4 @@ OSSL_ENCODER_CTX_set_cleanup ? 3_0_0 EXIST::FUNCTION: OSSL_DECODER_INSTANCE_get_input_type ? 3_0_0 EXIST::FUNCTION: OSSL_ENCODER_CTX_set_passphrase_cb ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_typenames_do_all ? 3_0_0 EXIST::FUNCTION: +OSSL_DECODER_INSTANCE_get_input_type ? 3_0_0 EXIST::FUNCTION: diff --git a/util/other.syms b/util/other.syms index b4acae2952..6c7ec4c9ca 100644 --- a/util/other.syms +++ b/util/other.syms @@ -46,7 +46,6 @@ OSSL_DECODER_CTX datatype OSSL_DECODER_CONSTRUCT datatype OSSL_DECODER_CLEANUP datatype OSSL_DECODER_INSTANCE datatype -OSSL_DECODER_CTX datatype OSSL_HTTP_bio_cb_t datatype OSSL_PARAM datatype OSSL_PROVIDER datatype -- 2.34.1