[openssl] master update

dev at ddvo.net dev at ddvo.net
Fri Aug 21 07:10:15 UTC 2020


The branch master has been updated
       via  5a7734cd0219faaad336990c9ceebc8efc2776b0 (commit)
       via  4561f15fdb0cf86257fd30292a9b82893c248350 (commit)
       via  bdd6784fdd0f6e8ffc7b9a3c19fcc6a029385160 (commit)
       via  b0248cbc3e2fa20e9c4d97845808537f9bd4206a (commit)
       via  6d1f50b520ce0a2eaa624686a26ffd4a5af00d93 (commit)
       via  cac30a69bcadcfcf5beb034abf958bbcdb8b83cb (commit)
       via  28e9f62b2dd5f59218bd7d5c3ef877dd06e5eb97 (commit)
       via  1930b58642a67eecf23708aa71df9e193e849a3c (commit)
       via  2300083887342650e1ad8071855d87a0e814dba4 (commit)
       via  ab28b59064b3f46c7a62b540cd17cad718738108 (commit)
       via  97e00da90282dddfc572c84d8468d85ab1925fba (commit)
       via  1a7cd250ad55a3c9d684a7259c20ea8075c2b08b (commit)
       via  7b1a3a506273bc043cefd7c2202300a9bf81daa0 (commit)
       via  cef3a008a667a742cec5317c84470e4a09600e17 (commit)
       via  ded346fad2f2c86bc13ac3beaf5e00e969f04442 (commit)
       via  4cdf44c46b699934b86b9d842cfd4448b7dbe58e (commit)
       via  09c2e26e640d78afe7da00d856ab113d9181e098 (commit)
       via  1bb6f70da33ab48a74327dd04121c94c015217ac (commit)
       via  06cee80a843cae6bcb2dcba7eab26c963e10f825 (commit)
       via  1a7ceb6c74d930fd5dfbcd06350b4cef0228936b (commit)
       via  bc03cfadc403137e1c274de4907b390841057cbf (commit)
       via  de3713d492556e684e71eccf3c20116d00616277 (commit)
      from  be63e58732cedc0bbc39777d1cf7556e55f146ef (commit)


- Log -----------------------------------------------------------------
commit 5a7734cd0219faaad336990c9ceebc8efc2776b0
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 19 00:48:57 2020 +0200

    Add libctx/provider support to cmp_msg_test
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 4561f15fdb0cf86257fd30292a9b82893c248350
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Aug 18 17:14:19 2020 +0200

    Add libctx/provider support to cmp_protect_test
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit bdd6784fdd0f6e8ffc7b9a3c19fcc6a029385160
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Aug 18 17:04:54 2020 +0200

    Add libctx/provider support to cmp_vfy_test
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit b0248cbc3e2fa20e9c4d97845808537f9bd4206a
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 22:20:23 2020 +0200

    Add libctx/provider support to cmp_client_test
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 6d1f50b520ce0a2eaa624686a26ffd4a5af00d93
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu Aug 13 17:44:54 2020 +0200

    Use in CMP+CRMF libctx and propq param added to sign/verify/HMAC/decrypt
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit cac30a69bcadcfcf5beb034abf958bbcdb8b83cb
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 22:15:24 2020 +0200

    cmp_msg.c: Copy libctx and propq of CMP_CTX to newly enrolled certificate
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 28e9f62b2dd5f59218bd7d5c3ef877dd06e5eb97
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed May 13 16:03:26 2020 +0200

    cmp_util.c: Add OPENSSL_CTX parameter to ossl_cmp_build_cert_chain(), improve its doc
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 1930b58642a67eecf23708aa71df9e193e849a3c
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed May 13 12:19:16 2020 +0200

    cmp_hdr.c: Adapt ossl_cmp_hdr_init() to use OPENSSL_CTX for random number generation
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 2300083887342650e1ad8071855d87a0e814dba4
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 19:16:03 2020 +0200

    crypto/cmp: Prevent misleading errors in case x509v3_cache_extensions() fails
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit ab28b59064b3f46c7a62b540cd17cad718738108
Author: Shane Lontis <shane.lontis at oracle.com>
Date:   Thu May 14 12:32:44 2020 +1000

    Add libctx/provider support to cmp_server_test
    
    Reviewed-by: David von Oheimb <david.von.oheimb at siemens.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 97e00da90282dddfc572c84d8468d85ab1925fba
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed May 13 11:58:52 2020 +0200

    Add OPENSSL_CTX parameter to OSSL_CRMF_pbmp_new() and improve its doc
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 1a7cd250ad55a3c9d684a7259c20ea8075c2b08b
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed May 13 09:28:24 2020 +0200

    Add libctx and propq parameters to OSSL_CMP_{SRV_},CTX_new() and ossl_cmp_mock_srv_new()
    
    Also remove not really to-the-point error message if call fails in apps/cmp.c
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 7b1a3a506273bc043cefd7c2202300a9bf81daa0
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Aug 18 16:03:29 2020 +0200

    cmp_vfy.c: Fix bug: must verify msg signature also in 3GPP mode
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit cef3a008a667a742cec5317c84470e4a09600e17
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed May 13 14:04:18 2020 +0200

    Update CMP header file references in internal CMP documentation
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit ded346fad2f2c86bc13ac3beaf5e00e969f04442
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu May 14 21:09:49 2020 +0200

    Add libctx and propq param to ASN.1 sign/verify/HMAC/decrypt
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 4cdf44c46b699934b86b9d842cfd4448b7dbe58e
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 21:07:12 2020 +0200

    x_x509.c: Simplify X509_new_with_libctx() using x509_set0_libctx()
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 09c2e26e640d78afe7da00d856ab113d9181e098
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu May 14 11:27:43 2020 +0200

    Re-word null->empty property; improve iteration.count example in property.pod
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 1bb6f70da33ab48a74327dd04121c94c015217ac
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 07:46:57 2020 +0200

    testutil: Add provider.c with test_get_libctx(), to use at least for SSL and CMP
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 06cee80a843cae6bcb2dcba7eab26c963e10f825
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 20:24:26 2020 +0200

    testutil: Make SETUP_TEST_FIXTURE return 0 on fixture == NULL
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit 1a7ceb6c74d930fd5dfbcd06350b4cef0228936b
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Fri May 15 18:46:59 2020 +0200

    Correct the #define's of EVP_PKEY_CTRL_SET1_ID and EVP_PKEY_CTRL_GET1_ID{,_LEN}
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit bc03cfadc403137e1c274de4907b390841057cbf
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 22:11:42 2020 +0200

    Add prerequisite #include directives to include/crypto/x509.h
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

commit de3713d492556e684e71eccf3c20116d00616277
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Aug 12 22:07:51 2020 +0200

    Make sure x509v3_cache_extensions() does not modify the error queue
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11808)

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

Summary of changes:
 apps/cmp.c                                         |  15 +-
 apps/cmp_mock_srv.c                                |   4 +-
 apps/cmp_mock_srv.h                                |   2 +-
 crypto/asn1/a_sign.c                               |  50 +++--
 crypto/asn1/a_verify.c                             |  43 ++--
 crypto/asn1/ameth_lib.c                            |   8 +-
 crypto/asn1/asn1_err.c                             |   2 +-
 crypto/cmp/cmp_client.c                            |   6 +-
 crypto/cmp/cmp_ctx.c                               |  49 ++++-
 crypto/cmp/cmp_err.c                               |   3 +-
 crypto/cmp/cmp_hdr.c                               |  28 +--
 crypto/cmp/cmp_local.h                             |  29 ++-
 crypto/cmp/cmp_msg.c                               |  26 ++-
 crypto/cmp/cmp_protect.c                           | 235 +++++++++++----------
 crypto/cmp/cmp_server.c                            |   6 +-
 crypto/cmp/cmp_util.c                              |  18 +-
 crypto/cmp/cmp_vfy.c                               | 131 ++++++------
 crypto/crmf/crmf_err.c                             |   4 +-
 crypto/crmf/crmf_lib.c                             |  91 ++++----
 crypto/crmf/crmf_pbm.c                             |  34 +--
 crypto/ec/ecx_meth.c                               |  12 +-
 crypto/err/openssl.txt                             |   5 +-
 crypto/evp/digest.c                                |  32 +++
 crypto/rsa/rsa_ameth.c                             |  10 +-
 crypto/x509/v3_purp.c                              |   2 +
 crypto/x509/x_all.c                                |  67 +-----
 crypto/x509/x_x509.c                               |   5 +-
 .../man3/ossl_cmp_asn1_octet_string_set1.pod       |  22 +-
 doc/internal/man3/ossl_cmp_hdr_init.pod            |   2 +-
 doc/internal/man3/ossl_cmp_mock_srv_new.pod        |   8 +-
 doc/internal/man3/ossl_cmp_msg_create.pod          |   2 +-
 doc/internal/man3/ossl_cmp_msg_protect.pod         |  53 ++++-
 doc/internal/man3/ossl_cmp_pkisi_get_status.pod    |  15 +-
 doc/man3/OSSL_CMP_CTX_new.pod                      |  11 +-
 doc/man3/OSSL_CMP_SRV_CTX_new.pod                  |   7 +-
 doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod               |  20 +-
 doc/man3/OSSL_CRMF_MSG_set0_validity.pod           |  19 +-
 doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod   |  28 +--
 doc/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod    |  10 +-
 doc/man3/OSSL_CRMF_pbmp_new.pod                    |  52 +++--
 doc/man7/property.pod                              |   8 +-
 fuzz/cmp.c                                         |   4 +-
 include/crypto/asn1.h                              |   7 +-
 include/crypto/evp.h                               |   3 +
 include/crypto/x509.h                              |   2 +
 include/openssl/asn1.h                             |  10 +
 include/openssl/asn1err.h                          |   1 -
 include/openssl/cmp.h                              |   4 +-
 include/openssl/cmperr.h                           |   2 +-
 include/openssl/crmf.h                             |  17 +-
 include/openssl/crmferr.h                          |   3 +-
 include/openssl/ec.h                               |   7 +-
 include/openssl/evp.h                              |  18 +-
 include/openssl/x509.h                             |  23 +-
 test/build.info                                    |   2 +-
 test/cipherlist_test.c                             |   9 +-
 test/cmp_client_test.c                             |  22 +-
 test/cmp_ctx_test.c                                |   2 +-
 test/cmp_hdr_test.c                                |   7 +-
 test/cmp_msg_test.c                                |  62 ++++--
 test/cmp_protect_test.c                            |  74 ++++---
 test/cmp_server_test.c                             |  18 +-
 test/cmp_testlib.c                                 |  20 +-
 test/cmp_testlib.h                                 |   4 +-
 test/cmp_vfy_test.c                                |  57 +++--
 test/ct_test.c                                     |  16 --
 test/recipes/65-test_cmp_client.t                  |  39 +++-
 test/recipes/65-test_cmp_msg.t                     |  34 ++-
 .../65-test_cmp_msg_data/new.key}                  |   0
 test/recipes/65-test_cmp_protect.t                 |  51 +++--
 test/recipes/65-test_cmp_server.t                  |  30 ++-
 test/recipes/65-test_cmp_vfy.t                     |  53 +++--
 test/ssl_test.c                                    |  27 +--
 test/ssl_test_ctx_test.c                           |   4 -
 test/testutil.h                                    |  48 +++--
 test/testutil/provider.c                           |  51 +++++
 util/libcrypto.num                                 |   2 +
 util/missingcrypto.txt                             |   2 +
 78 files changed, 1092 insertions(+), 817 deletions(-)
 copy test/{certs/root-key2.pem => recipes/65-test_cmp_msg_data/new.key} (100%)
 create mode 100644 test/testutil/provider.c

diff --git a/apps/cmp.c b/apps/cmp.c
index 350aa22628..97fa322b11 100644
--- a/apps/cmp.c
+++ b/apps/cmp.c
@@ -1156,7 +1156,8 @@ static int transform_opts(void)
 static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
 {
     OSSL_CMP_CTX *ctx; /* extra CMP (client) ctx partly used by server */
-    OSSL_CMP_SRV_CTX *srv_ctx = ossl_cmp_mock_srv_new();
+    OSSL_CMP_SRV_CTX *srv_ctx = ossl_cmp_mock_srv_new(app_get0_libctx(),
+                                                      app_get0_propq());
 
     if (srv_ctx == NULL)
         return NULL;
@@ -1652,8 +1653,11 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
             CMP_err1("digest algorithm name not recognized: '%s'", opt_digest);
             goto err;
         }
-        (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest);
-        (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest);
+        if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest)
+            || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest)) {
+            CMP_err1("digest algorithm name not supported: '%s'", opt_digest);
+            goto err;
+        }
     }
 
     if (opt_mac != NULL) {
@@ -2776,10 +2780,9 @@ int cmp_main(int argc, char **argv)
         }
     }
 
-    if ((cmp_ctx = OSSL_CMP_CTX_new()) == NULL) {
-        CMP_err("out of memory");
+    cmp_ctx = OSSL_CMP_CTX_new(app_get0_libctx(), app_get0_propq());
+    if (cmp_ctx == NULL)
         goto err;
-    }
     if (!OSSL_CMP_CTX_set_log_cb(cmp_ctx, print_to_bio_out)) {
         CMP_err1("cannot set up error reporting and logging for %s", prog);
         goto err;
diff --git a/apps/cmp_mock_srv.c b/apps/cmp_mock_srv.c
index c63e5f9943..3a0819008b 100644
--- a/apps/cmp_mock_srv.c
+++ b/apps/cmp_mock_srv.c
@@ -388,9 +388,9 @@ static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
     return 1;
 }
 
-OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void)
+OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OPENSSL_CTX *libctx, const char *propq)
 {
-    OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new();
+    OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(libctx, propq);
     mock_srv_ctx *ctx = mock_srv_ctx_new();
 
     if (srv_ctx != NULL && ctx != NULL
diff --git a/apps/cmp_mock_srv.h b/apps/cmp_mock_srv.h
index bddc44df5b..b4f82d1b81 100644
--- a/apps/cmp_mock_srv.h
+++ b/apps/cmp_mock_srv.h
@@ -16,7 +16,7 @@
 
 #  include <openssl/cmp.h>
 
-OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void);
+OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OPENSSL_CTX *libctx, const char *propq);
 void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
 
 int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c
index 300f30aa71..04edd1b28c 100644
--- a/crypto/asn1/a_sign.c
+++ b/crypto/asn1/a_sign.c
@@ -115,40 +115,50 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
 
 #endif
 
-int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
-                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
-                   EVP_PKEY *pkey, const EVP_MD *type)
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+                   ASN1_BIT_STRING *signature, const void *data,
+                   EVP_PKEY *pkey, const EVP_MD *md)
 {
-    int rv;
-    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    return ASN1_item_sign_with_libctx(it, algor1, algor2, signature, data, NULL,
+                                      pkey, md, NULL, NULL);
+}
+
+int ASN1_item_sign_with_libctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                               X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+                               const void *data, const ASN1_OCTET_STRING *id,
+                               EVP_PKEY *pkey, const EVP_MD *md,
+                               OPENSSL_CTX *libctx, const char *propq)
+{
+    int rv = 0;
+    EVP_MD_CTX *ctx = evp_md_ctx_new_with_libctx(pkey, id, libctx, propq);
 
     if (ctx == NULL) {
-        ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-    if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) {
-        EVP_MD_CTX_free(ctx);
+        ASN1err(0, ERR_R_MALLOC_FAILURE);
         return 0;
     }
+    if (!EVP_DigestSignInit(ctx, NULL, md, NULL, pkey))
+        goto err;
 
-    rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx);
+    rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, data, ctx);
 
+ err:
+    EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(ctx));
     EVP_MD_CTX_free(ctx);
     return rv;
 }
 
-int ASN1_item_sign_ctx(const ASN1_ITEM *it,
-                       X509_ALGOR *algor1, X509_ALGOR *algor2,
-                       ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+                       const void *data, EVP_MD_CTX *ctx)
 {
-    const EVP_MD *type;
+    const EVP_MD *md;
     EVP_PKEY *pkey;
     unsigned char *buf_in = NULL, *buf_out = NULL;
     size_t inl = 0, outl = 0, outll = 0;
     int signid, paramtype, buf_len = 0;
     int rv, pkey_id;
 
-    type = EVP_MD_CTX_md(ctx);
+    md = EVP_MD_CTX_md(ctx);
     pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
 
     if (pkey == NULL) {
@@ -202,7 +212,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
 
         rv = 3;
     } else if (pkey->ameth->item_sign) {
-        rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
+        rv = pkey->ameth->item_sign(ctx, it, data, algor1, algor2, signature);
         if (rv == 1)
             outl = signature->length;
         /*-
@@ -221,7 +231,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
     }
 
     if (rv == 2) {
-        if (type == NULL) {
+        if (md == NULL) {
             ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
             goto err;
         }
@@ -232,7 +242,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
 #endif
             pkey->ameth->pkey_id;
 
-        if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey_id)) {
+        if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(md), pkey_id)) {
             ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
                     ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
             goto err;
@@ -250,7 +260,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
 
     }
 
-    buf_len = ASN1_item_i2d(asn, &buf_in, it);
+    buf_len = ASN1_item_i2d(data, &buf_in, it);
     if (buf_len <= 0) {
         outl = 0;
         ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_INTERNAL_ERROR);
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index eb024e79c0..2b2c46a854 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -85,30 +85,33 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
 
 #endif
 
-int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
-                     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
+int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg,
+                     const ASN1_BIT_STRING *signature, const void *data,
+                     EVP_PKEY *pkey)
 {
+    return ASN1_item_verify_with_libctx(it, alg, signature, data, NULL, pkey,
+                                        NULL, NULL);
+}
+
+int ASN1_item_verify_with_libctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
+                                 const ASN1_BIT_STRING *signature,
+                                 const void *data,
+                                 const ASN1_OCTET_STRING *id, EVP_PKEY *pkey,
+                                 OPENSSL_CTX *libctx, const char *propq)
+{
+    EVP_MD_CTX *ctx;
     int rv = -1;
-    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
-    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
 
-    if (ctx == NULL || pctx == NULL) {
-        ASN1err(0, ERR_R_MALLOC_FAILURE);
-        goto err;
+    if ((ctx = evp_md_ctx_new_with_libctx(pkey, id, libctx, propq)) != NULL) {
+        rv = ASN1_item_verify_ctx(it, alg, signature, data, ctx);
+        EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(ctx));
+        EVP_MD_CTX_free(ctx);
     }
-
-    EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
-
-    rv = ASN1_item_verify_ctx(it, a, signature, asn, ctx);
-
- err:
-    EVP_PKEY_CTX_free(pctx);
-    EVP_MD_CTX_free(ctx);
     return rv;
 }
 
-int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a,
-                         ASN1_BIT_STRING *signature, void *asn,
+int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
+                         const ASN1_BIT_STRING *signature, const void *data,
                          EVP_MD_CTX *ctx)
 {
     EVP_PKEY *pkey;
@@ -130,7 +133,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a,
     }
 
     /* Convert signature OID into digest and public key OIDs */
-    if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
+    if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)) {
         ASN1err(0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
         goto err;
     }
@@ -140,7 +143,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a,
             ASN1err(0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
             goto err;
         }
-        ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey);
+        ret = pkey->ameth->item_verify(ctx, it, data, alg, signature, pkey);
         /*
          * Return values meaning:
          * <=0: error.
@@ -172,7 +175,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a,
         }
     }
 
-    inl = ASN1_item_i2d(asn, &buf_in, it);
+    inl = ASN1_item_i2d(data, &buf_in, it);
     if (inl <= 0) {
         ASN1err(0, ERR_R_INTERNAL_ERROR);
         goto err;
diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c
index 32074c460e..e473112d0b 100644
--- a/crypto/asn1/ameth_lib.c
+++ b/crypto/asn1/ameth_lib.c
@@ -361,13 +361,13 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
 void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
                             int (*item_verify) (EVP_MD_CTX *ctx,
                                                 const ASN1_ITEM *it,
-                                                void *asn,
-                                                X509_ALGOR *a,
-                                                ASN1_BIT_STRING *sig,
+                                                const void *data,
+                                                const X509_ALGOR *a,
+                                                const ASN1_BIT_STRING *sig,
                                                 EVP_PKEY *pkey),
                             int (*item_sign) (EVP_MD_CTX *ctx,
                                               const ASN1_ITEM *it,
-                                              void *asn,
+                                              const void *data,
                                               X509_ALGOR *alg1,
                                               X509_ALGOR *alg2,
                                               ASN1_BIT_STRING *sig))
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index 96878e2a46..6a599bc067 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 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
diff --git a/crypto/cmp/cmp_client.c b/crypto/cmp/cmp_client.c
index 37473c7a6c..b7319372e6 100644
--- a/crypto/cmp/cmp_client.c
+++ b/crypto/cmp/cmp_client.c
@@ -425,10 +425,8 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
         goto err;
     case OSSL_CMP_PKISTATUS_grantedWithMods:
         ossl_cmp_warn(ctx, "received \"grantedWithMods\" for certificate");
-        crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
         break;
     case OSSL_CMP_PKISTATUS_accepted:
-        crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
         break;
         /* get all information in case of a rejection before going to error */
     case OSSL_CMP_PKISTATUS_rejection:
@@ -438,19 +436,16 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
     case OSSL_CMP_PKISTATUS_revocationWarning:
         ossl_cmp_warn(ctx,
                       "received \"revocationWarning\" - a revocation of the cert is imminent");
-        crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
         break;
     case OSSL_CMP_PKISTATUS_revocationNotification:
         ossl_cmp_warn(ctx,
                       "received \"revocationNotification\" - a revocation of the cert has occurred");
-        crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
         break;
     case OSSL_CMP_PKISTATUS_keyUpdateWarning:
         if (bodytype != OSSL_CMP_PKIBODY_KUR) {
             CMPerr(0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING);
             goto err;
         }
-        crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
         break;
     default:
         ossl_cmp_log1(ERROR, ctx,
@@ -459,6 +454,7 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
         CMPerr(0, CMP_R_UNKNOWN_PKISTATUS);
         goto err;
     }
+    crt = ossl_cmp_certresponse_get1_cert(crep, ctx, privkey);
     if (crt == NULL) /* according to PKIStatus, we can expect a cert */
         CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND);
 
diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c
index 3081dfcc21..e731f15958 100644
--- a/crypto/cmp/cmp_ctx.c
+++ b/crypto/cmp/cmp_ctx.c
@@ -12,6 +12,7 @@
 #include <openssl/trace.h>
 #include <openssl/bio.h>
 #include <openssl/ocsp.h> /* for OCSP_REVOKED_STATUS_* */
+#include "crypto/x509.h" /* for x509v3_cache_extensions() */
 
 #include "cmp_local.h"
 
@@ -89,16 +90,34 @@ int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
     return 0;
 }
 
+static int cmp_ctx_set_md(OSSL_CMP_CTX *ctx, EVP_MD **pmd, int nid)
+{
+    EVP_MD *md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propq);
+    /* fetching in advance to be able to throw error early if unsupported */
+
+    if (md == NULL) {
+        CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM);
+        return 0;
+    }
+    EVP_MD_free(*pmd);
+    *pmd = md;
+    return 1;
+}
+
 /*
  * Allocates and initializes OSSL_CMP_CTX context structure with default values.
  * Returns new context on success, NULL on error
  */
-OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
+OSSL_CMP_CTX *OSSL_CMP_CTX_new(OPENSSL_CTX *libctx, const char *propq)
 {
     OSSL_CMP_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
 
     if (ctx == NULL)
-        return NULL;
+        goto err;
+
+    ctx->libctx = libctx;
+    if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)
+        goto err;
 
     ctx->log_verbosity = OSSL_CMP_LOG_INFO;
 
@@ -111,11 +130,13 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
         goto err;
 
     ctx->pbm_slen = 16;
-    ctx->pbm_owf = NID_sha256;
+    if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, NID_sha256))
+        goto err;
     ctx->pbm_itercnt = 500;
     ctx->pbm_mac = NID_hmac_sha1;
 
-    ctx->digest = NID_sha256;
+    if (!cmp_ctx_set_md(ctx, &ctx->digest, NID_sha256))
+        goto err;
     ctx->popoMethod = OSSL_CRMF_POPO_SIGNATURE;
     ctx->revocationReason = CRL_REASON_NONE;
 
@@ -124,6 +145,7 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
 
  err:
     OSSL_CMP_CTX_free(ctx);
+    X509err(0, ERR_R_MALLOC_FAILURE);
     return NULL;
 }
 
@@ -171,8 +193,10 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
     if (ctx->secretValue != NULL)
         OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length);
     ASN1_OCTET_STRING_free(ctx->secretValue);
+    EVP_MD_free(ctx->pbm_owf);
 
     X509_NAME_free(ctx->recipient);
+    EVP_MD_free(ctx->digest);
     ASN1_OCTET_STRING_free(ctx->transactionID);
     ASN1_OCTET_STRING_free(ctx->senderNonce);
     ASN1_OCTET_STRING_free(ctx->recipNonce);
@@ -574,6 +598,8 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, const TYPE *val) \
     return 1; \
 }
 
+#define X509_invalid(cert) (!x509v3_cache_extensions(cert))
+#define EVP_PKEY_invalid(key) 0
 #define DEFINE_OSSL_CMP_CTX_set1_up_ref(FIELD, TYPE) \
 int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
 { \
@@ -582,6 +608,11 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
         return 0; \
     } \
     \
+    /* prevent misleading error later on malformed cert or provider issue */ \
+    if (val != NULL && TYPE##_invalid(val)) { \
+        CMPerr(0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE); \
+        return 0; \
+    } \
     if (val != NULL && !TYPE##_up_ref(val)) \
         return 0; \
     TYPE##_free(ctx->FIELD); \
@@ -964,10 +995,12 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
         ctx->popoMethod = val;
         break;
     case OSSL_CMP_OPT_DIGEST_ALGNID:
-        ctx->digest = val;
+        if (!cmp_ctx_set_md(ctx, &ctx->digest, val))
+            return 0;
         break;
     case OSSL_CMP_OPT_OWF_ALGNID:
-        ctx->pbm_owf = val;
+        if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, val))
+            return 0;
         break;
     case OSSL_CMP_OPT_MAC_ALGNID:
         ctx->pbm_mac = val;
@@ -1031,9 +1064,9 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
     case OSSL_CMP_OPT_POPO_METHOD:
         return ctx->popoMethod;
     case OSSL_CMP_OPT_DIGEST_ALGNID:
-        return ctx->digest;
+        return EVP_MD_type(ctx->digest);
     case OSSL_CMP_OPT_OWF_ALGNID:
-        return ctx->pbm_owf;
+        return EVP_MD_type(ctx->pbm_owf);
     case OSSL_CMP_OPT_MAC_ALGNID:
         return ctx->pbm_mac;
     case OSSL_CMP_OPT_MSG_TIMEOUT:
diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c
index 87d0f0f1b0..19d1556426 100644
--- a/crypto/cmp/cmp_err.c
+++ b/crypto/cmp/cmp_err.c
@@ -33,8 +33,6 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     "cert and key do not match"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKAFTER_OUT_OF_RANGE),
     "checkafter out of range"},
-    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE),
-    "checking pbm no secret available"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING),
     "encountered keyupdatewarning"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_WAITING),
@@ -88,6 +86,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE),
     "missing key usage digitalsignature"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_P10CSR), "missing p10csr"},
+    {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PBM_SECRET), "missing pbm secret"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY),
     "missing private key"},
     {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PROTECTION), "missing protection"},
diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c
index 364d89a9b0..6bd1e581af 100644
--- a/crypto/cmp/cmp_hdr.c
+++ b/crypto/cmp/cmp_hdr.c
@@ -143,26 +143,16 @@ int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr)
     return ASN1_GENERALIZEDTIME_set(hdr->messageTime, time(NULL)) != NULL;
 }
 
-/* assign to *tgt a copy of src (or if NULL a random byte array of given len) */
-static int set1_aostr_else_random(ASN1_OCTET_STRING **tgt,
-                                  const ASN1_OCTET_STRING *src, size_t len)
+/* assign to *tgt a random byte array of given length */
+static int set_random(ASN1_OCTET_STRING **tgt, OSSL_CMP_CTX *ctx, size_t len)
 {
-    unsigned char *bytes = NULL;
+    unsigned char *bytes = OPENSSL_malloc(len);
     int res = 0;
 
-    if (src == NULL) { /* generate a random value if src == NULL */
-        if ((bytes = OPENSSL_malloc(len)) == NULL)
-            goto err;
-        if (RAND_bytes(bytes, len) <= 0) {
-            CMPerr(0, CMP_R_FAILURE_OBTAINING_RANDOM);
-            goto err;
-        }
+    if (bytes == NULL || RAND_bytes_ex(ctx->libctx, bytes, len) <= 0)
+        CMPerr(0, CMP_R_FAILURE_OBTAINING_RANDOM);
+    else
         res = ossl_cmp_asn1_octet_string_set1_bytes(tgt, bytes, len);
-    } else {
-        res = ossl_cmp_asn1_octet_string_set1(tgt, src);
-    }
-
- err:
     OPENSSL_free(bytes);
     return res;
 }
@@ -287,8 +277,7 @@ int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
 int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
 {
     if (ctx->transactionID == NULL
-            && !set1_aostr_else_random(&ctx->transactionID, NULL,
-                                       OSSL_CMP_TRANSACTIONID_LENGTH))
+        && !set_random(&ctx->transactionID, ctx, OSSL_CMP_TRANSACTIONID_LENGTH))
         return 0;
     return ossl_cmp_asn1_octet_string_set1(&hdr->transactionID,
                                            ctx->transactionID);
@@ -355,8 +344,7 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
      * is copied from the senderNonce of the previous message in the
      * transaction.
      */
-    if (!set1_aostr_else_random(&hdr->senderNonce, NULL,
-                                OSSL_CMP_SENDERNONCE_LENGTH))
+    if (!set_random(&hdr->senderNonce, ctx, OSSL_CMP_SENDERNONCE_LENGTH))
         return 0;
 
     /* store senderNonce - for cmp with recipNonce in next outgoing msg */
diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h
index 84309cc1af..41c10b22c1 100644
--- a/crypto/cmp/cmp_local.h
+++ b/crypto/cmp/cmp_local.h
@@ -28,6 +28,8 @@
  * this structure is used to store the context for CMP sessions
  */
 struct ossl_cmp_ctx_st {
+    OPENSSL_CTX *libctx;
+    const char *propq;
     OSSL_CMP_log_cb_t log_cb; /* log callback for error/debug/etc. output */
     OSSL_CMP_severity log_verbosity; /* level of verbosity of log output */
 
@@ -73,14 +75,14 @@ struct ossl_cmp_ctx_st {
     ASN1_OCTET_STRING *referenceValue; /* optional user name for MSG_MAC_ALG */
     ASN1_OCTET_STRING *secretValue; /* password/shared secret for MSG_MAC_ALG */
     /* PBMParameters for MSG_MAC_ALG */
-    size_t pbm_slen; /* currently fixed to 16 */
-    int pbm_owf; /* NID of one-way function (OWF), default: SHA256 */
-    int pbm_itercnt; /* currently fixed to 500 */
+    size_t pbm_slen; /* salt length, currently fixed to 16 */
+    EVP_MD *pbm_owf; /* one-way function (OWF), default: SHA256 */
+    int pbm_itercnt; /* OWF iteration count, currently fixed to 500 */
     int pbm_mac; /* NID of MAC algorithm, default: HMAC-SHA1 as per RFC 4210 */
 
     /* CMP message header and extra certificates */
     X509_NAME *recipient; /* to set in recipient in pkiheader */
-    int digest; /* NID of digest used in MSG_SIG_ALG and POPO, default SHA256 */
+    EVP_MD *digest; /* digest used in MSG_SIG_ALG and POPO, default SHA256 */
     ASN1_OCTET_STRING *transactionID; /* the current transaction ID */
     ASN1_OCTET_STRING *senderNonce; /* last nonce sent */
     ASN1_OCTET_STRING *recipNonce; /* last nonce received */
@@ -742,7 +744,9 @@ int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
                                     const ASN1_OCTET_STRING *src);
 int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
                                           const unsigned char *bytes, int len);
-STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert);
+STACK_OF(X509)
+    *ossl_cmp_build_cert_chain(OPENSSL_CTX *libctx, const char *propq,
+                               STACK_OF(X509) *certs, X509 *cert);
 
 /* from cmp_ctx.c */
 int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
@@ -890,14 +894,14 @@ ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc,
 OSSL_CMP_CERTRESPONSE *
 ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
                                           int rid);
-X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
-                                             const OSSL_CMP_CERTRESPONSE *crep);
+X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep,
+                                      const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey);
+OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
 
 /* from cmp_protect.c */
-ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
-                                          const ASN1_OCTET_STRING *secret,
-                                          EVP_PKEY *pkey);
 int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
+ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
+                                          const OSSL_CMP_MSG *msg);
 int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
 
 /* from cmp_vfy.c */
@@ -906,7 +910,10 @@ typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx,
                                                int invalid_protection, int arg);
 int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
                               ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
-int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
+int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
+                                ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
+int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx,
+                         const OSSL_CMP_MSG *msg, int accept_RAVerified);
 
 /* from cmp_client.c */
 int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info,
diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c
index d506e7b22b..64e00fc884 100644
--- a/crypto/cmp/cmp_msg.c
+++ b/crypto/cmp/cmp_msg.c
@@ -19,6 +19,7 @@
 #include <openssl/crmf.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
+#include "crypto/x509.h" /* for x509_set0_libctx() */
 
 DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS)
 DEFINE_STACK_OF(OSSL_CMP_ITAV)
@@ -354,8 +355,9 @@ OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type,
                                                type == OSSL_CMP_PKIBODY_KUR,
                                                OSSL_CMP_CERTREQID);
             if (local_crm == NULL
-                || !OSSL_CRMF_MSG_create_popo(local_crm, privkey, ctx->digest,
-                                              ctx->popoMethod))
+                || !OSSL_CRMF_MSG_create_popo(ctx->popoMethod, local_crm,
+                                              privkey, ctx->digest,
+                                              ctx->libctx, ctx->propq))
                 goto err;
         } else {
             if ((local_crm = OSSL_CRMF_MSG_dup(crm)) == NULL)
@@ -956,19 +958,18 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
     return NULL;
 }
 
-/*
- * CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned
- * certificate from the given certResponse B<crep>.
- * Uses the privkey in case of indirect POP from B<ctx>.
+/*-
+ * Retrieve the newly enrolled certificate from the given certResponse crep.
+ * In case of indirect POPO uses the libctx and propq from ctx and private key.
  * Returns a pointer to a copy of the found certificate, or NULL if not found.
  */
-X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
-                                             const OSSL_CMP_CERTRESPONSE *crep)
+X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep,
+                                      const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey)
 {
     OSSL_CMP_CERTORENCCERT *coec;
     X509 *crt = NULL;
 
-    if (!ossl_assert(crep != NULL))
+    if (!ossl_assert(crep != NULL && ctx != NULL))
         return NULL;
 
     if (crep->certifiedKeyPair
@@ -979,13 +980,14 @@ X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
             break;
         case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT:
             /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */
-            if (privkey == NULL) {
+            if (pkey == NULL) {
                 CMPerr(0, CMP_R_MISSING_PRIVATE_KEY);
                 return NULL;
             }
             crt =
                 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert,
-                                                      privkey);
+                                                      ctx->libctx, ctx->propq,
+                                                      pkey);
             break;
         default:
             CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE);
@@ -994,6 +996,8 @@ X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
     }
     if (crt == NULL)
         CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND);
+    else
+        (void)x509_set0_libctx(crt, ctx->libctx, ctx->propq);
     return crt;
 }
 
diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c
index 0f70c29953..212ef92f50 100644
--- a/crypto/cmp/cmp_protect.c
+++ b/crypto/cmp/cmp_protect.c
@@ -21,67 +21,62 @@
 DEFINE_STACK_OF(X509)
 
 /*
- * This function is also used for verification from cmp_vfy.
+ * This function is also used by the internal verify_PBMAC() in cmp_vfy.c.
  *
- * Calculate protection for given PKImessage utilizing the given credentials
- * and the algorithm parameters set inside the message header's protectionAlg.
+ * Calculate protection for given PKImessage according to
+ * the algorithm and parameters in the message header's protectionAlg
+ * using the credentials, library context, and property criteria in the ctx.
  *
- * secret or pkey must be set. Attempts doing PBMAC in case 'secret' is set
- * and else signature if 'pkey' is set - but will only
- * do the protection already marked in msg->header->protectionAlg.
- *
- * returns ptr to ASN1_BIT_STRING containing protection on success, else NULL
+ * returns ASN1_BIT_STRING representing the protection on success, else NULL
  */
-ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
-                                          const ASN1_OCTET_STRING *secret,
-                                          EVP_PKEY *pkey)
+ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
+                                          const OSSL_CMP_MSG *msg)
 {
     ASN1_BIT_STRING *prot = NULL;
     OSSL_CMP_PROTECTEDPART prot_part;
     const ASN1_OBJECT *algorOID = NULL;
-    int len;
-    size_t prot_part_der_len;
-    unsigned char *prot_part_der = NULL;
-    size_t sig_len;
-    unsigned char *protection = NULL;
     const void *ppval = NULL;
     int pptype = 0;
-    OSSL_CRMF_PBMPARAMETER *pbm = NULL;
-    ASN1_STRING *pbm_str = NULL;
-    const unsigned char *pbm_str_uc = NULL;
-    EVP_MD_CTX *evp_ctx = NULL;
-    int md_NID;
-    const EVP_MD *md = NULL;
 
-    if (!ossl_assert(msg != NULL))
+    if (!ossl_assert(ctx != NULL && msg != NULL))
         return NULL;
 
     /* construct data to be signed */
     prot_part.header = msg->header;
     prot_part.body = msg->body;
 
-    len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
-    if (len < 0 || prot_part_der == NULL) {
-        CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
-        goto end;
-    }
-    prot_part_der_len = (size_t) len;
-
     if (msg->header->protectionAlg == NULL) {
         CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
-        goto end;
+        return NULL;
     }
     X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg);
 
-    if (secret != NULL) {
+    if (OBJ_obj2nid(algorOID) == NID_id_PasswordBasedMAC) {
+        int len;
+        size_t prot_part_der_len;
+        unsigned char *prot_part_der = NULL;
+        size_t sig_len;
+        unsigned char *protection = NULL;
+        OSSL_CRMF_PBMPARAMETER *pbm = NULL;
+        ASN1_STRING *pbm_str = NULL;
+        const unsigned char *pbm_str_uc = NULL;
+
+        if (ctx->secretValue == NULL) {
+            CMPerr(0, CMP_R_MISSING_PBM_SECRET);
+            return NULL;
+        }
         if (ppval == NULL) {
             CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
-            goto end;
+            return NULL;
         }
-        if (NID_id_PasswordBasedMAC != OBJ_obj2nid(algorOID)) {
-            CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
+
+        len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
+        if (len < 0 || prot_part_der == NULL) {
+            CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
             goto end;
         }
+        prot_part_der_len = (size_t)len;
+
         pbm_str = (ASN1_STRING *)ppval;
         pbm_str_uc = pbm_str->data;
         pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, pbm_str->length);
@@ -90,50 +85,49 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
             goto end;
         }
 
-        if (!OSSL_CRMF_pbm_new(pbm, prot_part_der, prot_part_der_len,
-                               secret->data, secret->length,
+        if (!OSSL_CRMF_pbm_new(ctx->libctx, ctx->propq,
+                               pbm, prot_part_der, prot_part_der_len,
+                               ctx->secretValue->data, ctx->secretValue->length,
                                &protection, &sig_len))
             goto end;
-    } else if (pkey != NULL) {
-        /* TODO combine this with large parts of CRMF_poposigningkey_init() */
-        /* EVP_DigestSignInit() checks that pkey type is correct for the alg */
 
-        if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_NID, NULL)
-                || (md = EVP_get_digestbynid(md_NID)) == NULL
-                || (evp_ctx = EVP_MD_CTX_new()) == NULL) {
-            CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
-            goto end;
-        }
-        if (EVP_DigestSignInit(evp_ctx, NULL, md, NULL, pkey) <= 0
-                || EVP_DigestSignUpdate(evp_ctx, prot_part_der,
-                                        prot_part_der_len) <= 0
-                || EVP_DigestSignFinal(evp_ctx, NULL, &sig_len) <= 0
-                || (protection = OPENSSL_malloc(sig_len)) == NULL
-                || EVP_DigestSignFinal(evp_ctx, protection, &sig_len) <= 0) {
-            CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
-            goto end;
+        if ((prot = ASN1_BIT_STRING_new()) == NULL)
+            return NULL;
+        /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
+        prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        prot->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+        if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) {
+            ASN1_BIT_STRING_free(prot);
+            prot = NULL;
         }
+    end:
+        OSSL_CRMF_PBMPARAMETER_free(pbm);
+        OPENSSL_free(protection);
+        OPENSSL_free(prot_part_der);
+        return prot;
     } else {
-        CMPerr(0, CMP_R_INVALID_ARGS);
-        goto end;
-    }
+        int md_nid;
+        const EVP_MD *md = NULL;
 
-    if ((prot = ASN1_BIT_STRING_new()) == NULL)
-        goto end;
-    /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
-    prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-    prot->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-    if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) {
+        if (ctx->pkey == NULL) {
+            CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
+            return NULL;
+        }
+        if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_nid, NULL)
+                || (md = EVP_get_digestbynid(md_nid)) == NULL) {
+            CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
+            return NULL;
+        }
+
+        if ((prot = ASN1_BIT_STRING_new()) == NULL)
+            return NULL;
+        if (ASN1_item_sign_with_libctx(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART),
+                                       NULL, NULL, prot, &prot_part, NULL,
+                                       ctx->pkey, md, ctx->libctx, ctx->propq))
+            return prot;
         ASN1_BIT_STRING_free(prot);
-        prot = NULL;
+        return NULL;
     }
-
- end:
-    OSSL_CRMF_PBMPARAMETER_free(pbm);
-    EVP_MD_CTX_free(evp_ctx);
-    OPENSSL_free(protection);
-    OPENSSL_free(prot_part_der);
-    return prot;
 }
 
 int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
@@ -154,7 +148,8 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
         /* if we have untrusted certs, try to add intermediate certs */
         if (ctx->untrusted_certs != NULL) {
             STACK_OF(X509) *chain =
-                ossl_cmp_build_cert_chain(ctx->untrusted_certs, ctx->cert);
+                ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq,
+                                          ctx->untrusted_certs, ctx->cert);
             int res = X509_add_certs(msg->extraCerts, chain,
                                      X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
                                      | X509_ADD_FLAG_NO_SS);
@@ -181,24 +176,22 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
 /*
  * Create an X509_ALGOR structure for PasswordBasedMAC protection based on
  * the pbm settings in the context
- * returns pointer to X509_ALGOR on success, NULL on error
  */
-static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx)
+static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg)
 {
-    X509_ALGOR *alg = NULL;
     OSSL_CRMF_PBMPARAMETER *pbm = NULL;
     unsigned char *pbm_der = NULL;
     int pbm_der_len;
     ASN1_STRING *pbm_str = NULL;
 
     if (!ossl_assert(ctx != NULL))
-        return NULL;
+        return 0;
 
-    alg = X509_ALGOR_new();
-    pbm = OSSL_CRMF_pbmp_new(ctx->pbm_slen, ctx->pbm_owf, ctx->pbm_itercnt,
+    pbm = OSSL_CRMF_pbmp_new(ctx->libctx, ctx->pbm_slen,
+                             EVP_MD_type(ctx->pbm_owf), ctx->pbm_itercnt,
                              ctx->pbm_mac);
     pbm_str = ASN1_STRING_new();
-    if (alg == NULL || pbm == NULL || pbm_str == NULL)
+    if (pbm == NULL || pbm_str == NULL)
         goto err;
 
     if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0)
@@ -206,19 +199,49 @@ static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx)
 
     if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len))
         goto err;
+    if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL)
+        goto err;
     OPENSSL_free(pbm_der);
 
-    X509_ALGOR_set0(alg, OBJ_nid2obj(NID_id_PasswordBasedMAC),
+    X509_ALGOR_set0(*alg, OBJ_nid2obj(NID_id_PasswordBasedMAC),
                     V_ASN1_SEQUENCE, pbm_str);
     OSSL_CRMF_PBMPARAMETER_free(pbm);
-    return alg;
+    return 1;
 
  err:
     ASN1_STRING_free(pbm_str);
-    X509_ALGOR_free(alg);
     OPENSSL_free(pbm_der);
     OSSL_CRMF_PBMPARAMETER_free(pbm);
-    return NULL;
+    return 0;
+}
+
+static int set_sig_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg)
+{
+    int nid = 0;
+    ASN1_OBJECT *algo = NULL;
+
+    if (!OBJ_find_sigid_by_algs(&nid, EVP_MD_type(ctx->digest),
+                                EVP_PKEY_id(ctx->pkey))) {
+        CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
+        return 0;
+    }
+    if ((algo = OBJ_nid2obj(nid)) == NULL)
+        return 0;
+    if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL)
+        return 0;
+
+    if (X509_ALGOR_set0(*alg, algo, V_ASN1_UNDEF, NULL))
+        return 1;
+    ASN1_OBJECT_free(algo);
+    return 0;
+}
+
+static int set_senderKID(const OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg,
+                         const ASN1_OCTET_STRING *id)
+{
+    if (id == NULL)
+        id = ctx->referenceValue; /* standard for PBM, fallback for sig-based */
+    return id == NULL || ossl_cmp_hdr_set1_senderKID(msg->header, id);
 }
 
 int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
@@ -240,20 +263,18 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
 
     /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */
     if (ctx->secretValue != NULL) {
-        if ((msg->header->protectionAlg = create_pbmac_algor(ctx)) == NULL)
+        if (!set_pbmac_algor(ctx, &msg->header->protectionAlg))
             goto err;
-        if (ctx->referenceValue != NULL
-                && !ossl_cmp_hdr_set1_senderKID(msg->header,
-                                                ctx->referenceValue))
+        if (!set_senderKID(ctx, msg, NULL))
             goto err;
-    } else if (ctx->cert != NULL && ctx->pkey != NULL) {
+
         /*
-         * use MSG_SIG_ALG according to 5.1.3.3 if client Certificate and
-         * private key is given
+         * will add any additional certificates from ctx->extraCertsOut
+         * while not needed to validate the protection certificate,
+         * the option to do this might be handy for certain use cases
          */
-        const ASN1_OCTET_STRING *subjKeyIDStr = NULL;
-        int algNID = 0;
-        ASN1_OBJECT *alg = NULL;
+    } else if (ctx->cert != NULL && ctx->pkey != NULL) {
+        /* use MSG_SIG_ALG according to 5.1.3.3 if client cert and key given */
 
         /* make sure that key and certificate match */
         if (!X509_check_private_key(ctx->cert, ctx->pkey)) {
@@ -261,37 +282,21 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
             goto err;
         }
 
-        if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
-            goto err;
-        if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
-                                    EVP_PKEY_id(ctx->pkey))) {
-            CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
-            goto err;
-        }
-        if ((alg = OBJ_nid2obj(algNID)) == NULL)
+        if (!set_sig_algor(ctx, &msg->header->protectionAlg))
             goto err;
-        if (!X509_ALGOR_set0(msg->header->protectionAlg, alg,
-                             V_ASN1_UNDEF, NULL)) {
-            ASN1_OBJECT_free(alg);
+        /* set senderKID to keyIdentifier of the cert according to 5.1.1 */
+        if (!set_senderKID(ctx, msg, X509_get0_subject_key_id(ctx->cert)))
             goto err;
-        }
 
         /*
-         * set senderKID to keyIdentifier of the used certificate according
-         * to section 5.1.1
+         * will add ctx->cert followed, if possible, by its chain built
+         * from ctx->untrusted_certs, and then ctx->extraCertsOut
          */
-        subjKeyIDStr = X509_get0_subject_key_id(ctx->cert);
-        if (subjKeyIDStr == NULL)
-            subjKeyIDStr = ctx->referenceValue; /* fallback */
-        if (subjKeyIDStr != NULL
-                && !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
-            goto err;
     } else {
         CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
         goto err;
     }
-    if ((msg->protection =
-         ossl_cmp_calc_protection(msg, ctx->secretValue, ctx->pkey)) == NULL)
+    if ((msg->protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)
         goto err;
 
     /*
diff --git a/crypto/cmp/cmp_server.c b/crypto/cmp/cmp_server.c
index a9a86cb5de..2ba6cb7984 100644
--- a/crypto/cmp/cmp_server.c
+++ b/crypto/cmp/cmp_server.c
@@ -53,14 +53,14 @@ void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx)
     OPENSSL_free(srv_ctx);
 }
 
-OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void)
+OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OPENSSL_CTX *libctx, const char *propq)
 {
     OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));
 
     if (ctx == NULL)
         goto err;
 
-    if ((ctx->ctx = OSSL_CMP_CTX_new()) == NULL)
+    if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL)
         goto err;
 
     /* all other elements are initialized to 0 or NULL, respectively */
@@ -206,7 +206,7 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
         certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
     }
 
-    if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) {
+    if (!ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) {
         /* Proof of possession could not be verified */
         si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
                                      1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c
index 0ec69d0bb5..c4797f1691 100644
--- a/crypto/cmp/cmp_util.c
+++ b/crypto/cmp/cmp_util.c
@@ -206,19 +206,19 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
 }
 
 /*-
- * Builds up the certificate chain of certs as high up as possible using
- * the given list of certs containing all possible intermediate certificates and
- * optionally the (possible) trust anchor(s). See also ssl_add_cert_chain().
+ * Builds up the chain of intermediate CA certificates
+ * starting from the given certificate <cert> as high up as possible using
+ * the given list of candidate certificates, similarly to ssl_add_cert_chain().
  *
  * Intended use of this function is to find all the certificates above the trust
  * anchor needed to verify an EE's own certificate.  Those are supposed to be
- * included in the ExtraCerts field of every first sent message of a transaction
+ * included in the ExtraCerts field of every first CMP message of a transaction
  * when MSG_SIG_ALG is utilized.
  *
  * NOTE: This allocates a stack and increments the reference count of each cert,
  * so when not needed any more the stack and all its elements should be freed.
- * NOTE: in case there is more than one possibility for the chain,
- * OpenSSL seems to take the first one, check X509_verify_cert() for details.
+ * NOTE: In case there is more than one possibility for the chain,
+ * OpenSSL seems to take the first one; check X509_verify_cert() for details.
  *
  * returns a pointer to a stack of (up_ref'ed) X509 certificates containing:
  *      - the EE certificate given in the function arguments (cert)
@@ -226,7 +226,9 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
  *        whereas the (self-signed) trust anchor is not included
  * returns NULL on error
  */
-STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert)
+STACK_OF(X509)
+    *ossl_cmp_build_cert_chain(OPENSSL_CTX *libctx, const char *propq,
+                               STACK_OF(X509) *certs, X509 *cert)
 {
     STACK_OF(X509) *chain = NULL, *result = NULL;
     X509_STORE *store = X509_STORE_new();
@@ -237,7 +239,7 @@ STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert)
         goto err;
     }
 
-    csc = X509_STORE_CTX_new();
+    csc = X509_STORE_CTX_new_with_libctx(libctx, propq);
     if (csc == NULL)
         goto err;
 
diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c
index 27dc612baf..b50a3fe83a 100644
--- a/crypto/cmp/cmp_vfy.c
+++ b/crypto/cmp/cmp_vfy.c
@@ -24,23 +24,12 @@
 
 DEFINE_STACK_OF(X509)
 
-/*-
- * Verify a message protected by signature according to section 5.1.3.3
- * (sha1+RSA/DSA or any other algorithm supported by OpenSSL).
- *
- * Returns 1 on successful validation and 0 otherwise.
- */
+/* Verify a message protected by signature according to RFC section 5.1.3.3 */
 static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
                             const OSSL_CMP_MSG *msg, X509 *cert)
 {
-    EVP_MD_CTX *ctx = NULL;
     OSSL_CMP_PROTECTEDPART prot_part;
-    int digest_nid, pk_nid;
-    const EVP_MD *digest = NULL;
     EVP_PKEY *pubkey = NULL;
-    int len;
-    size_t prot_part_der_len = 0;
-    unsigned char *prot_part_der = NULL;
     BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */
     int res = 0;
 
@@ -60,35 +49,13 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
         goto sig_err;
     }
 
-    /* create the DER representation of protected part */
     prot_part.header = msg->header;
     prot_part.body = msg->body;
 
-    len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
-    if (len < 0 || prot_part_der == NULL)
-        goto end;
-    prot_part_der_len = (size_t) len;
-
-    /* verify signature of protected part */
-    if (!OBJ_find_sigid_algs(ossl_cmp_hdr_get_protection_nid(msg->header),
-                             &digest_nid, &pk_nid)
-            || digest_nid == NID_undef || pk_nid == NID_undef
-            || (digest = EVP_get_digestbynid(digest_nid)) == NULL) {
-        CMPerr(0, CMP_R_ALGORITHM_NOT_SUPPORTED);
-        goto sig_err;
-    }
-
-    /* check msg->header->protectionAlg is consistent with public key type */
-    if (EVP_PKEY_type(pk_nid) != EVP_PKEY_base_id(pubkey)) {
-        CMPerr(0, CMP_R_WRONG_ALGORITHM_OID);
-        goto sig_err;
-    }
-    if ((ctx = EVP_MD_CTX_new()) == NULL)
-        goto end;
-    if (EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pubkey)
-            && EVP_DigestVerify(ctx, msg->protection->data,
-                                msg->protection->length,
-                                prot_part_der, prot_part_der_len) == 1) {
+    if (ASN1_item_verify_with_libctx(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART),
+                                     msg->header->protectionAlg,
+                                     msg->protection, &prot_part, NULL, pubkey,
+                                     cmp_ctx->libctx, cmp_ctx->propq) > 0) {
         res = 1;
         goto end;
     }
@@ -101,8 +68,6 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
     res = 0;
 
  end:
-    EVP_MD_CTX_free(ctx);
-    OPENSSL_free(prot_part_der);
     EVP_PKEY_free(pubkey);
     BIO_free(bio);
 
@@ -110,14 +75,13 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
 }
 
 /* Verify a message protected with PBMAC */
-static int verify_PBMAC(const OSSL_CMP_MSG *msg,
-                        const ASN1_OCTET_STRING *secret)
+static int verify_PBMAC(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
 {
     ASN1_BIT_STRING *protection = NULL;
     int valid = 0;
 
     /* generate expected protection for the message */
-    if ((protection = ossl_cmp_calc_protection(msg, secret, NULL)) == NULL)
+    if ((protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)
         return 0; /* failed to generate protection string! */
 
     valid = msg->protection != NULL && msg->protection->length >= 0
@@ -156,7 +120,7 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
         return 0;
     }
 
-    if ((csc = X509_STORE_CTX_new()) == NULL
+    if ((csc = X509_STORE_CTX_new_with_libctx(ctx->libctx, ctx->propq)) == NULL
             || !X509_STORE_CTX_init(csc, trusted_store,
                                     cert, ctx->untrusted_certs))
         goto err;
@@ -304,18 +268,23 @@ static int cert_acceptable(const OSSL_CMP_CTX *ctx,
 
     if (!check_kid(ctx, X509_get0_subject_key_id(cert), msg->header->senderKID))
         return 0;
+    /* prevent misleading error later in case x509v3_cache_extensions() fails */
+    if (!x509v3_cache_extensions(cert)) {
+        ossl_cmp_warn(ctx, "cert appears to be invalid");
+        return 0;
+    }
+    if (!verify_signature(ctx, msg, cert)) {
+        ossl_cmp_warn(ctx, "msg signature verification failed");
+        return 0;
+    }
     /* acceptable also if there is no senderKID in msg header */
     ossl_cmp_info(ctx, " cert seems acceptable");
     return 1;
 }
 
-static int check_msg_valid_cert(const OSSL_CMP_CTX *ctx, X509_STORE *store,
-                                X509 *scrt, const OSSL_CMP_MSG *msg)
+static int check_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *store,
+                           X509 *scrt)
 {
-    if (!verify_signature(ctx, msg, scrt)) {
-        ossl_cmp_warn(ctx, "msg signature verification failed");
-        return 0;
-    }
     if (OSSL_CMP_validate_cert_path(ctx, store, scrt))
         return 1;
 
@@ -328,11 +297,11 @@ static int check_msg_valid_cert(const OSSL_CMP_CTX *ctx, X509_STORE *store,
  * Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security
  * (NDS); Authentication Framework (AF)], only to use for IP messages
  * and if the ctx option is explicitly set: use self-issued certificates
- * from extraCerts as trust anchor to validate sender cert and msg -
+ * from extraCerts as trust anchor to validate sender cert -
  * provided it also can validate the newly enrolled certificate
  */
-static int check_msg_valid_cert_3gpp(const OSSL_CMP_CTX *ctx, X509 *scrt,
-                                     const OSSL_CMP_MSG *msg)
+static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx,
+                                const OSSL_CMP_MSG *msg, X509 *scrt)
 {
     int valid = 0;
     X509_STORE *store;
@@ -355,11 +324,11 @@ static int check_msg_valid_cert_3gpp(const OSSL_CMP_CTX *ctx, X509 *scrt,
          * verify that the newly enrolled certificate (which assumed rid ==
          * OSSL_CMP_CERTREQID) can also be validated with the same trusted store
          */
-        EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
+        EVP_PKEY *pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
         OSSL_CMP_CERTRESPONSE *crep =
             ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip,
                                                       OSSL_CMP_CERTREQID);
-        X509 *newcrt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
+        X509 *newcrt = ossl_cmp_certresponse_get1_cert(crep, ctx, pkey);
         /*
          * maybe better use get_cert_status() from cmp_client.c, which catches
          * errors
@@ -378,8 +347,8 @@ static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert,
 {
     return cert_acceptable(ctx, "previously validated", "sender cert",
                            cert, NULL, NULL, msg)
-        && (check_msg_valid_cert(ctx, ctx->trusted, cert, msg)
-            || check_msg_valid_cert_3gpp(ctx, cert, msg));
+        && (check_cert_path(ctx, ctx->trusted, cert)
+            || check_cert_path_3gpp(ctx, msg, cert));
 }
 
 /*-
@@ -411,8 +380,8 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
                              already_checked1, already_checked2, msg))
             continue;
         n_acceptable_certs++;
-        if (mode_3gpp ? check_msg_valid_cert_3gpp(ctx, cert, msg)
-                      : check_msg_valid_cert(ctx, ctx->trusted, cert, msg)) {
+        if (mode_3gpp ? check_cert_path_3gpp(ctx, msg, cert)
+                      : check_cert_path(ctx, ctx->trusted, cert)) {
             /* store successful sender cert for further msgs in transaction */
             if (!X509_up_ref(cert))
                 return 0;
@@ -598,13 +567,34 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
     switch (ossl_cmp_hdr_get_protection_nid(msg->header)) {
         /* 5.1.3.1.  Shared Secret Information */
     case NID_id_PasswordBasedMAC:
-        if (ctx->secretValue == 0) {
-            CMPerr(0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE);
-            break;
-        }
-
-        if (verify_PBMAC(msg, ctx->secretValue))
+        if (verify_PBMAC(ctx, msg)) {
+            /*
+             * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
+             * "shared secret information", then any certificate transported in
+             * the caPubs field may be directly trusted as a root CA
+             * certificate by the initiator.'
+             */
+            switch (ossl_cmp_msg_get_bodytype(msg)) {
+            case -1:
+                return 0;
+            case OSSL_CMP_PKIBODY_IP:
+            case OSSL_CMP_PKIBODY_CP:
+            case OSSL_CMP_PKIBODY_KUP:
+            case OSSL_CMP_PKIBODY_CCP:
+                if (ctx->trusted != NULL) {
+                    STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
+                    /* value.ip is same for cp, kup, and ccp */
+
+                    if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
+                        /* adds both self-issued and not self-issued certs */
+                        return 0;
+                }
+                break;
+            default:
+                break;
+            }
             return 1;
+        }
         break;
 
         /*
@@ -802,7 +792,7 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
                 if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
                     /* adds both self-issued and not self-issued certs */
                     return 0;
-                }
+            }
             break;
         default:
             break;
@@ -811,7 +801,8 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
     return 1;
 }
 
-int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
+int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx,
+                         const OSSL_CMP_MSG *msg, int acceptRAVerified)
 {
     if (!ossl_assert(msg != NULL && msg->body != NULL))
         return 0;
@@ -820,7 +811,8 @@ int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
         {
             X509_REQ *req = msg->body->value.p10cr;
 
-            if (X509_REQ_verify(req, X509_REQ_get0_pubkey(req)) <= 0) {
+            if (X509_REQ_verify_with_libctx(req, X509_REQ_get0_pubkey(req),
+                                            ctx->libctx, ctx->propq) <= 0) {
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
                 CMPerr(0, CMP_R_REQUEST_NOT_ACCEPTED);
                 return 0;
@@ -832,7 +824,8 @@ int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
     case OSSL_CMP_PKIBODY_CR:
     case OSSL_CMP_PKIBODY_KUR:
         if (!OSSL_CRMF_MSGS_verify_popo(msg->body->value.ir, OSSL_CMP_CERTREQID,
-                                        accept_RAVerified)) {
+                                        acceptRAVerified,
+                                        ctx->libctx, ctx->propq)) {
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
             return 0;
 #endif
diff --git a/crypto/crmf/crmf_err.c b/crypto/crmf/crmf_err.c
index 159d5b2c91..61a1488838 100644
--- a/crypto/crmf/crmf_err.c
+++ b/crypto/crmf/crmf_err.c
@@ -30,6 +30,8 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
     "iterationcount below 100"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"},
+    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED),
+    "poposkinput not supported"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY),
     "popo inconsistent public key"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"},
@@ -45,8 +47,6 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
     "setting owf algor failure"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM),
     "unsupported algorithm"},
-    {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY),
-    "unsupported alg for popsigningkey"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER),
     "unsupported cipher"},
     {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO),
diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c
index 7530120ff3..3202f357c1 100644
--- a/crypto/crmf/crmf_lib.c
+++ b/crypto/crmf/crmf_lib.c
@@ -353,57 +353,47 @@ int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm,
     return 0;
 }
 
-/* TODO: support cases 1+2 (besides case 3) defined in RFC 4211, section 4.1. */
-static int CRMF_poposigningkey_init(OSSL_CRMF_POPOSIGNINGKEY *ps,
-                                    OSSL_CRMF_CERTREQUEST *cr,
-                                    EVP_PKEY *pkey, int dgst)
+static int create_popo_signature(OSSL_CRMF_POPOSIGNINGKEY *ps,
+                                 const OSSL_CRMF_CERTREQUEST *cr,
+                                 EVP_PKEY *pkey, const EVP_MD *digest,
+                                 OPENSSL_CTX *libctx, const char *propq)
 {
-    int ret = 0;
-    EVP_MD *fetched_md = NULL;
-    const EVP_MD *md = EVP_get_digestbynid(dgst);
-
     if (ps == NULL || cr == NULL || pkey == NULL) {
-        CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_NULL_ARGUMENT);
+        CRMFerr(0, CRMF_R_NULL_ARGUMENT);
         return 0;
     }
-
-    /* If we didn't find legacy MD, we try an implicit fetch */
-    if (md == NULL)
-        md = fetched_md = EVP_MD_fetch(NULL, OBJ_nid2sn(dgst), NULL);
-
-    if (md == NULL) {
-        CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
-                CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
+    if (ps->poposkInput != NULL) {
+        /* TODO: support cases 1+2 defined in RFC 4211, section 4.1 */
+        CRMFerr(0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED);
         return 0;
     }
 
-    ret = ASN1_item_sign(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
-                         ps->algorithmIdentifier, NULL, ps->signature,
-                         cr, pkey, md);
-
-    EVP_MD_free(fetched_md);
-    return ret;
+    return ASN1_item_sign_with_libctx(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
+                                      ps->algorithmIdentifier, NULL,
+                                      ps->signature, cr, NULL, pkey, digest,
+                                      libctx, propq);
 }
 
 
-int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
-                              int dgst, int ppmtd)
+int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm,
+                              EVP_PKEY *pkey, const EVP_MD *digest,
+                              OPENSSL_CTX *libctx, const char *propq)
 {
     OSSL_CRMF_POPO *pp = NULL;
     ASN1_INTEGER *tag = NULL;
 
-    if (crm == NULL || (ppmtd == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) {
+    if (crm == NULL || (meth == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) {
         CRMFerr(CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, CRMF_R_NULL_ARGUMENT);
         return 0;
     }
 
-    if (ppmtd == OSSL_CRMF_POPO_NONE)
+    if (meth == OSSL_CRMF_POPO_NONE)
         goto end;
     if ((pp = OSSL_CRMF_POPO_new()) == NULL)
         goto err;
-    pp->type = ppmtd;
+    pp->type = meth;
 
-    switch (ppmtd) {
+    switch (meth) {
     case OSSL_CRMF_POPO_RAVERIFIED:
         if ((pp->value.raVerified = ASN1_NULL_new()) == NULL)
             goto err;
@@ -412,8 +402,11 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
     case OSSL_CRMF_POPO_SIGNATURE:
         {
             OSSL_CRMF_POPOSIGNINGKEY *ps = OSSL_CRMF_POPOSIGNINGKEY_new();
-            if (ps == NULL
-                    || !CRMF_poposigningkey_init(ps, crm->certReq, pkey, dgst)) {
+
+            if (ps == NULL)
+                goto err;
+            if (!create_popo_signature(ps, crm->certReq, pkey, digest,
+                                       libctx, propq)) {
                 OSSL_CRMF_POPOSIGNINGKEY_free(ps);
                 goto err;
             }
@@ -451,11 +444,14 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
 
 /* verifies the Proof-of-Possession of the request with the given rid in reqs */
 int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
-                               int rid, int acceptRAVerified)
+                               int rid, int acceptRAVerified,
+                               OPENSSL_CTX *libctx, const char *propq)
 {
     OSSL_CRMF_MSG *req = NULL;
     X509_PUBKEY *pubkey = NULL;
     OSSL_CRMF_POPOSIGNINGKEY *sig = NULL;
+    const ASN1_ITEM *it;
+    void *asn;
 
     if (reqs == NULL || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL) {
         CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, CRMF_R_NULL_ARGUMENT);
@@ -499,21 +495,21 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
              * TODO check the contents of the authInfo sub-field,
              * see RFC 4211 https://tools.ietf.org/html/rfc4211#section-4.1
              */
-            if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT),
-                                 sig->algorithmIdentifier, sig->signature,
-                                 sig->poposkInput,
-                                 X509_PUBKEY_get0(pubkey)) < 1)
-                return 0;
+            it = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT);
+            asn = sig->poposkInput;
         } else {
             if (req->certReq->certTemplate->subject == NULL) {
                 CRMFerr(0, CRMF_R_POPO_MISSING_SUBJECT);
                 return 0;
             }
-            if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
-                                 sig->algorithmIdentifier, sig->signature,
-                                 req->certReq, X509_PUBKEY_get0(pubkey)) < 1)
-                return 0;
+            it = ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST);
+            asn = req->certReq;
         }
+        if (ASN1_item_verify_with_libctx(it, sig->algorithmIdentifier,
+                                         sig->signature, asn, NULL,
+                                         X509_PUBKEY_get0(pubkey),
+                                         libctx, propq) < 1)
+            return 0;
         break;
     case OSSL_CRMF_POPO_KEYENC:
         /*
@@ -594,8 +590,10 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
  * returns a pointer to the decrypted certificate
  * returns NULL on error or if no certificate available
  */
-X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
-                                            EVP_PKEY *pkey)
+X509
+*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
+                                       OPENSSL_CTX *libctx, const char *propq,
+                                       EVP_PKEY *pkey)
 {
     X509 *cert = NULL; /* decrypted certificate */
     EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */
@@ -629,7 +627,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecer
     }
     cikeysize = EVP_CIPHER_key_length(cipher);
     /* first the symmetric key needs to be decrypted */
-    pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+    pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq);
     if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx)) {
         ASN1_BIT_STRING *encKey = ecert->encSymmKey;
         size_t failure;
@@ -685,10 +683,11 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecer
     outlen += n;
 
     /* convert decrypted certificate from DER to internal ASN.1 structure */
-    if ((cert = d2i_X509(NULL, &p, outlen)) == NULL) {
+    if ((cert = X509_new_with_libctx(libctx, propq)) == NULL)
+        goto end;
+    if (d2i_X509(&cert, &p, outlen) == NULL)
         CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
                 CRMF_R_ERROR_DECODING_CERTIFICATE);
-    }
  end:
     EVP_PKEY_CTX_free(pkctx);
     OPENSSL_free(outbuf);
diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c
index f674eeeff7..3aedf8b57f 100644
--- a/crypto/crmf/crmf_pbm.c
+++ b/crypto/crmf/crmf_pbm.c
@@ -29,14 +29,15 @@
 
 /*-
  * creates and initializes OSSL_CRMF_PBMPARAMETER (section 4.4)
- * |slen| SHOULD be > 8    (16 is common)
+ * |slen| SHOULD be at least 8 (16 is common)
  * |owfnid| e.g., NID_sha256
- * |itercnt| MUST be > 100 (500 is common)
+ * |itercnt| MUST be >= 100 (e.g., 500) and <= OSSL_CRMF_PBM_MAX_ITERATION_COUNT
  * |macnid| e.g., NID_hmac_sha1
  * returns pointer to OSSL_CRMF_PBMPARAMETER on success, NULL on error
  */
-OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid,
-                                           int itercnt, int macnid)
+OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OPENSSL_CTX *libctx, size_t slen,
+                                           int owfnid, size_t itercnt,
+                                           int macnid)
 {
     OSSL_CRMF_PBMPARAMETER *pbm = NULL;
     unsigned char *salt = NULL;
@@ -51,7 +52,7 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid,
      */
     if ((salt = OPENSSL_malloc(slen)) == NULL)
         goto err;
-    if (RAND_bytes(salt, (int)slen) <= 0) {
+    if (RAND_bytes_ex(libctx, salt, (int)slen) <= 0) {
         CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_FAILURE_OBTAINING_RANDOM);
         goto err;
     }
@@ -82,6 +83,10 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid,
         CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_ITERATIONCOUNT_BELOW_100);
         goto err;
     }
+    if (itercnt > OSSL_CRMF_PBM_MAX_ITERATION_COUNT) {
+        CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_BAD_PBM_ITERATIONCOUNT);
+        goto err;
+    }
 
     if (!ASN1_INTEGER_set(pbm->iterationCount, itercnt)) {
         CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_CRMFERROR);
@@ -117,14 +122,16 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid,
  * |maclen| if not NULL, will set variable to the length of the mac on success
  * returns 1 on success, 0 on error
  */
-int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
+/* TODO try to combine with other MAC calculations in the libray */
+int OSSL_CRMF_pbm_new(OPENSSL_CTX *libctx, const char *propq,
+                      const OSSL_CRMF_PBMPARAMETER *pbmp,
                       const unsigned char *msg, size_t msglen,
                       const unsigned char *sec, size_t seclen,
                       unsigned char **out, size_t *outlen)
 {
     int mac_nid, hmac_md_nid = NID_undef;
-    const char *mdname = NULL;
-    const EVP_MD *m = NULL;
+    const char *mdname;
+    EVP_MD *owf = NULL;
     EVP_MD_CTX *ctx = NULL;
     unsigned char basekey[EVP_MAX_MD_SIZE];
     unsigned int bklen = EVP_MAX_MD_SIZE;
@@ -148,7 +155,8 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
      * compute the key used in the MAC process.  All implementations MUST
      * support SHA-1.
      */
-    if ((m = EVP_get_digestbyobj(pbmp->owf->algorithm)) == NULL) {
+    mdname = OBJ_nid2sn(OBJ_obj2nid(pbmp->owf->algorithm));
+    if ((owf = EVP_MD_fetch(libctx, mdname, propq)) == NULL) {
         CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM);
         goto err;
     }
@@ -157,7 +165,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
         goto err;
 
     /* compute the basekey of the salted secret */
-    if (!EVP_DigestInit_ex(ctx, m, NULL))
+    if (!EVP_DigestInit_ex(ctx, owf, NULL))
         goto err;
     /* first the secret */
     if (!EVP_DigestUpdate(ctx, sec, seclen))
@@ -176,7 +184,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
 
     /* the first iteration was already done above */
     while (--iterations > 0) {
-        if (!EVP_DigestInit_ex(ctx, m, NULL))
+        if (!EVP_DigestInit_ex(ctx, owf, NULL))
             goto err;
         if (!EVP_DigestUpdate(ctx, basekey, bklen))
             goto err;
@@ -201,7 +209,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
                                                     (char *)mdname, 0);
     macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
                                                      basekey, bklen);
-    if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL
+    if ((mac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL
             || (mctx = EVP_MAC_CTX_new(mac)) == NULL
             || !EVP_MAC_CTX_set_params(mctx, macparams)
             || !EVP_MAC_init(mctx)
@@ -212,10 +220,10 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
     ok = 1;
 
  err:
-    /* cleanup */
     OPENSSL_cleanse(basekey, bklen);
     EVP_MAC_CTX_free(mctx);
     EVP_MAC_free(mac);
+    EVP_MD_free(owf);
     EVP_MD_CTX_free(ctx);
 
     if (ok == 1) {
diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c
index 8b63e6918d..75693e35f7 100644
--- a/crypto/ec/ecx_meth.c
+++ b/crypto/ec/ecx_meth.c
@@ -570,9 +570,9 @@ static int ecd_size448(const EVP_PKEY *pkey)
     return ED448_SIGSIZE;
 }
 
-static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
-                           X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
-                           EVP_PKEY *pkey)
+static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
+                           const void *asn, const X509_ALGOR *sigalg,
+                           const ASN1_BIT_STRING *str, EVP_PKEY *pkey)
 {
     const ASN1_OBJECT *obj;
     int ptype;
@@ -592,7 +592,8 @@ static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
     return 2;
 }
 
-static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
+                              const void *asn,
                               X509_ALGOR *alg1, X509_ALGOR *alg2,
                               ASN1_BIT_STRING *str)
 {
@@ -612,7 +613,8 @@ static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
     return 1;
 }
 
-static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
+                            const void *asn,
                             X509_ALGOR *alg1, X509_ALGOR *alg2,
                             ASN1_BIT_STRING *str)
 {
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index e83f1013ec..10531ead7a 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -40,7 +40,6 @@ ASN1_F_ASN1_ITEM_FLAGS_I2D:118:asn1_item_flags_i2d
 ASN1_F_ASN1_ITEM_I2D_BIO:192:ASN1_item_i2d_bio
 ASN1_F_ASN1_ITEM_I2D_FP:193:ASN1_item_i2d_fp
 ASN1_F_ASN1_ITEM_PACK:198:ASN1_item_pack
-ASN1_F_ASN1_ITEM_SIGN:195:ASN1_item_sign
 ASN1_F_ASN1_ITEM_SIGN_CTX:220:ASN1_item_sign_ctx
 ASN1_F_ASN1_ITEM_UNPACK:199:ASN1_item_unpack
 ASN1_F_ASN1_ITEM_VERIFY:197:ASN1_item_verify
@@ -2094,7 +2093,6 @@ CMP_R_CERTREQMSG_NOT_FOUND:157:certreqmsg not found
 CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found
 CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match
 CMP_R_CHECKAFTER_OUT_OF_RANGE:181:checkafter out of range
-CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE:166:checking pbm no secret available
 CMP_R_ENCOUNTERED_KEYUPDATEWARNING:176:encountered keyupdatewarning
 CMP_R_ENCOUNTERED_WAITING:162:encountered waiting
 CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection
@@ -2125,6 +2123,7 @@ CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\
 	missing key input for creating protection
 CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE:142:missing key usage digitalsignature
 CMP_R_MISSING_P10CSR:121:missing p10csr
+CMP_R_MISSING_PBM_SECRET:166:missing pbm secret
 CMP_R_MISSING_PRIVATE_KEY:131:missing private key
 CMP_R_MISSING_PROTECTION:143:missing protection
 CMP_R_MISSING_REFERENCE_CERT:168:missing reference cert
@@ -2297,6 +2296,7 @@ CRMF_R_FAILURE_OBTAINING_RANDOM:107:failure obtaining random
 CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100
 CRMF_R_MALFORMED_IV:101:malformed iv
 CRMF_R_NULL_ARGUMENT:109:null argument
+CRMF_R_POPOSKINPUT_NOT_SUPPORTED:113:poposkinput not supported
 CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key
 CRMF_R_POPO_MISSING:121:popo missing
 CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key
@@ -2305,7 +2305,6 @@ CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED:120:popo raverified not accepted
 CRMF_R_SETTING_MAC_ALGOR_FAILURE:110:setting mac algor failure
 CRMF_R_SETTING_OWF_ALGOR_FAILURE:111:setting owf algor failure
 CRMF_R_UNSUPPORTED_ALGORITHM:112:unsupported algorithm
-CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY:113:unsupported alg for popsigningkey
 CRMF_R_UNSUPPORTED_CIPHER:114:unsupported cipher
 CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\
 	unsupported method for creating popo
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 7476efd9bc..7caab8a5f7 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -13,6 +13,7 @@
 #include <stdio.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
+#include <openssl/ec.h>
 #include <openssl/engine.h>
 #include <openssl/params.h>
 #include <openssl/core_names.h>
@@ -73,6 +74,37 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
     return 1;
 }
 
+#ifndef FIPS_MODULE
+EVP_MD_CTX *evp_md_ctx_new_with_libctx(EVP_PKEY *pkey,
+                                       const ASN1_OCTET_STRING *id,
+                                       OPENSSL_CTX *libctx, const char *propq)
+{
+    EVP_MD_CTX *ctx;
+    EVP_PKEY_CTX *pctx = NULL;
+
+    if ((ctx = EVP_MD_CTX_new()) == NULL
+        || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq)) == NULL) {
+        ASN1err(0, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+# ifndef OPENSSL_NO_EC
+    if (id != NULL && EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0) {
+        ASN1err(0, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+# endif
+
+    EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
+    return ctx;
+
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    EVP_MD_CTX_free(ctx);
+    return NULL;
+}
+#endif
+
 EVP_MD_CTX *EVP_MD_CTX_new(void)
 {
     return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 749cd8764b..130f6156c5 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -696,7 +696,7 @@ static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx)
  */
 
 static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
-                          X509_ALGOR *sigalg, EVP_PKEY *pkey)
+                          const X509_ALGOR *sigalg, EVP_PKEY *pkey)
 {
     int rv = -1;
     int saltlen;
@@ -876,9 +876,9 @@ static int rsa_cms_verify(CMS_SignerInfo *si)
  * is encountered requiring special handling. We currently only handle PSS.
  */
 
-static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
-                           X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
-                           EVP_PKEY *pkey)
+static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
+                           const void *asn, const X509_ALGOR *sigalg,
+                           const ASN1_BIT_STRING *sig, EVP_PKEY *pkey)
 {
     /* Sanity check: make sure it is PSS */
     if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) {
@@ -920,7 +920,7 @@ static int rsa_cms_sign(CMS_SignerInfo *si)
 }
 #endif
 
-static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn,
                          X509_ALGOR *alg1, X509_ALGOR *alg2,
                          ASN1_BIT_STRING *sig)
 {
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index 9e0190a038..d7d0aae3b3 100644
--- a/crypto/x509/v3_purp.c
+++ b/crypto/x509/v3_purp.c
@@ -396,6 +396,7 @@ int x509v3_cache_extensions(X509 *x)
         CRYPTO_THREAD_unlock(x->lock);
         return (x->ex_flags & EXFLAG_INVALID) == 0;
     }
+    ERR_set_mark();
 
     if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL))
             x->ex_flags |= EXFLAG_INVALID;
@@ -572,6 +573,7 @@ int x509v3_cache_extensions(X509 *x)
      * all stores are visible on all processors. Hence the release fence.
      */
 #endif
+    ERR_pop_to_mark();
     CRYPTO_THREAD_unlock(x->lock);
 
     return (x->ex_flags & EXFLAG_INVALID) == 0;
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index 12a666884b..a8ad292074 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -27,76 +27,23 @@
 #include "crypto/pkcs7.h"
 #include "crypto/x509.h"
 
-static void clean_id_ctx(EVP_MD_CTX *ctx)
-{
-    EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(ctx);
-
-    EVP_PKEY_CTX_free(pctx);
-    EVP_MD_CTX_free(ctx);
-}
-
-static EVP_MD_CTX *make_id_ctx(EVP_PKEY *r, ASN1_OCTET_STRING *id,
-                               OPENSSL_CTX *libctx, const char *propq)
-{
-    EVP_MD_CTX *ctx = NULL;
-    EVP_PKEY_CTX *pctx = NULL;
-
-    if ((ctx = EVP_MD_CTX_new()) == NULL
-        || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, r, propq)) == NULL) {
-        X509err(0, ERR_R_MALLOC_FAILURE);
-        goto error;
-    }
-
-#ifndef OPENSSL_NO_EC
-    if (id != NULL) {
-        if (EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0) {
-            X509err(0, ERR_R_MALLOC_FAILURE);
-            goto error;
-        }
-    }
-#endif
-
-    EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
-
-    return ctx;
- error:
-    EVP_PKEY_CTX_free(pctx);
-    EVP_MD_CTX_free(ctx);
-    return NULL;
-}
-
 int X509_verify(X509 *a, EVP_PKEY *r)
 {
-    int rv = 0;
-    EVP_MD_CTX *ctx = NULL;
-    ASN1_OCTET_STRING *id = NULL;
-
     if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature))
         return 0;
 
-    id = a->distinguishing_id;
-    if ((ctx = make_id_ctx(r, id, a->libctx, a->propq)) != NULL) {
-        rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
-                                  &a->signature, &a->cert_info, ctx);
-        clean_id_ctx(ctx);
-    }
-    return rv;
+    return ASN1_item_verify_with_libctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
+                                        &a->signature, &a->cert_info,
+                                        a->distinguishing_id, r,
+                                        a->libctx, a->propq);
 }
 
 int X509_REQ_verify_with_libctx(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx,
                                 const char *propq)
 {
-    int rv = 0;
-    EVP_MD_CTX *ctx = NULL;
-    ASN1_OCTET_STRING *id = NULL;
-
-    id = a->distinguishing_id;
-    if ((ctx = make_id_ctx(r, id, libctx, propq)) != NULL) {
-        rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), &a->sig_alg,
-                                  a->signature, &a->req_info, ctx);
-        clean_id_ctx(ctx);
-    }
-    return rv;
+    return ASN1_item_verify_with_libctx(ASN1_ITEM_rptr(X509_REQ_INFO),
+                                        &a->sig_alg, a->signature, &a->req_info,
+                                        a->distinguishing_id, r, libctx, propq);
 }
 
 int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 64bf5faa83..5ee284666c 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -152,10 +152,7 @@ X509 *X509_new_with_libctx(OPENSSL_CTX *libctx, const char *propq)
     X509 *cert = NULL;
 
     cert = (X509 *)ASN1_item_new((X509_it()));
-    if (cert != NULL) {
-        cert->libctx = libctx;
-        cert->propq = propq;
-    }
+    (void)x509_set0_libctx(cert, libctx, propq);
     return cert;
 }
 
diff --git a/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod b/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod
index 3d91f8a073..a154cda1c9 100644
--- a/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod
+++ b/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod
@@ -3,9 +3,8 @@
 =head1 NAME
 
 ossl_cmp_asn1_octet_string_set1,
-ossl_cmp_asn1_octet_string_set1_bytes,
-ossl_cmp_build_cert_chain
-- misc internal utility functions
+ossl_cmp_asn1_octet_string_set1_bytes
+- ASN.1 octet string utility functions
 
 =head1 SYNOPSIS
 
@@ -16,32 +15,19 @@ ossl_cmp_build_cert_chain
  int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
                                            const unsigned char *bytes, int len);
 
- STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert);
-
 =head1 DESCRIPTION
 
 ossl_cmp_asn1_octet_string_set1() frees any previous value of the variable
 referenced via the I<tgt> argument and assigns either a copy of
 the ASN1_OCTET_STRING given as the I<src> argument or NULL.
-It returns 1 on success, 0 on error.
 
 ossl_cmp_asn1_octet_string_set1_bytes() frees any previous value of the variable
 referenced via the I<tgt> argument and assigns either a copy of the given byte
-string (with the given length) or NULL. It returns 1 on success, 0 on error.
-
-ossl_cmp_build_cert_chain() builds up the certificate chain of cert as high up
-as possible using the given X509_STORE containing all possible intermediate
-certificates and optionally the (possible) trust anchor(s).
+string (with the given length) or NULL.
 
 =head1 RETURN VALUES
 
-ossl_cmp_build_cert_chain()
-returns NULL on error, else a pointer to a stack of (up_ref'ed) certificates
-containing the EE certificate given in the function arguments (cert)
-and all intermediate certificates up the chain toward the trust anchor.
-The (self-signed) trust anchor is not included.
-
-All other functions return 1 on success, 0 on error.
+All functions return 1 on success, 0 on error.
 
 =head1 HISTORY
 
diff --git a/doc/internal/man3/ossl_cmp_hdr_init.pod b/doc/internal/man3/ossl_cmp_hdr_init.pod
index 0c6405054f..60259dd4bd 100644
--- a/doc/internal/man3/ossl_cmp_hdr_init.pod
+++ b/doc/internal/man3/ossl_cmp_hdr_init.pod
@@ -22,7 +22,7 @@ ossl_cmp_hdr_init
 
 =head1 SYNOPSIS
 
-  #include "cmp_int.h"
+  #include "cmp_local.h"
 
   int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
   int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
diff --git a/doc/internal/man3/ossl_cmp_mock_srv_new.pod b/doc/internal/man3/ossl_cmp_mock_srv_new.pod
index da1f44b391..3a90edfa4a 100644
--- a/doc/internal/man3/ossl_cmp_mock_srv_new.pod
+++ b/doc/internal/man3/ossl_cmp_mock_srv_new.pod
@@ -15,9 +15,9 @@ ossl_cmp_mock_srv_set_checkAfterTime
 
 =head1 SYNOPSIS
 
- #include <openssl/cmp.h>
+ #include "apps/cmp_mock_srv.h"
 
- OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void);
+ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OPENSSL_CTX *libctx, const char *propq);
  void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
 
  int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
@@ -33,7 +33,9 @@ ossl_cmp_mock_srv_set_checkAfterTime
 
 =head1 DESCRIPTION
 
-ossl_cmp_mock_srv_new() allocates the contexts for the CMP mock server.
+ossl_cmp_mock_srv_new() allocates the contexts for the CMP mock server
+associated with the library context I<libctx> and property query string
+I<propq>, both of which may be NULL to select the defaults.
 
 ossl_cmp_mock_srv_free() deallocates the contexts for the CMP mock server.
 
diff --git a/doc/internal/man3/ossl_cmp_msg_create.pod b/doc/internal/man3/ossl_cmp_msg_create.pod
index 0a10a6567e..aca0a996f4 100644
--- a/doc/internal/man3/ossl_cmp_msg_create.pod
+++ b/doc/internal/man3/ossl_cmp_msg_create.pod
@@ -12,7 +12,7 @@ ossl_cmp_msg_gen_ITAVs_push1
 
 =head1 SYNOPSIS
 
-  #include "cmp_int.h"
+  #include "cmp_local.h"
 
   const char *ossl_cmp_bodytype_to_string(int type);
   int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg);
diff --git a/doc/internal/man3/ossl_cmp_msg_protect.pod b/doc/internal/man3/ossl_cmp_msg_protect.pod
index bf859cdbda..6c33db6954 100644
--- a/doc/internal/man3/ossl_cmp_msg_protect.pod
+++ b/doc/internal/man3/ossl_cmp_msg_protect.pod
@@ -2,31 +2,56 @@
 
 =head1 NAME
 
+ossl_cmp_build_cert_chain,
+ossl_cmp_calc_protection,
 ossl_cmp_msg_protect,
 ossl_cmp_msg_add_extraCerts
 - functions for producing CMP message protection
 
 =head1 SYNOPSIS
 
-  #include "cmp_int.h"
+ #include "cmp_local.h"
 
-  int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
-  int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
+ STACK_OF(X509)
+     *ossl_cmp_build_cert_chain(OPENSSL_CTX *libctx, const char *propq,
+                                STACK_OF(X509) *certs, X509 *cert);
+ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
+                                           const OSSL_CMP_MSG *msg);
+ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
+ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
 
 =head1 DESCRIPTION
 
-ossl_cmp_msg_protect() (re-)protects the given message B<msg> using an algorithm
-depending on the available context information given in the B<ctx>.
+ossl_cmp_build_cert_chain() builds up the chain of intermediate CA certificates
+starting from the given certificate I<cert> as high up as possible using
+the given list of candidate certificates, similarly to ssl_add_cert_chain().
+It internally uses a B<X509_STORE_CTX> structure associated with the library
+context I<libctx> and property query string I<propq>, both of which may be NULL.
+Intended use of this function is to find all the certificates above the trust
+anchor needed to verify an EE's own certificate.
+Those are supposed to be included in the ExtraCerts field of every first
+CMP message of a transaction when MSG_SIG_ALG is utilized.
+This allocates a stack and increments the reference count of each cert,
+so when not needed any more the stack and all its elements should be freed.
+In case there is more than one possibility for the chain,
+OpenSSL seems to take the first one; check X509_verify_cert() for details.
+
+ossl_cmp_calc_protection() calculates the protection for the given I<msg>
+according to the algorithm and parameters in the message header's protectionAlg
+using the credentials, library context, and property criteria in the I<ctx>.
+
+ossl_cmp_msg_protect() (re-)protects the given message I<msg> using an algorithm
+depending on the available context information given in the I<ctx>.
 If there is a secretValue it selects PBMAC, else if there is a protection cert
-it selects Signature and uses B<ossl_cmp_msg_add_extraCerts()>.
+it selects Signature and uses L<ossl_cmp_msg_add_extraCerts(3)>.
 It also sets the protectionAlg field in the message header accordingly.
 
 ossl_cmp_msg_add_extraCerts() adds elements to the extraCerts field in the given
-message B<msg>. It tries to build the certificate chain of the client cert in
-the B<ctx> if present by using certificates in ctx->untrusted_certs;
+message I<msg>. It tries to build the certificate chain of the client cert in
+the I<ctx> if present by using certificates in ctx->untrusted_certs;
 if no untrusted certs are set, it will at least add the client certificate.
 In any case all the certificates explicitly specified to be sent out (i.e.,
-B<ctx->extraCertsOut>) are added. Note that it will NOT add the root certificate
+I<ctx->extraCertsOut>) are added. Note that it will NOT add the root certificate
 of the chain, i.e, the trust anchor (unless it is part of extraCertsOut).
 
 =head1 NOTES
@@ -35,7 +60,15 @@ CMP is defined in RFC 4210 (and CRMF in RFC 4211).
 
 =head1 RETURN VALUES
 
-All functions return 1 on success, 0 on error.
+ossl_cmp_build_cert_chain() returns NULL on error,
+else a pointer to a stack of (up_ref'ed) certificates
+containing the EE certificate given in the function arguments (cert)
+and all intermediate certificates up the chain toward the trust anchor.
+The (self-signed) trust anchor is not included.
+
+ossl_cmp_calc_protection() returns the protection on success, else NULL.
+
+All other functions return 1 on success, 0 on error.
 
 =head1 HISTORY
 
diff --git a/doc/internal/man3/ossl_cmp_pkisi_get_status.pod b/doc/internal/man3/ossl_cmp_pkisi_get_status.pod
index cd32c9015d..21f6f90b39 100644
--- a/doc/internal/man3/ossl_cmp_pkisi_get_status.pod
+++ b/doc/internal/man3/ossl_cmp_pkisi_get_status.pod
@@ -2,6 +2,7 @@
 
 =head1 NAME
 
+ossl_cmp_certresponse_get1_cert,
 ossl_cmp_pkisi_get_status,
 ossl_cmp_PKIStatus_to_string,
 ossl_cmp_pkisi_get0_statusString,
@@ -42,6 +43,8 @@ ossl_cmp_pkisi_check_pkifailureinfo
 # define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq    26
 # define OSSL_CMP_PKIFAILUREINFO_MAX                 26
 
+  X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep,
+                                        const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey);
   int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
   const char *ossl_cmp_PKIStatus_to_string(int status);
   OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
@@ -50,19 +53,23 @@ ossl_cmp_pkisi_check_pkifailureinfo
 
 =head1 DESCRIPTION
 
-ossl_cmp_pkisi_get_status() returns the PKIStatus of B<si>, or -1 on error.
+ossl_cmp_certresponse_get1_cert() returns a pointer to a copy of the newly
+enrolled certificate from the given certResponse I<crep>, or NULL on error.
+In case of indirect POPO uses data from the I<ctx> and the private key I<pkey>.
+
+ossl_cmp_pkisi_get_status() returns the PKIStatus of I<si>, or -1 on error.
 
 ossl_cmp_PKIStatus_to_string() returns a human-readable string representing
 the PKIStatus values as specified in RFC 4210, Appendix F.
 
 ossl_cmp_pkisi_get0_statusString() returns a direct pointer to the statusString
-field contained in B<si>.
+field contained in I<si>.
 
 ossl_cmp_pkisi_get_pkifailureinfo() returns the PKIFailureInfo bits
-of B<si>, encoded as integer, or -1 on error.
+of I<si>, encoded as integer, or -1 on error.
 
 ossl_cmp_pkisi_check_pkifailureinfo() returns the state of the bit (0 or 1)
-with index B<index> in the PKIFailureInfo of the B<si>, or -1 on error.
+with index I<index> in the PKIFailureInfo of the I<si>, or -1 on error.
 
 =head1 NOTES
 
diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod
index 368d73f820..62e1a562c9 100644
--- a/doc/man3/OSSL_CMP_CTX_new.pod
+++ b/doc/man3/OSSL_CMP_CTX_new.pod
@@ -64,7 +64,7 @@ OSSL_CMP_CTX_set1_senderNonce
 
  #include <openssl/cmp.h>
 
- OSSL_CMP_CTX *OSSL_CMP_CTX_new(void);
+ OSSL_CMP_CTX *OSSL_CMP_CTX_new(OPENSSL_CTX *libctx, const char *propq);
  void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx);
  int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx);
  int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val);
@@ -158,8 +158,13 @@ OSSL_CMP_CTX_set1_senderNonce
 This is the context API for using CMP (Certificate Management Protocol) with
 OpenSSL.
 
-OSSL_CMP_CTX_new() allocates and initializes an OSSL_CMP_CTX structure to
-default values, e.g., proof-of-possession method is set to POPOSigningKey.
+OSSL_CMP_CTX_new() allocates an B<OSSL_CMP_CTX> structure associated with
+the library context I<libctx> and property query string I<propq>,
+both of which may be NULL to select the defaults.
+It initializes the remaining fields to their default values - for instance,
+the logging verbosity is set to OSSL_CMP_LOG_INFO,
+the message timeout is set to 120 seconds,
+and the proof-of-possession method is set to OSSL_CRMF_POPO_SIGNATURE.
 
 OSSL_CMP_CTX_free() deallocates an OSSL_CMP_CTX structure.
 
diff --git a/doc/man3/OSSL_CMP_SRV_CTX_new.pod b/doc/man3/OSSL_CMP_SRV_CTX_new.pod
index 27d4f6ca1e..7d87d7df2c 100644
--- a/doc/man3/OSSL_CMP_SRV_CTX_new.pod
+++ b/doc/man3/OSSL_CMP_SRV_CTX_new.pod
@@ -29,7 +29,7 @@ OSSL_CMP_SRV_CTX_set_grant_implicit_confirm
                                             const OSSL_CMP_MSG *req);
  OSSL_CMP_MSG *OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
                                            const OSSL_CMP_MSG *req);
- OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void);
+ OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OPENSSL_CTX *libctx, const char *propq);
  void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx);
 
  typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_cert_request_cb_t)(
@@ -95,8 +95,9 @@ B<OSSL_CMP_SRV_process_request()> that can be used by a CMP client
 in the same way as B<OSSL_CMP_MSG_http_perform()>.
 The B<OSSL_CMP_SRV_CTX> must be set as I<transfer_cb_arg> of I<client_ctx>.
 
-OSSL_CMP_SRV_CTX_new() creates and initializes an OSSL_CMP_SRV_CTX structure
-and returns a pointer to it on success, NULL on error.
+OSSL_CMP_SRV_CTX_new() creates and initializes an B<OSSL_CMP_SRV_CTX> structure
+associated with the library context I<libctx> and property query string 
+I<propq>, both of which may be NULL to select the defaults.
 
 OSSL_CMP_SRV_CTX_free() deletes the given I<srv_ctx>.
 
diff --git a/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod b/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod
index 8e8bd7263f..e71cc52422 100644
--- a/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod
+++ b/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod
@@ -26,6 +26,7 @@ OSSL_CRMF_MSG_get_certReqId
 
  X509
  *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
+                                        OPENSSL_CTX *libctx, const char *propq,
                                         EVP_PKEY *pkey);
 
  int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm);
@@ -33,27 +34,28 @@ OSSL_CRMF_MSG_get_certReqId
 
 =head1 DESCRIPTION
 
-OSSL_CRMF_MSG_get0_tmpl() retrieves the certificate template of B<crm>.
+OSSL_CRMF_MSG_get0_tmpl() retrieves the certificate template of I<crm>.
 
 OSSL_CRMF_CERTTEMPLATE_get0_serialNumber() retrieves the serialNumber of the
-given certificate template B<tmpl>.
+given certificate template I<tmpl>.
 
 OSSL_CRMF_CERTTEMPLATE_get0_issuer() retrieves the issuer name of the
-given certificate template B<tmpl>.
+given certificate template I<tmpl>.
 
 OSSL_CRMF_CERTID_get0_serialNumber retrieves the serialNumber
-of the given CertId B<cid>.
+of the given CertId I<cid>.
 
 OSSL_CRMF_CERTID_get0_issuer retrieves the issuer name
-of the given CertId B<cid>, which must be of ASN.1 type GEN_DIRNAME.
+of the given CertId I<cid>, which must be of ASN.1 type GEN_DIRNAME.
 
 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert() decrypts the certificate in the given
-encryptedValue B<ecert>, using the private key B<pkey>.
-This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2.
+encryptedValue I<ecert>, using the private key I<pkey>, library context
+I<libctx> and property query string I<propq> (see L<OPENSSL_CTX(3)>).
+This is needed for the indirect POPO method as in RFC 4210 section 5.2.8.2.
 The function returns the decrypted certificate as a copy, leaving its ownership
 with the caller, who is responsible for freeing it.
 
-OSSL_CRMF_MSG_get_certReqId() retrieves the certReqId of B<crm>.
+OSSL_CRMF_MSG_get_certReqId() retrieves the certReqId of I<crm>.
 
 
 =head1 RETURN VALUES
@@ -65,7 +67,7 @@ All other functions return a pointer with the intended result or NULL on error.
 
 =head1 SEE ALSO
 
-B<RFC 4211>
+RFC 4211
 
 =head1 HISTORY
 
diff --git a/doc/man3/OSSL_CRMF_MSG_set0_validity.pod b/doc/man3/OSSL_CRMF_MSG_set0_validity.pod
index 54ebe0f856..8612049d73 100644
--- a/doc/man3/OSSL_CRMF_MSG_set0_validity.pod
+++ b/doc/man3/OSSL_CRMF_MSG_set0_validity.pod
@@ -30,11 +30,13 @@ OSSL_CRMF_MSGS_verify_popo
 
  int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext);
 
- int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
-                               int dgst, int ppmtd);
+ int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm,
+                               EVP_PKEY *pkey, const EVP_MD *digest,
+                               OPENSSL_CTX *libctx, const char *propq);
 
  int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
-                                int rid, int acceptRAVerified);
+                                int rid, int acceptRAVerified,
+                                OPENSSL_CTX *libctx, const char *propq);
 
 =head1 DESCRIPTION
 
@@ -59,11 +61,13 @@ OSSL_CRMF_MSG_push0_extension() pushes the X509 extension I<ext> to the
 extensions in the certTemplate of I<crm>.  Consumes I<ext>.
 
 OSSL_CRMF_MSG_create_popo() creates and sets the Proof-of-Possession (POPO)
-according to the method I<ppmtd> in I<crm>.
+according to the method I<meth> in I<crm>.<
+The library context I<libctx> and property query string I<propq>,
+may be NULL to select the defaults.
 In case the method is OSSL_CRMF_POPO_SIGNATURE the POPO is calculated
-using the private I<pkey> and the digest algorithm NID I<dgst>.
+using the private key I<pkey> and the digest method I<digest>.
 
-I<ppmtd> can be one of the following:
+I<meth> can be one of the following:
 
 =over 8
 
@@ -86,7 +90,8 @@ challenge-response exchange (challengeResp) not yet supported.
 =back
 
 OSSL_CRMF_MSGS_verify_popo verifies the Proof-of-Possession of the request with
-the given I<rid> in the list of I<reqs>. Optionally accepts RAVerified.
+the given I<rid> in the list of I<reqs>. Optionally accepts RAVerified. It can
+make use of the library context I<libctx> and property query string I<propq>.
 
 =head1 RETURN VALUES
 
diff --git a/doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod b/doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod
index 78423c7001..9a76567a10 100644
--- a/doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod
+++ b/doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod
@@ -40,42 +40,42 @@ OSSL_CRMF_CERTID_gen
 =head1 DESCRIPTION
 
 OSSL_CRMF_MSG_set1_regCtrl_regToken() sets the regToken control in the given
-B<msg> copying the given B<tok> as value. See RFC 4211, section 6.1.
+I<msg> copying the given I<tok> as value. See RFC 4211, section 6.1.
 
 OSSL_CRMF_MSG_set1_regCtrl_authenticator() sets the authenticator control in
-the given B<msg> copying the given B<auth> as value. See RFC 4211, section 6.2.
+the given I<msg> copying the given I<auth> as value. See RFC 4211, section 6.2.
 
-OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo() pushes the given B<spi>
-to B<si>. Consumes the B<spi> pointer.
+OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo() pushes the given I<spi>
+to I<si>. Consumes the I<spi> pointer.
 
-OSSL_CRMF_MSG_set0_SinglePubInfo() sets in the given SinglePubInfo B<spi>
-the B<method> and publication location, in the form of a GeneralName, B<nm>.
-The publication location is optional, and therefore B<nm> may be NULL.
-The function consumes the B<nm> pointer if present.
+OSSL_CRMF_MSG_set0_SinglePubInfo() sets in the given SinglePubInfo I<spi>
+the I<method> and publication location, in the form of a GeneralName, I<nm>.
+The publication location is optional, and therefore I<nm> may be NULL.
+The function consumes the I<nm> pointer if present.
 Available methods are:
  # define OSSL_CRMF_PUB_METHOD_DONTCARE 0
  # define OSSL_CRMF_PUB_METHOD_X500     1
  # define OSSL_CRMF_PUB_METHOD_WEB      2
  # define OSSL_CRMF_PUB_METHOD_LDAP     3
 
-OSSL_CRMF_MSG_set_PKIPublicationInfo_action() sets the action in the given B<pi>
-using the given B<action> as value. See RFC 4211, section 6.3.
+OSSL_CRMF_MSG_set_PKIPublicationInfo_action() sets the action in the given I<pi>
+using the given I<action> as value. See RFC 4211, section 6.3.
 Available actions are:
  # define OSSL_CRMF_PUB_ACTION_DONTPUBLISH   0
  # define OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH 1
 
 OSSL_CRMF_MSG_set1_regCtrl_pkiPublicationInfo() sets the pkiPublicationInfo
-control in the given B<msg> copying the given B<tok> as value. See RFC 4211,
+control in the given I<msg> copying the given I<tok> as value. See RFC 4211,
 section 6.3.
 
 OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey() sets the protocolEncrKey control in
-the given B<msg> copying the given B<pubkey> as value. See RFC 4211 section 6.6.
+the given I<msg> copying the given I<pubkey> as value. See RFC 4211 section 6.6.
 
 OSSL_CRMF_MSG_set1_regCtrl_oldCertID() sets the oldCertID control in the given
-B<msg> copying the given B<cid> as value. See RFC 4211, section 6.5.
+I<msg> copying the given I<cid> as value. See RFC 4211, section 6.5.
 
 OSSL_CRMF_CERTID_gen produces an OSSL_CRMF_CERTID_gen structure copying the
-given B<issuer> name and B<serial> number.
+given I<issuer> name and I<serial> number.
 
 =head1 RETURN VALUES
 
diff --git a/doc/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod b/doc/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod
index 32a4933e7d..a9309bbf29 100644
--- a/doc/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod
+++ b/doc/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod
@@ -17,11 +17,11 @@ OSSL_CRMF_MSG_set1_regInfo_certReq
 
 =head1 DESCRIPTION
 
-OSSL_CRMF_MSG_set1_regInfo_utf8Pairs() adds a copy of the given B<utf8pairs>
-value as utf8Pairs regInfo to the given B<msg>. See RFC 4211 section 7.1.
+OSSL_CRMF_MSG_set1_regInfo_utf8Pairs() adds a copy of the given I<utf8pairs>
+value as utf8Pairs regInfo to the given I<msg>. See RFC 4211 section 7.1.
 
-OSSL_CRMF_MSG_set1_regInfo_certReq() adds a copy of the given B<cr> value
-as certReq regInfo to the given B<msg>. See RFC 4211 section 7.2.
+OSSL_CRMF_MSG_set1_regInfo_certReq() adds a copy of the given I<cr> value
+as certReq regInfo to the given I<msg>. See RFC 4211 section 7.2.
 
 =head1 RETURN VALUES
 
@@ -30,7 +30,7 @@ All functions return 1 on success, 0 on error.
 =head1 NOTES
 
 Calling these functions multiple times adds multiple instances of the respective
-control to the regInfo structure of the given B<msg>. While RFC 4211 expects
+control to the regInfo structure of the given I<msg>. While RFC 4211 expects
 multiple utf8Pairs in one regInfo structure, it does not allow multiple certReq.
 
 =head1 SEE ALSO
diff --git a/doc/man3/OSSL_CRMF_pbmp_new.pod b/doc/man3/OSSL_CRMF_pbmp_new.pod
index 8e07032cd1..b4fd62a296 100644
--- a/doc/man3/OSSL_CRMF_pbmp_new.pod
+++ b/doc/man3/OSSL_CRMF_pbmp_new.pod
@@ -8,39 +8,49 @@ OSSL_CRMF_pbmp_new
 
 =head1 SYNOPSIS
 
-  #include <openssl/crmf.h>
+ #include <openssl/crmf.h>
 
-  int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
-                        const unsigned char *msg, size_t msglen,
-                        const unsigned char *sec, size_t seclen,
-                        unsigned char **mac, size_t *maclen);
+ int OSSL_CRMF_pbm_new(OPENSSL_CTX *libctx, const char *propq,
+                       const OSSL_CRMF_PBMPARAMETER *pbmp,
+                       const unsigned char *msg, size_t msglen,
+                       const unsigned char *sec, size_t seclen,
+                       unsigned char **mac, size_t *maclen);
 
-  OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t saltlen, int owfnid,
-                                             int itercnt, int macnid);
+ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OPENSSL_CTX *libctx, size_t saltlen,
+                                            int owfnid, size_t itercnt,
+                                            int macnid);
 
 =head1 DESCRIPTION
 
 OSSL_CRMF_pbm_new() generates a PBM (Password-Based MAC) based on given PBM
-parameters B<pbmp>, message B<msg>, and secret B<sec>, along with the respective
-lengths B<msglen> and B<seclen>. On success writes the address of the newly
-allocated MAC via the B<mac> reference parameter and writes the length via the
-B<maclen> reference parameter unless it its NULL.
-
-The iteration count must be at least 100, as stipulated by RFC 4211, and is
-limited to at most 100000 to avoid DoS through manipulated or otherwise
-malformed input.
-
-OSSL_CRMF_pbmp_new() initializes and returns a new PBMParameter
-structure with a new random salt of given length B<saltlen>, OWF (one-way
-function) NID B<owfnid>, iteration count B<itercnt>, and MAC NID B<macnid>.
+parameters I<pbmp>, message I<msg>, and secret I<sec>, along with the respective
+lengths I<msglen> and I<seclen>.
+The optional library context I<libctx> and I<propq> parameters may be used
+to influence the selection of the MAC algorithm referenced in the I<pbmp>;
+see L<provider(7)/Fetching algorithms> for further information.
+On success writes the address of the newly
+allocated MAC via the I<mac> reference parameter and writes the length via the
+I<maclen> reference parameter unless it its NULL.
+
+OSSL_CRMF_pbmp_new() initializes and returns a new B<PBMParameter> structure
+with a new random salt of given length I<saltlen>,
+OWF (one-way function) NID I<owfnid>, OWF iteration count I<itercnt>,
+and MAC NID I<macnid>.
+The library context I<libctx> parameter may be used to select the provider
+for the random number generation (DRBG) and may be NULL for the default.
 
 =head1 NOTES
 
 The algorithms for the OWF (one-way function) and for the MAC (message
-authentication code) may be any with a NID defined in B<openssl/objects.h>.
+authentication code) may be any with a NID defined in C<openssl/objects.h>.
 As specified by RFC 4210, these should include NID_hmac_sha1.
 
-RFC 4210 recommends that the salt SHOULD be at least 8 bytes (64 bits) long.
+RFC 4210 recommends that the salt SHOULD be at least 8 bytes (64 bits) long,
+where 16 bytes is common.
+
+The iteration count must be at least 100, as stipulated by RFC 4211, and is
+limited to at most 100000 to avoid DoS through manipulated or otherwise
+malformed input.
 
 =head1 RETURN VALUES
 
diff --git a/doc/man7/property.pod b/doc/man7/property.pod
index d3fe38157b..90368b1f8d 100644
--- a/doc/man7/property.pod
+++ b/doc/man7/property.pod
@@ -42,9 +42,9 @@ property names like
 A I<property> is a I<name=value> pair.
 A I<property definition> is a sequence of comma separated properties.
 There can be any number of properties in a definition.
-For example: "" defines a null property definition; "my.foo=bar"
-defines a property named I<my.foo> which has a string value I<bar> and
-"iteration.count=3" defines a property named I<iteration.count> which
+For example: "" defines an empty property definition (i.e., no restriction);
+"my.foo=bar" defines a property named I<my.foo> which has a string value I<bar>
+and "iteration.count=3" defines a property named I<iteration.count> which
 has a numeric value of I<3>.
 The full syntax for property definitions appears below.
 
@@ -60,7 +60,7 @@ provider defines I<provider=legacy> for all of their algorithms.
 =head2 Queries
 
 A I<property query clause> is a single conditional test.
-For example, "fips=yes", "provider!=default" or "?iteration.count!=3".
+For example, "fips=yes", "provider!=default" or "?iteration.count=3".
 The first two represent mandatory clauses, such clauses B<must> match
 for any algorithm to even be under consideration.
 The third clause represents an optional clause.
diff --git a/fuzz/cmp.c b/fuzz/cmp.c
index a63ef9c238..44a0c1adeb 100644
--- a/fuzz/cmp.c
+++ b/fuzz/cmp.c
@@ -171,8 +171,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
     msg = d2i_OSSL_CMP_MSG_bio(in, NULL);
     if (msg != NULL) {
         BIO *out = BIO_new(BIO_s_null());
-        OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new();
-        OSSL_CMP_CTX *client_ctx = OSSL_CMP_CTX_new();
+        OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(NULL, NULL);
+        OSSL_CMP_CTX *client_ctx = OSSL_CMP_CTX_new(NULL, NULL);
 
         i2d_OSSL_CMP_MSG_bio(out, msg);
         ASN1_item_print(out, (ASN1_VALUE *)msg, 4,
diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h
index d3683649bc..68672d1a02 100644
--- a/include/crypto/asn1.h
+++ b/include/crypto/asn1.h
@@ -49,9 +49,10 @@ struct evp_pkey_asn1_method_st {
                             const unsigned char **pder, int derlen);
     int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder);
     /* Custom ASN1 signature verification */
-    int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
-                        X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
-    int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+    int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data,
+                        const X509_ALGOR *a, const ASN1_BIT_STRING *sig,
+                        EVP_PKEY *pkey);
+    int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data,
                       X509_ALGOR *alg1, X509_ALGOR *alg2,
                       ASN1_BIT_STRING *sig);
     int (*siginf_set) (X509_SIG_INFO *siginf, const X509_ALGOR *alg,
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index d2b2584357..512b4d6f48 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -769,6 +769,9 @@ int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
 
 EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx,
                              const char *propq);
+EVP_MD_CTX *evp_md_ctx_new_with_libctx(EVP_PKEY *pkey,
+                                       const ASN1_OCTET_STRING *id,
+                                       OPENSSL_CTX *libctx, const char *propq);
 #endif /* !defined(FIPS_MODULE) */
 void evp_method_store_flush(OPENSSL_CTX *libctx);
 int evp_set_default_properties_int(OPENSSL_CTX *libctx, const char *propq,
diff --git a/include/crypto/x509.h b/include/crypto/x509.h
index c663b68abd..a3c05f15b8 100644
--- a/include/crypto/x509.h
+++ b/include/crypto/x509.h
@@ -8,6 +8,8 @@
  */
 
 #include "internal/refcount.h"
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
 
 /* Internal X509 structures and functions: not for application use */
 
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index a62d4d7755..b47e8e823e 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -678,6 +678,16 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x);
                      CHECKED_PTR_OF(const type, x)))
 
 void *ASN1_item_dup(const ASN1_ITEM *it, const void *x);
+int ASN1_item_sign_with_libctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                               X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+                               const void *data, const ASN1_OCTET_STRING *id,
+                               EVP_PKEY *pkey, const EVP_MD *md,
+                               OPENSSL_CTX *libctx, const char *propq);
+int ASN1_item_verify_with_libctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
+                                 const ASN1_BIT_STRING *signature,
+                                 const void *data,
+                                 const ASN1_OCTET_STRING *id, EVP_PKEY *pkey,
+                                 OPENSSL_CTX *libctx, const char *propq);
 
 /* ASN1 alloc/free macros for when a type is only used internally */
 
diff --git a/include/openssl/asn1err.h b/include/openssl/asn1err.h
index 3247e0f445..f610d8816d 100644
--- a/include/openssl/asn1err.h
+++ b/include/openssl/asn1err.h
@@ -59,7 +59,6 @@ int ERR_load_ASN1_strings(void);
 #  define ASN1_F_ASN1_ITEM_I2D_BIO                         0
 #  define ASN1_F_ASN1_ITEM_I2D_FP                          0
 #  define ASN1_F_ASN1_ITEM_PACK                            0
-#  define ASN1_F_ASN1_ITEM_SIGN                            0
 #  define ASN1_F_ASN1_ITEM_SIGN_CTX                        0
 #  define ASN1_F_ASN1_ITEM_UNPACK                          0
 #  define ASN1_F_ASN1_ITEM_VERIFY                          0
diff --git a/include/openssl/cmp.h b/include/openssl/cmp.h
index 519117d622..cf79a4c71f 100644
--- a/include/openssl/cmp.h
+++ b/include/openssl/cmp.h
@@ -243,7 +243,7 @@ void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav);
 void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg);
 
 /* from cmp_ctx.c */
-OSSL_CMP_CTX *OSSL_CMP_CTX_new(void);
+OSSL_CMP_CTX *OSSL_CMP_CTX_new(OPENSSL_CTX *libctx, const char *propq);
 void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx);
 int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx);
 /* various CMP options: */
@@ -375,7 +375,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                            const OSSL_CMP_MSG *req);
 OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
                                            const OSSL_CMP_MSG *req);
-OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void);
+OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OPENSSL_CTX *libctx, const char *propq);
 void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx);
 typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_cert_request_cb_t)
     (OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req, int certReqId,
diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h
index f18ba386bc..2ae82974a9 100644
--- a/include/openssl/cmperr.h
+++ b/include/openssl/cmperr.h
@@ -45,7 +45,6 @@ int ERR_load_CMP_strings(void);
 #  define CMP_R_CERTRESPONSE_NOT_FOUND                     113
 #  define CMP_R_CERT_AND_KEY_DO_NOT_MATCH                  114
 #  define CMP_R_CHECKAFTER_OUT_OF_RANGE                    181
-#  define CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE           166
 #  define CMP_R_ENCOUNTERED_KEYUPDATEWARNING               176
 #  define CMP_R_ENCOUNTERED_WAITING                        162
 #  define CMP_R_ERROR_CALCULATING_PROTECTION               115
@@ -75,6 +74,7 @@ int ERR_load_CMP_strings(void);
 #  define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION  130
 #  define CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE         142
 #  define CMP_R_MISSING_P10CSR                             121
+#  define CMP_R_MISSING_PBM_SECRET                         166
 #  define CMP_R_MISSING_PRIVATE_KEY                        131
 #  define CMP_R_MISSING_PROTECTION                         143
 #  define CMP_R_MISSING_REFERENCE_CERT                     168
diff --git a/include/openssl/crmf.h b/include/openssl/crmf.h
index bf0e32d499..022f0bb9d2 100644
--- a/include/openssl/crmf.h
+++ b/include/openssl/crmf.h
@@ -67,9 +67,11 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSGS)
 typedef struct ossl_crmf_optionalvalidity_st OSSL_CRMF_OPTIONALVALIDITY;
 
 /* crmf_pbm.c */
-OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid,
-                                           int itercnt, int macnid);
-int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
+OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OPENSSL_CTX *libctx, size_t slen,
+                                           int owfnid, size_t itercnt,
+                                           int macnid);
+int OSSL_CRMF_pbm_new(OPENSSL_CTX *libctx, const char *propq,
+                      const OSSL_CRMF_PBMPARAMETER *pbmp,
                       const unsigned char *msg, size_t msglen,
                       const unsigned char *sec, size_t seclen,
                       unsigned char **mac, size_t *maclen);
@@ -118,10 +120,12 @@ int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext);
 #  define OSSL_CRMF_POPO_SIGNATURE  1
 #  define OSSL_CRMF_POPO_KEYENC     2
 #  define OSSL_CRMF_POPO_KEYAGREE   3
-int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
-                              int dgst, int ppmtd);
+int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm,
+                              EVP_PKEY *pkey, const EVP_MD *digest,
+                              OPENSSL_CTX *libctx, const char *propq);
 int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
-                               int rid, int acceptRAVerified);
+                               int rid, int acceptRAVerified,
+                               OPENSSL_CTX *libctx, const char *propq);
 OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm);
 ASN1_INTEGER
 *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl);
@@ -137,6 +141,7 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
                                 const ASN1_INTEGER *serial);
 X509
 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
+                                       OPENSSL_CTX *libctx, const char *propq,
                                        EVP_PKEY *pkey);
 
 #  ifdef __cplusplus
diff --git a/include/openssl/crmferr.h b/include/openssl/crmferr.h
index 17e5c85cc2..a4c194e094 100644
--- a/include/openssl/crmferr.h
+++ b/include/openssl/crmferr.h
@@ -10,6 +10,7 @@
 
 #ifndef OPENSSL_CRMFERR_H
 # define OPENSSL_CRMFERR_H
+# pragma once
 
 # include <openssl/opensslconf.h>
 # include <openssl/symhacks.h>
@@ -62,6 +63,7 @@ int ERR_load_CRMF_strings(void);
 #  define CRMF_R_ITERATIONCOUNT_BELOW_100                  108
 #  define CRMF_R_MALFORMED_IV                              101
 #  define CRMF_R_NULL_ARGUMENT                             109
+#  define CRMF_R_POPOSKINPUT_NOT_SUPPORTED                 113
 #  define CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY              117
 #  define CRMF_R_POPO_MISSING                              121
 #  define CRMF_R_POPO_MISSING_PUBLIC_KEY                   118
@@ -70,7 +72,6 @@ int ERR_load_CRMF_strings(void);
 #  define CRMF_R_SETTING_MAC_ALGOR_FAILURE                 110
 #  define CRMF_R_SETTING_OWF_ALGOR_FAILURE                 111
 #  define CRMF_R_UNSUPPORTED_ALGORITHM                     112
-#  define CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY         113
 #  define CRMF_R_UNSUPPORTED_CIPHER                        114
 #  define CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO      115
 #  define CRMF_R_UNSUPPORTED_POPO_METHOD                   116
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 35dbeb9301..822e3e9b28 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -1500,9 +1500,10 @@ int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm);
 #  define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN             (EVP_PKEY_ALG_CTRL + 8)
 #  define EVP_PKEY_CTRL_EC_KDF_UKM                    (EVP_PKEY_ALG_CTRL + 9)
 #  define EVP_PKEY_CTRL_GET_EC_KDF_UKM                (EVP_PKEY_ALG_CTRL + 10)
-#  define EVP_PKEY_CTRL_SET1_ID                       (EVP_PKEY_ALG_CTRL + 11)
-#  define EVP_PKEY_CTRL_GET1_ID                       (EVP_PKEY_ALG_CTRL + 12)
-#  define EVP_PKEY_CTRL_GET1_ID_LEN                   (EVP_PKEY_ALG_CTRL + 13)
+/* TODO move next three #defines to evp.h when 'breaking' change is possible */
+#  define EVP_PKEY_CTRL_SET1_ID                       15
+#  define EVP_PKEY_CTRL_GET1_ID                       16
+#  define EVP_PKEY_CTRL_GET1_ID_LEN                   17
 
 /* KDF types */
 #  define EVP_PKEY_ECDH_KDF_NONE                      1
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 189112efaa..62015a7b1b 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1446,13 +1446,13 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
 void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
                             int (*item_verify) (EVP_MD_CTX *ctx,
                                                 const ASN1_ITEM *it,
-                                                void *asn,
-                                                X509_ALGOR *a,
-                                                ASN1_BIT_STRING *sig,
+                                                const void *data,
+                                                const X509_ALGOR *a,
+                                                const ASN1_BIT_STRING *sig,
                                                 EVP_PKEY *pkey),
                             int (*item_sign) (EVP_MD_CTX *ctx,
                                               const ASN1_ITEM *it,
-                                              void *asn,
+                                              const void *data,
                                               X509_ALGOR *alg1,
                                               X509_ALGOR *alg2,
                                               ASN1_BIT_STRING *sig));
@@ -1532,28 +1532,20 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
 
 # define EVP_PKEY_CTRL_MD                1
 # define EVP_PKEY_CTRL_PEER_KEY          2
-
 # define EVP_PKEY_CTRL_PKCS7_ENCRYPT     3
 # define EVP_PKEY_CTRL_PKCS7_DECRYPT     4
-
 # define EVP_PKEY_CTRL_PKCS7_SIGN        5
-
 # define EVP_PKEY_CTRL_SET_MAC_KEY       6
-
 # define EVP_PKEY_CTRL_DIGESTINIT        7
-
 /* Used by GOST key encryption in TLS */
 # define EVP_PKEY_CTRL_SET_IV            8
-
 # define EVP_PKEY_CTRL_CMS_ENCRYPT       9
 # define EVP_PKEY_CTRL_CMS_DECRYPT       10
 # define EVP_PKEY_CTRL_CMS_SIGN          11
-
 # define EVP_PKEY_CTRL_CIPHER            12
-
 # define EVP_PKEY_CTRL_GET_MD            13
-
 # define EVP_PKEY_CTRL_SET_DIGEST_SIZE   14
+/* TODO move here three #defines of EVP_PKEY_CTRL_*ET1_ID* from ec.h */
 
 # define EVP_PKEY_ALG_CTRL               0x1000
 
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index c373fc9845..9aef28c954 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -621,33 +621,30 @@ X509_INFO *X509_INFO_new(void);
 void X509_INFO_free(X509_INFO *a);
 char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size);
 
+/* TODO move this block of decls to asn1.h when 'breaking change' is possible */
 DEPRECATEDIN_3_0(int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
                                  ASN1_BIT_STRING *signature, char *data,
                                  EVP_PKEY *pkey))
-
 DEPRECATEDIN_3_0(int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type,
                                  char *data,
                                  unsigned char *md, unsigned int *len))
-
 DEPRECATEDIN_3_0(int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
                                X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
                                char *data, EVP_PKEY *pkey, const EVP_MD *type))
-
 int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
                      unsigned char *md, unsigned int *len);
-
-int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
-                     ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
-int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
-                         ASN1_BIT_STRING *signature, void *data,
+int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg,
+                     const ASN1_BIT_STRING *signature, const void *data,
+                     EVP_PKEY *pkey);
+int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
+                         const ASN1_BIT_STRING *signature, const void *data,
                          EVP_MD_CTX *ctx);
-
-int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
-                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
-                   EVP_PKEY *pkey, const EVP_MD *type);
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+                   ASN1_BIT_STRING *signature, const void *data,
+                   EVP_PKEY *pkey, const EVP_MD *md);
 int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
                        X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
-                       void *asn, EVP_MD_CTX *ctx);
+                       const void *data, EVP_MD_CTX *ctx);
 
 long X509_get_version(const X509 *x);
 int X509_set_version(X509 *x, long version);
diff --git a/test/build.info b/test/build.info
index 11fce8e279..3ad16b51b1 100644
--- a/test/build.info
+++ b/test/build.info
@@ -22,7 +22,7 @@ IF[{- !$disabled{tests} -}]
           testutil/driver.c testutil/tests.c testutil/cb.c testutil/stanza.c \
           testutil/format_output.c \
           testutil/test_cleanup.c testutil/main.c testutil/testutil_init.c \
-          testutil/options.c testutil/test_options.c \
+          testutil/options.c testutil/test_options.c testutil/provider.c \
           testutil/apps_mem.c testutil/random.c $LIBAPPSSRC
   INCLUDE[libtestutil.a]=../include ../apps/include ..
   DEPEND[libtestutil.a]=../libcrypto
diff --git a/test/cipherlist_test.c b/test/cipherlist_test.c
index f850d7bbe9..0f337b4054 100644
--- a/test/cipherlist_test.c
+++ b/test/cipherlist_test.c
@@ -199,8 +199,6 @@ static int execute_test(CIPHERLIST_TEST_FIXTURE *fixture)
 static int test_default_cipherlist_implicit(void)
 {
     SETUP_CIPHERLIST_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     EXECUTE_CIPHERLIST_TEST();
     return result;
 }
@@ -208,8 +206,6 @@ static int test_default_cipherlist_implicit(void)
 static int test_default_cipherlist_explicit(void)
 {
     SETUP_CIPHERLIST_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     if (!TEST_true(SSL_CTX_set_cipher_list(fixture->server, "DEFAULT"))
             || !TEST_true(SSL_CTX_set_cipher_list(fixture->client, "DEFAULT")))
         tear_down(fixture);
@@ -220,11 +216,8 @@ static int test_default_cipherlist_explicit(void)
 /* SSL_CTX_set_cipher_list() should fail if it clears all TLSv1.2 ciphers. */
 static int test_default_cipherlist_clear(void)
 {
-    SETUP_CIPHERLIST_TEST_FIXTURE();
     SSL *s = NULL;
-
-    if (fixture == NULL)
-        return 0;
+    SETUP_CIPHERLIST_TEST_FIXTURE();
 
     if (!TEST_int_eq(SSL_CTX_set_cipher_list(fixture->server, "no-such"), 0))
         goto end;
diff --git a/test/cmp_client_test.c b/test/cmp_client_test.c
index d305eb5610..9fb3050ac0 100644
--- a/test/cmp_client_test.c
+++ b/test/cmp_client_test.c
@@ -33,6 +33,9 @@ typedef struct test_fixture {
     STACK_OF(X509) *caPubs;
 } CMP_SES_TEST_FIXTURE;
 
+static OPENSSL_CTX *libctx = NULL;
+static OSSL_PROVIDER *default_null_provider = NULL, *provider = NULL;
+
 static EVP_PKEY *server_key = NULL;
 static X509 *server_cert = NULL;
 static EVP_PKEY *client_key = NULL;
@@ -62,7 +65,7 @@ static CMP_SES_TEST_FIXTURE *set_up(const char *const test_case_name)
     if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
         return NULL;
     fixture->test_case_name = test_case_name;
-    if (!TEST_ptr(fixture->srv_ctx = ossl_cmp_mock_srv_new())
+    if (!TEST_ptr(fixture->srv_ctx = ossl_cmp_mock_srv_new(libctx, NULL))
             || !OSSL_CMP_SRV_CTX_set_accept_unprotected(fixture->srv_ctx, 1)
             || !ossl_cmp_mock_srv_set1_certOut(fixture->srv_ctx, client_cert)
             || (srv_cmp_ctx =
@@ -70,7 +73,7 @@ static CMP_SES_TEST_FIXTURE *set_up(const char *const test_case_name)
             || !OSSL_CMP_CTX_set1_cert(srv_cmp_ctx, server_cert)
             || !OSSL_CMP_CTX_set1_pkey(srv_cmp_ctx, server_key))
         goto err;
-    if (!TEST_ptr(fixture->cmp_ctx = ctx = OSSL_CMP_CTX_new())
+    if (!TEST_ptr(fixture->cmp_ctx = ctx = OSSL_CMP_CTX_new(libctx, NULL))
             || !OSSL_CMP_CTX_set_log_cb(fixture->cmp_ctx, print_to_bio_out)
             || !OSSL_CMP_CTX_set_transfer_cb(ctx, OSSL_CMP_CTX_server_perform)
             || !OSSL_CMP_CTX_set_transfer_cb_arg(ctx, fixture->srv_ctx)
@@ -343,9 +346,13 @@ void cleanup_tests(void)
     EVP_PKEY_free(server_key);
     X509_free(client_cert);
     EVP_PKEY_free(client_key);
+    OPENSSL_CTX_free(libctx);
     return;
 }
 
+#define USAGE "server.key server.crt client.key client.crt client.csr module_name [module_conf_file]\n"
+OPT_TEST_DECLARE_USAGE(USAGE)
+
 int setup_tests(void)
 {
     if (!test_skip_common_options()) {
@@ -358,15 +365,18 @@ int setup_tests(void)
             || !TEST_ptr(client_key_f = test_get_argument(2))
             || !TEST_ptr(client_cert_f = test_get_argument(3))
             || !TEST_ptr(pkcs10_f = test_get_argument(4))) {
-        TEST_error("usage: cmp_client_test server.key server.crt client.key client.crt client.csr\n");
+        TEST_error("usage: cmp_client_test %s", USAGE);
         return 0;
     }
 
+    if (!test_get_libctx(&libctx, &default_null_provider, &provider, 5, USAGE))
+        return 0;
+
     if (!TEST_ptr(server_key = load_pem_key(server_key_f))
-            || !TEST_ptr(server_cert = load_pem_cert(server_cert_f))
+            || !TEST_ptr(server_cert = load_pem_cert(server_cert_f, libctx))
             || !TEST_ptr(client_key = load_pem_key(client_key_f))
-            || !TEST_ptr(client_cert = load_pem_cert(client_cert_f))
-            || !TEST_int_eq(1, RAND_bytes(ref, sizeof(ref)))) {
+            || !TEST_ptr(client_cert = load_pem_cert(client_cert_f, libctx))
+            || !TEST_int_eq(1, RAND_bytes_ex(libctx, ref, sizeof(ref)))) {
         cleanup_tests();
         return 0;
     }
diff --git a/test/cmp_ctx_test.c b/test/cmp_ctx_test.c
index 898053424e..184e5bf498 100644
--- a/test/cmp_ctx_test.c
+++ b/test/cmp_ctx_test.c
@@ -37,7 +37,7 @@ static OSSL_CMP_CTX_TEST_FIXTURE *set_up(const char *const test_case_name)
 
     if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
         return NULL;
-    if (!TEST_ptr(fixture->ctx = OSSL_CMP_CTX_new())) {
+    if (!TEST_ptr(fixture->ctx = OSSL_CMP_CTX_new(NULL, NULL))) {
         tear_down(fixture);
         return NULL;
     }
diff --git a/test/cmp_hdr_test.c b/test/cmp_hdr_test.c
index cd30c49762..4dcf998e26 100644
--- a/test/cmp_hdr_test.c
+++ b/test/cmp_hdr_test.c
@@ -38,7 +38,7 @@ static CMP_HDR_TEST_FIXTURE *set_up(const char *const test_case_name)
     if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
         return NULL;
     fixture->test_case_name = test_case_name;
-    if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new()))
+    if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new(NULL, NULL)))
         goto err;
     if (!TEST_ptr(fixture->hdr = OSSL_CMP_PKIHEADER_new()))
         goto err;
@@ -402,9 +402,10 @@ static int execute_HDR_init_test(CMP_HDR_TEST_FIXTURE *fixture)
 
 static int test_HDR_init_with_ref(void)
 {
-    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
     unsigned char ref[CMP_TEST_REFVALUE_LENGTH];
 
+    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
+
     fixture->expected = 1;
     if (!TEST_int_eq(1, RAND_bytes(ref, sizeof(ref)))
             || !TEST_true(OSSL_CMP_CTX_set1_referenceValue(fixture->cmp_ctx,
@@ -418,9 +419,9 @@ static int test_HDR_init_with_ref(void)
 
 static int test_HDR_init_with_subject(void)
 {
-    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
     X509_NAME *subject = NULL;
 
+    SETUP_TEST_FIXTURE(CMP_HDR_TEST_FIXTURE, set_up);
     fixture->expected = 1;
     if (!TEST_ptr(subject = X509_NAME_new())
             || !TEST_true(X509_NAME_ADD(subject, "CN", "Common Name"))
diff --git a/test/cmp_msg_test.c b/test/cmp_msg_test.c
index 92989f95e1..b9309a6983 100644
--- a/test/cmp_msg_test.c
+++ b/test/cmp_msg_test.c
@@ -13,6 +13,7 @@
 
 DEFINE_STACK_OF(OSSL_CMP_CERTRESPONSE)
 
+static const char *newkey_f;
 static const char *server_cert_f;
 static const char *pkcs10_f;
 
@@ -31,6 +32,19 @@ typedef struct test_fixture {
     OSSL_CMP_PKISI *si;
 } CMP_MSG_TEST_FIXTURE;
 
+static OPENSSL_CTX *libctx = NULL;
+static OSSL_PROVIDER *default_null_provider = NULL, *provider = NULL;
+
+/* TODO(3.0) Clean this up - See issue #12680 */
+static X509 *X509_dup_with_libctx(const X509 *cert)
+{
+    X509 *dup = X509_dup(cert);
+
+    if (dup != NULL)
+        x509_set0_libctx(dup, libctx, NULL);
+    return dup;
+}
+
 static unsigned char ref[CMP_TEST_REFVALUE_LENGTH];
 
 static void tear_down(CMP_MSG_TEST_FIXTURE *fixture)
@@ -51,7 +65,7 @@ static CMP_MSG_TEST_FIXTURE *set_up(const char *const test_case_name)
         return NULL;
     fixture->test_case_name = test_case_name;
 
-    if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new())
+    if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new(libctx, NULL))
             || !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 1))
             || !TEST_true(OSSL_CMP_CTX_set1_referenceValue(fixture->cmp_ctx,
                                                            ref, sizeof(ref)))) {
@@ -137,14 +151,16 @@ static int set1_newPkey(OSSL_CMP_CTX *ctx, EVP_PKEY *pkey)
 
 static int test_cmp_create_ir_protection_set(void)
 {
-    SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
-    OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
+    OSSL_CMP_CTX *ctx;
     unsigned char secret[16];
 
+    SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
+
+    ctx = fixture->cmp_ctx;
     fixture->bodytype = OSSL_CMP_PKIBODY_IR;
     fixture->err_code = -1;
     fixture->expected = 1;
-    if (!TEST_int_eq(1, RAND_bytes(secret, sizeof(secret)))
+    if (!TEST_int_eq(1, RAND_bytes_ex(libctx, secret, sizeof(secret)))
             || !TEST_true(SET_OPT_UNPROTECTED_SEND(ctx, 0))
             || !TEST_true(set1_newPkey(ctx, newkey))
             || !TEST_true(OSSL_CMP_CTX_set1_secretValue(ctx, secret,
@@ -213,10 +229,11 @@ static int test_cmp_create_certreq_with_invalid_bodytype(void)
 
 static int test_cmp_create_p10cr(void)
 {
-    SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
-    OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
+    OSSL_CMP_CTX *ctx;
     X509_REQ *p10cr = NULL;
 
+    SETUP_TEST_FIXTURE(CMP_MSG_TEST_FIXTURE, set_up);
+    ctx = fixture->cmp_ctx;
     fixture->bodytype = OSSL_CMP_PKIBODY_P10CR;
     fixture->err_code = CMP_R_ERROR_CREATING_CERTREQ;
     fixture->expected = 1;
@@ -280,7 +297,7 @@ static int test_cmp_create_certconf(void)
     fixture->fail_info = 0;
     fixture->expected = 1;
     if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx,
-                                             X509_dup(cert)))) {
+                                             X509_dup_with_libctx(cert)))) {
         tear_down(fixture);
         fixture = NULL;
     }
@@ -294,7 +311,7 @@ static int test_cmp_create_certconf_badAlg(void)
     fixture->fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badAlg;
     fixture->expected = 1;
     if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx,
-                                             X509_dup(cert)))) {
+                                             X509_dup_with_libctx(cert)))) {
         tear_down(fixture);
         fixture = NULL;
     }
@@ -308,7 +325,7 @@ static int test_cmp_create_certconf_fail_info_max(void)
     fixture->fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_MAX;
     fixture->expected = 1;
     if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx,
-                                             X509_dup(cert)))) {
+                                             X509_dup_with_libctx(cert)))) {
         tear_down(fixture);
         fixture = NULL;
     }
@@ -373,6 +390,7 @@ static int test_cmp_create_genm(void)
 
 static int execute_certrep_create(CMP_MSG_TEST_FIXTURE *fixture)
 {
+    OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
     OSSL_CMP_CERTREPMESSAGE *crepmsg = OSSL_CMP_CERTREPMESSAGE_new();
     OSSL_CMP_CERTRESPONSE *read_cresp, *cresp = OSSL_CMP_CERTRESPONSE_new();
     EVP_PKEY *privkey;
@@ -388,7 +406,7 @@ static int execute_certrep_create(CMP_MSG_TEST_FIXTURE *fixture)
     cresp->certifiedKeyPair->certOrEncCert->type =
         OSSL_CMP_CERTORENCCERT_CERTIFICATE;
     if ((cresp->certifiedKeyPair->certOrEncCert->value.certificate =
-         X509_dup(cert)) == NULL
+         X509_dup_with_libctx(cert)) == NULL
             || !sk_OSSL_CMP_CERTRESPONSE_push(crepmsg->response, cresp))
         goto err;
     cresp = NULL;
@@ -397,8 +415,8 @@ static int execute_certrep_create(CMP_MSG_TEST_FIXTURE *fixture)
         goto err;
     if (!TEST_ptr_null(ossl_cmp_certrepmessage_get0_certresponse(crepmsg, 88)))
         goto err;
-    privkey = OSSL_CMP_CTX_get0_newPkey(fixture->cmp_ctx, 1); /* may be NULL */
-    certfromresp = ossl_cmp_certresponse_get1_certificate(privkey, read_cresp);
+    privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); /* may be NULL */
+    certfromresp = ossl_cmp_certresponse_get1_cert(read_cresp, ctx, privkey);
     if (certfromresp == NULL || !TEST_int_eq(X509_cmp(cert, certfromresp), 0))
         goto err;
 
@@ -534,8 +552,12 @@ void cleanup_tests(void)
 {
     EVP_PKEY_free(newkey);
     X509_free(cert);
+    OPENSSL_CTX_free(libctx);
 }
 
+#define USAGE "new.key server.crt pkcs10.der module_name [module_conf_file]\n"
+OPT_TEST_DECLARE_USAGE(USAGE)
+
 int setup_tests(void)
 {
     if (!test_skip_common_options()) {
@@ -543,15 +565,19 @@ int setup_tests(void)
         return 0;
     }
 
-    if (!TEST_ptr(server_cert_f = test_get_argument(0))
-            || !TEST_ptr(pkcs10_f = test_get_argument(1))) {
-        TEST_error("usage: cmp_msg_test server.crt pkcs10.der\n");
+    if (!TEST_ptr(newkey_f = test_get_argument(0))
+            || !TEST_ptr(server_cert_f = test_get_argument(1))
+            || !TEST_ptr(pkcs10_f = test_get_argument(2))) {
+        TEST_error("usage: cmp_msg_test %s", USAGE);
         return 0;
     }
 
-    if (!TEST_ptr(newkey = gen_rsa())
-            || !TEST_ptr(cert = load_pem_cert(server_cert_f))
-            || !TEST_int_eq(1, RAND_bytes(ref, sizeof(ref)))) {
+    if (!test_get_libctx(&libctx, &default_null_provider, &provider, 3, USAGE))
+        return 0;
+
+    if (!TEST_ptr(newkey = load_pem_key(newkey_f))
+            || !TEST_ptr(cert = load_pem_cert(server_cert_f, libctx))
+            || !TEST_int_eq(1, RAND_bytes_ex(libctx, ref, sizeof(ref)))) {
         cleanup_tests();
         return 0;
     }
diff --git a/test/cmp_protect_test.c b/test/cmp_protect_test.c
index 1d1e009aca..6413c20a23 100644
--- a/test/cmp_protect_test.c
+++ b/test/cmp_protect_test.c
@@ -23,8 +23,6 @@ typedef struct test_fixture {
     /* for protection tests */
     OSSL_CMP_MSG *msg;
     OSSL_CMP_PKISI *si; /* for error and response messages */
-    ASN1_OCTET_STRING *secret;
-    EVP_PKEY *privkey;
     EVP_PKEY *pubkey;
     unsigned char *mem;
     int memlen;
@@ -35,11 +33,13 @@ typedef struct test_fixture {
     int expected;
 } CMP_PROTECT_TEST_FIXTURE;
 
+static OPENSSL_CTX *libctx = NULL;
+static OSSL_PROVIDER *default_null_provider = NULL, *provider = NULL;
+
 static void tear_down(CMP_PROTECT_TEST_FIXTURE *fixture)
 {
     OSSL_CMP_CTX_free(fixture->cmp_ctx);
     OSSL_CMP_MSG_free(fixture->msg);
-    ASN1_OCTET_STRING_free(fixture->secret);
     OSSL_CMP_PKISI_free(fixture->si);
 
     OPENSSL_free(fixture->mem);
@@ -56,7 +56,7 @@ static CMP_PROTECT_TEST_FIXTURE *set_up(const char *const test_case_name)
     if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
         return NULL;
     fixture->test_case_name = test_case_name;
-    if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new())) {
+    if (!TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new(libctx, NULL))) {
         tear_down(fixture);
         return NULL;
     }
@@ -75,8 +75,7 @@ static X509 *endentity1 = NULL, *endentity2 = NULL,
 static int execute_calc_protection_fails_test(CMP_PROTECT_TEST_FIXTURE *fixture)
 {
     ASN1_BIT_STRING *protection =
-        ossl_cmp_calc_protection(fixture->msg, fixture->secret,
-                                 fixture->privkey);
+        ossl_cmp_calc_protection(fixture->cmp_ctx, fixture->msg);
     int res = TEST_ptr_null(protection);
 
     ASN1_BIT_STRING_free(protection);
@@ -86,7 +85,7 @@ static int execute_calc_protection_fails_test(CMP_PROTECT_TEST_FIXTURE *fixture)
 static int execute_calc_protection_pbmac_test(CMP_PROTECT_TEST_FIXTURE *fixture)
 {
     ASN1_BIT_STRING *protection =
-        ossl_cmp_calc_protection(fixture->msg, fixture->secret, NULL);
+        ossl_cmp_calc_protection(fixture->cmp_ctx, fixture->msg);
     int res = TEST_ptr(protection)
             && TEST_true(ASN1_STRING_cmp(protection,
                                          fixture->msg->protection) == 0);
@@ -101,13 +100,12 @@ static int execute_calc_protection_pbmac_test(CMP_PROTECT_TEST_FIXTURE *fixture)
  */
 static int verify_signature(OSSL_CMP_MSG *msg,
                             ASN1_BIT_STRING *protection,
-                            EVP_PKEY *pkey, int digest_nid)
+                            EVP_PKEY *pkey, EVP_MD *digest)
 {
     OSSL_CMP_PROTECTEDPART prot_part;
     unsigned char *prot_part_der = NULL;
     int len;
     EVP_MD_CTX *ctx = NULL;
-    const EVP_MD *digest = EVP_get_digestbynid(digest_nid);
     int res;
 
     prot_part.header = OSSL_CMP_MSG_get0_header(msg);
@@ -131,7 +129,7 @@ static int execute_calc_protection_signature_test(CMP_PROTECT_TEST_FIXTURE *
                                                   fixture)
 {
     ASN1_BIT_STRING *protection =
-        ossl_cmp_calc_protection(fixture->msg, NULL, fixture->privkey);
+        ossl_cmp_calc_protection(fixture->cmp_ctx, fixture->msg);
     int ret = (TEST_ptr(protection)
                    && TEST_true(ASN1_STRING_cmp(protection,
                                                 fixture->msg->protection) == 0)
@@ -161,8 +159,8 @@ static int test_cmp_calc_protection_pkey(void)
 {
     SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
     fixture->pubkey = loadedpubkey;
-    fixture->privkey = loadedprivkey;
-    if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))) {
+    if (!TEST_true(OSSL_CMP_CTX_set1_pkey(fixture->cmp_ctx, loadedprivkey))
+            || !TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))) {
         tear_down(fixture);
         fixture = NULL;
     }
@@ -175,9 +173,8 @@ static int test_cmp_calc_protection_pbmac(void)
     unsigned char sec_insta[] = { 'i', 'n', 's', 't', 'a' };
 
     SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
-    if (!TEST_ptr(fixture->secret = ASN1_OCTET_STRING_new())
-            || !TEST_true(ASN1_OCTET_STRING_set
-                          (fixture->secret, sec_insta, sizeof(sec_insta)))
+    if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx,
+                                                 sec_insta, sizeof(sec_insta)))
             || !TEST_ptr(fixture->msg = load_pkimsg(ip_PBM_f))) {
         tear_down(fixture);
         fixture = NULL;
@@ -214,8 +211,7 @@ static int test_MSG_protect_with_msg_sig_alg_protection_plus_rsa_key(void)
     SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
     fixture->expected = 1;
 
-    if (!TEST_ptr(fixture->msg =
-                  OSSL_CMP_MSG_dup(ir_unprotected))
+    if (!TEST_ptr(fixture->msg = OSSL_CMP_MSG_dup(ir_unprotected))
             || !TEST_true(SET_OPT_UNPROTECTED_SEND(fixture->cmp_ctx, 0))
             /*
              * Use half of the 16 bytes of random input
@@ -252,9 +248,10 @@ static int test_MSG_protect_with_certificate_and_key(void)
 
 static int test_MSG_protect_certificate_based_without_cert(void)
 {
-    SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
-    OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
+    OSSL_CMP_CTX *ctx;
 
+    SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up);
+    ctx = fixture->cmp_ctx;
     fixture->expected = 0;
     if (!TEST_ptr(fixture->msg =
                   OSSL_CMP_MSG_dup(ir_unprotected))
@@ -334,14 +331,16 @@ static int test_MSG_add_extraCerts(void)
 /* The cert chain tests use EC certs so we skip them in no-ec builds */
 static int execute_cmp_build_cert_chain_test(CMP_PROTECT_TEST_FIXTURE *fixture)
 {
-    STACK_OF(X509) *result = NULL;
     int ret = 0;
+    OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
+    STACK_OF(X509) *chain =
+        ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq,
+                                  fixture->certs, fixture->cert);
 
-    if (TEST_ptr(result = ossl_cmp_build_cert_chain(fixture->certs,
-                                                    fixture->cert))) {
+    if (TEST_ptr(chain)) {
         /* Check whether chain built is equal to the expected one */
-        ret = TEST_int_eq(0, STACK_OF_X509_cmp(result, fixture->chain));
-        sk_X509_pop_free(result, X509_free);
+        ret = TEST_int_eq(0, STACK_OF_X509_cmp(chain, fixture->chain));
+        sk_X509_pop_free(chain, X509_free);
     }
     return ret;
 }
@@ -481,9 +480,14 @@ void cleanup_tests(void)
     X509_free(intermediate);
     OSSL_CMP_MSG_free(ir_protected);
     OSSL_CMP_MSG_free(ir_unprotected);
-
+    OPENSSL_CTX_free(libctx);
 }
 
+#define USAGE "server.pem IR_protected.der IR_unprotected.der IP_PBM.der " \
+    "server.crt server.pem EndEntity1.crt EndEntity2.crt Root_CA.crt " \
+    "Intermediate_CA.crt module_name [module_conf_file]\n"
+OPT_TEST_DECLARE_USAGE(USAGE)
+
 int setup_tests(void)
 {
     char *server_f;
@@ -510,15 +514,15 @@ int setup_tests(void)
             || !TEST_ptr(endentity2_f = test_get_argument(7))
             || !TEST_ptr(root_f = test_get_argument(8))
             || !TEST_ptr(intermediate_f = test_get_argument(9))) {
-        TEST_error("usage: cmp_protect_test server.pem "
-                   "IR_protected.der IR_unprotected.der IP_PBM.der "
-                   "server.crt server.pem"
-                   "EndEntity1.crt EndEntity2.crt "
-                   "Root_CA.crt Intermediate_CA.crt\n");
+        TEST_error("usage: cmp_protect_test %s", USAGE);
         return 0;
     }
+
+    if (!test_get_libctx(&libctx, &default_null_provider, &provider, 10, USAGE))
+        return 0;
+
     if (!TEST_ptr(loadedkey = load_pem_key(server_key_f))
-            || !TEST_ptr(cert = load_pem_cert(server_cert_f)))
+            || !TEST_ptr(cert = load_pem_cert(server_cert_f, libctx)))
         return 0;
 
     if (!TEST_ptr(loadedprivkey = load_pem_key(server_f)))
@@ -528,10 +532,10 @@ int setup_tests(void)
     if (!TEST_ptr(ir_protected = load_pkimsg(ir_protected_f))
             || !TEST_ptr(ir_unprotected = load_pkimsg(ir_unprotected_f)))
         return 0;
-    if (!TEST_ptr(endentity1 = load_pem_cert(endentity1_f))
-            || !TEST_ptr(endentity2 = load_pem_cert(endentity2_f))
-            || !TEST_ptr(root = load_pem_cert(root_f))
-            || !TEST_ptr(intermediate = load_pem_cert(intermediate_f)))
+    if (!TEST_ptr(endentity1 = load_pem_cert(endentity1_f, libctx))
+            || !TEST_ptr(endentity2 = load_pem_cert(endentity2_f, libctx))
+            || !TEST_ptr(root = load_pem_cert(root_f, libctx))
+            || !TEST_ptr(intermediate = load_pem_cert(intermediate_f, libctx)))
         return 0;
     if (!TEST_int_eq(1, RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH)))
         return 0;
diff --git a/test/cmp_server_test.c b/test/cmp_server_test.c
index 13159299e9..4b3525d7bd 100644
--- a/test/cmp_server_test.c
+++ b/test/cmp_server_test.c
@@ -18,6 +18,8 @@ typedef struct test_fixture {
     OSSL_CMP_MSG *req;
 } CMP_SRV_TEST_FIXTURE;
 
+static OPENSSL_CTX *libctx = NULL;
+static OSSL_PROVIDER *default_null_provider = NULL, *provider = NULL;
 static OSSL_CMP_MSG *request = NULL;
 
 static void tear_down(CMP_SRV_TEST_FIXTURE *fixture)
@@ -33,7 +35,7 @@ static CMP_SRV_TEST_FIXTURE *set_up(const char *const test_case_name)
     if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
         return NULL;
     fixture->test_case_name = test_case_name;
-    if (!TEST_ptr(fixture->srv_ctx = OSSL_CMP_SRV_CTX_new()))
+    if (!TEST_ptr(fixture->srv_ctx = OSSL_CMP_SRV_CTX_new(libctx, NULL)))
         goto err;
     return fixture;
 
@@ -67,7 +69,7 @@ static int execute_test_handle_request(CMP_SRV_TEST_FIXTURE *fixture)
     OSSL_CMP_ERRORMSGCONTENT *errorContent;
     int res = 0;
 
-    if (!TEST_ptr(client_ctx = OSSL_CMP_CTX_new())
+    if (!TEST_ptr(client_ctx = OSSL_CMP_CTX_new(libctx, NULL))
             || !TEST_true(OSSL_CMP_CTX_set_transfer_cb_arg(client_ctx, ctx)))
         goto end;
 
@@ -119,9 +121,16 @@ static int test_handle_request(void)
 void cleanup_tests(void)
 {
     OSSL_CMP_MSG_free(request);
+    OSSL_PROVIDER_unload(default_null_provider);
+    OSSL_PROVIDER_unload(provider);
+    OPENSSL_CTX_free(libctx);
     return;
 }
 
+#define USAGE \
+    "CR_protected_PBM_1234.der module_name [module_conf_file]\n"
+OPT_TEST_DECLARE_USAGE(USAGE)
+
 int setup_tests(void)
 {
     const char *request_f;
@@ -132,10 +141,13 @@ int setup_tests(void)
     }
 
     if (!TEST_ptr(request_f = test_get_argument(0))) {
-        TEST_error("usage: cmp_server_test CR_protected_PBM_1234.der\n");
+        TEST_error("usage: cmp_server_test %s", USAGE);
         return 0;
     }
 
+    if (!test_get_libctx(&libctx, &default_null_provider, &provider, 1, USAGE))
+        return 0;
+
     if (!TEST_ptr(request = load_pkimsg(request_f))) {
         cleanup_tests();
         return 0;
diff --git a/test/cmp_testlib.c b/test/cmp_testlib.c
index ef33aa8e83..ffa43cd81c 100644
--- a/test/cmp_testlib.c
+++ b/test/cmp_testlib.c
@@ -28,15 +28,16 @@ EVP_PKEY *load_pem_key(const char *file)
     return key;
 }
 
-X509 *load_pem_cert(const char *file)
+X509 *load_pem_cert(const char *file, OPENSSL_CTX *libctx)
 {
     X509 *cert = NULL;
     BIO *bio = NULL;
 
     if (!TEST_ptr(bio = BIO_new(BIO_s_file())))
         return NULL;
-    if (TEST_int_gt(BIO_read_filename(bio, file), 0))
-        (void)TEST_ptr(cert = PEM_read_bio_X509(bio, NULL, NULL, NULL));
+    if (TEST_int_gt(BIO_read_filename(bio, file), 0)
+            && TEST_ptr(cert = X509_new_with_libctx(libctx, NULL)))
+        (void)TEST_ptr(cert = PEM_read_bio_X509(bio, &cert, NULL, NULL));
 
     BIO_free(bio);
     return cert;
@@ -62,19 +63,6 @@ X509_REQ *load_csr(const char *file)
     return csr;
 }
 
-EVP_PKEY *gen_rsa(void)
-{
-    EVP_PKEY_CTX *ctx = NULL;
-    EVP_PKEY *pkey = NULL;
-
-    (void)(TEST_ptr(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL))
-               && TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)
-               && TEST_int_gt(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048), 0)
-               && TEST_int_gt(EVP_PKEY_keygen(ctx, &pkey), 0));
-    EVP_PKEY_CTX_free(ctx);
-    return pkey;
-}
-
 /*
  * Checks whether the syntax of msg conforms to ASN.1
  */
diff --git a/test/cmp_testlib.h b/test/cmp_testlib.h
index 9277510579..e24074cdd7 100644
--- a/test/cmp_testlib.h
+++ b/test/cmp_testlib.h
@@ -15,6 +15,7 @@
 # include <openssl/cmp.h>
 # include <openssl/pem.h>
 # include <openssl/rand.h>
+# include "crypto/x509.h" /* for x509_set0_libctx() and x509_dup_with_libctx() */
 
 # include "../crypto/cmp/cmp_local.h"
 
@@ -23,11 +24,10 @@
 # ifndef OPENSSL_NO_CMP
 #  define CMP_TEST_REFVALUE_LENGTH 15 /* arbitrary value */
 EVP_PKEY *load_pem_key(const char *file);
-X509 *load_pem_cert(const char *file);
+X509 *load_pem_cert(const char *file, OPENSSL_CTX *libctx);
 X509_REQ *load_csr(const char *file);
 OSSL_CMP_MSG *load_pkimsg(const char *file);
 int valid_asn1_encoding(const OSSL_CMP_MSG *msg);
-EVP_PKEY *gen_rsa(void);
 int STACK_OF_X509_cmp(const STACK_OF(X509) *sk1, const STACK_OF(X509) *sk2);
 int STACK_OF_X509_push1(STACK_OF(X509) *sk, X509 *cert);
 int print_to_bio_out(const char *func, const char *file, int line,
diff --git a/test/cmp_vfy_test.c b/test/cmp_vfy_test.c
index fcecca2500..1aec50d657 100644
--- a/test/cmp_vfy_test.c
+++ b/test/cmp_vfy_test.c
@@ -38,6 +38,9 @@ typedef struct test_fixture {
     int additional_arg;
 } CMP_VFY_TEST_FIXTURE;
 
+static OPENSSL_CTX *libctx = NULL;
+static OSSL_PROVIDER *default_null_provider = NULL, *provider = NULL;
+
 static void tear_down(CMP_VFY_TEST_FIXTURE *fixture)
 {
     OSSL_CMP_MSG_free(fixture->msg);
@@ -56,7 +59,7 @@ static CMP_VFY_TEST_FIXTURE *set_up(const char *const test_case_name)
         return NULL;
     fixture->test_case_name = test_case_name;
     if (ts == NULL
-            || !TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new())
+            || !TEST_ptr(fixture->cmp_ctx = OSSL_CMP_CTX_new(libctx, NULL))
             || !OSSL_CMP_CTX_set0_trustedStore(fixture->cmp_ctx, ts)
             || !OSSL_CMP_CTX_set_log_cb(fixture->cmp_ctx, print_to_bio_out)) {
         tear_down(fixture);
@@ -98,7 +101,7 @@ static int execute_verify_popo_test(CMP_VFY_TEST_FIXTURE *fixture)
             return 0;
     }
     return TEST_int_eq(fixture->expected,
-                       ossl_cmp_verify_popo(fixture->msg,
+                       ossl_cmp_verify_popo(fixture->cmp_ctx, fixture->msg,
                                             fixture->additional_arg));
 }
 
@@ -140,13 +143,14 @@ static int execute_validate_cert_path_test(CMP_VFY_TEST_FIXTURE *fixture)
 
 static int test_validate_msg_mac_alg_protection(void)
 {
-    SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
     /* secret value belonging to cmp-test/CMP_IP_waitingStatus_PBM.der */
     const unsigned char sec_1[] = {
         '9', 'p', 'p', '8', '-', 'b', '3', '5', 'i', '-', 'X', 'd', '3',
         'Q', '-', 'u', 'd', 'N', 'R'
     };
 
+    SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
+
     fixture->expected = 1;
     if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx, sec_1,
                                                  sizeof(sec_1)))
@@ -161,11 +165,12 @@ static int test_validate_msg_mac_alg_protection(void)
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 static int test_validate_msg_mac_alg_protection_bad(void)
 {
-    SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
     const unsigned char sec_bad[] = {
         '9', 'p', 'p', '8', '-', 'b', '3', '5', 'i', '-', 'X', 'd', '3',
         'Q', '-', 'u', 'd', 'N', 'r'
     };
+
+    SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
     fixture->expected = 0;
 
     if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx, sec_bad,
@@ -192,9 +197,11 @@ static int add_untrusted(OSSL_CMP_CTX *ctx, X509 *cert)
 
 static int test_validate_msg_signature_partial_chain(int expired)
 {
+    X509_STORE *ts;
+
     SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up);
-    X509_STORE *ts = OSSL_CMP_CTX_get0_trustedStore(fixture->cmp_ctx);
 
+    ts = OSSL_CMP_CTX_get0_trustedStore(fixture->cmp_ctx);
     fixture->expected = !expired;
     if (ts == NULL
             || !TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f))
@@ -543,9 +550,21 @@ void cleanup_tests(void)
     X509_free(instaca_cert);
     OSSL_CMP_MSG_free(ir_unprotected);
     OSSL_CMP_MSG_free(ir_rmprotection);
+    OPENSSL_CTX_free(libctx);
     return;
 }
 
+
+#define USAGE "server.crt client.crt " \
+    "EndEntity1.crt EndEntity2.crt " \
+    "Root_CA.crt Intermediate_CA.crt " \
+    "CMP_IR_protected.der CMP_IR_unprotected.der " \
+    "IP_waitingStatus_PBM.der IR_rmprotection.der " \
+    "insta.cert.pem insta_ca.cert.pem " \
+    "IR_protected_0_extraCerts.der " \
+    "IR_protected_2_extraCerts.der module_name [module_conf_file]\n"
+OPT_TEST_DECLARE_USAGE(USAGE)
+
 int setup_tests(void)
 {
     /* Set test time stamps */
@@ -578,31 +597,27 @@ int setup_tests(void)
             || !TEST_ptr(instaca_f = test_get_argument(11))
             || !TEST_ptr(ir_protected_0_extracerts = test_get_argument(12))
             || !TEST_ptr(ir_protected_2_extracerts = test_get_argument(13))) {
-        TEST_error("usage: cmp_vfy_test server.crt client.crt "
-                   "EndEntity1.crt EndEntity2.crt "
-                   "Root_CA.crt Intermediate_CA.crt "
-                   "CMP_IR_protected.der CMP_IR_unprotected.der "
-                   "IP_waitingStatus_PBM.der IR_rmprotection.der "
-                   "insta.cert.pem insta_ca.cert.pem "
-                   "IR_protected_0_extraCerts.der "
-                   "IR_protected_2_extraCerts.der\n");
+        TEST_error("usage: cmp_vfy_test %s", USAGE);
         return 0;
     }
 
+    if (!test_get_libctx(&libctx, &default_null_provider, &provider, 14, USAGE))
+        return 0;
+
     /* Load certificates for cert chain */
-    if (!TEST_ptr(endentity1 = load_pem_cert(endentity1_f))
-            || !TEST_ptr(endentity2 = load_pem_cert(endentity2_f))
-            || !TEST_ptr(root = load_pem_cert(root_f))
-            || !TEST_ptr(intermediate = load_pem_cert(intermediate_f)))
+    if (!TEST_ptr(endentity1 = load_pem_cert(endentity1_f, libctx))
+            || !TEST_ptr(endentity2 = load_pem_cert(endentity2_f, libctx))
+            || !TEST_ptr(root = load_pem_cert(root_f, NULL))
+            || !TEST_ptr(intermediate = load_pem_cert(intermediate_f, libctx)))
         goto err;
 
-    if (!TEST_ptr(insta_cert = load_pem_cert(instacert_f))
-            || !TEST_ptr(instaca_cert = load_pem_cert(instaca_f)))
+    if (!TEST_ptr(insta_cert = load_pem_cert(instacert_f, libctx))
+            || !TEST_ptr(instaca_cert = load_pem_cert(instaca_f, libctx)))
         goto err;
 
     /* Load certificates for message validation */
-    if (!TEST_ptr(srvcert = load_pem_cert(server_f))
-            || !TEST_ptr(clcert = load_pem_cert(client_f)))
+    if (!TEST_ptr(srvcert = load_pem_cert(server_f, libctx))
+            || !TEST_ptr(clcert = load_pem_cert(client_f, libctx)))
         goto err;
     if (!TEST_int_eq(1, RAND_bytes(rand_data, OSSL_CMP_TRANSACTIONID_LENGTH)))
         goto err;
diff --git a/test/ct_test.c b/test/ct_test.c
index 79ffcbf9a2..2e161a74d2 100644
--- a/test/ct_test.c
+++ b/test/ct_test.c
@@ -338,8 +338,6 @@ end:
 static int test_no_scts_in_certificate(void)
 {
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->certs_dir = certs_dir;
     fixture->certificate_file = "leaf.pem";
     fixture->issuer_file = "subinterCA.pem";
@@ -351,8 +349,6 @@ static int test_no_scts_in_certificate(void)
 static int test_one_sct_in_certificate(void)
 {
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->certs_dir = certs_dir;
     fixture->certificate_file = "embeddedSCTs1.pem";
     fixture->issuer_file = "embeddedSCTs1_issuer.pem";
@@ -366,8 +362,6 @@ static int test_one_sct_in_certificate(void)
 static int test_multiple_scts_in_certificate(void)
 {
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->certs_dir = certs_dir;
     fixture->certificate_file = "embeddedSCTs3.pem";
     fixture->issuer_file = "embeddedSCTs3_issuer.pem";
@@ -381,8 +375,6 @@ static int test_multiple_scts_in_certificate(void)
 static int test_verify_one_sct(void)
 {
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->certs_dir = certs_dir;
     fixture->certificate_file = "embeddedSCTs1.pem";
     fixture->issuer_file = "embeddedSCTs1_issuer.pem";
@@ -395,8 +387,6 @@ static int test_verify_one_sct(void)
 static int test_verify_multiple_scts(void)
 {
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->certs_dir = certs_dir;
     fixture->certificate_file = "embeddedSCTs3.pem";
     fixture->issuer_file = "embeddedSCTs3_issuer.pem";
@@ -409,8 +399,6 @@ static int test_verify_multiple_scts(void)
 static int test_verify_fails_for_future_sct(void)
 {
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->epoch_time_in_ms = 1365094800000ULL; /* Apr 4 17:00:00 2013 GMT */
     fixture->certs_dir = certs_dir;
     fixture->certificate_file = "embeddedSCTs1.pem";
@@ -443,8 +431,6 @@ static int test_decode_tls_sct(void)
         "\xED\xBF\x08";
 
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->tls_sct_list = tls_sct_list;
     fixture->tls_sct_list_len = 0x7a;
     fixture->sct_dir = ct_dir;
@@ -463,8 +449,6 @@ static int test_encode_tls_sct(void)
     SCT *sct = NULL;
 
     SETUP_CT_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
 
     fixture->sct_list = sk_SCT_new_null();
     if (!TEST_ptr(sct = SCT_new_from_base64(SCT_VERSION_V1, log_id,
diff --git a/test/recipes/65-test_cmp_client.t b/test/recipes/65-test_cmp_client.t
index 1b54940e94..de60599cf0 100644
--- a/test/recipes/65-test_cmp_client.t
+++ b/test/recipes/65-test_cmp_client.t
@@ -9,19 +9,40 @@
 # https://www.openssl.org/source/license.html
 
 use strict;
-use OpenSSL::Test qw/:DEFAULT data_file/;
+use OpenSSL::Test qw/:DEFAULT data_file srctop_file srctop_dir bldtop_file bldtop_dir/;
 use OpenSSL::Test::Utils;
 
-setup("test_cmp_client");
+BEGIN {
+    setup("test_cmp_client");
+}
+
+use lib srctop_dir('Configurations');
+use lib bldtop_dir('.');
+use platform;
+
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
 
 plan skip_all => "This test is not supported in a no-cmp or no-ec build"
     if disabled("cmp") || disabled("ec");
 
-plan tests => 1;
+plan tests => 2 + ($no_fips ? 0 : 2); #fips install + fips test
+
+my @basic_cmd = ("cmp_client_test",
+                 data_file("server.key"),
+                 data_file("server.crt"),
+                 data_file("client.key"),
+                 data_file("client.crt"),
+                 data_file("client.csr"));
+
+ok(run(test([@basic_cmd, "none"])));
+
+ok(run(test([@basic_cmd, "default", srctop_file("test", "default.cnf")])));
+
+unless ($no_fips) {
+    ok(run(app(['openssl', 'fipsinstall',
+                '-out', bldtop_file('providers', 'fipsmodule.cnf'),
+                '-module', bldtop_file('providers', platform->dso('fips'))])),
+       "fipsinstall");
 
-ok(run(test(["cmp_client_test",
-             data_file("server.key"),
-             data_file("server.crt"),
-             data_file("client.key"),
-             data_file("client.crt"),
-             data_file("client.csr")])));
+    ok(run(test([@basic_cmd, "fips", srctop_file("test", "fips.cnf")])));
+}
diff --git a/test/recipes/65-test_cmp_msg.t b/test/recipes/65-test_cmp_msg.t
index e1b08ccfa2..0347c1a2a9 100644
--- a/test/recipes/65-test_cmp_msg.t
+++ b/test/recipes/65-test_cmp_msg.t
@@ -9,16 +9,38 @@
 # https://www.openssl.org/source/license.html
 
 use strict;
-use OpenSSL::Test qw/:DEFAULT data_file/;
+use OpenSSL::Test qw/:DEFAULT data_file srctop_file srctop_dir bldtop_file bldtop_dir/;
 use OpenSSL::Test::Utils;
 
-setup("test_cmp_msg");
+BEGIN {
+    setup("test_cmp_msg");
+}
+
+use lib srctop_dir('Configurations');
+use lib bldtop_dir('.');
+use platform;
+
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
 
 plan skip_all => "This test is not supported in a no-cmp build"
     if disabled("cmp");
 
-plan tests => 1;
+plan tests => 2 + ($no_fips ? 0 : 2); #fips install + fips test
+
+my @basic_cmd = ("cmp_msg_test",
+                 data_file("new.key"),
+                 data_file("server.crt"),
+                 data_file("pkcs10.der"));
+
+ok(run(test([@basic_cmd, "none"])));
+
+ok(run(test([@basic_cmd, "default", srctop_file("test", "default.cnf")])));
+
+unless ($no_fips) {
+    ok(run(app(['openssl', 'fipsinstall',
+                '-out', bldtop_file('providers', 'fipsmodule.cnf'),
+                '-module', bldtop_file('providers', platform->dso('fips'))])),
+       "fipsinstall");
 
-ok(run(test(["cmp_msg_test",
-             data_file("server.crt"),
-             data_file("pkcs10.der")])));
+    ok(run(test([@basic_cmd, "fips", srctop_file("test", "fips.cnf")])));
+}
diff --git a/test/certs/root-key2.pem b/test/recipes/65-test_cmp_msg_data/new.key
similarity index 100%
copy from test/certs/root-key2.pem
copy to test/recipes/65-test_cmp_msg_data/new.key
diff --git a/test/recipes/65-test_cmp_protect.t b/test/recipes/65-test_cmp_protect.t
index cc36d2674d..19185e112b 100644
--- a/test/recipes/65-test_cmp_protect.t
+++ b/test/recipes/65-test_cmp_protect.t
@@ -9,10 +9,18 @@
 # https://www.openssl.org/source/license.html
 
 use strict;
-use OpenSSL::Test qw/:DEFAULT data_file/;
+use OpenSSL::Test qw/:DEFAULT data_file srctop_file srctop_dir bldtop_file bldtop_dir/;
 use OpenSSL::Test::Utils;
 
-setup("test_cmp_protect");
+BEGIN {
+    setup("test_cmp_protect");
+}
+
+use lib srctop_dir('Configurations');
+use lib bldtop_dir('.');
+use platform;
+
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
 
 plan skip_all => "This test is not supported in a no-cmp build"
     if disabled("cmp");
@@ -20,16 +28,29 @@ plan skip_all => "This test is not supported in a no-cmp build"
 plan skip_all => "This test is not supported in a shared library build on Windows"
     if $^O eq 'MSWin32' && !disabled("shared");
 
-plan tests => 1;
-
-ok(run(test(["cmp_protect_test",
-             data_file("server.pem"),
-             data_file("IR_protected.der"),
-             data_file("IR_unprotected.der"),
-             data_file("IP_PBM.der"),
-             data_file("server.crt"),
-             data_file("server.pem"),
-             data_file("EndEntity1.crt"),
-             data_file("EndEntity2.crt"),
-             data_file("Root_CA.crt"),
-             data_file("Intermediate_CA.crt")])));
+plan tests => 2 + ($no_fips ? 0 : 2); #fips install + fips test
+
+my @basic_cmd = ("cmp_protect_test",
+                 data_file("server.pem"),
+                 data_file("IR_protected.der"),
+                 data_file("IR_unprotected.der"),
+                 data_file("IP_PBM.der"),
+                 data_file("server.crt"),
+                 data_file("server.pem"),
+                 data_file("EndEntity1.crt"),
+                 data_file("EndEntity2.crt"),
+                 data_file("Root_CA.crt"),
+                 data_file("Intermediate_CA.crt"));
+
+ok(run(test([@basic_cmd, "none"])));
+
+ok(run(test([@basic_cmd, "default", srctop_file("test", "default.cnf")])));
+
+unless ($no_fips) {
+    ok(run(app(['openssl', 'fipsinstall',
+                '-out', bldtop_file('providers', 'fipsmodule.cnf'),
+                '-module', bldtop_file('providers', platform->dso('fips'))])),
+       "fipsinstall");
+
+    ok(run(test([@basic_cmd, "fips", srctop_file("test", "fips.cnf")])));
+}
diff --git a/test/recipes/65-test_cmp_server.t b/test/recipes/65-test_cmp_server.t
index 87dbdb10b2..5864163f01 100644
--- a/test/recipes/65-test_cmp_server.t
+++ b/test/recipes/65-test_cmp_server.t
@@ -9,10 +9,18 @@
 # https://www.openssl.org/source/license.html
 
 use strict;
-use OpenSSL::Test qw/:DEFAULT data_file/;
+use OpenSSL::Test qw/:DEFAULT data_file srctop_file srctop_dir bldtop_file bldtop_dir/;
 use OpenSSL::Test::Utils;
 
-setup("test_cmp_server");
+BEGIN {
+    setup("test_cmp_server");
+}
+
+use lib srctop_dir('Configurations');
+use lib bldtop_dir('.');
+use platform;
+
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
 
 plan skip_all => "This test is not supported in a no-cmp build"
     if disabled("cmp");
@@ -20,7 +28,19 @@ plan skip_all => "This test is not supported in a no-cmp build"
 plan skip_all => "This test is not supported in a no-ec build"
     if disabled("ec");
 
-plan tests => 1;
+plan tests => 2 + ($no_fips ? 0 : 2); #fips install + fips test
+
+my @basic_cmd = ("cmp_server_test", data_file("CR_protected_PBM_1234.der"));
+
+ok(run(test([@basic_cmd, "none"])));
+
+ok(run(test([@basic_cmd, "default", srctop_file("test", "default.cnf")])));
+
+unless ($no_fips) {
+    ok(run(app(['openssl', 'fipsinstall',
+                '-out', bldtop_file('providers', 'fipsmodule.cnf'),
+                '-module', bldtop_file('providers', platform->dso('fips'))])),
+       "fipsinstall");
 
-ok(run(test(["cmp_server_test",
-             data_file("CR_protected_PBM_1234.der")])));
+    ok(run(test([@basic_cmd, "fips", srctop_file("test", "fips.cnf")])));
+}
diff --git a/test/recipes/65-test_cmp_vfy.t b/test/recipes/65-test_cmp_vfy.t
index 8b3911ea36..800dabcd85 100644
--- a/test/recipes/65-test_cmp_vfy.t
+++ b/test/recipes/65-test_cmp_vfy.t
@@ -9,10 +9,18 @@
 # https://www.openssl.org/source/license.html
 
 use strict;
-use OpenSSL::Test qw/:DEFAULT data_file/;
+use OpenSSL::Test qw/:DEFAULT data_file srctop_file srctop_dir bldtop_file bldtop_dir/;
 use OpenSSL::Test::Utils;
 
-setup("test_cmp_vfy");
+BEGIN {
+    setup("test_cmp_vfy");
+}
+
+use lib srctop_dir('Configurations');
+use lib bldtop_dir('.');
+use platform;
+
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
 
 plan skip_all => "This test is not supported in a no-cmp build"
     if disabled("cmp");
@@ -20,17 +28,30 @@ plan skip_all => "This test is not supported in a no-cmp build"
 plan skip_all => "This test is not supported in a no-ec build"
     if disabled("ec");
 
-plan tests => 1;
-
-ok(run(test(["cmp_vfy_test",
-             data_file("server.crt"),     data_file("client.crt"),
-             data_file("EndEntity1.crt"), data_file("EndEntity2.crt"),
-             data_file("Root_CA.crt"),    data_file("Intermediate_CA.crt"),
-             data_file("IR_protected.der"),
-             data_file("IR_unprotected.der"),
-             data_file("IP_waitingStatus_PBM.der"),
-             data_file("IR_rmprotection.der"),
-             data_file("insta.cert.pem"),
-             data_file("insta_ca.cert.pem"),
-             data_file("IR_protected_0_extraCerts.der"),
-             data_file("IR_protected_2_extraCerts.der")])));
+plan tests => 2 + ($no_fips ? 0 : 2); #fips install + fips test
+
+my @basic_cmd = ("cmp_vfy_test",
+                 data_file("server.crt"),     data_file("client.crt"),
+                 data_file("EndEntity1.crt"), data_file("EndEntity2.crt"),
+                 data_file("Root_CA.crt"),    data_file("Intermediate_CA.crt"),
+                 data_file("IR_protected.der"),
+                 data_file("IR_unprotected.der"),
+                 data_file("IP_waitingStatus_PBM.der"),
+                 data_file("IR_rmprotection.der"),
+                 data_file("insta.cert.pem"),
+                 data_file("insta_ca.cert.pem"),
+                 data_file("IR_protected_0_extraCerts.der"),
+                 data_file("IR_protected_2_extraCerts.der"));
+
+ok(run(test([@basic_cmd, "none"])));
+
+ok(run(test([@basic_cmd, "default", srctop_file("test", "default.cnf")])));
+
+unless ($no_fips) {
+    ok(run(app(['openssl', 'fipsinstall',
+                '-out', bldtop_file('providers', 'fipsmodule.cnf'),
+                '-module', bldtop_file('providers', platform->dso('fips'))])),
+       "fipsinstall");
+
+    ok(run(test([@basic_cmd, "fips", srctop_file("test", "fips.cnf")])));
+}
diff --git a/test/ssl_test.c b/test/ssl_test.c
index 5880468f93..18e92c7f77 100644
--- a/test/ssl_test.c
+++ b/test/ssl_test.c
@@ -513,12 +513,12 @@ err:
     return ret;
 }
 
-OPT_TEST_DECLARE_USAGE("conf_file modulename [fips_conf_file]\n")
+#define USAGE "conf_file module_name [module_conf_file]\n"
+OPT_TEST_DECLARE_USAGE(USAGE)
 
 int setup_tests(void)
 {
     long num_tests;
-    const char *modulename;
 
     if (!test_skip_common_options()) {
         TEST_error("Error parsing test options\n");
@@ -529,29 +529,14 @@ int setup_tests(void)
             /* argv[1] should point to the test conf file */
             || !TEST_int_gt(NCONF_load(conf, test_get_argument(0), NULL), 0)
             || !TEST_int_ne(NCONF_get_number_e(conf, NULL, "num_tests",
-                                               &num_tests), 0))
+                                               &num_tests), 0)) {
+        TEST_error("usage: ssl_test %s", USAGE);
         return 0;
+    }
 
-    if (!TEST_ptr(modulename = test_get_argument(1)))
+    if (!test_get_libctx(&libctx, &defctxnull, &thisprov, 1, USAGE))
         return 0;
 
-    if (strcmp(modulename, "none") != 0) {
-        const char *configfile = test_get_argument(2);
-
-        defctxnull = OSSL_PROVIDER_load(NULL, "null");
-        libctx = OPENSSL_CTX_new();
-        if (!TEST_ptr(libctx))
-            return 0;
-
-        if (configfile != NULL
-                && !TEST_true(OPENSSL_CTX_load_config(libctx, configfile)))
-            return 0;
-
-        thisprov = OSSL_PROVIDER_load(libctx, modulename);
-        if (!TEST_ptr(thisprov))
-            return 0;
-    }
-
     ADD_ALL_TESTS(test_handshake, (int)num_tests);
     return 1;
 }
diff --git a/test/ssl_test_ctx_test.c b/test/ssl_test_ctx_test.c
index 16ce32a33f..91f418095f 100644
--- a/test/ssl_test_ctx_test.c
+++ b/test/ssl_test_ctx_test.c
@@ -151,8 +151,6 @@ static void tear_down(SSL_TEST_CTX_TEST_FIXTURE *fixture)
 static int test_empty_configuration(void)
 {
     SETUP_SSL_TEST_CTX_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->test_section = "ssltest_default";
     fixture->expected_ctx->expected_result = SSL_TEST_SUCCESS;
     EXECUTE_SSL_TEST_CTX_TEST();
@@ -162,8 +160,6 @@ static int test_empty_configuration(void)
 static int test_good_configuration(void)
 {
     SETUP_SSL_TEST_CTX_TEST_FIXTURE();
-    if (fixture == NULL)
-        return 0;
     fixture->test_section = "ssltest_good";
     fixture->expected_ctx->method = SSL_TEST_METHOD_DTLS;
     fixture->expected_ctx->handshake_mode = SSL_TEST_HANDSHAKE_RESUME;
diff --git a/test/testutil.h b/test/testutil.h
index 88a3cbc9a8..14483fd405 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -10,12 +10,13 @@
 #ifndef OSSL_TESTUTIL_H
 # define OSSL_TESTUTIL_H
 
-#include <stdarg.h>
+# include <stdarg.h>
 
-#include <openssl/err.h>
-#include <openssl/e_os2.h>
-#include <openssl/bn.h>
-#include "opt.h"
+# include <openssl/provider.h>
+# include <openssl/err.h>
+# include <openssl/e_os2.h>
+# include <openssl/bn.h>
+# include "opt.h"
 
 /*-
  * Simple unit tests should implement setup_tests().
@@ -67,6 +68,7 @@
  * object called "fixture". It will also allocate the "result" variable used
  * by EXECUTE_TEST. set_up() should take a const char* specifying the test
  * case name and return a TEST_FIXTURE_TYPE by reference.
+ * If case set_up() fails then 0 is returned.
  *
  * EXECUTE_TEST will pass fixture to execute_func() by reference, call
  * tear_down(), and return the result of execute_func(). execute_func() should
@@ -94,7 +96,11 @@
  */
 # define SETUP_TEST_FIXTURE(TEST_FIXTURE_TYPE, set_up)\
     TEST_FIXTURE_TYPE *fixture = set_up(TEST_CASE_NAME); \
-    int result = 0
+    int result = 0; \
+\
+    if (fixture == NULL) \
+        return 0
+
 
 # define EXECUTE_TEST(execute_func, tear_down)\
     if (fixture != NULL) {\
@@ -120,7 +126,7 @@
 
 
 /* The default test enum which should be common to all tests */
-#define OPT_TEST_ENUM \
+# define OPT_TEST_ENUM \
     OPT_TEST_HELP = 500, \
     OPT_TEST_LIST, \
     OPT_TEST_SINGLE, \
@@ -129,7 +135,7 @@
     OPT_TEST_SEED
 
 /* The Default test OPTIONS common to all tests (without a usage string) */
-#define OPT_TEST_OPTIONS \
+# define OPT_TEST_OPTIONS \
     { OPT_HELP_STR, 1,  '-', "Valid options are:\n" }, \
     { "help", OPT_TEST_HELP, '-', "Display this summary" }, \
     { "list", OPT_TEST_LIST, '-', "Display the list of tests available" }, \
@@ -139,12 +145,12 @@
     { "seed", OPT_TEST_SEED, 'n', "Seed value to randomize tests with" }
 
 /* The Default test OPTIONS common to all tests starting with an additional usage string */
-#define OPT_TEST_OPTIONS_WITH_EXTRA_USAGE(usage) \
+# define OPT_TEST_OPTIONS_WITH_EXTRA_USAGE(usage) \
     { OPT_HELP_STR, 1, '-', "Usage: %s [options] " usage }, \
     OPT_TEST_OPTIONS
 
 /* The Default test OPTIONS common to all tests with an default usage string */
-#define OPT_TEST_OPTIONS_DEFAULT_USAGE \
+# define OPT_TEST_OPTIONS_DEFAULT_USAGE \
     { OPT_HELP_STR, 1, '-', "Usage: %s [options]\n" }, \
     OPT_TEST_OPTIONS
 
@@ -152,7 +158,7 @@
  * Optional Cases that need to be ignored by the test app when using opt_next(),
  * (that are handled internally).
  */
-#define OPT_TEST_CASES \
+# define OPT_TEST_CASES \
          OPT_TEST_HELP: \
     case OPT_TEST_LIST: \
     case OPT_TEST_SINGLE: \
@@ -174,7 +180,7 @@
  *      well as the additional options that need to be handled.
  *  (3) case OPT_TEST_CASES: break; inside the opt_next() handling code.
  */
-#define OPT_TEST_DECLARE_USAGE(usage_str) \
+# define OPT_TEST_DECLARE_USAGE(usage_str) \
 const OPTIONS *test_get_options(void) \
 { \
     enum { OPT_TEST_ENUM }; \
@@ -199,6 +205,10 @@ size_t test_get_argument_count(void);
  */
 int test_skip_common_options(void);
 
+int test_get_libctx(OPENSSL_CTX **libctx,
+                    OSSL_PROVIDER **default_null_provider,
+                    OSSL_PROVIDER **provider, int argn, const char *usage);
+
 /*
  * Internal helpers. Test programs shouldn't use these directly, but should
  * rather link to one of the helper main() methods.
@@ -230,17 +240,17 @@ const OPTIONS *test_get_options(void);
  *  Test assumption verification helpers.
  */
 
-#define PRINTF_FORMAT(a, b)
-#if defined(__GNUC__) && defined(__STDC_VERSION__)
+# define PRINTF_FORMAT(a, b)
+# if defined(__GNUC__) && defined(__STDC_VERSION__)
   /*
    * Because we support the 'z' modifier, which made its appearance in C99,
    * we can't use __attribute__ with pre C99 dialects.
    */
-# if __STDC_VERSION__ >= 199901L
-#  undef PRINTF_FORMAT
-#  define PRINTF_FORMAT(a, b)   __attribute__ ((format(printf, a, b)))
+#  if __STDC_VERSION__ >= 199901L
+#   undef PRINTF_FORMAT
+#   define PRINTF_FORMAT(a, b)   __attribute__ ((format(printf, a, b)))
+#  endif
 # endif
-#endif
 
 # define DECLARE_COMPARISON(type, name, opname)                         \
     int test_ ## name ## _ ## opname(const char *, int,                 \
@@ -498,7 +508,7 @@ void test_output_memory(const char *name, const unsigned char *m, size_t l);
 /*
  * Utilities to parse a test file.
  */
-#define TESTMAXPAIRS        150
+# define TESTMAXPAIRS        150
 
 typedef struct pair_st {
     char *key;
diff --git a/test/testutil/provider.c b/test/testutil/provider.c
new file mode 100644
index 0000000000..f7c7b1cdb6
--- /dev/null
+++ b/test/testutil/provider.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2018-2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "../testutil.h"
+#include <openssl/provider.h>
+#include <string.h>
+
+int test_get_libctx(OPENSSL_CTX **libctx,
+                    OSSL_PROVIDER **default_null_provider,
+                    OSSL_PROVIDER **provider, int argn, const char *usage)
+{
+    const char *module_name;
+
+    if (!TEST_ptr(module_name = test_get_argument(argn))) {
+        TEST_error("usage: <prog> %s", usage);
+        return 0;
+    }
+    if (strcmp(module_name, "none") != 0) {
+        const char *config_fname = test_get_argument(argn + 1);
+
+        *default_null_provider = OSSL_PROVIDER_load(NULL, "null");
+        *libctx = OPENSSL_CTX_new();
+        if (!TEST_ptr(*libctx)) {
+            TEST_error("Failed to create libctx\n");
+            goto err;
+        }
+
+        if (config_fname != NULL
+                && !TEST_true(OPENSSL_CTX_load_config(*libctx, config_fname))) {
+            TEST_error("Error loading config file %s\n", config_fname);
+            goto err;
+        }
+
+        *provider = OSSL_PROVIDER_load(*libctx, module_name);
+        if (!TEST_ptr(*provider)) {
+            TEST_error("Failed to load provider %s\n", module_name);
+            goto err;
+        }
+    }
+    return 1;
+
+ err:
+    ERR_print_errors_fp(stderr);
+    return 0;
+}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index a9b914839a..19a9b4c9d3 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4926,6 +4926,8 @@ PKCS8_pkey_add1_attr_by_OBJ             ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_private_check                  ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_pairwise_check                 ?	3_0_0	EXIST::FUNCTION:
 ASN1_item_verify_ctx                    ?	3_0_0	EXIST::FUNCTION:
+ASN1_item_sign_with_libctx              ?	3_0_0	EXIST::FUNCTION:
+ASN1_item_verify_with_libctx            ?	3_0_0	EXIST::FUNCTION:
 RAND_DRBG_set_callback_data             ?	3_0_0	NOEXIST::FUNCTION:
 RAND_DRBG_get_callback_data             ?	3_0_0	NOEXIST::FUNCTION:
 BIO_socket_wait                         ?	3_0_0	EXIST::FUNCTION:SOCK
diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt
index 3aa3b5065b..97208d364e 100644
--- a/util/missingcrypto.txt
+++ b/util/missingcrypto.txt
@@ -156,9 +156,11 @@ ASN1_item_pack(3)
 ASN1_item_print(3)
 ASN1_item_sign(3)
 ASN1_item_sign_ctx(3)
+ASN1_item_sign_with_libctx(3)
 ASN1_item_unpack(3)
 ASN1_item_verify(3)
 ASN1_item_verify_ctx(3)
+ASN1_item_verify_with_libctx(3)
 ASN1_mbstring_copy(3)
 ASN1_mbstring_ncopy(3)
 ASN1_object_size(3)


More information about the openssl-commits mailing list