TS ESS: Invert the search logic of ts_check_signing_certs() to correctly cover cert...
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Wed, 10 Mar 2021 16:21:37 +0000 (17:21 +0100)
committerDr. David von Oheimb <dev@ddvo.net>
Thu, 18 Mar 2021 06:03:52 +0000 (07:03 +0100)
Fixes #14190

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

12 files changed:
CHANGES.md
crypto/ess/ess_lib.c
crypto/ts/ts_rsp_verify.c
include/crypto/ess.h
test/recipes/80-test_tsa.t
test/recipes/80-test_tsa_data/all-zero.tsq [new file with mode: 0644]
test/recipes/80-test_tsa_data/comodo-aaa.pem [new file with mode: 0644]
test/recipes/80-test_tsa_data/sectigo-all-zero.tsr [new file with mode: 0644]
test/recipes/80-test_tsa_data/sectigo-signer.pem [new file with mode: 0644]
test/recipes/80-test_tsa_data/sectigo-time-stamping-ca.pem [new file with mode: 0644]
test/recipes/80-test_tsa_data/user-trust-ca-aaa.pem [new file with mode: 0644]
test/recipes/80-test_tsa_data/user-trust-ca.pem [new file with mode: 0644]

index e51e61a96b1493003f0bdae90d04ae376e0ad430..ad6b7edd29ef3bfcd5aae22fd30bef1e47e7efb7 100644 (file)
@@ -58,6 +58,14 @@ OpenSSL 3.0
 
    *Richard Levitte*
 
+ * Improved adherence to Enhanced Security Services (ESS, RFC 2634 and RFC 5035)
+   for the TSP implementation.
+   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,
index a5cf5d8aa795a67d11f51c9b51e60544cfcca65d..7dda6adc98b9202cbfb84b9b41065abc08bdf65e 100644 (file)
@@ -359,3 +359,42 @@ int ossl_ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2) *cert_ids,
 
     return -1;
 }
+
+/* Returns < 0 if certificate is not found, certificate index otherwise. */
+int ossl_ess_find_cid(const STACK_OF(X509) *certs,
+                      ESS_CERT_ID *cid, ESS_CERT_ID_V2 *cid_v2)
+{
+    unsigned char cert_digest[EVP_MAX_MD_SIZE];
+    unsigned int len, cid_hash_len;
+    int i;
+    const ESS_ISSUER_SERIAL *is;
+
+    if (certs == NULL || (cid == NULL && cid_v2 == NULL))
+        return -1;
+
+    /* Look for cert with cid in the certs. */
+    for (i = 0; i < sk_X509_num(certs); ++i) {
+        const X509 *cert = sk_X509_value(certs, i);
+        const EVP_MD *md;
+
+        /* TODO(3.0): fetch sha algorithm from providers */
+        if (cid != NULL)
+            md = EVP_sha1();
+        else
+            md = cid_v2->hash_alg == NULL ? EVP_sha256() :
+                EVP_get_digestbyobj(cid_v2->hash_alg->algorithm);
+        cid_hash_len = cid != NULL ? cid->hash->length : cid_v2->hash->length;
+        if (!X509_digest(cert, md, cert_digest, &len)
+                || cid_hash_len != len)
+            return -1;
+
+        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;
+            if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0)
+                return i;
+        }
+    }
+
+    return -1;
+}
index b45ca28b5d6c2c99e8300ed4c59fd730b3abe74f..6884360869a69084e96477644c8cebc7c7b848a1 100644 (file)
@@ -206,52 +206,32 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
                                   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 i, j;
     int ret = 0;
 
+    /*
+     * Check if first ESSCertIDs matches signer cert
+     * and each further ESSCertIDs matches any cert in the chain.
+     */
     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;
-            }
+        for (i = 0; i < sk_ESS_CERT_ID_num(ss->cert_ids); i++) {
+            j = ossl_ess_find_cid(chain, sk_ESS_CERT_ID_value(ss->cert_ids, i),
+                                  NULL);
+            if (j < 0 || (i == 0 && j != 0))
+                goto err;
         }
+        ret = 1;
     } 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;
-
-        /*
-         * 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;
-            }
+        for (i = 0; i < sk_ESS_CERT_ID_V2_num(ssv2->cert_ids); i++) {
+            j = ossl_ess_find_cid(chain, NULL,
+                                  sk_ESS_CERT_ID_V2_value(ssv2->cert_ids, i));
+            if (j < 0 || (i == 0 && j != 0))
+                goto err;
         }
-    } else {
-        goto err;
+        ret = 1;
     }
 
-    ret = 1;
  err:
     if (!ret)
         ERR_raise(ERR_LIB_TS, TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
index 5abd229869c2d41e136aa44f6a14c2012085108b..099e3de9a5af1bc65bd57e13252d6e183b6d31c9 100644 (file)
@@ -32,6 +32,8 @@ ESS_SIGNING_CERT_V2 *ossl_ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
 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_find_cid(const STACK_OF(X509) *certs,
+                      ESS_CERT_ID *cid, ESS_CERT_ID_V2 *cid_v2);
 
 /*-
  * IssuerSerial ::= SEQUENCE {
index 3cb8399c870fb60f2c1aaa6c00730c4fd1790d9d..6fa005aebc45679b8d5ac8094605e3a57e48f7b8 100644 (file)
@@ -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 (file)
index 0000000..60d9574
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 (file)
index 0000000..33c71ba
--- /dev/null
@@ -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 (file)
index 0000000..a65f35f
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 (file)
index 0000000..6adf133
--- /dev/null
@@ -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 (file)
index 0000000..f65021c
--- /dev/null
@@ -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 (file)
index 0000000..cc2d08b
--- /dev/null
@@ -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 (file)
index 0000000..2795cf3
--- /dev/null
@@ -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-----