The branch master has been updated via 70c06aafa691a77861bd3d3aaf93afa2a55e04ce (commit) from ecadfdadde491572b0bdf3c5a95e7a6a004585c6 (commit)
- Log ----------------------------------------------------------------- commit 70c06aafa691a77861bd3d3aaf93afa2a55e04ce Author: Richard Levitte <levi...@openssl.org> Date: Fri Oct 2 14:21:51 2020 +0200 DECODER: Allow precise result type for OSSL_DECODER_CTX_new_by_EVP_PKEY() There is some data that is very difficult to guess. For example, DSA parameters and X9.42 DH parameters look exactly the same, a SEQUENCE of 3 INTEGER. Therefore, callers may need the possibility to select the exact keytype that they expect to get. This will also allow use to translate d2i_TYPEPrivateKey(), d2i_TYPEPublicKey() and d2i_TYPEParams() into OSSL_DECODER terms much more smoothly. Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/13061) ----------------------------------------------------------------------- Summary of changes: crypto/encode_decode/decoder_pkey.c | 20 ++++++++++++-------- crypto/store/store_result.c | 3 ++- doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod | 13 ++++++++++--- include/crypto/decoder.h | 2 +- include/openssl/decoder.h | 3 ++- providers/implementations/storemgmt/file_store.c | 3 ++- test/endecode_test.c | 2 +- 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c index 2e07d0d7cc..75c491f4ac 100644 --- a/crypto/encode_decode/decoder_pkey.c +++ b/crypto/encode_decode/decoder_pkey.c @@ -188,6 +188,7 @@ static void decoder_clean_EVP_PKEY_construct_arg(void *construct_data) struct collected_data_st { struct decoder_EVP_PKEY_data_st *process_data; + const char *keytype; STACK_OF(OPENSSL_CSTRING) *names; OSSL_DECODER_CTX *ctx; @@ -198,6 +199,8 @@ static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) { struct collected_data_st *data = arg; + if (data->keytype != NULL && !EVP_KEYMGMT_is_a(keymgmt, data->keytype)) + return; if (data->error_occured) return; @@ -253,7 +256,7 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg) } int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, - EVP_PKEY **pkey, + EVP_PKEY **pkey, const char *keytype, OPENSSL_CTX *libctx, const char *propquery) { @@ -264,14 +267,14 @@ int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL || (data->process_data = OPENSSL_zalloc(sizeof(*data->process_data))) == NULL - || (data->process_data->keymgmts - = sk_EVP_KEYMGMT_new_null()) == NULL + || (data->process_data->keymgmts = sk_EVP_KEYMGMT_new_null()) == NULL || (data->names = sk_OPENSSL_CSTRING_new_null()) == NULL) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); goto err; } data->process_data->object = (void **)pkey; data->ctx = ctx; + data->keytype = keytype; /* First, find all keymgmts to form goals */ EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, data); @@ -320,10 +323,10 @@ int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, return ok; } -OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, - const char *input_type, - OPENSSL_CTX *libctx, - const char *propquery) +OSSL_DECODER_CTX * +OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, + const char *input_type, const char *keytype, + OPENSSL_CTX *libctx, const char *propquery) { OSSL_DECODER_CTX *ctx = NULL; @@ -332,7 +335,8 @@ OSSL_DECODER_CTX *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_setup_for_EVP_PKEY(ctx, pkey, libctx, propquery) + && ossl_decoder_ctx_setup_for_EVP_PKEY(ctx, pkey, keytype, + libctx, propquery) && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)) return ctx; diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c index a591ef23ec..8ba4f8880c 100644 --- a/crypto/store/store_result.c +++ b/crypto/store/store_result.c @@ -257,7 +257,8 @@ static EVP_PKEY *try_key_value(struct extracted_param_data_st *data, if (membio == NULL) return 0; - decoderctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pk, "DER", libctx, propq); + decoderctx = + OSSL_DECODER_CTX_new_by_EVP_PKEY(&pk, "DER", NULL, libctx, propq); (void)OSSL_DECODER_CTX_set_passphrase_cb(decoderctx, cb, cbarg); /* No error if this couldn't be decoded */ 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 4190c4232b..c57438072b 100644 --- a/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod +++ b/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod @@ -14,7 +14,8 @@ OSSL_DECODER_CTX_set_passphrase_cb #include <openssl/decoder.h> OSSL_DECODER_CTX * - OSSL_DECODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, const char *input_type, + OSSL_DECODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, + const char *input_type, const char *keytype, OPENSSL_CTX *libctx, const char *propquery); int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, @@ -44,8 +45,14 @@ 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)>. +which specifies a starting input type. NULL is valid input and signifies +that the decoder implementations will find out the input type on their own. +This is further explained in L<OSSL_DECODER_CTX_set_input_type(3)>. + +The search of decoder implementations can also be limited with I<keytype>, +which specifies the expected resulting keytype. NULL is valid input and +signifies that the decoder implementations will find out the keytype on +their own from the input they get. If no suitable decoder implementation is found, OSSL_DECODER_CTX_new_by_EVP_PKEY() still creates a B<OSSL_DECODER_CTX>, but diff --git a/include/crypto/decoder.h b/include/crypto/decoder.h index b465752971..f025b3ec37 100644 --- a/include/crypto/decoder.h +++ b/include/crypto/decoder.h @@ -32,7 +32,7 @@ int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, OSSL_DECODER_INSTANCE *di); int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, - EVP_PKEY **pkey, + EVP_PKEY **pkey, const char *keytype, OPENSSL_CTX *libctx, const char *propquery); diff --git a/include/openssl/decoder.h b/include/openssl/decoder.h index 3da4577437..66790f43c8 100644 --- a/include/openssl/decoder.h +++ b/include/openssl/decoder.h @@ -112,7 +112,8 @@ int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *in); * an implicit OSSL_DECODER_fetch(), suitable for the object of that type. */ OSSL_DECODER_CTX * -OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, const char *input_type, +OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, + const char *input_type, const char *keytype, OPENSSL_CTX *libctx, const char *propquery); # ifdef __cplusplus diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c index c194578937..c4b1de40d1 100644 --- a/providers/implementations/storemgmt/file_store.c +++ b/providers/implementations/storemgmt/file_store.c @@ -582,7 +582,8 @@ static int file_setup_decoders(struct file_ctx_st *ctx) * Since we're setting up our own constructor, we don't need to care * more than that... */ - if (!ossl_decoder_ctx_setup_for_EVP_PKEY(ctx->_.file.decoderctx, &dummy, + if (!ossl_decoder_ctx_setup_for_EVP_PKEY(ctx->_.file.decoderctx, + &dummy, NULL, libctx, ctx->_.file.propq) || !OSSL_DECODER_CTX_add_extra(ctx->_.file.decoderctx, libctx, ctx->_.file.propq)) { diff --git a/test/endecode_test.c b/test/endecode_test.c index 7f37a99a6d..70258afcc0 100644 --- a/test/endecode_test.c +++ b/test/endecode_test.c @@ -201,7 +201,7 @@ static int decode_EVP_PKEY_prov(void **object, void *encoded, long encoded_len, const unsigned char *upass = (const unsigned char *)pass; int ok = 0; - if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, NULL, + if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, NULL, NULL, NULL, NULL)) || (pass != NULL && !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))