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;
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;
/*
* 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) {
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;
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)
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;
/* 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 {
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)) {
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
* 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;
/*
/* 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);
{
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;
}
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);
}
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
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;
}
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) {
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
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<OSSL_DECODER_CTX> is a context with which B<OSSL_DECODER>
-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<OSSL_DECODER_CTX> 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<OSSL_DECODER_from_bio(3)>, 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<DER>, 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<OSSL_DECODER_INSTANCE> 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_CTX>.
-OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array of parameter descriptors.
+OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)> array of
+parameter descriptors.
-OSSL_DECODER_CTX_set_params() attempts to set parameters specified
-with an L<OSSL_PARAM(3)> array I<params>. These parameters are passed
-to all decoders that have been added to the I<ctx> 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<OSSL_PARAM(3)> array I<params>. These parameters are passed to all
+decoders that have been added to the I<ctx> so far. Parameters that an
+implementation doesn't recognise should be ignored by it.
OSSL_DECODER_CTX_free() frees the given context I<ctx>.
+OSSL_DECODER_CTX_add_decoder() populates the B<OSSL_DECODER_CTX> I<ctx> 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<ctx>.
+
+OSSL_DECODER_CTX_set_construct() sets the constructor I<construct>.
+
+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<cleanup>
+function. This is called by L<OSSL_DECODER_CTX_free(3)>.
+
+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<decoder_inst> that the constructor got and an object
+I<reference>, unpacks the object which it refers to, and exports it by
+creating an L<OSSL_PARAM(3)> array that it then passes to I<export_cb>,
+along with I<export_arg>.
+
+=head2 Constructor
+
+A B<OSSL_DECODER_CONSTRUCT> gets the following arguments:
+
+=over 4
+
+=item I<decoder_inst>
+
+The B<OSSL_DECODER_INSTANCE> for the decoder from which the constructor gets
+its data.
+
+=item I<object>
+
+A provider-native object abstraction produced by the decoder. Further
+information on the provider-native object abstraction can be found in
+L<provider-object(7)>.
+
+=item I<construct_data>
+
+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<decoder_inst>.
+
+OSSL_DECODER_INSTANCE_get_decoder_ctx() can be used to get the decoder
+method's provider context from a decoder instance I<decoder_inst>.
+
+OSSL_DECODER_INSTANCE_get_input_type() can be used to get the decoder
+method's input type from a decoder instance I<decoder_inst>.
+
=head1 RETURN VALUES
-OSSL_DECODER_CTX_new() returns a pointer to a
-B<OSSL_DECODER_CTX>, or NULL if the context structure couldn't be
-allocated.
+OSSL_DECODER_CTX_new() returns a pointer to a B<OSSL_DECODER_CTX>, or NULL
+if the context structure couldn't be allocated.
+
+OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)> 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<ctx> is NULL.
+
+OSSL_DECODER_export() returns 1 on success, or 0 on failure.
-OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array, or NULL if none is available.
+OSSL_DECODER_INSTANCE_decoder() returns an B<OSSL_DECODER> 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
=head1 DESCRIPTION
-OSSL_DECODER_CTX_new_by_EVP_PKEY() is a utility function that
-creates a B<OSSL_DECODER_CTX>, 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<EVP_KEYMGMT(3)> implementations, and then builds a list of all
-potential decoder implementations that may be able to process the
-encoded input into data suitable for B<EVP_PKEY>s. All these
-implementations are implicitly fetched using I<libctx> and I<propquery>.
-
-The search of decoder implementations can be limited with
-I<input_type>, which specifies a starting input type. This is further
-explained in L<OSSL_DECODER_CTX_set_input_type(3)>.
-
-If no suitable decoder was found, OSSL_DECODER_CTX_new_by_EVP_PKEY()
-still creates a B<OSSL_DECODER_CTX>, but with no associated
-decoder (L<OSSL_DECODER_CTX_num_decoders(3)> returns
-zero). This helps the caller distinguish between an error when
-creating the B<OSSL_DECODER_CTX>, 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<OSSL_PASSPHRASE_CALLBACK> function.
-
-The internal B<OSSL_PASSPHRASE_CALLBACK> 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<OSSL_DECODER_from_bio(3)> call).
+OSSL_DECODER_CTX_new_by_EVP_PKEY() is a utility function that creates a
+B<OSSL_DECODER_CTX>, 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<EVP_KEYMGMT(3)> implementations, and then builds a list of all potential
+decoder implementations that may be able to process the encoded input into
+data suitable for B<EVP_PKEY>s. All these implementations are implicitly
+fetched using I<libctx> and I<propquery>.
+
+The search of decoder implementations can be limited with I<input_type>,
+which specifies a starting input type. This is further explained in
+L<OSSL_DECODER_CTX_set_input_type(3)>.
+
+If no suitable decoder implementation is found,
+OSSL_DECODER_CTX_new_by_EVP_PKEY() still creates a B<OSSL_DECODER_CTX>, but
+with no associated decoder (L<OSSL_DECODER_CTX_get_num_decoders(3)> returns
+zero). This helps the caller to distinguish between an error when creating
+the B<OSSL_ENCODER_CTX> 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<OSSL_PASSPHRASE_CALLBACK> function.
+
+The internal B<OSSL_PASSPHRASE_CALLBACK> 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<OSSL_DECODER_from_bio(3)> call).
=head1 RETURN VALUES
OSSL_DECODER_CTX_new_by_EVP_PKEY() returns a pointer to a
B<OSSL_DECODER_CTX>, 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<EVP_PKEY> in OSSL_DECODER_CTX_new_by_EVP_PKEY() matches the type
-name, thus making for the naming pattern
-B<OSSL_DECODER_CTX_new_by_I<TYPE>>() when new types are handled.
+B<EVP_PKEY> in OSSL_DECODER_CTX_new_by_EVP_PKEY() matches the type name,
+thus making for the naming pattern B<OSSL_DECODER_CTX_new_by_I<TYPE>>() when
+new types are handled.
=head1 SEE ALSO
=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
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
=head1 DESCRIPTION
-The B<OSSL_DECODER_CTX> 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<DER>, 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<OSSL_DECODER_INSTANCE> 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<ctx>, with the input coming from the B<BIO> I<in>. 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<ctx>,
+with the input coming from the B<BIO> I<in>. 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<FILE> I<fp>.
-OSSL_DECODER_CTX_add_decoder() populates the B<OSSL_DECODER_CTX>
-I<ctx> 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<ctx>.
-
-OSSL_DECODER_CTX_set_construct() sets the constructor I<construct>.
-
-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<cleanup>
-function. This is called by L<OSSL_DECODER_CTX_free(3)>.
-
-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<decoder_inst> that the constructor got and an object
-I<reference>, unpacks the object which it refers to, and exports it by creating
-an L<OSSL_PARAM(3)> array that it then passes to I<export_cb>, along with
-I<export_arg>.
-
-OSSL_DECODER_INSTANCE_decoder() can be used to get the
-decoder method from a decoder instance I<decoder_inst>.
-
-OSSL_DECODER_INSTANCE_decoder-ctx() can be used to get the
-decoder method's provider context from a decoder instance
-I<decoder_inst>.
-
-=head2 Constructor
-
-A B<OSSL_DECODER_CONSTRUCT> gets the following arguments:
-
-=over 4
-
-=item I<decoder_inst>
-
-The B<OSSL_DECODER_INSTANCE> for the decoder from which
-the constructor gets its data.
-
-=item I<object>
-
-A provider-native object abstraction produced by the decoder. Further
-information on the provider-native object abstraction can be found in
-L<provider-object(7)>.
-
-=item I<construct_data>
-
-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<ctx> is NULL.
-
-OSSL_DECODER_export() returns 1 on success, or 0 on failure.
-
-OSSL_DECODER_INSTANCE_decoder() returns an
-B<OSSL_DECODER> 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!
#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 */
/* 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);
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);
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:
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:
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