summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-10-26 13:06:01 +0100
committerRichard Levitte <levitte@openssl.org>2020-11-11 11:42:06 +0100
commitebfdb63d96496274106b4192fda6039cbb272bae (patch)
tree783610da2aeff10d1c1944e077600c153e7125e0
parentf7626d0bfab35acd89c2c6542fc6504954191a14 (diff)
DECODER: Add support for specifying the outermost input structure
Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13248)
-rw-r--r--crypto/encode_decode/decoder_lib.c58
-rw-r--r--crypto/encode_decode/encoder_local.h22
-rw-r--r--include/openssl/core_names.h5
-rw-r--r--include/openssl/decoder.h6
-rw-r--r--util/libcrypto.num3
5 files changed, 87 insertions, 7 deletions
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
index 20350a8cd6..64e6bcc185 100644
--- a/crypto/encode_decode/decoder_lib.c
+++ b/crypto/encode_decode/decoder_lib.c
@@ -98,6 +98,21 @@ int OSSL_DECODER_from_data(OSSL_DECODER_CTX *ctx, const unsigned char **pdata,
return ret;
}
+int OSSL_DECODER_CTX_set_selection(OSSL_DECODER_CTX *ctx, int selection)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ /*
+ * 0 is a valid selection, and means that the caller leaves
+ * it to code to discover what the selection is.
+ */
+ ctx->selection = selection;
+ return 1;
+}
+
int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
const char *input_type)
{
@@ -114,11 +129,27 @@ int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
return 1;
}
+int OSSL_DECODER_CTX_set_input_structure(OSSL_DECODER_CTX *ctx,
+ const char *input_structure)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ /*
+ * NULL is a valid starting input type, and means that the caller leaves
+ * it to code to discover what the starting input type is.
+ */
+ ctx->input_structure = input_structure;
+ return 1;
+}
+
OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder,
void *decoderctx)
{
OSSL_DECODER_INSTANCE *decoder_inst = NULL;
- OSSL_PARAM params[2];
+ OSSL_PARAM params[3];
if (!ossl_assert(decoder != NULL)) {
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
@@ -140,16 +171,22 @@ OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder,
goto err;
}
- /* Cache the input type for this encoder */
+ /* Cache the input type for this decoder */
params[0] =
OSSL_PARAM_construct_utf8_ptr(OSSL_DECODER_PARAM_INPUT_TYPE,
(char **)&decoder_inst->input_type, 0);
- params[1] = OSSL_PARAM_construct_end();
+ params[1] =
+ OSSL_PARAM_construct_utf8_ptr(OSSL_DECODER_PARAM_INPUT_STRUCTURE,
+ (char **)&decoder_inst->input_structure,
+ 0);
+ params[2] = OSSL_PARAM_construct_end();
if (!decoder->get_params(params)
|| !OSSL_PARAM_modified(&params[0]))
goto err;
+ decoder_inst->flag_input_structure_was_set =
+ OSSL_PARAM_modified(&params[1]);
decoder_inst->decoder = decoder;
decoder_inst->decoderctx = decoderctx;
return decoder_inst;
@@ -171,7 +208,7 @@ void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst)
}
int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx,
- OSSL_DECODER_INSTANCE *di)
+ OSSL_DECODER_INSTANCE *di)
{
if (ctx->decoder_insts == NULL
&& (ctx->decoder_insts =
@@ -225,7 +262,7 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
* what the existing ones want as input, and push those newly fetched
* decoders on top of the same stack.
* Then it does the same again, but looping over the newly fetched
- * decoders, until there are no more encoders to be fetched, or
+ * decoders, until there are no more decoders to be fetched, or
* when we have done this 10 times.
*
* we do this with sliding windows on the stack by keeping track of indexes
@@ -439,6 +476,16 @@ OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst)
return decoder_inst->input_type;
}
+const char *
+OSSL_DECODER_INSTANCE_get_input_structure(OSSL_DECODER_INSTANCE *decoder_inst,
+ int *was_set)
+{
+ if (decoder_inst == NULL)
+ return NULL;
+ *was_set = decoder_inst->flag_input_structure_was_set;
+ return decoder_inst->input_structure;
+}
+
static int decoder_process(const OSSL_PARAM params[], void *arg)
{
struct decoder_process_data_st *data = arg;
@@ -564,6 +611,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
/* Recurse */
new_data.current_decoder_inst_index = i;
ok = new_decoder->decode(new_decoderctx, (OSSL_CORE_BIO *)bio,
+ new_data.ctx->selection,
decoder_process, &new_data,
ossl_pw_passphrase_callback_dec,
&new_data.ctx->pwdata);
diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h
index a57d0cd16c..9378393a42 100644
--- a/crypto/encode_decode/encoder_local.h
+++ b/crypto/encode_decode/encoder_local.h
@@ -96,6 +96,9 @@ struct ossl_decoder_instance_st {
OSSL_DECODER *decoder; /* Never NULL */
void *decoderctx; /* Never NULL */
const char *input_type; /* Never NULL */
+ const char *input_structure; /* May be NULL */
+
+ unsigned int flag_input_structure_was_set : 1;
};
DEFINE_STACK_OF(OSSL_DECODER_INSTANCE)
@@ -108,6 +111,25 @@ struct ossl_decoder_ctx_st {
* regardless of their respective input type.
*/
const char *start_input_type;
+ /*
+ * The desired input structure, if that's relevant for the type of
+ * object being encoded. It may be used for selection of the ending
+ * decoder implementations in a chain, i.e. those chosen using the
+ * expected output data type.
+ */
+ const char *input_structure;
+ /*
+ * Select what parts of an object are expected. This may affect what
+ * decoder implementations are selected, because there are structures
+ * that look different depending on this selection; for example, EVP_PKEY
+ * objects often have different encoding structures for private keys,
+ * public keys and key parameters.
+ * This selection is bit encoded, and the bits correspond to selection
+ * bits available with the provider side operation. For example, when
+ * encoding an EVP_PKEY, the OSSL_KEYMGMT_SELECT_ macros are used for
+ * this.
+ */
+ int selection;
/*
* Decoders that are components of any current decoding path.
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 43be4ae145..11a4168cc1 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -457,8 +457,9 @@ extern "C" {
#define OSSL_ENCODER_PARAM_INPUT_TYPE "input-type"
#define OSSL_ENCODER_PARAM_OUTPUT_TYPE "output-type"
-#define OSSL_DECODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES
-#define OSSL_DECODER_PARAM_INPUT_TYPE "input-type"
+#define OSSL_DECODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES
+#define OSSL_DECODER_PARAM_INPUT_TYPE "input-type"
+#define OSSL_DECODER_PARAM_INPUT_STRUCTURE "input-structure"
/* Passphrase callback parameters */
#define OSSL_PASSPHRASE_PARAM_INFO "info"
diff --git a/include/openssl/decoder.h b/include/openssl/decoder.h
index 1c6bc8e498..8b360e6198 100644
--- a/include/openssl/decoder.h
+++ b/include/openssl/decoder.h
@@ -68,8 +68,11 @@ int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
* These will discover all provided methods
*/
+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,
OSSL_LIB_CTX *libctx, const char *propq);
@@ -82,6 +85,9 @@ 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);
+const char *
+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 *params,
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 9437e30e85..40e1fcb43a 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5285,3 +5285,6 @@ EVP_PKEY_CTX_get0_libctx ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_get0_propq ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_set1_encoded_public_key ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_get1_encoded_public_key ? 3_0_0 EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_selection ? 3_0_0 EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_input_structure ? 3_0_0 EXIST::FUNCTION:
+OSSL_DECODER_INSTANCE_get_input_structure ? 3_0_0 EXIST::FUNCTION: