[openssl] master update

dev at ddvo.net dev at ddvo.net
Thu Mar 18 06:04:34 UTC 2021


The branch master has been updated
       via  63b64f19c13d59d68dc2e525f454aea62a739842 (commit)
       via  bef876f97e26309ccd20f916cf1e5e305735ee98 (commit)
       via  6b937ae3a7a2dfac55d25a18bd6d5a084c24e3d5 (commit)
       via  49f07be43d031f0407db8ae1b8cdf6452a79e558 (commit)
      from  d07d8057991712261323c05bb022d000a01404d0 (commit)


- Log -----------------------------------------------------------------
commit 63b64f19c13d59d68dc2e525f454aea62a739842
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Fri Mar 12 19:45:40 2021 +0100

    TS and CMS CAdES-BES: Refactor check_signing_certs() funcs into common ESS func
    
    Also constify related CMS/PKCS7 functions and improve error codes thrown.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14503)

commit bef876f97e26309ccd20f916cf1e5e305735ee98
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Fri Mar 12 15:54:34 2021 +0100

    ts_check_signing_certs(): Make sure both ESSCertID and ESSCertIDv2 are checked
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14503)

commit 6b937ae3a7a2dfac55d25a18bd6d5a084c24e3d5
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Wed Mar 10 17:21:37 2021 +0100

    TS ESS: Invert the search logic of ts_check_signing_certs() to correctly cover cert ID list
    
    Fixes #14190
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14503)

commit 49f07be43d031f0407db8ae1b8cdf6452a79e558
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Sat Mar 13 11:29:19 2021 +0100

    apps.c: Fix missing newline in warn_cert_msg() output
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14503)

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

Summary of changes:
 CHANGES.md                                         |   9 ++
 apps/cms.c                                         |   6 +-
 apps/lib/apps.c                                    |   2 +-
 crypto/cms/cms_att.c                               |   3 +-
 crypto/cms/cms_err.c                               |   2 -
 crypto/cms/cms_ess.c                               |  63 +---------
 crypto/cms/cms_local.h                             |   3 +-
 crypto/cms/cms_smime.c                             |   2 +-
 crypto/err/openssl.txt                             |  10 +-
 crypto/ess/ess_asn1.c                              |   4 +-
 crypto/ess/ess_err.c                               |  14 ++-
 crypto/ess/ess_lib.c                               | 127 ++++++++++++---------
 crypto/pkcs7/pk7_doit.c                            |   8 +-
 crypto/ts/ts_rsp_verify.c                          |  60 ++--------
 doc/man1/openssl-cms.pod.in                        |  26 +++--
 doc/man1/openssl-ts.pod.in                         |  11 +-
 doc/man3/CMS_verify.pod                            |   4 +-
 include/crypto/cms.h                               |   4 +-
 include/crypto/ess.h                               |  12 +-
 include/crypto/esserr.h                            |   2 +-
 include/openssl/cms.h.in                           |   3 +-
 include/openssl/cmserr.h                           |   1 -
 include/openssl/esserr.h                           |   6 +
 include/openssl/pkcs7.h.in                         |   4 +-
 test/recipes/80-test_cms.t                         |  10 +-
 test/recipes/80-test_tsa.t                         |  96 +++++++++++-----
 test/recipes/80-test_tsa_data/all-zero.tsq         | Bin 0 -> 59 bytes
 test/recipes/80-test_tsa_data/comodo-aaa.pem       |  25 ++++
 test/recipes/80-test_tsa_data/sectigo-all-zero.tsr | Bin 0 -> 4981 bytes
 test/recipes/80-test_tsa_data/sectigo-signer.pem   |  40 +++++++
 .../80-test_tsa_data/sectigo-time-stamping-ca.pem  |  39 +++++++
 .../recipes/80-test_tsa_data/user-trust-ca-aaa.pem |  32 ++++++
 test/recipes/80-test_tsa_data/user-trust-ca.pem    |  34 ++++++
 33 files changed, 415 insertions(+), 247 deletions(-)
 create mode 100644 test/recipes/80-test_tsa_data/all-zero.tsq
 create mode 100644 test/recipes/80-test_tsa_data/comodo-aaa.pem
 create mode 100644 test/recipes/80-test_tsa_data/sectigo-all-zero.tsr
 create mode 100644 test/recipes/80-test_tsa_data/sectigo-signer.pem
 create mode 100644 test/recipes/80-test_tsa_data/sectigo-time-stamping-ca.pem
 create mode 100644 test/recipes/80-test_tsa_data/user-trust-ca-aaa.pem
 create mode 100644 test/recipes/80-test_tsa_data/user-trust-ca.pem

diff --git a/CHANGES.md b/CHANGES.md
index e51e61a96b..f6800a337d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -58,6 +58,15 @@ OpenSSL 3.0
 
    *Richard Levitte*
 
+ * Improved adherence to Enhanced Security Services (ESS, RFC 2634 and RFC 5035)
+   for the TSP and CMS Advanced Electronic Signatures (CAdES) implementations.
+   As required by RFC 5035 check both ESSCertID and ESSCertIDv2 if both present.
+   Correct the semantics of checking the validation chain in case ESSCertID{,v2}
+   contains more than one certificate identifier: This means that all
+   certificates referenced there MUST be part of the validation chain.
+
+   *David von Oheimb*
+
  * The implementation of the EVP ciphers CAST5-ECB, CAST5-CBC, CAST5-OFB,
    CAST5-CFB, BF-ECB, BF-CBC, BF-OFB, BF-CFB, IDEA-ECB, IDEC-CBC, IDEA-OFB,
    IDEA-CFB, SEED-ECB, SEED-CBC, SEED-OFB, SEED-CFB, RC2-ECB, RC2-CBC,
diff --git a/apps/cms.c b/apps/cms.c
index cea1b73d88..b03e981a56 100644
--- a/apps/cms.c
+++ b/apps/cms.c
@@ -126,7 +126,7 @@ const OPTIONS cms_options[] = {
     {"sign", OPT_SIGN, '-', "Sign message"},
     {"sign_receipt", OPT_SIGN_RECEIPT, '-', "Generate a signed receipt for the message"},
     {"resign", OPT_RESIGN, '-', "Resign a signed message"},
-    {"cades", OPT_CADES, '-', "Include signer certificate digest"},
+    {"cades", OPT_CADES, '-', "Include or check signingCertificate (CAdES-BES)"},
     {"verify", OPT_VERIFY, '-', "Verify signed message"},
     {"verify_retcode", OPT_VERIFY_RETCODE, '-',
         "Exit non-zero on verification failure"},
@@ -728,12 +728,12 @@ int cms_main(int argc, char **argv)
     if ((flags & CMS_CADES) != 0) {
         if ((flags & CMS_NOATTR) != 0) {
             BIO_puts(bio_err, "Incompatible options: "
-                     "CAdES required signed attributes\n");
+                     "CAdES requires signed attributes\n");
             goto opthelp;
         }
         if (operation == SMIME_VERIFY
                 && (flags & (CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY)) != 0) {
-            BIO_puts(bio_err, "Incompatible options: CAdES validation require"
+            BIO_puts(bio_err, "Incompatible options: CAdES validation requires"
                      " certs and signed attributes validations\n");
             goto opthelp;
         }
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index f992eab053..61b3ebc6de 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -661,7 +661,7 @@ static void warn_cert_msg(const char *uri, X509 *cert, const char *msg)
 {
     char *subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
 
-    BIO_printf(bio_err, "Warning: certificate from '%s' with subject '%s' %s",
+    BIO_printf(bio_err, "Warning: certificate from '%s' with subject '%s' %s\n",
                uri, subj, msg);
     OPENSSL_free(subj);
 }
diff --git a/crypto/cms/cms_att.c b/crypto/cms/cms_att.c
index a9ef0357e5..2ac118b9e6 100644
--- a/crypto/cms/cms_att.c
+++ b/crypto/cms/cms_att.c
@@ -125,7 +125,8 @@ int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
     return 0;
 }
 
-void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid,
+void *CMS_signed_get0_data_by_OBJ(const CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *oid,
                                   int lastpos, int type)
 {
     return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
index 173e1596f6..81249ce689 100644
--- a/crypto/cms/cms_err.c
+++ b/crypto/cms/cms_err.c
@@ -59,8 +59,6 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO),
     "error setting recipientinfo"},
-    {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE),
-    "ess no signing certid attribute"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR),
     "ess signing certid mismatch error"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c
index b8b0076e03..5982035c45 100644
--- a/crypto/cms/cms_ess.c
+++ b/crypto/cms/cms_ess.c
@@ -46,67 +46,14 @@ int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
     return 1;
 }
 
-/*
-    First, get the ESS_SIGNING_CERT(V2) signed attribute from |si|.
-    Then check matching of each cert of trust |chain| with one of 
-    the |cert_ids|(Hash+IssuerID) list from this ESS_SIGNING_CERT.
-    Derived from ts_check_signing_certs()
-*/
-int ossl_ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain)
+int ossl_cms_check_signing_certs(const CMS_SignerInfo *si,
+                                 const STACK_OF(X509) *chain)
 {
     ESS_SIGNING_CERT *ss = NULL;
     ESS_SIGNING_CERT_V2 *ssv2 = NULL;
-    X509 *cert;
-    int i = 0, ret = 0;
-
-    if (ossl_cms_signerinfo_get_signing_cert(si, &ss) > 0
-            && ss->cert_ids != NULL) {
-        STACK_OF(ESS_CERT_ID) *cert_ids = ss->cert_ids;
-
-        cert = sk_X509_value(chain, 0);
-        if (ossl_ess_find_cert(cert_ids, cert) != 0)
-            goto err;
-
-        /*
-         * Check the other certificates of the chain.
-         * Fail if no signing certificate ids found for each certificate.
-         */
-        if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
-            /* for each chain cert, try to find its cert id */
-            for (i = 1; i < sk_X509_num(chain); ++i) {
-                cert = sk_X509_value(chain, i);
-                if (ossl_ess_find_cert(cert_ids, cert) < 0)
-                    goto err;
-            }
-        }
-    } else if (ossl_cms_signerinfo_get_signing_cert_v2(si, &ssv2) > 0
-                   && ssv2->cert_ids!= NULL) {
-        STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = ssv2->cert_ids;
-
-        cert = sk_X509_value(chain, 0);
-        if (ossl_ess_find_cert_v2(cert_ids_v2, cert) != 0)
-            goto err;
-
-        /*
-         * Check the other certificates of the chain.
-         * Fail if no signing certificate ids found for each certificate.
-         */
-        if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) {
-            /* for each chain cert, try to find its cert id */
-            for (i = 1; i < sk_X509_num(chain); ++i) {
-                cert = sk_X509_value(chain, i);
-                if (ossl_ess_find_cert_v2(cert_ids_v2, cert) < 0)
-                    goto err;
-            }
-        }
-    } else {
-        ERR_raise(ERR_LIB_CMS, CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE);
-        return 0;
-    }
-    ret = 1;
- err:
-    if (!ret)
-        ERR_raise(ERR_LIB_CMS, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR);
+    int ret = ossl_cms_signerinfo_get_signing_cert(si, &ss) >= 0
+        && ossl_cms_signerinfo_get_signing_cert_v2(si, &ssv2) >= 0
+        && ossl_ess_check_signing_certs(ss, ssv2, chain, 1);
 
     ESS_SIGNING_CERT_free(ss);
     ESS_SIGNING_CERT_V2_free(ssv2);
diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h
index 2429202fa8..0827c55a1c 100644
--- a/crypto/cms/cms_local.h
+++ b/crypto/cms/cms_local.h
@@ -473,7 +473,8 @@ void ossl_cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms);
 
 
 /* ESS routines */
-int ossl_ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain);
+int ossl_cms_check_signing_certs(const CMS_SignerInfo *si,
+                                 const STACK_OF(X509) *chain);
 
 int ossl_cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt);
 int ossl_cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt);
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
index ac4ad2d490..3ab4cd2e6f 100644
--- a/crypto/cms/cms_smime.c
+++ b/crypto/cms/cms_smime.c
@@ -381,7 +381,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
             if (cadesVerify) {
                 STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL;
 
-                if (ossl_ess_check_signing_certs(si, si_chain) <= 0)
+                if (ossl_cms_check_signing_certs(si, si_chain) <= 0)
                     goto err;
             }
         }
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 53e8c4cd39..68c2ea8aa3 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -299,7 +299,6 @@ CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\
 	error reading messagedigest attribute
 CMS_R_ERROR_SETTING_KEY:115:error setting key
 CMS_R_ERROR_SETTING_RECIPIENTINFO:116:error setting recipientinfo
-CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE:182:ess no signing certid attribute
 CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error
 CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length
 CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter
@@ -629,9 +628,16 @@ ENGINE_R_UNIMPLEMENTED_CIPHER:146:unimplemented cipher
 ENGINE_R_UNIMPLEMENTED_DIGEST:147:unimplemented digest
 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD:101:unimplemented public key method
 ENGINE_R_VERSION_INCOMPATIBILITY:145:version incompatibility
+ESS_R_EMPTY_ESS_CERT_ID_LIST:107:empty ess cert id list
+ESS_R_ESS_CERT_DIGEST_ERROR:103:ess cert digest error
+ESS_R_ESS_CERT_ID_NOT_FOUND:104:ess cert id not found
+ESS_R_ESS_CERT_ID_WRONG_ORDER:105:ess cert id wrong order
+ESS_R_ESS_DIGEST_ALG_UNKNOWN:106:ess digest alg unknown
 ESS_R_ESS_SIGNING_CERTIFICATE_ERROR:102:ess signing certificate error
 ESS_R_ESS_SIGNING_CERT_ADD_ERROR:100:ess signing cert add error
 ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR:101:ess signing cert v2 add error
+ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE:108:\
+	missing signing certificate attribute
 EVP_R_AES_KEY_SETUP_FAILED:143:aes key setup failed
 EVP_R_ARIA_KEY_SETUP_FAILED:176:aria key setup failed
 EVP_R_BAD_ALGORITHM_NAME:200:bad algorithm name
@@ -706,9 +712,9 @@ EVP_R_NO_KEY_SET:154:no key set
 EVP_R_NO_OPERATION_SET:149:no operation set
 EVP_R_NULL_MAC_PKEY_CTX:208:null mac pkey ctx
 EVP_R_ONLY_ONESHOT_SUPPORTED:177:only oneshot supported
+EVP_R_OPERATION_NOT_INITIALIZED:151:operation not initialized
 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\
 	operation not supported for this keytype
-EVP_R_OPERATION_NOT_INITIALIZED:151:operation not initialized
 EVP_R_OUTPUT_WOULD_OVERFLOW:202:output would overflow
 EVP_R_PARAMETER_TOO_LARGE:187:parameter too large
 EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers
diff --git a/crypto/ess/ess_asn1.c b/crypto/ess/ess_asn1.c
index 37bac4e707..08a0be8cc4 100644
--- a/crypto/ess/ess_asn1.c
+++ b/crypto/ess/ess_asn1.c
@@ -65,7 +65,7 @@ IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2)
  * Returns < 0 if attribute is not found, 1 if found, or 
  * -1 on attribute parsing failure.
  */
-int ossl_cms_signerinfo_get_signing_cert_v2(CMS_SignerInfo *si,
+int ossl_cms_signerinfo_get_signing_cert_v2(const CMS_SignerInfo *si,
                                             ESS_SIGNING_CERT_V2 **psc)
 {
     ASN1_STRING *str;
@@ -92,7 +92,7 @@ int ossl_cms_signerinfo_get_signing_cert_v2(CMS_SignerInfo *si,
  * Returns < 0 if attribute is not found, 1 if found, or 
  * -1 on attribute parsing failure.
  */
-int ossl_cms_signerinfo_get_signing_cert(CMS_SignerInfo *si,
+int ossl_cms_signerinfo_get_signing_cert(const CMS_SignerInfo *si,
                                          ESS_SIGNING_CERT **psc)
 {
     ASN1_STRING *str;
diff --git a/crypto/ess/ess_err.c b/crypto/ess/ess_err.c
index 450c07edac..2ece3443bd 100644
--- a/crypto/ess/ess_err.c
+++ b/crypto/ess/ess_err.c
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 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
@@ -15,12 +15,24 @@
 #ifndef OPENSSL_NO_ERR
 
 static const ERR_STRING_DATA ESS_str_reasons[] = {
+    {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_EMPTY_ESS_CERT_ID_LIST),
+    "empty ess cert id list"},
+    {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_DIGEST_ERROR),
+    "ess cert digest error"},
+    {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_ID_NOT_FOUND),
+    "ess cert id not found"},
+    {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_ID_WRONG_ORDER),
+    "ess cert id wrong order"},
+    {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_DIGEST_ALG_UNKNOWN),
+    "ess digest alg unknown"},
     {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERTIFICATE_ERROR),
     "ess signing certificate error"},
     {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERT_ADD_ERROR),
     "ess signing cert add error"},
     {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR),
     "ess signing cert v2 add error"},
+    {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE),
+    "missing signing certificate attribute"},
     {0, NULL}
 };
 
diff --git a/crypto/ess/ess_lib.c b/crypto/ess/ess_lib.c
index a5cf5d8aa7..ec1de943e4 100644
--- a/crypto/ess/ess_lib.c
+++ b/crypto/ess/ess_lib.c
@@ -192,7 +192,7 @@ static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg,
     return NULL;
 }
 
-ESS_SIGNING_CERT *ossl_ess_signing_cert_get(PKCS7_SIGNER_INFO *si)
+ESS_SIGNING_CERT *ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO *si)
 {
     ASN1_TYPE *attr;
     const unsigned char *p;
@@ -204,7 +204,7 @@ ESS_SIGNING_CERT *ossl_ess_signing_cert_get(PKCS7_SIGNER_INFO *si)
     return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
 }
 
-ESS_SIGNING_CERT_V2 *ossl_ess_signing_cert_v2_get(PKCS7_SIGNER_INFO *si)
+ESS_SIGNING_CERT_V2 *ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO *si)
 {
     ASN1_TYPE *attr;
     const unsigned char *p;
@@ -289,73 +289,92 @@ static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL *is, const X509 *cert)
     return ASN1_INTEGER_cmp(is->serial, X509_get0_serialNumber(cert));
 }
 
-/* Returns < 0 if certificate is not found, certificate index otherwise. */
-int ossl_ess_find_cert(const STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
+/*
+ * Find cert referenced by |cid| (if not NULL, else |cidv2|) in |certs|.
+ * If the cid{,v2} index is 0, the cert must be in the first in |certs| list.
+ * Return 0 on not found, -1 on error, else 1 + the position in |certs|.
+ */
+static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2,
+                int index, const STACK_OF(X509) *certs)
 {
+    const X509 *cert;
+    const EVP_MD *md;
+    unsigned char cert_digest[EVP_MAX_MD_SIZE];
+    unsigned int len, cid_hash_len;
+    const ESS_ISSUER_SERIAL *is;
     int i;
-    unsigned char cert_sha1[SHA_DIGEST_LENGTH];
 
-    if (cert_ids == NULL || cert == NULL)
-        return -1;
-
-    /* Recompute SHA1 hash of certificate if necessary (side effect). */
-    if (!x509v3_cache_extensions(cert))
+    if (cid == NULL && cid_v2 == NULL) {
+        ERR_raise(ERR_LIB_ESS, ERR_R_PASSED_INVALID_ARGUMENT);
         return -1;
+    }
 
-    /* TODO(3.0): fetch sha1 algorithm from providers */
-    if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL))
-        return -1;
+    /* Look for cert with cid in the certs. */
+    for (i = 0; i < sk_X509_num(certs); ++i) {
+        cert = sk_X509_value(certs, i);
 
-    /* Look for cert in the cert_ids vector. */
-    for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
-        const ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
+        if (cid != NULL)
+            md = EVP_sha1();
+        else
+            md = cid_v2->hash_alg == NULL ? EVP_sha256() :
+                EVP_get_digestbyobj(cid_v2->hash_alg->algorithm);
+        if (md == NULL) {
+            ERR_raise(ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN);
+            return -1;
+        }
 
-        if (cid->hash->length == SHA_DIGEST_LENGTH
-            && memcmp(cid->hash->data, cert_sha1, SHA_DIGEST_LENGTH) == 0) {
-            const ESS_ISSUER_SERIAL *is = cid->issuer_serial;
+        cid_hash_len = cid != NULL ? cid->hash->length : cid_v2->hash->length;
+        if (!X509_digest(cert, md, cert_digest, &len)
+                || cid_hash_len != len) {
+            ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_DIGEST_ERROR);
+            return -1;
+        }
 
-            if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0)
-                return i;
+        if (memcmp(cid != NULL ? cid->hash->data : cid_v2->hash->data,
+                   cert_digest, len) == 0) {
+            is = cid != NULL ? cid->issuer_serial : cid_v2->issuer_serial;
+            /* Well, it's not really required to match the serial numbers. */
+            if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0) {
+                if ((i == 0) == (index == 0))
+                    return i + 1;
+                ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_WRONG_ORDER);
+                return -1;
+            }
         }
     }
 
-    return -1;
+    ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_NOT_FOUND);
+    return 0;
 }
 
-/* Returns < 0 if certificate is not found, certificate index otherwise. */
-int ossl_ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2) *cert_ids,
-                          const X509 *cert)
+/*
+ * If ESSCertID and/or ESSCertIDv2 exist, which must be non-empty if given,
+ * check if their first ID entry matches the signer cert first in chain
+ * and each further ID entry matches any further cert in the chain.
+ */
+int ossl_ess_check_signing_certs(const ESS_SIGNING_CERT *ss,
+                                 const ESS_SIGNING_CERT_V2 *ssv2,
+                                 const STACK_OF(X509) *chain,
+                                 int require_signing_cert)
 {
+    int n_v1 = ss == NULL ? -1 : sk_ESS_CERT_ID_num(ss->cert_ids);
+    int n_v2 = ssv2 == NULL ? -1 : sk_ESS_CERT_ID_V2_num(ssv2->cert_ids);
     int i;
-    unsigned char cert_digest[EVP_MAX_MD_SIZE];
-    unsigned int len;
-
-    /* Look for cert in the cert_ids vector. */
-    for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) {
-        const ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i);
-        const EVP_MD *md;
-
-        if (cid == NULL)
-            return -1;
-        if (cid->hash_alg != NULL)
-            md = EVP_get_digestbyobj(cid->hash_alg->algorithm);
-        else
-            md = EVP_sha256();
 
-        /* TODO(3.0): fetch sha1 algorithm from providers */
-        if (!X509_digest(cert, md, cert_digest, &len))
-            return -1;
-
-        if (cid->hash->length != (int)len)
-            return -1;
-
-        if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) {
-            const ESS_ISSUER_SERIAL *is = cid->issuer_serial;
-
-            if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0)
-                return i;
-        }
+    if (require_signing_cert && ss == NULL && ssv2 == NULL) {
+        ERR_raise(ERR_LIB_CMS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE);
+        return 0;
     }
-
-    return -1;
+    if (n_v1 == 0 || n_v2 == 0) {
+        ERR_raise(ERR_LIB_ESS, ESS_R_EMPTY_ESS_CERT_ID_LIST);
+        return 0;
+    }
+    /* If both ss and ssv2 exist, as required evaluate them independently. */
+    for (i = 0; i < n_v1; i++)
+        if (find(sk_ESS_CERT_ID_value(ss->cert_ids, i), NULL, i, chain) <= 0)
+            return 0;
+    for (i = 0; i < n_v2; i++)
+        if (find(NULL, sk_ESS_CERT_ID_V2_value(ssv2->cert_ids, i), i, chain) <= 0)
+            return 0;
+    return 1;
 }
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index c9e4d719aa..c7a50ff57e 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -18,7 +18,7 @@
 
 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
                          void *value);
-static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
+static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid);
 
 int PKCS7_type_is_other(PKCS7 *p7)
 {
@@ -1209,17 +1209,17 @@ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
     return ri->issuer_and_serial;
 }
 
-ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
+ASN1_TYPE *PKCS7_get_signed_attribute(const PKCS7_SIGNER_INFO *si, int nid)
 {
     return get_attribute(si->auth_attr, nid);
 }
 
-ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
+ASN1_TYPE *PKCS7_get_attribute(const PKCS7_SIGNER_INFO *si, int nid)
 {
     return get_attribute(si->unauth_attr, nid);
 }
 
-static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
+static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid)
 {
     int idx;
     X509_ATTRIBUTE *xa;
diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c
index b45ca28b5d..4660647ffc 100644
--- a/crypto/ts/ts_rsp_verify.c
+++ b/crypto/ts/ts_rsp_verify.c
@@ -17,8 +17,8 @@
 
 static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
                           X509 *signer, STACK_OF(X509) **chain);
-static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
-                                  STACK_OF(X509) *chain);
+static int ts_check_signing_certs(const PKCS7_SIGNER_INFO *si,
+                                  const STACK_OF(X509) *chain);
 
 static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
                                     PKCS7 *token, TS_TST_INFO *tst_info);
@@ -202,59 +202,13 @@ end:
     return ret;
 }
 
-static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
-                                  STACK_OF(X509) *chain)
+static int ts_check_signing_certs(const PKCS7_SIGNER_INFO *si,
+                                  const STACK_OF(X509) *chain)
 {
-    ESS_SIGNING_CERT *ss = ossl_ess_signing_cert_get(si);
-    STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
-    ESS_SIGNING_CERT_V2 *ssv2 = ossl_ess_signing_cert_v2_get(si);
-    STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = NULL;
-    X509 *cert;
-    int i = 0;
-    int ret = 0;
-
-    if (ss != NULL) {
-        cert_ids = ss->cert_ids;
-        cert = sk_X509_value(chain, 0);
-        if (ossl_ess_find_cert(cert_ids, cert) != 0)
-            goto err;
-
-        /*
-         * Check the other certificates of the chain if there are more than one
-         * certificate ids in cert_ids.
-         */
-        if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
-            for (i = 1; i < sk_X509_num(chain); ++i) {
-                cert = sk_X509_value(chain, i);
-                if (ossl_ess_find_cert(cert_ids, cert) < 0)
-                    goto err;
-            }
-        }
-    } else if (ssv2 != NULL) {
-        cert_ids_v2 = ssv2->cert_ids;
-        cert = sk_X509_value(chain, 0);
-        if (ossl_ess_find_cert_v2(cert_ids_v2, cert) != 0)
-            goto err;
+    ESS_SIGNING_CERT *ss = ossl_ess_get_signing_cert(si);
+    ESS_SIGNING_CERT_V2 *ssv2 = ossl_ess_get_signing_cert_v2(si);
+    int ret = ossl_ess_check_signing_certs(ss, ssv2, chain, 1);
 
-        /*
-         * Check the other certificates of the chain if there are more than one
-         * certificate ids in cert_ids.
-         */
-        if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) {
-            for (i = 1; i < sk_X509_num(chain); ++i) {
-                cert = sk_X509_value(chain, i);
-                if (ossl_ess_find_cert_v2(cert_ids_v2, cert) < 0)
-                    goto err;
-            }
-        }
-    } else {
-        goto err;
-    }
-
-    ret = 1;
- err:
-    if (!ret)
-        ERR_raise(ERR_LIB_TS, TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
     ESS_SIGNING_CERT_free(ss);
     ESS_SIGNING_CERT_V2_free(ssv2);
     return ret;
diff --git a/doc/man1/openssl-cms.pod.in b/doc/man1/openssl-cms.pod.in
index 847ebaccd8..54e258a8f3 100644
--- a/doc/man1/openssl-cms.pod.in
+++ b/doc/man1/openssl-cms.pod.in
@@ -161,9 +161,12 @@ Resign a message: take an existing message and one or more new signers.
 
 =item B<-cades>
 
-Add an ESS signing-certificate or ESS signing-certificate-v2 signed-attribute to the SignerInfo, in order to make
-the signature comply with the requirements for a CAdES Basic Electronic Signature (CAdES-BES). See the NOTES
-section for more details.
+When used with B<-sign>,
+add an ESS signingCertificate or ESS signingCertificateV2 signed-attribute
+to the SignerInfo, in order to make the signature comply with the requirements
+for a CAdES Basic Electronic Signature (CAdES-BES).
+When used with B<-verify>, require and check signer certificate digest.
+See the NOTES section for more details.
 
 =item B<-data_create>
 
@@ -564,7 +567,8 @@ with caution. For a fuller description see L<CMS_decrypt(3)>).
 
 =head1 CADES BASIC ELECTRONIC SIGNATURE (CADES-BES)
 
-A CAdES Basic Electronic Signature (CAdES-BES), as defined in the European Standard ETSI EN 319 122-1 V1.1.1, contains:
+A CAdES Basic Electronic Signature (CAdES-BES),
+as defined in the European Standard ETSI EN 319 122-1 V1.1.1, contains:
 
 =over 4
 
@@ -582,19 +586,19 @@ Message-digest of the eContent OCTET STRING within encapContentInfo being signed
 
 =item *
 
-An ESS signing-certificate or ESS signing-certificate-v2 attribute, as defined 
-in Enhanced Security Services (ESS), RFC 2634 and RFC 5035.
-An ESS signing-certificate attribute only allows for the use of SHA-1 as a digest algorithm.
-An ESS signing-certificate-v2 attribute allows for the use of any digest algorithm.
+An ESS signingCertificate or ESS signingCertificateV2 attribute,
+as defined in Enhanced Security Services (ESS), RFC 2634 and RFC 5035.
+An ESS signingCertificate attribute only allows for SHA-1 as digest algorithm.
+An ESS signingCertificateV2 attribute allows for any digest algorithm.
 
 =item *
 
 The digital signature value computed on the user data and, when present, on the signed attributes.
 
 NOTE that the B<-cades> option applies to the B<-sign> or B<-verify> operations.
-With this option, the B<-verify> operation also checks that the signing-certificates
-attribute is present, and its value matches the verification trust chain built
-during the verification process.
+With this option, the B<-verify> operation also requires that the
+signingCertificate attribute is present and checks that the given identifiers
+match the verification trust chain built during the verification process.
 
 =back
 
diff --git a/doc/man1/openssl-ts.pod.in b/doc/man1/openssl-ts.pod.in
index 402a7a879a..c68f79c156 100644
--- a/doc/man1/openssl-ts.pod.in
+++ b/doc/man1/openssl-ts.pod.in
@@ -469,12 +469,13 @@ the TSA name field of the response. Default is no. (Optional)
 
 The SignedData objects created by the TSA always contain the
 certificate identifier of the signing certificate in a signed
-attribute (see RFC 2634, Enhanced Security Services). If this option
-is set to yes and either the B<certs> variable or the B<-chain> option
+attribute (see RFC 2634, Enhanced Security Services).
+If this variable is set to no, only this signing certificate identifier
+is included in the SigningCertificate signed attribute.
+If this variable is set to yes and the B<certs> variable or the B<-chain> option
 is specified then the certificate identifiers of the chain will also
-be included in the SigningCertificate signed attribute. If this
-variable is set to no, only the signing certificate identifier is
-included. Default is no. (Optional)
+be included, where the B<-chain> option overrides the B<certs> variable.
+Default is no.  (Optional)
 
 =item B<ess_cert_id_alg>
 
diff --git a/doc/man3/CMS_verify.pod b/doc/man3/CMS_verify.pod
index d56540290f..89f50a2010 100644
--- a/doc/man3/CMS_verify.pod
+++ b/doc/man3/CMS_verify.pod
@@ -72,8 +72,8 @@ If B<CMS_NO_ATTR_VERIFY> is set the signed attributes signature is not
 verified, unless CMS_CADES flag is also set.
 
 If B<CMS_CADES> is set, each signer certificate is checked against the 
-"ESS signing-certificate" extension added in the signed attributes of the 
-signature.
+ESS signingCertificate or ESS signingCertificateV2 extension
+that is required in the signed attributes of the signature.
 
 If B<CMS_NO_CONTENT_VERIFY> is set then the content digest is not checked.
 
diff --git a/include/crypto/cms.h b/include/crypto/cms.h
index f1cf6bd6bf..fe1aed0c09 100644
--- a/include/crypto/cms.h
+++ b/include/crypto/cms.h
@@ -18,9 +18,9 @@
 int ossl_cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc);
 int ossl_cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc);
 
-int ossl_cms_signerinfo_get_signing_cert_v2(CMS_SignerInfo *si,
+int ossl_cms_signerinfo_get_signing_cert_v2(const CMS_SignerInfo *si,
                                             ESS_SIGNING_CERT_V2 **psc);
-int ossl_cms_signerinfo_get_signing_cert(CMS_SignerInfo *si,
+int ossl_cms_signerinfo_get_signing_cert(const CMS_SignerInfo *si,
                                          ESS_SIGNING_CERT **psc);
 # endif /* OPENSSL_NO_CMS */
 
diff --git a/include/crypto/ess.h b/include/crypto/ess.h
index 5abd229869..1961e39067 100644
--- a/include/crypto/ess.h
+++ b/include/crypto/ess.h
@@ -13,14 +13,14 @@
 
 /* internal ESS related stuff */
 
-ESS_SIGNING_CERT *ossl_ess_signing_cert_get(PKCS7_SIGNER_INFO *si);
+ESS_SIGNING_CERT *ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO *si);
 int ossl_ess_signing_cert_add(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
 
 ESS_SIGNING_CERT *ossl_ess_signing_cert_new_init(X509 *signcert,
                                                  STACK_OF(X509) *certs,
                                                  int issuer_needed);
 
-ESS_SIGNING_CERT_V2 *ossl_ess_signing_cert_v2_get(PKCS7_SIGNER_INFO *si);
+ESS_SIGNING_CERT_V2 *ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO *si);
 int ossl_ess_signing_cert_v2_add(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT_V2 *sc);
 
 ESS_SIGNING_CERT_V2 *ossl_ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
@@ -28,10 +28,10 @@ ESS_SIGNING_CERT_V2 *ossl_ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
                                                        STACK_OF(X509) *certs,
                                                        int issuer_needed);
 
-/* Returns < 0 if certificate is not found, certificate index otherwise. */
-int ossl_ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2) *cert_ids,
-                          const X509 *cert);
-int ossl_ess_find_cert(const STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
+int ossl_ess_check_signing_certs(const ESS_SIGNING_CERT *ss,
+                                 const ESS_SIGNING_CERT_V2 *ssv2,
+                                 const STACK_OF(X509) *chain,
+                                 int require_signing_cert);
 
 /*-
  * IssuerSerial ::= SEQUENCE {
diff --git a/include/crypto/esserr.h b/include/crypto/esserr.h
index d253356a90..a87d4fabce 100644
--- a/include/crypto/esserr.h
+++ b/include/crypto/esserr.h
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2021 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/include/openssl/cms.h.in b/include/openssl/cms.h.in
index 5ffd3b4405..e2912b47cc 100644
--- a/include/openssl/cms.h.in
+++ b/include/openssl/cms.h.in
@@ -310,7 +310,8 @@ int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
 int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
                                 const char *attrname, int type,
                                 const void *bytes, int len);
-void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid,
+void *CMS_signed_get0_data_by_OBJ(const CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *oid,
                                   int lastpos, int type);
 
 int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h
index 418e8baff9..1c4f4c799d 100644
--- a/include/openssl/cmserr.h
+++ b/include/openssl/cmserr.h
@@ -49,7 +49,6 @@
 #  define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE      114
 #  define CMS_R_ERROR_SETTING_KEY                          115
 #  define CMS_R_ERROR_SETTING_RECIPIENTINFO                116
-#  define CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE            182
 #  define CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR          183
 #  define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH               117
 #  define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER           176
diff --git a/include/openssl/esserr.h b/include/openssl/esserr.h
index 2eb82c1eb7..0b9e89e4cb 100644
--- a/include/openssl/esserr.h
+++ b/include/openssl/esserr.h
@@ -21,8 +21,14 @@
 /*
  * ESS reason codes.
  */
+# define ESS_R_EMPTY_ESS_CERT_ID_LIST                     107
+# define ESS_R_ESS_CERT_DIGEST_ERROR                      103
+# define ESS_R_ESS_CERT_ID_NOT_FOUND                      104
+# define ESS_R_ESS_CERT_ID_WRONG_ORDER                    105
+# define ESS_R_ESS_DIGEST_ALG_UNKNOWN                     106
 # define ESS_R_ESS_SIGNING_CERTIFICATE_ERROR              102
 # define ESS_R_ESS_SIGNING_CERT_ADD_ERROR                 100
 # define ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR              101
+# define ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE      108
 
 #endif
diff --git a/include/openssl/pkcs7.h.in b/include/openssl/pkcs7.h.in
index df53acc2a1..87dda54115 100644
--- a/include/openssl/pkcs7.h.in
+++ b/include/openssl/pkcs7.h.in
@@ -304,8 +304,8 @@ int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type,
                                void *data);
 int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
                         void *value);
-ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
-ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_attribute(const PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(const PKCS7_SIGNER_INFO *si, int nid);
 int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
                                 STACK_OF(X509_ATTRIBUTE) *sk);
 int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
index 8e3275c2e5..1837a51bbe 100644
--- a/test/recipes/80-test_cms.t
+++ b/test/recipes/80-test_cms.t
@@ -451,10 +451,11 @@ my @smime_cms_cades_tests = (
 );
 
 my @smime_cms_cades_ko_tests = (
-    [ "signed content DER format, RSA key, but verified as CAdES-BES compatible",
+    [ "sign content DER format, RSA key, not CAdES-BES compatible",
       [ @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
         "-certfile", catfile($smdir, "smroot.pem"),
         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
+      "fail to verify token because requiring CAdES-BES compatibility",
       [ @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
       \&final_compare
@@ -798,16 +799,15 @@ subtest "CAdES; cms incompatible arguments tests\n" => sub {
 };
 
 subtest "CAdES ko tests\n" => sub {
-    plan tests => (scalar @smime_cms_cades_ko_tests);
+    plan tests => 2 * scalar @smime_cms_cades_ko_tests;
 
     foreach (@smime_cms_cades_ko_tests) {
       SKIP: {
         my $skip_reason = check_availability($$_[0]);
         skip $skip_reason, 1 if $skip_reason;
 
-        ok(run(app(["openssl", "cms", @{$$_[1]}]))
-            && !run(app(["openssl", "cms", @{$$_[2]}])),
-            $$_[0]);
+        ok(run(app(["openssl", "cms", @{$$_[1]}])), $$_[0]);
+        ok(!run(app(["openssl", "cms", @{$$_[3]}])), $$_[2]);
         }
     }
 };
diff --git a/test/recipes/80-test_tsa.t b/test/recipes/80-test_tsa.t
index 3cb8399c87..6fa005aebc 100644
--- a/test/recipes/80-test_tsa.t
+++ b/test/recipes/80-test_tsa.t
@@ -48,40 +48,42 @@ sub create_tsa_cert {
                 "-extfile", $openssl_conf, "-extensions", $EXT])));
 }
 
-sub create_time_stamp_response {
+sub create_resp {
+    my $config = shift;
+    my $chain = shift;
     my $queryfile = shift;
     my $outputfile = shift;
-    my $datafile = shift;
 
-    ok(run(app([@REPLY, "-section", "$datafile",
-                "-queryfile", "$queryfile", "-out", "$outputfile"])));
+    ok(run(app([@REPLY, "-section", $config, "-queryfile", $queryfile,
+                "-chain", $chain, # this overrides "certs" entry in config
+                "-out", $outputfile])));
 }
 
-sub verify_time_stamp_response {
+sub verify_ok {
+    my $datafile = shift;
     my $queryfile = shift;
     my $inputfile = shift;
-    my $datafile = shift;
+    my $untrustedfile = shift;
 
-    ok(run(app([@VERIFY, "-queryfile", "$queryfile",
-                "-in", "$inputfile", "-CAfile", "tsaca.pem",
-                "-untrusted", "tsa_cert1.pem"])));
-    ok(run(app([@VERIFY, "-data", "$datafile",
-                "-in", "$inputfile", "-CAfile", "tsaca.pem",
-                "-untrusted", "tsa_cert1.pem"])));
+    ok(run(app([@VERIFY, "-queryfile", $queryfile, "-in", $inputfile,
+                "-CAfile", "tsaca.pem", "-untrusted", $untrustedfile])));
+    ok(run(app([@VERIFY, "-data", $datafile, "-in", $inputfile,
+                "-CAfile", "tsaca.pem", "-untrusted", $untrustedfile])));
 }
 
-sub verify_time_stamp_response_fail {
+sub verify_fail {
     my $queryfile = shift;
     my $inputfile = shift;
+    my $untrustedfile = shift; # is needed for resp2, but not for resp1
+    my $cafile = shift;
 
-    ok(!run(app([@VERIFY, "-queryfile", "$queryfile",
-                 "-in", "$inputfile", "-CAfile", "tsaca.pem",
-                 "-untrusted", "tsa_cert1.pem"])));
+    ok(!run(app([@VERIFY, "-queryfile", $queryfile, "-in", $inputfile,
+                 "-untrusted", $untrustedfile, "-CAfile", $cafile])));
 }
 
 # main functions
 
-plan tests => 20;
+plan tests => 27;
 
 note "setting up TSA test directory";
 indir "tsa" => sub
@@ -123,14 +125,19 @@ indir "tsa" => sub
         'printing req1.req');
 
      subtest 'generating valid response for req1.req' => sub {
-         create_time_stamp_response("req1.tsq", "resp1.tsr", "tsa_config1")
+         create_resp("tsa_config1", "tsaca.pem", "req1.tsq", "resp1.tsr")
+     };
+
+     subtest 'generating response with wrong 2nd certid for req1.req' => sub {
+         create_resp("tsa_config1", "tsa_cert1.pem", "req1.tsq",
+                     "resp1_invalid.tsr")
      };
 
      ok(run(app([@REPLY, "-in", "resp1.tsr", "-text"])),
         'printing response');
 
      subtest 'verifying valid response' => sub {
-         verify_time_stamp_response("req1.tsq", "resp1.tsr", $testtsa)
+         verify_ok($testtsa, "req1.tsq", "resp1.tsr", "tsa_cert1.pem")
      };
 
      skip "failed", 11
@@ -156,7 +163,7 @@ indir "tsa" => sub
 
      skip "failed", 8
          unless subtest 'generating valid response for req2.req' => sub {
-             create_time_stamp_response("req2.tsq", "resp2.tsr", "tsa_config1")
+             create_resp("tsa_config1", "tsaca.pem", "req2.tsq", "resp2.tsr")
      };
 
      skip "failed", 7
@@ -180,16 +187,32 @@ indir "tsa" => sub
      ok(run(app([@REPLY, "-in", "resp2.tsr", "-text"])),
         'printing response');
 
-     subtest 'verifying valid response' => sub {
-         verify_time_stamp_response("req2.tsq", "resp2.tsr", $testtsa)
+     subtest 'verifying valid resp1, wrong untrusted is not used' => sub {
+         verify_ok($testtsa, "req1.tsq", "resp1.tsr", "tsa_cert2.pem")
+     };
+
+     subtest 'verifying invalid resp1 with wrong 2nd certid' => sub {
+         verify_fail($testtsa, "req1.tsq", "resp1_invalid.tsr", "tsa_cert2.pem")
      };
 
-     subtest 'verifying response against wrong request, it should fail' => sub {
-         verify_time_stamp_response_fail("req1.tsq", "resp2.tsr")
+     subtest 'verifying valid resp2, correct untrusted being used' => sub {
+         verify_ok($testtsa, "req2.tsq", "resp2.tsr", "tsa_cert1.pem")
      };
 
-     subtest 'verifying response against wrong request, it should fail' => sub {
-         verify_time_stamp_response_fail("req2.tsq", "resp1.tsr")
+     subtest 'verifying resp2 against wrong req1 should fail' => sub {
+         verify_fail("req1.tsq", "resp2.tsr", "tsa_cert1.pem", "tsaca.pem")
+     };
+
+     subtest 'verifying resp1 against wrong req2 should fail' => sub {
+         verify_fail("req2.tsq", "resp1.tsr", "tsa_cert1.pem", "tsaca.pem")
+     };
+
+     subtest 'verifying resp1 using wrong untrusted should fail' => sub {
+         verify_fail("req2.tsq", "resp2.tsr", "tsa_cert2.pem", "tsaca.pem")
+     };
+
+     subtest 'verifying resp1 using wrong root should fail' => sub {
+         verify_fail("req1.tsq", "resp1.tsr", "tsa_cert1.pem", "tsa_cert1.pem")
      };
 
      skip "failure", 2
@@ -200,8 +223,25 @@ indir "tsa" => sub
      ok(run(app([@QUERY, "-in", "req3.tsq", "-text"])),
         'printing req3.req');
 
-     subtest 'verifying response against wrong request, it should fail' => sub {
-         verify_time_stamp_response_fail("req3.tsq", "resp1.tsr")
+     subtest 'verifying resp1 against wrong req3 should fail' => sub {
+         verify_fail("req3.tsq", "resp1.tsr", "tsa_cert1.pem", "tsaca.pem")
      };
     }
+
+    # verifying response with two ESSCertIDs, referring to leaf cert
+    # "sectigo-signer.pem" and intermediate cert "sectigo-time-stamping-ca.pem"
+    # 1. validation chain contains these certs and root "user-trust-ca.pem"
+    ok(run(app([@VERIFY, "-no_check_time",
+                "-queryfile", data_file("all-zero.tsq"),
+                "-in", data_file("sectigo-all-zero.tsr"),
+                "-CAfile", data_file("user-trust-ca.pem")])),
+     "validation with two ESSCertIDs and 3-element chain");
+    # 2. validation chain contains these certs, a cross-cert, and different root
+    ok(run(app([@VERIFY, "-no_check_time",
+                "-queryfile", data_file("all-zero.tsq"),
+                "-in", data_file("sectigo-all-zero.tsr"),
+                "-untrusted", data_file("user-trust-ca-aaa.pem"),
+                "-CAfile", data_file("comodo-aaa.pem")])),
+     "validation with two ESSCertIDs and 4-element chain");
+
 }, create => 1, cleanup => 1
diff --git a/test/recipes/80-test_tsa_data/all-zero.tsq b/test/recipes/80-test_tsa_data/all-zero.tsq
new file mode 100644
index 0000000000..60d9574e61
Binary files /dev/null and b/test/recipes/80-test_tsa_data/all-zero.tsq differ
diff --git a/test/recipes/80-test_tsa_data/comodo-aaa.pem b/test/recipes/80-test_tsa_data/comodo-aaa.pem
new file mode 100644
index 0000000000..33c71ba9db
--- /dev/null
+++ b/test/recipes/80-test_tsa_data/comodo-aaa.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
diff --git a/test/recipes/80-test_tsa_data/sectigo-all-zero.tsr b/test/recipes/80-test_tsa_data/sectigo-all-zero.tsr
new file mode 100644
index 0000000000..a65f35fceb
Binary files /dev/null and b/test/recipes/80-test_tsa_data/sectigo-all-zero.tsr differ
diff --git a/test/recipes/80-test_tsa_data/sectigo-signer.pem b/test/recipes/80-test_tsa_data/sectigo-signer.pem
new file mode 100644
index 0000000000..6adf1338fa
--- /dev/null
+++ b/test/recipes/80-test_tsa_data/sectigo-signer.pem
@@ -0,0 +1,40 @@
+-----BEGIN CERTIFICATE-----
+MIIHBzCCBO+gAwIBAgIRAIx3oACP9NGwxj2fOkiDjWswDQYJKoZIhvcNAQEMBQAw
+fTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSUwIwYDVQQD
+ExxTZWN0aWdvIFJTQSBUaW1lIFN0YW1waW5nIENBMB4XDTIwMTAyMzAwMDAwMFoX
+DTMyMDEyMjIzNTk1OVowgYQxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVy
+IE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28g
+TGltaXRlZDEsMCoGA1UEAwwjU2VjdGlnbyBSU0EgVGltZSBTdGFtcGluZyBTaWdu
+ZXIgIzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCRh0ssi8HxHqCe
+0wfGAcpSsL55eV0JZgYtLzV9u8D7J9pCalkbJUzq70DWmn4yyGqBfbRcPlYQgTU6
+IjaM+/ggKYesdNAbYrw/ZIcCX+/FgO8GHNxeTpOHuJreTAdOhcxwxQ177MPZ45fp
+yxnbVkVs7ksgbMk+bP3wm/Eo+JGZqvxawZqCIDq37+fWuCVJwjkbh4E5y8O3Os2f
+UAQfGpmkgAJNHQWoVdNtUoCD5m5IpV/BiVhgiu/xrM2HYxiOdMuEh0FpY4G89h+q
+fNfBQc6tq3aLIIDULZUHjcf1CxcemuXWmWlRx06mnSlv53mTDTJjU67MximKIMFg
+xvICLMT5yCLf+SeCoYNRwrzJghohhLKXvNSvRByWgiKVKoVUrvH9Pkl0dPyOrj+l
+cvTDWgGqUKWLdpUbZuvv2t+ULtka60wnfUwF9/gjXcRXyCYFevyBI19UCTgqYtWq
+yt/tz1OrH/ZEnNWZWcVWZFv3jlIPZvyYP0QGE2Ru6eEVYFClsezPuOjJC77FhPfd
+Cp3avClsPVbtv3hntlvIXhQcua+ELXei9zmVN29OfxzGPATWMcV+7z3oUX5xrSR0
+Gyzc+Xyq78J2SWhi1Yv1A9++fY4PNnVGW5N2xIPugr4srjcS8bxWw+StQ8O3ZpZe
+lDL6oPariVD6zqDzCIEa0USnzPe4MQIDAQABo4IBeDCCAXQwHwYDVR0jBBgwFoAU
+GqH4YRkgD8NBd0UojtE1XwYSBFUwHQYDVR0OBBYEFGl1N3u7nTVCTr9X05rbnwHR
+rt7QMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoG
+CCsGAQUFBwMIMEAGA1UdIAQ5MDcwNQYMKwYBBAGyMQECAQMIMCUwIwYIKwYBBQUH
+AgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMEQGA1UdHwQ9MDswOaA3oDWGM2h0
+dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1JTQVRpbWVTdGFtcGluZ0NBLmNy
+bDB0BggrBgEFBQcBAQRoMGYwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQuc2VjdGln
+by5jb20vU2VjdGlnb1JTQVRpbWVTdGFtcGluZ0NBLmNydDAjBggrBgEFBQcwAYYX
+aHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggIBAEoDeJBC
+M+x7GoMJNjOYVbudQAYwa0Vq8ZQOGVD/WyVeO+E5xFu66ZWQNze93/tk7OWCt5XM
+V1VwS070qIfdIoWmV7u4ISfUoCoxlIoHIZ6Kvaca9QIVy0RQmYzsProDd6aCApDC
+LpOpviE0dWO54C0PzwE3y42i+rhamq6hep4TkxlVjwmQLt/qiBcW62nW4SW9RQiX
+gNdUIChPynuzs6XSALBgNGXE48XDpeS6hap6adt1pD55aJo2i0OuNtRhcjwOhWIN
+oF5w22QvAcfBoccklKOyPG6yXqLQ+qjRuCUcFubA1X9oGsRlKTUqLYi86q501oLn
+wIi44U948FzKwEBcwp/VMhws2jysNvcGUpqjQDAXsCkWmcmqt4hJ9+gLJTO1P22v
+n18KVt8SscPuzpF36CAT6Vwkx+pEC0rmE4QcTesNtbiGoDCni6GftCzMwBYjyZHl
+QgNLgM7kTeYqAT7AXoWgJKEXQNXb2+eYEKTx6hkbgFT6R4nomIGpdcAO39BolHmh
+oJ6OtrdCZsvZ2WsvTdjePjIeIOTsnE1CjZ3HM5mCN0TUJikmQI54L7nu+i/x8Y/+
+ULh43RSW3hwOcLAqhWqxbGjpKuQQK24h/dN8nTfkKgbWw/HXaONPB3mBCBP+smRe
+6bE85tB4I7IJLOImYr87qZdRzMdEMoGyr8/f
+-----END CERTIFICATE-----
diff --git a/test/recipes/80-test_tsa_data/sectigo-time-stamping-ca.pem b/test/recipes/80-test_tsa_data/sectigo-time-stamping-ca.pem
new file mode 100644
index 0000000000..f65021c95c
--- /dev/null
+++ b/test/recipes/80-test_tsa_data/sectigo-time-stamping-ca.pem
@@ -0,0 +1,39 @@
+-----BEGIN CERTIFICATE-----
+MIIG7DCCBNSgAwIBAgIQMA9vrN1mmHR8qUY2p3gtuTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTkw
+NTAyMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjB9MQswCQYDVQQGEwJHQjEbMBkGA1UE
+CBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQK
+Ew9TZWN0aWdvIExpbWl0ZWQxJTAjBgNVBAMTHFNlY3RpZ28gUlNBIFRpbWUgU3Rh
+bXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDIGwGv2Sx+
+iJl9AZg/IJC9nIAhVJO5z6A+U++zWsB21hoEpc5Hg7XrxMxJNMvzRWW5+adkFiYJ
++9UyUnkuyWPCE5u2hj8BBZJmbyGr1XEQeYf0RirNxFrJ29ddSU1yVg/cyeNTmDoq
+HvzOWEnTv/M5u7mkI0Ks0BXDf56iXNc48RaycNOjxN+zxXKsLgp3/A2UUrf8H5Vz
+JD0BKLwPDU+zkQGObp0ndVXRFzs0IXuXAZSvf4DP0REKV4TJf1bgvUacgr6Unb+0
+ILBgfrhN9Q0/29DqhYyKVnHRLZRMyIw80xSinL0m/9NTIMdgaZtYClT0Bef9Maz5
+yIUXx7gpGaQpL0bj3duRX58/Nj4OMGcrRrc1r5a+2kxgzKi7nw0U1BjEMJh0giHP
+Yla1IXMSHv2qyghYh3ekFesZVf/QOVQtJu5FGjpvzdeE8NfwKMVPZIMC1Pvi3vG8
+Aij0bdonigbSlofe6GsO8Ft96XZpkyAcSpcsdxkrk5WYnJee647BeFbGRCXfBhKa
+Bi2fA179g6JTZ8qx+o2hZMmIklnLqEbAyfKm/31X2xJ2+opBJNQb/HKlFKLUrUMc
+pEmLQTkUAx4p+hulIq6lw02C0I3aa7fb9xhAV3PwcaP7Sn1FNsH3jYL6uckNU4B9
++rY5WDLvbxhQiddPnTO9GrWdod6VQXqngwIDAQABo4IBWjCCAVYwHwYDVR0jBBgw
+FoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFBqh+GEZIA/DQXdFKI7R
+NV8GEgRVMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMBMGA1Ud
+JQQMMAoGCCsGAQUFBwMIMBEGA1UdIAQKMAgwBgYEVR0gADBQBgNVHR8ESTBHMEWg
+Q6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVNFUlRydXN0UlNBQ2VydGlm
+aWNhdGlvbkF1dGhvcml0eS5jcmwwdgYIKwYBBQUHAQEEajBoMD8GCCsGAQUFBzAC
+hjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vVVNFUlRydXN0UlNBQWRkVHJ1c3RD
+QS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJ
+KoZIhvcNAQEMBQADggIBAG1UgaUzXRbhtVOBkXXfA3oyCy0lhBGysNsqfSoF9bw7
+J/RaoLlJWZApbGHLtVDb4n35nwDvQMOt0+LkVvlYQc/xQuUQff+wdB+PxlwJ+TNe
+6qAcJlhc87QRD9XVw+K81Vh4v0h24URnbY+wQxAPjeT5OGK/EwHFhaNMxcyyUzCV
+pNb0llYIuM1cfwGWvnJSajtCN3wWeDmTk5SbsdyybUFtZ83Jb5A9f0VywRsj1sJV
+hGbks8VmBvbz1kteraMrQoohkv6ob1olcGKBc2NeoLvY3NdK0z2vgwY4Eh0khy3k
+/ALWPncEvAQ2ted3y5wujSMYuaPCRx3wXdahc1cFaJqnyTdlHb7qvNhCg0MFpYum
+Cf/RoZSmTqo9CfUFbLfSZFrYKiLCS53xOV5M3kg9mzSWmglfjv33sVKRzj+J9hyh
+tal1H3G/W0NdZT1QgW6r8NDT/LKzH7aZlib0PHmLXGTMze4nmuWgwAxyh8FuTVrT
+HurwROYybxzrF06Uw3hlIDsPQaof6aFBnf6xuKBlKjTg3qj5PObBMLvAoGMs/FwW
+AKjQxH/qEZ0eBsambTJdtDgJK0kHqv3sMNrxpy/Pt/360KOE2See+wFmd7lWEOEg
+bsausfm2usg1XTN2jvF8IAwqd661ogKGuinutFoAsYyr4/kKyVRd1LlqdJ69SK6Y
+-----END CERTIFICATE-----
diff --git a/test/recipes/80-test_tsa_data/user-trust-ca-aaa.pem b/test/recipes/80-test_tsa_data/user-trust-ca-aaa.pem
new file mode 100644
index 0000000000..cc2d08bdd2
--- /dev/null
+++ b/test/recipes/80-test_tsa_data/user-trust-ca-aaa.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7
+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD
+VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE
+AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4
+MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5
+MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO
+ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI
+s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG
+vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ
+Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb
+IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0
+tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E
+xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV
+icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5
+D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ
+WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ
+5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG
+KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg
+EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID
+ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG
+BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t
+L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr
+BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA
+A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+
+rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+
+/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA
+CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F
+zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA
+vGp4z7h/jnZymQyd/teRCBaho1+V
+-----END CERTIFICATE-----
diff --git a/test/recipes/80-test_tsa_data/user-trust-ca.pem b/test/recipes/80-test_tsa_data/user-trust-ca.pem
new file mode 100644
index 0000000000..2795cf3130
--- /dev/null
+++ b/test/recipes/80-test_tsa_data/user-trust-ca.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----


More information about the openssl-commits mailing list