]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Further decoder tuning possibly better perf
authorViktor Dukhovni <openssl-users@dukhovni.org>
Thu, 27 Feb 2025 17:17:08 +0000 (04:17 +1100)
committerGeert <geert@hendrickx.be>
Sat, 1 Mar 2025 15:04:09 +0000 (02:04 +1100)
- The decoder should consider fewer options based on
  more precise tracking of the desired input type
  (DER, PVK, MSBLOB), algorithm (RSA, EC, ...),
  input structure (SPKI, P8, ...).

How much this affects actual use-cases is harder to estimate, we'll just
have to run before/after perf tests.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26927)

14 files changed:
apps/lib/apps.c
crypto/encode_decode/decoder_lib.c
crypto/encode_decode/decoder_pkey.c
crypto/err/openssl.txt
crypto/pem/pem_err.c
crypto/pem/pvkfmt.c
crypto/store/store_result.c
engines/e_loader_attic.c
include/crypto/decoder.h
include/crypto/pem.h
include/openssl/pemerr.h
providers/implementations/storemgmt/file_store.c
providers/implementations/storemgmt/file_store_any2obj.c
test/endecode_test.c

index 85e5094b9e7967c2fa1bd61b7d386ab77d212816..b31b1b47e2f660a48f8fb2077d4f60a5d5f8813e 100644 (file)
@@ -898,6 +898,10 @@ static const char *format2string(int format)
         return "PEM";
     case FORMAT_ASN1:
         return "DER";
+    case FORMAT_PVK:
+        return "PVK";
+    case FORMAT_MSBLOB:
+        return "MSBLOB";
     }
     return NULL;
 }
index 32ec18594f6ae8637d3d34375dbfc87846425443..adfa196aa8286b8b7f0a14813fe01c28259672d0 100644 (file)
@@ -210,6 +210,34 @@ int OSSL_DECODER_CTX_set_input_structure(OSSL_DECODER_CTX *ctx,
     return 1;
 }
 
+OSSL_DECODER_INSTANCE *
+ossl_decoder_instance_new_forprov(OSSL_DECODER *decoder, void *provctx,
+                                  const char *input_structure)
+{
+    void *decoderctx;
+
+    if (!ossl_assert(decoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    decoderctx = decoder->newctx(provctx);
+    if (decoderctx == NULL)
+        return 0;
+    if (input_structure != NULL && decoder->set_ctx_params != NULL) {
+        OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+        params[0] =
+            OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
+                                             (char *)input_structure, 0);
+        if (!decoder->set_ctx_params(decoderctx, params)) {
+            decoder->freectx(decoderctx);
+            return 0;
+        }
+    }
+    return ossl_decoder_instance_new(decoder, decoderctx);
+}
+
 OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder,
                                                  void *decoderctx)
 {
@@ -448,15 +476,15 @@ static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg)
         if ((decoderctx = decoder->newctx(provctx)) == NULL)
             return;
 
-        if (data->ctx->input_structure != NULL) {
+        if (decoder->set_ctx_params != NULL
+            && data->ctx->input_structure != NULL) {
             OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
             const char *str = data->ctx->input_structure;
 
             params[0] =
                 OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
                                                  (char *)str, 0);
-            if (decoder->set_ctx_params != NULL
-                && !decoder->set_ctx_params(decoderctx, params)) {
+            if (!decoder->set_ctx_params(decoderctx, params)) {
                 decoder->freectx(decoderctx);
                 return;
             }
@@ -906,6 +934,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
             sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
         OSSL_DECODER *new_decoder =
             OSSL_DECODER_INSTANCE_get_decoder(new_decoder_inst);
+        const char *new_decoder_name = NULL;
         void *new_decoderctx =
             OSSL_DECODER_INSTANCE_get_decoder_ctx(new_decoder_inst);
         const char *new_input_type =
@@ -916,12 +945,13 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
                                                       &n_i_s_was_set);
 
         OSSL_TRACE_BEGIN(DECODER) {
+            new_decoder_name = OSSL_DECODER_get0_name(new_decoder);
             BIO_printf(trc_out,
                        "(ctx %p) %s [%u] Considering decoder instance %p (decoder %p):\n"
                        "    %s with %s\n",
                        (void *)new_data.ctx, LEVEL, (unsigned int)i,
                        (void *)new_decoder_inst, (void *)new_decoder,
-                       OSSL_DECODER_get0_name(new_decoder),
+                       new_decoder_name,
                        OSSL_DECODER_get0_properties(new_decoder));
         } OSSL_TRACE_END(DECODER);
 
@@ -1026,9 +1056,9 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
         /* Recurse */
         OSSL_TRACE_BEGIN(DECODER) {
             BIO_printf(trc_out,
-                       "(ctx %p) %s [%u] Running decoder instance %p\n",
+                       "(ctx %p) %s [%u] Running decoder instance %s (%p)\n",
                        (void *)new_data.ctx, LEVEL, (unsigned int)i,
-                       (void *)new_decoder_inst);
+                       new_decoder_name, (void *)new_decoder_inst);
         } OSSL_TRACE_END(DECODER);
 
         /*
@@ -1048,10 +1078,10 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
 
         OSSL_TRACE_BEGIN(DECODER) {
             BIO_printf(trc_out,
-                       "(ctx %p) %s [%u] Running decoder instance %p => %d"
+                       "(ctx %p) %s [%u] Running decoder instance %s (%p) => %d"
                        " (recursed further: %s, construct called: %s)\n",
                        (void *)new_data.ctx, LEVEL, (unsigned int)i,
-                       (void *)new_decoder_inst, ok,
+                       new_decoder_name, (void *)new_decoder_inst, ok,
                        new_data.flag_next_level_called ? "yes" : "no",
                        new_data.flag_construct_called ? "yes" : "no");
         } OSSL_TRACE_END(DECODER);
index def735b874a63ba7a9a7dc18cfd25fc1ad29a72c..d3ba7fd16b495b0384aa29cc529ef3dc9ec81620 100644 (file)
@@ -252,6 +252,20 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
         return;
     }
 
+    /*
+     * Input types must be compatible, but we must accept DER encoders when the
+     * start input type is "PEM".
+     */
+    if (data->ctx->start_input_type != NULL
+        && di->input_type != NULL
+        && OPENSSL_strcasecmp(di->input_type, data->ctx->start_input_type) != 0
+        && (OPENSSL_strcasecmp(di->input_type, "DER") != 0
+            || OPENSSL_strcasecmp(data->ctx->start_input_type, "PEM") != 0)) {
+        /* Mismatch is not an error, continue. */
+        ossl_decoder_instance_free(di);
+        return;
+    }
+
     OSSL_TRACE_BEGIN(DECODER) {
         BIO_printf(trc_out,
                    "(ctx %p) Checking out decoder %p:\n"
index 4e36b787b76a9b5e4470ffee0ae84e3d23a8f361..17981605c02861f67c7d7cc776d7d739664208eb 100644 (file)
@@ -966,6 +966,7 @@ PEM_R_UNSUPPORTED_CIPHER:113:unsupported cipher
 PEM_R_UNSUPPORTED_ENCRYPTION:114:unsupported encryption
 PEM_R_UNSUPPORTED_KEY_COMPONENTS:126:unsupported key components
 PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE:110:unsupported public key type
+PEM_R_UNSUPPORTED_PVK_KEY_TYPE:133:unsupported pvk key type
 PKCS12_R_CALLBACK_FAILED:115:callback failed
 PKCS12_R_CANT_PACK_STRUCTURE:100:can't pack structure
 PKCS12_R_CONTENT_TYPE_NOT_DATA:121:content type not data
index 5fa9fc09bec7c9228f91c3b09f6dead2d69ae150..e5e5facfb468a044124683cd9ee74cc9c70620bb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -59,6 +59,8 @@ static const ERR_STRING_DATA PEM_str_reasons[] = {
     "unsupported key components"},
     {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
     "unsupported public key type"},
+    {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_PVK_KEY_TYPE),
+     "unsupported pvk key type"},
     {0, NULL}
 };
 
index ed7905661bbfe5379535cdb5e45e4a26a057a967..903b09e2477b7477960b12afe252b201dac0af0a 100644 (file)
@@ -758,7 +758,7 @@ int i2b_PublicKey_bio(BIO *out, const EVP_PKEY *pk)
 }
 
 int ossl_do_PVK_header(const unsigned char **in, unsigned int length,
-                       int skip_magic,
+                       int skip_magic, int *isdss,
                        unsigned int *psaltlen, unsigned int *pkeylen)
 {
     const unsigned char *p = *in;
@@ -782,9 +782,26 @@ int ossl_do_PVK_header(const unsigned char **in, unsigned int length,
     }
     /* Skip reserved */
     p += 4;
-    /*
-     * keytype =
-     */ read_ledword(&p);
+    /* Check the key type */
+    switch (read_ledword(&p)) {
+    case MS_KEYTYPE_KEYX:
+        if (*isdss == 1) {
+            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_RSA_KEY_BLOB);
+            return 0;
+        }
+        *isdss = 0;
+        break;
+    case MS_KEYTYPE_SIGN:
+        if (*isdss == 0) {
+            ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_DSS_KEY_BLOB);
+            return 0;
+        }
+        *isdss = 1;
+        break;
+    default:
+        ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PVK_KEY_TYPE);
+        return 0;
+    }
     is_encrypted = read_ledword(&p);
     *psaltlen = read_ledword(&p);
     *pkeylen = read_ledword(&p);
@@ -945,7 +962,7 @@ static void *do_PVK_key_bio(BIO *in, pem_password_cb *cb, void *u,
     }
     p = pvk_hdr;
 
-    if (!ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen))
+    if (!ossl_do_PVK_header(&p, 24, 0, isdss, &saltlen, &keylen))
         return 0;
     buflen = (int)keylen + saltlen;
     buf = OPENSSL_malloc(buflen);
index 517495d33456b31711f71a4853c8ce8e70670988..cc551d719584742bb220df9d91e87684867bd274 100644 (file)
@@ -63,6 +63,7 @@
 struct extracted_param_data_st {
     int object_type;
     const char *data_type;
+    const char *input_type;
     const char *data_structure;
     const char *utf8_data;
     const void *octet_data;
@@ -115,6 +116,10 @@ int ossl_store_handle_load_result(const OSSL_PARAM params[], void *arg)
     if (p != NULL
         && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.data_structure))
         return 0;
+    p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_INPUT_TYPE);
+    if (p != NULL
+        && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.input_type))
+        return 0;
     p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE);
     if (p != NULL && !OSSL_PARAM_get_octet_string_ptr(p, &helper_data.ref,
                                                       &helper_data.ref_size))
@@ -288,7 +293,7 @@ static EVP_PKEY *try_key_value(struct extracted_param_data_st *data,
     }
 
     decoderctx =
-        OSSL_DECODER_CTX_new_for_pkey(&pk, NULL, data->data_structure,
+        OSSL_DECODER_CTX_new_for_pkey(&pk, data->input_type, data->data_structure,
                                       data->data_type, selection, libctx,
                                       propq);
     (void)OSSL_DECODER_CTX_set_passphrase_cb(decoderctx, cb, cbarg);
index 154f36cbdd16444a85007d4ff7eeb2de81872921..2d58d3c929cae8914240ddc099db5829cbb5771d 100644 (file)
@@ -1368,12 +1368,13 @@ static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method,
 
     {
         unsigned int saltlen = 0, keylen = 0;
+        int isdss = -1;
         unsigned char peekbuf[24] = { 0, };
         const unsigned char *p = peekbuf;
 
         if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0)
             return 0;
-        if (!ossl_do_PVK_header(&p, sizeof(peekbuf), 0, &saltlen, &keylen))
+        if (!ossl_do_PVK_header(&p, sizeof(peekbuf), 0, &isdss, &saltlen, &keylen))
             return 0;
     }
 
index e4195786f505ab91e29837c809a6af37a2921f52..a962af675ae61273791cc2455c1bfce2ae805543 100644 (file)
@@ -23,6 +23,9 @@ void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
                                   OSSL_PROVIDER *prov);
 
 OSSL_DECODER_INSTANCE *
+ossl_decoder_instance_new_forprov(OSSL_DECODER *decoder, void *provctx,
+                                  const char *input_structure);
+OSSL_DECODER_INSTANCE *
 ossl_decoder_instance_new(OSSL_DECODER *decoder, void *decoderctx);
 void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst);
 int ossl_decoder_ctx_get_harderr(const OSSL_DECODER_CTX *ctx);
index 2cb4253d6a1462e3c7acab61d8da920428747eaa..cf4c117ea974959e5e9665a4a87f4d790f6eb581 100644 (file)
@@ -24,7 +24,7 @@ int ossl_do_blob_header(const unsigned char **in, unsigned int length,
                         int *pisdss, int *pispub);
 unsigned int ossl_blob_length(unsigned bitlen, int isdss, int ispub);
 int ossl_do_PVK_header(const unsigned char **in, unsigned int length,
-                       int skip_magic,
+                       int skip_magic, int *isdss,
                        unsigned int *psaltlen, unsigned int *pkeylen);
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 #  ifndef OPENSSL_NO_DSA
index 18f6d9ef4cfda759524fbd8d6b68fd998e6174f0..3530775bdc634460eeaad4b0234e8397f06fffa2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -54,5 +54,6 @@
 # define PEM_R_UNSUPPORTED_ENCRYPTION                     114
 # define PEM_R_UNSUPPORTED_KEY_COMPONENTS                 126
 # define PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE                110
+# define PEM_R_UNSUPPORTED_PVK_KEY_TYPE                   133
 
 #endif
index b1b32b56f61570aa7356577e482f37e998059788..36b6e26b6bc99dfe7b2b9d237a499b364eb7fd23 100644 (file)
@@ -416,6 +416,7 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
 {
     OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx);
     const OSSL_ALGORITHM *to_algo = NULL;
+    const char *input_structure = NULL;
     int ok = 0;
 
     /* Setup for this session, so only if not already done */
@@ -440,8 +441,9 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
          */
         switch (ctx->expected_type) {
         case OSSL_STORE_INFO_PUBKEY:
+            input_structure = "SubjectPublicKeyInfo";
             if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx,
-                                                      "SubjectPublicKeyInfo")) {
+                                                      input_structure)) {
                 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
                 goto err;
             }
@@ -456,22 +458,25 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
              * might then get a password prompt for a key when reading only
              * certs from a file.
              */
+            input_structure = "EncryptedPrivateKeyInfo";
             if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx,
-                                                      "EncryptedPrivateKeyInfo")) {
+                                                      input_structure)) {
                 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
                 goto err;
             }
             break;
         case OSSL_STORE_INFO_CERT:
+            input_structure = "Certificate";
             if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx,
-                                                      "Certificate")) {
+                                                      input_structure)) {
                 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
                 goto err;
             }
             break;
         case OSSL_STORE_INFO_CRL:
+            input_structure = "CertificateList";
             if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx,
-                                                      "CertificateList")) {
+                                                      input_structure)) {
                 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
                 goto err;
             }
@@ -485,6 +490,7 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
              to_algo++) {
             OSSL_DECODER *to_obj = NULL;
             OSSL_DECODER_INSTANCE *to_obj_inst = NULL;
+            const char *input_type;
 
             /*
              * Create the internal last resort decoder implementation
@@ -494,10 +500,25 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
              */
             to_obj = ossl_decoder_from_algorithm(0, to_algo, NULL);
             if (to_obj != NULL)
-                to_obj_inst = ossl_decoder_instance_new(to_obj, ctx->provctx);
+                to_obj_inst =
+                    ossl_decoder_instance_new_forprov(to_obj, ctx->provctx,
+                                                      input_structure);
             OSSL_DECODER_free(to_obj);
             if (to_obj_inst == NULL)
                 goto err;
+            /*
+             * The input type has to match unless, the input type is PEM
+             * and the decoder input type is DER, in which case we'll pick
+             * up additional decoders.
+             */
+            input_type = OSSL_DECODER_INSTANCE_get_input_type(to_obj_inst);
+            if (ctx->_.file.input_type != NULL
+                && OPENSSL_strcasecmp(input_type, ctx->_.file.input_type) != 0
+                && (OPENSSL_strcasecmp(ctx->_.file.input_type, "PEM") != 0
+                    || OPENSSL_strcasecmp(input_type, "der") != 0)) {
+                ossl_decoder_instance_free(to_obj_inst);
+                continue;
+            }
 
             if (!ossl_decoder_ctx_add_decoder_inst(ctx->_.file.decoderctx,
                                                    to_obj_inst)) {
index b8fa591085600ac0649432ddfc9579a55707c6fc..b995d4268794ce70f6da8f5f94fc177c58b0c2b9 100644 (file)
@@ -32,6 +32,7 @@
 #include <openssl/asn1err.h>
 #include <openssl/params.h>
 #include "internal/asn1.h"
+#include "internal/sizes.h"
 #include "crypto/pem.h"          /* For internal PVK and "blob" headers */
 #include "prov/bio.h"
 #include "file_store_local.h"
 static OSSL_FUNC_decoder_newctx_fn any2obj_newctx;
 static OSSL_FUNC_decoder_freectx_fn any2obj_freectx;
 
+struct any2obj_ctx_st {
+    PROV_CTX *provctx;
+    char data_structure[OSSL_MAX_CODEC_STRUCT_SIZE];
+};
+
 static void *any2obj_newctx(void *provctx)
 {
-    return provctx;
+    struct any2obj_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx != NULL)
+        ctx->provctx = provctx;
+    return ctx;
 }
 
-static void any2obj_freectx(void *vctx)
+static void any2obj_freectx(void *ctx)
 {
+    OPENSSL_free(ctx);
 }
 
-static int any2obj_decode_final(void *provctx, int objtype, BUF_MEM *mem,
+static int any2obj_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    struct any2obj_ctx_st *ctx = vctx;
+    const OSSL_PARAM *p;
+    char *str;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_STRUCTURE);
+    str = ctx->data_structure;
+    if (p != NULL
+        && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->data_structure)))
+        return 0;
+
+    return 1;
+}
+
+static const OSSL_PARAM *any2obj_settable_ctx_params(ossl_unused void *provctx)
+{
+    static const OSSL_PARAM settables[] = {
+        OSSL_PARAM_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, NULL, 0),
+        OSSL_PARAM_END
+    };
+    return settables;
+}
+
+static int any2obj_decode_final(void *vctx, int objtype, const char *input_type,
+                                const char *data_type, BUF_MEM *mem,
                                 OSSL_CALLBACK *data_cb, void *data_cbarg)
 {
+    struct any2obj_ctx_st *ctx = vctx;
     /*
      * 1 indicates that we successfully decoded something, or not at all.
      * Ending up "empty handed" is not an error.
@@ -64,14 +101,21 @@ static int any2obj_decode_final(void *provctx, int objtype, BUF_MEM *mem,
     int ok = 1;
 
     if (mem != NULL) {
-        OSSL_PARAM params[3];
-
-        params[0] =
-            OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype);
-        params[1] =
-            OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
-                                              mem->data, mem->length);
-        params[2] = OSSL_PARAM_construct_end();
+        OSSL_PARAM params[6], *p = params;
+
+        if (data_type != NULL)
+            *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
+                                                    (char *)data_type, 0);
+        if (input_type != NULL)
+            *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_INPUT_TYPE,
+                                                    (char *)input_type, 0);
+        if (*ctx->data_structure != '\0')
+            *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
+                                                    (char *)ctx->data_structure, 0);
+        *p++ = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype);
+        *p++ = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
+                                                 mem->data, mem->length);
+        *p = OSSL_PARAM_construct_end();
 
         ok = data_cb(params, data_cbarg);
         BUF_MEM_free(mem);
@@ -80,11 +124,12 @@ static int any2obj_decode_final(void *provctx, int objtype, BUF_MEM *mem,
 }
 
 static OSSL_FUNC_decoder_decode_fn der2obj_decode;
-static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
+static int der2obj_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
                           OSSL_CALLBACK *data_cb, void *data_cbarg,
                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
-    BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
+    struct any2obj_ctx_st *ctx = vctx;
+    BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin);
     BUF_MEM *mem = NULL;
     int ok;
 
@@ -101,16 +146,17 @@ static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
     BIO_free(in);
 
     /* any2obj_decode_final() frees |mem| for us */
-    return any2obj_decode_final(provctx, OSSL_OBJECT_UNKNOWN, mem,
+    return any2obj_decode_final(ctx, OSSL_OBJECT_UNKNOWN, NULL, NULL, mem,
                                 data_cb, data_cbarg);
 }
 
 static OSSL_FUNC_decoder_decode_fn msblob2obj_decode;
-static int msblob2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
+static int msblob2obj_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
                              OSSL_CALLBACK *data_cb, void *data_cbarg,
                              OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
-    BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
+    struct any2obj_ctx_st *ctx = vctx;
+    BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin);
     BUF_MEM *mem = NULL;
     size_t mem_len = 0, mem_want;
     const unsigned char *p;
@@ -165,7 +211,8 @@ static int msblob2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
     }
 
     /* any2obj_decode_final() frees |mem| for us */
-    return any2obj_decode_final(provctx, OSSL_OBJECT_PKEY, mem,
+    return any2obj_decode_final(ctx, OSSL_OBJECT_PKEY, "msblob",
+                                isdss ? "DSA" : "RSA", mem,
                                 data_cb, data_cbarg);
 
  err:
@@ -175,16 +222,17 @@ static int msblob2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
 }
 
 static OSSL_FUNC_decoder_decode_fn pvk2obj_decode;
-static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
+static int pvk2obj_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
                              OSSL_CALLBACK *data_cb, void *data_cbarg,
                              OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
-    BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
+    struct any2obj_ctx_st *ctx = vctx;
+    BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin);
     BUF_MEM *mem = NULL;
     size_t mem_len = 0, mem_want;
     const unsigned char *p;
     unsigned int saltlen, keylen;
-    int ok = 0;
+    int ok = 0, isdss = -1;
 
     if (in == NULL)
         goto err;
@@ -206,7 +254,7 @@ static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
 
     ERR_set_mark();
     p = (unsigned char *)&mem->data[0];
-    ok = ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen) > 0;
+    ok = ossl_do_PVK_header(&p, 24, 0, &isdss, &saltlen, &keylen) > 0;
     ERR_pop_to_mark();
     if (!ok)
         goto next;
@@ -232,7 +280,8 @@ static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
     }
 
     /* any2obj_decode_final() frees |mem| for us */
-    return any2obj_decode_final(provctx, OSSL_OBJECT_PKEY, mem,
+    return any2obj_decode_final(ctx, OSSL_OBJECT_PKEY, "pvk",
+                                ok ? (isdss ? "DSA" : "RSA") : NULL, mem,
                                 data_cb, data_cbarg);
 
  err:
@@ -246,6 +295,10 @@ static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
         { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))any2obj_newctx },        \
         { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))any2obj_freectx },      \
         { OSSL_FUNC_DECODER_DECODE, (void (*)(void))fromtype##2obj_decode }, \
+        { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS,                             \
+          (void (*)(void))any2obj_settable_ctx_params },                     \
+        { OSSL_FUNC_DECODER_SET_CTX_PARAMS,                                  \
+          (void (*)(void))any2obj_set_ctx_params },                          \
         OSSL_DISPATCH_END                                                    \
     }
 
index 19b31302d9abb041eb2135da2ac723b1aa6b72f6..602026505f73d390d252f107e0565bdaad58992c 100644 (file)
@@ -702,9 +702,9 @@ static int check_PVK(const char *file, const int line,
 {
     const unsigned char *in = data;
     unsigned int saltlen = 0, keylen = 0;
-    int ok = ossl_do_PVK_header(&in, data_len, 0, &saltlen, &keylen);
+    int isdss = -1;
 
-    return ok;
+    return ossl_do_PVK_header(&in, data_len, 0, &isdss, &saltlen, &keylen);
 }
 
 static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)