[openssl] master update

Richard Levitte levitte at openssl.org
Sun Sep 5 19:36:38 UTC 2021


The branch master has been updated
       via  d4458e59f62b0d102069e53da41f1d5305a66912 (commit)
       via  0195cdd28fde7d0897e368fdcd4e92509425faad (commit)
       via  602bfb8b98125f6745cd40dbc5fce9614ae5e418 (commit)
       via  821b3956ec698927281a5b29c55cd87eb7b2793d (commit)
       via  98408852c167d895a662dcda824fd5170cad3f7d (commit)
       via  73dd5d67c506cfeb9bf6183f0c19832c7d3f174d (commit)
      from  d7b5f06ede163851d39f5a8b507bd0670deeaa21 (commit)


- Log -----------------------------------------------------------------
commit d4458e59f62b0d102069e53da41f1d5305a66912
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Sep 3 15:00:47 2021 +0200

    test/recipes/25-test_verify.t: Add a couple of tests of mixed PEM files
    
    Fixes #16224
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16466)

commit 0195cdd28fde7d0897e368fdcd4e92509425faad
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Sep 1 22:18:45 2021 +0200

    ENCODER PROV: Add encoders with EncryptedPrivateKeyInfo output
    
    Since EncryptedPrivateKeyInfo is a recognised structure, it's
    reasonable to think that someone might want to specify it.
    
    To be noted is that if someone specifies the structure PrivateKeyInfo
    but has also passed a passphrase callback, the result will still
    become a EncryptedPrivateKeyInfo structure.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16466)

commit 602bfb8b98125f6745cd40dbc5fce9614ae5e418
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Sep 1 17:34:38 2021 +0200

    Adjust test/endecoder_test.c
    
    The protected tests need to specify the structure EncryptedPrivateKeyInfo
    rather than PrivateKeyInfo, since that's the outermost structure.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16466)

commit 821b3956ec698927281a5b29c55cd87eb7b2793d
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Aug 30 13:22:18 2021 +0200

    OSSL_STORE 'file:' scheme: Set input structure for certificates and CRLs
    
    When the user expects to load a certificate or a CRL through the
    OSSL_STORE loading function, the 'file:' implementation sets the
    corresponding structure names in the internal decoder context.
    This is especially geared for PEM files, which often contain a mix of
    objects, and password prompting should be avoided for objects that
    need them, but aren't what the caller is looking for.
    
    Fixes #16224
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16466)

commit 98408852c167d895a662dcda824fd5170cad3f7d
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Aug 30 13:19:30 2021 +0200

    PEM to DER decoder: Specify object type and data structure more consistently
    
    The data structure wasn't given for recognised certificates or CRLs.
    It's better, though, to specify it for those objects as well, so they
    can be used to filter what actually gets decoded, which will be
    helpful for our OSSL_STORE 'file:' scheme implementation.
    
    Fixes #16224
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16466)

commit 73dd5d67c506cfeb9bf6183f0c19832c7d3f174d
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Aug 30 13:16:42 2021 +0200

    DECODER: check the first decoded structure name against user given structure
    
    In a chain of decoders, the first that specifies an input structure
    gets it compared with the structure specified by the user, if there is
    one.  If they aren't the same, that decoder is skipped.
    
    Because the first structure can appear anywhere along a chain of
    decoders, not just the decoders associated with the resulting OpenSSL
    type, the code that checked the structure name when building up the
    chain of decoders is removed.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16466)

-----------------------------------------------------------------------

Summary of changes:
 crypto/encode_decode/decoder_lib.c                 | 23 ++++++++++++++
 crypto/encode_decode/decoder_pkey.c                | 35 ---------------------
 providers/encoders.inc                             | 29 +++++++++++++++--
 .../implementations/encode_decode/decode_pem2der.c |  9 +++---
 .../implementations/encode_decode/encode_key2any.c | 36 +++++++++++++++++++++-
 .../implementations/include/prov/implementations.h | 22 +++++++++++++
 providers/implementations/storemgmt/file_store.c   | 25 +++++++++++++++
 test/endecode_test.c                               |  4 +--
 test/recipes/25-test_verify.t                      | 33 +++++++++++++++++++-
 9 files changed, 170 insertions(+), 46 deletions(-)

diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
index 938f97c282..10a38b6f82 100644
--- a/crypto/encode_decode/decoder_lib.c
+++ b/crypto/encode_decode/decoder_lib.c
@@ -38,6 +38,7 @@ struct decoder_process_data_st {
      */
     unsigned int flag_next_level_called : 1;
     unsigned int flag_construct_called : 1;
+    unsigned int flag_input_structure_checked : 1;
 };
 
 static int decoder_process(const OSSL_PARAM params[], void *arg);
@@ -904,6 +905,26 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
             continue;
         }
 
+        /*
+         * If the decoder we're currently considering specifies a structure,
+         * and this check hasn't already been done earlier in this chain of
+         * decoder_process() calls, check that it matches the user provided
+         * input structure, if one is given.
+         */
+        if (!data->flag_input_structure_checked
+            && ctx->input_structure != NULL
+            && new_input_structure != NULL) {
+            data->flag_input_structure_checked = 1;
+            if (strcasecmp(new_input_structure, ctx->input_structure) != 0) {
+                OSSL_TRACE_BEGIN(DECODER) {
+                    BIO_printf(trc_out,
+                               "(ctx %p) %s [%u] the previous decoder's data structure doesn't match the input structure given by the user, skipping...\n",
+                               (void *)new_data.ctx, LEVEL, (unsigned int)i);
+                } OSSL_TRACE_END(DECODER);
+                continue;
+            }
+        }
+
         /*
          * Checking the return value of BIO_reset() or BIO_seek() is unsafe.
          * Furthermore, BIO_reset() is unsafe to use if the source BIO happens
@@ -933,6 +954,8 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
         ERR_set_mark();
 
         new_data.current_decoder_inst_index = i;
+        new_data.flag_input_structure_checked
+            = data->flag_input_structure_checked;
         ok = new_decoder->decode(new_decoderctx, cbio,
                                  new_data.ctx->selection,
                                  decoder_process, &new_data,
diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c
index edbea4face..475117a463 100644
--- a/crypto/encode_decode/decoder_pkey.c
+++ b/crypto/encode_decode/decoder_pkey.c
@@ -215,32 +215,6 @@ static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg)
     }
 }
 
-/*
- * The input structure check is only done on the initial decoder
- * implementations.
- */
-static int 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;
-}
-
 struct collect_decoder_data_st {
     STACK_OF(OPENSSL_CSTRING) *names;
     OSSL_DECODER_CTX *ctx;
@@ -310,15 +284,6 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg)
                            OSSL_DECODER_get0_properties(decoder));
             } OSSL_TRACE_END(DECODER);
 
-            if (!decoder_check_input_structure(data->ctx, di)) {
-                OSSL_TRACE_BEGIN(DECODER) {
-                    BIO_printf(trc_out,
-                               "    REJECTED: not the desired input structure\n");
-                } OSSL_TRACE_END(DECODER);
-                ossl_decoder_instance_free(di);
-                /* Not a fatal error. Just return */
-                return;
-            }
             if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) {
                 ossl_decoder_instance_free(di);
                 data->error_occurred = 1;
diff --git a/providers/encoders.inc b/providers/encoders.inc
index 193a9175a7..95e287c8b9 100644
--- a/providers/encoders.inc
+++ b/providers/encoders.inc
@@ -15,6 +15,7 @@
 #define ENCODER_STRUCTURE_type_specific_params          "type-specific"
 #define ENCODER_STRUCTURE_type_specific                 "type-specific"
 #define ENCODER_STRUCTURE_type_specific_no_pub          "type-specific"
+#define ENCODER_STRUCTURE_EncryptedPrivateKeyInfo       "EncryptedPrivateKeyInfo"
 #define ENCODER_STRUCTURE_PrivateKeyInfo                "PrivateKeyInfo"
 #define ENCODER_STRUCTURE_SubjectPublicKeyInfo          "SubjectPublicKeyInfo"
 #define ENCODER_STRUCTURE_DH                            "dh"
@@ -127,28 +128,36 @@ ENCODER("DSA", dsa, yes, pvk),
 #endif
 
 /*
- * Entries for PKCS#8 (PrivateKeyInfo) and SubjectPublicKeyInfo.
- * The "der" ones are added convenience for any user that wants to use
- * OSSL_ENCODER directly.
+ * Entries for encrypted PKCS#8 (EncryptedPrivateKeyInfo), unencrypted PKCS#8
+ * (PrivateKeyInfo) and SubjectPublicKeyInfo.  The "der" ones are added
+ * convenience for any user that wants to use OSSL_ENCODER directly.
  * The "pem" ones also support PEM_write_bio_PrivateKey() and
  * PEM_write_bio_PUBKEY().
  */
+ENCODER_w_structure("RSA", rsa, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("RSA", rsa, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("RSA", rsa, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("RSA", rsa, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("RSA", rsa, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("RSA", rsa, yes, pem, SubjectPublicKeyInfo),
 
+ENCODER_w_structure("RSA-PSS", rsapss, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("RSA-PSS", rsapss, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("RSA-PSS", rsapss, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, SubjectPublicKeyInfo),
 
 #ifndef OPENSSL_NO_DH
+ENCODER_w_structure("DH", dh, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("DH", dh, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("DH", dh, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("DH", dh, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("DH", dh, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("DH", dh, yes, pem, SubjectPublicKeyInfo),
 
+ENCODER_w_structure("DHX", dhx, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("DHX", dhx, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("DHX", dhx, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("DHX", dhx, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("DHX", dhx, yes, der, SubjectPublicKeyInfo),
@@ -156,6 +165,8 @@ ENCODER_w_structure("DHX", dhx, yes, pem, SubjectPublicKeyInfo),
 #endif
 
 #ifndef OPENSSL_NO_DSA
+ENCODER_w_structure("DSA", dsa, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("DSA", dsa, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("DSA", dsa, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("DSA", dsa, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("DSA", dsa, yes, der, SubjectPublicKeyInfo),
@@ -163,32 +174,44 @@ ENCODER_w_structure("DSA", dsa, yes, pem, SubjectPublicKeyInfo),
 #endif
 
 #ifndef OPENSSL_NO_EC
+ENCODER_w_structure("EC", ec, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("EC", ec, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("EC", ec, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("EC", ec, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("EC", ec, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("EC", ec, yes, pem, SubjectPublicKeyInfo),
 
+ENCODER_w_structure("X25519", x25519, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("X25519", x25519, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("X25519", x25519, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("X25519", x25519, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("X25519", x25519, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("X25519", x25519, yes, pem, SubjectPublicKeyInfo),
 
+ENCODER_w_structure("X448", x448, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("X448", x448, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("X448", x448, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("X448", x448, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("X448", x448, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("X448", x448, yes, pem, SubjectPublicKeyInfo),
 
+ENCODER_w_structure("ED25519", ed25519, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ED25519", ed25519, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("ED25519", ed25519, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("ED25519", ed25519, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("ED25519", ed25519, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("ED25519", ed25519, yes, pem, SubjectPublicKeyInfo),
 
+ENCODER_w_structure("ED448", ed448, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ED448", ed448, yes, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, pem, SubjectPublicKeyInfo),
 
 # ifndef OPENSSL_NO_SM2
+ENCODER_w_structure("SM2", sm2, no, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("SM2", sm2, no, pem, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("SM2", sm2, no, der, PrivateKeyInfo),
 ENCODER_w_structure("SM2", sm2, no, pem, PrivateKeyInfo),
 ENCODER_w_structure("SM2", sm2, no, der, SubjectPublicKeyInfo),
diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c
index 5db3689f30..6c537d26ae 100644
--- a/providers/implementations/encode_decode/decode_pem2der.c
+++ b/providers/implementations/encode_decode/decode_pem2der.c
@@ -123,10 +123,10 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
          * though there is no provider interface to handle such objects, yet.
          * However, this is beneficial for the OSSL_STORE result handler.
          */
-        { PEM_STRING_X509, OSSL_OBJECT_CERT, NULL, NULL },
-        { PEM_STRING_X509_TRUSTED, OSSL_OBJECT_CERT, NULL, NULL },
-        { PEM_STRING_X509_OLD, OSSL_OBJECT_CERT, NULL, NULL },
-        { PEM_STRING_X509_CRL, OSSL_OBJECT_CRL, NULL, NULL }
+        { PEM_STRING_X509, OSSL_OBJECT_CERT, NULL, "Certificate" },
+        { PEM_STRING_X509_TRUSTED, OSSL_OBJECT_CERT, NULL, "Certificate" },
+        { PEM_STRING_X509_OLD, OSSL_OBJECT_CERT, NULL, "Certificate" },
+        { PEM_STRING_X509_CRL, OSSL_OBJECT_CRL, NULL, "CertificateList" }
     };
     struct pem2der_ctx_st *ctx = vctx;
     char *pem_name = NULL, *pem_header = NULL;
@@ -178,6 +178,7 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
         char *data_type = (char *)pem_name_map[i].data_type;
         char *data_structure = (char *)pem_name_map[i].data_structure;
 
+        objtype = pem_name_map[i].object_type;
         if (data_type != NULL)
             *p++ =
                 OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c
index 855866cbfe..f142f2b242 100644
--- a/providers/implementations/encode_decode/encode_key2any.c
+++ b/providers/implementations/encode_decode/encode_key2any.c
@@ -167,7 +167,6 @@ static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid,
  * key_to_epki_* produce encoded output with the private key data in a
  * EncryptedPrivateKeyInfo structure (defined by PKCS#8).  They require
  * that there's an intent to encrypt, anything else is an error.
- * They are currently only called from the corresponding key_to_pki_ function.
  *
  * key_to_pki_* primarly produce encoded output with the private key data
  * in a PrivateKeyInfo structure (also defined by PKCS#8).  However, if
@@ -510,6 +509,8 @@ static int dh_pki_priv_to_der(const void *dh, unsigned char **pder)
     return ret;
 }
 
+# define dh_epki_priv_to_der dh_pki_priv_to_der
+
 static int dh_type_specific_params_to_der(const void *dh, unsigned char **pder)
 {
     if (DH_test_flags(dh, DH_FLAG_TYPE_DHX))
@@ -623,6 +624,8 @@ static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder)
     return ret;
 }
 
+# define dsa_epki_priv_to_der dsa_pki_priv_to_der
+
 # define dsa_type_specific_priv_to_der   (i2d_of_void *)i2d_DSAPrivateKey
 # define dsa_type_specific_pub_to_der    (i2d_of_void *)i2d_DSAPublicKey
 # define dsa_type_specific_params_to_der (i2d_of_void *)i2d_DSAparams
@@ -721,6 +724,8 @@ static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder)
     return ret; /* return the length of the der encoded data */
 }
 
+# define ec_epki_priv_to_der ec_pki_priv_to_der
+
 # define ec_type_specific_params_to_der (i2d_of_void *)i2d_ECParameters
 # define ec_type_specific_pub_to_der    (i2d_of_void *)i2o_ECPublicKey
 # define ec_type_specific_priv_to_der   (i2d_of_void *)i2d_ECPrivateKey
@@ -786,6 +791,8 @@ static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder)
     return keybloblen;
 }
 
+# define ecx_epki_priv_to_der ecx_pki_priv_to_der
+
 /*
  * ED25519, ED448, X25519 and X448 only has PKCS#8 / SubjectPublicKeyInfo
  * representation, so we don't define ecx_type_specific_[priv,pub,params]_to_der.
@@ -889,6 +896,7 @@ static int prepare_rsa_params(const void *rsa, int nid, int save,
  * field as well as the SubjectPublicKeyInfo |subjectPublicKey| field.
  */
 #define rsa_pki_priv_to_der             rsa_type_specific_priv_to_der
+#define rsa_epki_priv_to_der            rsa_type_specific_priv_to_der
 #define rsa_spki_pub_to_der             rsa_type_specific_pub_to_der
 #define rsa_type_specific_priv_to_der   (i2d_of_void *)i2d_RSAPrivateKey
 #define rsa_type_specific_pub_to_der    (i2d_of_void *)i2d_RSAPublicKey
@@ -1116,6 +1124,10 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout,
 #define DO_PrivateKeyInfo(impl, type, output)                               \
     DO_PRIVATE_KEY(impl, type, pki, output)
 
+#define DO_EncryptedPrivateKeyInfo_selection_mask DO_PRIVATE_KEY_selection_mask
+#define DO_EncryptedPrivateKeyInfo(impl, type, output)                      \
+    DO_PRIVATE_KEY(impl, type, epki, output)
+
 /* SubjectPublicKeyInfo is a structure for public keys only */
 #define DO_SubjectPublicKeyInfo_selection_mask DO_PUBLIC_KEY_selection_mask
 #define DO_SubjectPublicKeyInfo(impl, type, output)                         \
@@ -1328,53 +1340,75 @@ MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, pem);
  * For PEM, these are expected to be used by PEM_write_bio_PrivateKey(),
  * PEM_write_bio_PUBKEY() and PEM_write_bio_Parameters().
  */
+MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, der);
 MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, pem);
 MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, pem);
+MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, der);
 MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, pem);
 MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, pem);
 #ifndef OPENSSL_NO_DH
+MAKE_ENCODER(dh, dh, EVP_PKEY_DH, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(dh, dh, EVP_PKEY_DH, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, der);
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, pem);
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, pem);
+MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, der);
 MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, pem);
 MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, pem);
 #endif
 #ifndef OPENSSL_NO_DSA
+MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, der);
 MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, pem);
 MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, pem);
 #endif
 #ifndef OPENSSL_NO_EC
+MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, der);
 MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, pem);
 MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem);
 # ifndef OPENSSL_NO_SM2
+MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, der);
 MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, pem);
 MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem);
 # endif
+MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, der);
 MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, pem);
 MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, pem);
+MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der);
 MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem);
 MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem);
+MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, der);
 MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, pem);
 MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, pem);
+MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der);
 MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem);
 MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der);
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index 8bdd491d0d..73e1823742 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -327,6 +327,8 @@ extern const OSSL_DISPATCH ossl_rsa_asym_kem_functions[];
 /* Encoders */
 extern const OSSL_DISPATCH ossl_rsa_to_PKCS1_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_PKCS1_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsa_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsa_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_RSA_der_encoder_functions[];
@@ -341,6 +343,8 @@ extern const OSSL_DISPATCH ossl_rsa_to_type_specific_keypair_pem_encoder_functio
 
 extern const OSSL_DISPATCH ossl_rsapss_to_PKCS1_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_PKCS1_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsapss_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsapss_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -351,6 +355,8 @@ extern const OSSL_DISPATCH ossl_dh_to_DH_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_DH_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_PKCS3_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_PKCS3_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dh_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dh_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -361,6 +367,8 @@ extern const OSSL_DISPATCH ossl_dh_to_text_encoder_functions[];
 
 extern const OSSL_DISPATCH ossl_dhx_to_DHX_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_DHX_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dhx_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dhx_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -373,6 +381,8 @@ extern const OSSL_DISPATCH ossl_dhx_to_text_encoder_functions[];
 
 extern const OSSL_DISPATCH ossl_dsa_to_DSA_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_DSA_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dsa_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dsa_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -386,6 +396,8 @@ extern const OSSL_DISPATCH ossl_dsa_to_text_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_EC_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_EC_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_blob_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ec_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ec_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -400,6 +412,8 @@ extern const OSSL_DISPATCH ossl_ec_to_text_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_SM2_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_SM2_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_blob_encoder_functions[];
+extern const OSSL_DISPATCH ossl_sm2_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_sm2_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -409,6 +423,8 @@ extern const OSSL_DISPATCH ossl_sm2_to_type_specific_no_pub_der_encoder_function
 extern const OSSL_DISPATCH ossl_sm2_to_text_encoder_functions[];
 #endif
 
+extern const OSSL_DISPATCH ossl_ed25519_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ed25519_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -416,6 +432,8 @@ extern const OSSL_DISPATCH ossl_ed25519_to_SubjectPublicKeyInfo_pem_encoder_func
 extern const OSSL_DISPATCH ossl_ed25519_to_OSSL_current_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_text_encoder_functions[];
 
+extern const OSSL_DISPATCH ossl_ed448_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ed448_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -423,6 +441,8 @@ extern const OSSL_DISPATCH ossl_ed448_to_SubjectPublicKeyInfo_pem_encoder_functi
 extern const OSSL_DISPATCH ossl_ed448_to_OSSL_current_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_text_encoder_functions[];
 
+extern const OSSL_DISPATCH ossl_x25519_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_x25519_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -430,6 +450,8 @@ extern const OSSL_DISPATCH ossl_x25519_to_SubjectPublicKeyInfo_pem_encoder_funct
 extern const OSSL_DISPATCH ossl_x25519_to_OSSL_current_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_text_encoder_functions[];
 
+extern const OSSL_DISPATCH ossl_x448_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_x448_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x448_to_PrivateKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x448_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x448_to_SubjectPublicKeyInfo_der_encoder_functions[];
diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c
index 6ccda2b33f..34cb70fdf8 100644
--- a/providers/implementations/storemgmt/file_store.c
+++ b/providers/implementations/storemgmt/file_store.c
@@ -437,6 +437,31 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
             goto err;
         }
 
+        /*
+         * Where applicable, set the outermost structure name.
+         * The goal is to avoid the STORE object types that are
+         * potentially password protected but aren't interesting
+         * for this load.
+         */
+        switch (ctx->expected_type) {
+        case OSSL_STORE_INFO_CERT:
+            if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx,
+                                                      "Certificate")) {
+                ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
+                goto err;
+            }
+            break;
+        case OSSL_STORE_INFO_CRL:
+            if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx,
+                                                      "CertificateList")) {
+                ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
+                goto err;
+            }
+            break;
+        default:
+            break;
+        }
+
         for (to_algo = ossl_any_to_obj_algorithm;
              to_algo->algorithm_names != NULL;
              to_algo++) {
diff --git a/test/endecode_test.c b/test/endecode_test.c
index d28ea3c812..1698867b40 100644
--- a/test/endecode_test.c
+++ b/test/endecode_test.c
@@ -703,7 +703,7 @@ static int test_protected_via_DER(const char *type, EVP_PKEY *key)
     return test_encode_decode(__FILE__, __LINE__, type, key,
                               OSSL_KEYMGMT_SELECT_KEYPAIR
                               | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
-                              "DER", "PrivateKeyInfo",
+                              "DER", "EncryptedPrivateKeyInfo",
                               pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_mem, check_protected_PKCS8_DER,
@@ -726,7 +726,7 @@ static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
     return test_encode_decode(__FILE__, __LINE__, type, key,
                               OSSL_KEYMGMT_SELECT_KEYPAIR
                               | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
-                              "PEM", "PrivateKeyInfo",
+                              "PEM", "EncryptedPrivateKeyInfo",
                               pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_text, check_protected_PKCS8_PEM,
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index acb26f0afd..f7a9f626ca 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -11,6 +11,7 @@ use strict;
 use warnings;
 
 use File::Spec::Functions qw/canonpath/;
+use File::Copy;
 use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips with/;
 use OpenSSL::Test::Utils;
 
@@ -28,7 +29,7 @@ sub verify {
     run(app([@args]));
 }
 
-plan tests => 157;
+plan tests => 159;
 
 # Canonical success
 ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -448,3 +449,33 @@ SKIP: {
    ok_nofips(verify("sm2", "", ["sm2-ca-cert"], [], "-vfyopt", "hexdistid:31323334353637383132333435363738"),
        "SM2 hex ID test");
 }
+
+# Mixed content tests
+my $cert_file = srctop_file('test', 'certs', 'root-cert.pem');
+my $rsa_file = srctop_file('test', 'certs', 'key-pass-12345.pem');
+
+SKIP: {
+    my $certplusrsa_file = 'certplusrsa.pem';
+    my $certplusrsa;
+
+    skip "Couldn't create certplusrsa.pem", 1
+        unless ( open $certplusrsa, '>', $certplusrsa_file
+                 and copy($cert_file, $certplusrsa)
+                 and copy($rsa_file, $certplusrsa) );
+
+    ok(run(app([ qw(openssl verify -trusted), $certplusrsa_file, $cert_file ])),
+       'Mixed cert + key file test');
+}
+
+SKIP: {
+    my $rsapluscert_file = 'rsapluscert.pem';
+    my $rsapluscert;
+
+    skip "Couldn't create rsapluscert.pem", 1
+        unless ( open $rsapluscert, '>', $rsapluscert_file
+                 and copy($rsa_file, $rsapluscert)
+                 and copy($cert_file, $rsapluscert) );
+
+    ok(run(app([ qw(openssl verify -trusted), $rsapluscert_file, $cert_file ])),
+       'Mixed key + cert file test');
+}


More information about the openssl-commits mailing list