mirror of
https://github.com/openssl/openssl.git
synced 2025-03-31 20:10:45 +08:00
DECODER: Add input structure support for EVP_PKEY decoding
OSSL_DECODER_CTX_new_by_EVP_PKEY() takes one more argument to express the desired outermost structure for the input. Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13248)
This commit is contained in:
parent
67c91ca23e
commit
df65c06b59
@ -9,6 +9,7 @@
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/core_object.h>
|
||||
#include <openssl/provider.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ui.h>
|
||||
#include <openssl/decoder.h>
|
||||
@ -16,6 +17,7 @@
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/decoder.h"
|
||||
#include "encoder_local.h"
|
||||
#include "e_os.h" /* strcasecmp on Windows */
|
||||
|
||||
int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
|
||||
const unsigned char *kstr,
|
||||
@ -231,10 +233,40 @@ static void collect_name(const char *name, void *arg)
|
||||
data->error_occured = 0; /* All is good now */
|
||||
}
|
||||
|
||||
/*
|
||||
* The input structure check is only done on the initial decoder
|
||||
* implementations.
|
||||
*/
|
||||
static int collect_decoder_check_input_structure(OSSL_DECODER_CTX *ctx,
|
||||
OSSL_DECODER_INSTANCE *di)
|
||||
{
|
||||
int di_is_was_set = 0;
|
||||
const char *di_is =
|
||||
OSSL_DECODER_INSTANCE_get_input_structure(di, &di_is_was_set);
|
||||
|
||||
/*
|
||||
* If caller didn't give an input structure name, the decoder is accepted
|
||||
* unconditionally with regards to the input structure.
|
||||
*/
|
||||
if (ctx->input_structure == NULL)
|
||||
return 1;
|
||||
/*
|
||||
* If the caller did give an input structure name, the decoder must have
|
||||
* a matching input structure to be accepted.
|
||||
*/
|
||||
if (di_is != NULL
|
||||
&& strcasecmp(ctx->input_structure, di_is) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void collect_decoder(OSSL_DECODER *decoder, void *arg)
|
||||
{
|
||||
struct collected_data_st *data = arg;
|
||||
size_t i, end_i;
|
||||
const OSSL_PROVIDER *prov = OSSL_DECODER_provider(decoder);
|
||||
void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
|
||||
void *decoderctx = NULL;
|
||||
|
||||
if (data->error_occured)
|
||||
return;
|
||||
@ -246,10 +278,30 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg)
|
||||
end_i = sk_OPENSSL_CSTRING_num(data->names);
|
||||
for (i = 0; i < end_i; i++) {
|
||||
const char *name = sk_OPENSSL_CSTRING_value(data->names, i);
|
||||
OSSL_DECODER_INSTANCE *di = NULL;
|
||||
|
||||
if (!OSSL_DECODER_is_a(decoder, name))
|
||||
continue;
|
||||
(void)OSSL_DECODER_CTX_add_decoder(data->ctx, decoder);
|
||||
if (OSSL_DECODER_is_a(decoder, name)
|
||||
/*
|
||||
* Either the caller didn't give a selection, or if they did,
|
||||
* the decoder must tell us if it supports that selection to
|
||||
* be accepted. If the decoder doesn't have |does_selection|,
|
||||
* it's seen as taking anything.
|
||||
*/
|
||||
&& (decoder->does_selection == NULL
|
||||
|| decoder->does_selection(provctx, data->ctx->selection))
|
||||
&& (decoderctx = decoder->newctx(provctx)) != NULL
|
||||
&& (di = ossl_decoder_instance_new(decoder, decoderctx)) != NULL) {
|
||||
/* If successful so far, don't free these directly */
|
||||
decoderctx = NULL;
|
||||
|
||||
if (collect_decoder_check_input_structure(data->ctx, di)
|
||||
&& ossl_decoder_ctx_add_decoder_inst(data->ctx, di))
|
||||
di = NULL; /* If successfully added, don't free it */
|
||||
}
|
||||
|
||||
/* Free what can be freed */
|
||||
ossl_decoder_instance_free(di);
|
||||
decoder->freectx(decoderctx);
|
||||
}
|
||||
|
||||
data->error_occured = 0; /* All is good now */
|
||||
@ -325,7 +377,9 @@ int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx,
|
||||
|
||||
OSSL_DECODER_CTX *
|
||||
OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
|
||||
const char *input_type, const char *keytype,
|
||||
const char *input_type,
|
||||
const char *input_structure,
|
||||
const char *keytype, int selection,
|
||||
OSSL_LIB_CTX *libctx, const char *propquery)
|
||||
{
|
||||
OSSL_DECODER_CTX *ctx = NULL;
|
||||
@ -335,6 +389,8 @@ OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
|
||||
return NULL;
|
||||
}
|
||||
if (OSSL_DECODER_CTX_set_input_type(ctx, input_type)
|
||||
&& OSSL_DECODER_CTX_set_input_structure(ctx, input_structure)
|
||||
&& OSSL_DECODER_CTX_set_selection(ctx, selection)
|
||||
&& ossl_decoder_ctx_setup_for_EVP_PKEY(ctx, pkey, keytype,
|
||||
libctx, propquery)
|
||||
&& OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery))
|
||||
|
@ -7,7 +7,9 @@ OSSL_DECODER_CTX_new,
|
||||
OSSL_DECODER_settable_ctx_params,
|
||||
OSSL_DECODER_CTX_set_params,
|
||||
OSSL_DECODER_CTX_free,
|
||||
OSSL_DECODER_CTX_set_selection,
|
||||
OSSL_DECODER_CTX_set_input_type,
|
||||
OSSL_DECODER_CTX_set_input_structure,
|
||||
OSSL_DECODER_CTX_add_decoder,
|
||||
OSSL_DECODER_CTX_add_extra,
|
||||
OSSL_DECODER_CTX_get_num_decoders,
|
||||
@ -23,7 +25,8 @@ 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
|
||||
OSSL_DECODER_INSTANCE_get_input_type,
|
||||
OSSL_DECODER_INSTANCE_get_input_structure
|
||||
- Decoder context routines
|
||||
|
||||
=head1 SYNOPSIS
|
||||
@ -38,8 +41,11 @@ OSSL_DECODER_INSTANCE_get_input_type
|
||||
const OSSL_PARAM params[]);
|
||||
void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx);
|
||||
|
||||
int OSSL_DECODER_CTX_set_selection(OSSL_DECODER_CTX *ctx, int selection);
|
||||
int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
|
||||
const char *input_type);
|
||||
int OSSL_DECODER_CTX_set_input_structure(OSSL_DECODER_CTX *ctx,
|
||||
const char *input_structure);
|
||||
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);
|
||||
@ -51,6 +57,8 @@ OSSL_DECODER_INSTANCE_get_input_type
|
||||
OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst);
|
||||
const char *
|
||||
OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst);
|
||||
OSSL_DECODER_INSTANCE_get_input_structure(OSSL_DECODER_INSTANCE *decoder_inst,
|
||||
int *was_set);
|
||||
|
||||
typedef int OSSL_DECODER_CONSTRUCT(OSSL_DECODER_INSTANCE *decoder_inst,
|
||||
const OSSL_PARAM *object,
|
||||
@ -128,6 +136,11 @@ 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_set_input_structure() sets the name of the structure that
|
||||
the input is expected to have. This may be used to determines what decoder
|
||||
implementations may be used. NULL is a valid input structure, when it's not
|
||||
relevant, or when the decoder implementations are expected to figure it out.
|
||||
|
||||
OSSL_DECODER_CTX_get_num_decoders() gets the number of decoders currently
|
||||
added to the context I<ctx>.
|
||||
|
||||
@ -179,14 +192,19 @@ 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() can be used to get the decoder
|
||||
implementation 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>.
|
||||
implementation'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>.
|
||||
implementation's input type from a decoder instance I<decoder_inst>.
|
||||
|
||||
OSSL_DECODER_INSTANCE_get_input_structure() can be used to get the input
|
||||
structure for the decoder implementation from a decoder instance
|
||||
I<decoder_inst>.
|
||||
This may be NULL.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
|
@ -121,7 +121,9 @@ int OSSL_DECODER_from_data(OSSL_DECODER_CTX *ctx, const unsigned char **pdata,
|
||||
*/
|
||||
OSSL_DECODER_CTX *
|
||||
OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
|
||||
const char *input_type, const char *keytype,
|
||||
const char *input_type,
|
||||
const char *input_struct,
|
||||
const char *keytype, int selection,
|
||||
OSSL_LIB_CTX *libctx, const char *propquery);
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
Loading…
x
Reference in New Issue
Block a user