Home | History | Annotate | Line # | Download | only in recipes
      1 #! /usr/bin/env perl
      2 # Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
      3 #
      4 # Licensed under the Apache License 2.0 (the "License").  You may not use
      5 # this file except in compliance with the License.  You can obtain a copy
      6 # in the file LICENSE in the source distribution or at
      7 # https://www.openssl.org/source/license.html
      8 
      9 
     10 use strict;
     11 use warnings;
     12 
     13 use POSIX;
     14 use File::Spec::Functions qw/splitdir curdir catfile/;
     15 use File::Compare;
     16 use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file data_file/;
     17 use OpenSSL::Test::Utils;
     18 
     19 setup("test_tsa");
     20 
     21 plan skip_all => "TS is not supported by this OpenSSL build"
     22     if disabled("ts");
     23 
     24 # All these are modified inside indir further down. They need to exist
     25 # here, however, to be available in all subroutines.
     26 my $openssl_conf;
     27 my $testtsa;
     28 my $tsacakey;
     29 my $CAtsa;
     30 my @QUERY = ("openssl", "ts", "-query");
     31 my @REPLY;
     32 my @VERIFY = ("openssl", "ts", "-verify");
     33 
     34 sub create_tsa_cert {
     35     my $INDEX = shift;
     36     my $EXT = shift;
     37     my $r = 1;
     38     $ENV{TSDNSECT} = "ts_cert_dn";
     39 
     40     ok(run(app(["openssl", "req", "-config", $openssl_conf, "-new",
     41                 "-out", "tsa_req${INDEX}.pem",
     42                 "-key", srctop_file("test", "certs", "alt${INDEX}-key.pem"),
     43                 "-keyout", "tsa_key${INDEX}.pem"])));
     44     note "using extension $EXT";
     45     ok(run(app(["openssl", "x509", "-req",
     46                 "-in", "tsa_req${INDEX}.pem",
     47                 "-out", "tsa_cert${INDEX}.pem",
     48                 "-CA", "tsaca.pem", "-CAkey", $tsacakey,
     49                 "-CAcreateserial",
     50                 "-extfile", $openssl_conf, "-extensions", $EXT])));
     51 }
     52 
     53 sub create_resp {
     54     my $config = shift;
     55     my $chain = shift;
     56     my $queryfile = shift;
     57     my $outputfile = shift;
     58 
     59     ok(run(app([@REPLY, "-section", $config, "-queryfile", $queryfile,
     60                 "-chain", $chain, # this overrides "certs" entry in config
     61                 "-out", $outputfile])));
     62 }
     63 
     64 sub verify_ok {
     65     my $datafile = shift;
     66     my $queryfile = shift;
     67     my $inputfile = shift;
     68     my $untrustedfile = shift;
     69 
     70     ok(run(app([@VERIFY, "-queryfile", $queryfile, "-in", $inputfile,
     71                 "-CAfile", "tsaca.pem", "-untrusted", $untrustedfile])));
     72     ok(run(app([@VERIFY, "-data", $datafile, "-in", $inputfile,
     73                 "-CAfile", "tsaca.pem", "-untrusted", $untrustedfile])));
     74 }
     75 
     76 sub verify_fail {
     77     my $queryfile = shift;
     78     my $inputfile = shift;
     79     my $untrustedfile = shift; # is needed for resp2, but not for resp1
     80     my $cafile = shift;
     81 
     82     ok(!run(app([@VERIFY, "-queryfile", $queryfile, "-in", $inputfile,
     83                  "-untrusted", $untrustedfile, "-CAfile", $cafile])));
     84 }
     85 
     86 # main functions
     87 
     88 plan tests => 27;
     89 
     90 note "setting up TSA test directory";
     91 indir "tsa" => sub
     92 {
     93     $openssl_conf = srctop_file("test", "CAtsa.cnf");
     94     $testtsa = srctop_file("test", "recipes", "80-test_tsa.t");
     95     $tsacakey = srctop_file("test", "certs", "ca-key.pem");
     96     $CAtsa = srctop_file("test", "CAtsa.cnf");
     97     @REPLY = ("openssl", "ts", "-config", $openssl_conf, "-reply");
     98 
     99     # ../apps/CA.pl needs these
    100     $ENV{OPENSSL_CONFIG} = "-config $openssl_conf";
    101     $ENV{OPENSSL} = cmdstr(app(["openssl"]), display => 1);
    102 
    103  SKIP: {
    104      $ENV{TSDNSECT} = "ts_ca_dn";
    105      skip "failed", 19
    106          unless ok(run(app(["openssl", "req", "-config", $openssl_conf,
    107                             "-new", "-x509", "-noenc",
    108                             "-out", "tsaca.pem", "-key", $tsacakey])),
    109                    'creating a new CA for the TSA tests');
    110 
    111      skip "failed", 18
    112          unless subtest 'creating tsa_cert1.pem TSA server cert' => sub {
    113              create_tsa_cert("1", "tsa_cert")
    114      };
    115 
    116      skip "failed", 17
    117          unless subtest 'creating tsa_cert2.pem non-TSA server cert' => sub {
    118              create_tsa_cert("2", "non_tsa_cert")
    119      };
    120 
    121      skip "failed", 16
    122          unless ok(run(app([@QUERY, "-data", $testtsa,
    123                             "-tspolicy", "tsa_policy1", "-cert",
    124                             "-out", "req1.tsq"])),
    125                    'creating req1.req time stamp request for file testtsa');
    126 
    127      ok(run(app([@QUERY, "-in", "req1.tsq", "-text"])),
    128         'printing req1.req');
    129 
    130      subtest 'generating valid response for req1.req' => sub {
    131          create_resp("tsa_config1", "tsaca.pem", "req1.tsq", "resp1.tsr")
    132      };
    133 
    134      subtest 'generating response with wrong 2nd certid for req1.req' => sub {
    135          create_resp("tsa_config1", "tsa_cert1.pem", "req1.tsq",
    136                      "resp1_invalid.tsr")
    137      };
    138 
    139      ok(run(app([@REPLY, "-in", "resp1.tsr", "-text"])),
    140         'printing response');
    141 
    142      subtest 'verifying valid response' => sub {
    143          verify_ok($testtsa, "req1.tsq", "resp1.tsr", "tsa_cert1.pem")
    144      };
    145 
    146      skip "failed", 11
    147          unless subtest 'verifying valid token' => sub {
    148              ok(run(app([@REPLY, "-in", "resp1.tsr",
    149                          "-out", "resp1.tsr.token", "-token_out"])));
    150              ok(run(app([@VERIFY, "-queryfile", "req1.tsq",
    151                          "-in", "resp1.tsr.token", "-token_in",
    152                          "-CAfile", "tsaca.pem"])));
    153              ok(run(app([@VERIFY, "-data", $testtsa,
    154                          "-in", "resp1.tsr.token", "-token_in",
    155                          "-CAfile", "tsaca.pem"])));
    156      };
    157 
    158      skip "failed", 10
    159          unless ok(run(app([@QUERY, "-data", $testtsa,
    160                             "-tspolicy", "tsa_policy2", "-no_nonce",
    161                             "-out", "req2.tsq"])),
    162                    'creating req2.req time stamp request for file testtsa');
    163 
    164      ok(run(app([@QUERY, "-in", "req2.tsq", "-text"])),
    165         'printing req2.req');
    166 
    167      skip "failed", 8
    168          unless subtest 'generating valid response for req2.req' => sub {
    169              create_resp("tsa_config1", "tsaca.pem", "req2.tsq", "resp2.tsr")
    170      };
    171 
    172      skip "failed", 7
    173          unless subtest 'checking -token_in and -token_out options with -reply' => sub {
    174              my $RESPONSE2="resp2.tsr.copy.tsr";
    175              my $TOKEN_DER="resp2.tsr.token.der";
    176 
    177              ok(run(app([@REPLY, "-in", "resp2.tsr",
    178                          "-out", "$TOKEN_DER", "-token_out"])));
    179              ok(run(app([@REPLY, "-in", "$TOKEN_DER",
    180                          "-token_in", "-out", "$RESPONSE2"])));
    181              is(compare($RESPONSE2, "resp2.tsr"), 0);
    182              ok(run(app([@REPLY, "-in", "resp2.tsr",
    183                          "-text", "-token_out"])));
    184              ok(run(app([@REPLY, "-in", "$TOKEN_DER",
    185                          "-token_in", "-text", "-token_out"])));
    186              ok(run(app([@REPLY, "-queryfile", "req2.tsq",
    187                          "-text", "-token_out"])));
    188      };
    189 
    190      ok(run(app([@REPLY, "-in", "resp2.tsr", "-text"])),
    191         'printing response');
    192 
    193      subtest 'verifying valid resp1, wrong untrusted is not used' => sub {
    194          verify_ok($testtsa, "req1.tsq", "resp1.tsr", "tsa_cert2.pem")
    195      };
    196 
    197      subtest 'verifying invalid resp1 with wrong 2nd certid' => sub {
    198          verify_fail($testtsa, "req1.tsq", "resp1_invalid.tsr", "tsa_cert2.pem")
    199      };
    200 
    201      subtest 'verifying valid resp2, correct untrusted being used' => sub {
    202          verify_ok($testtsa, "req2.tsq", "resp2.tsr", "tsa_cert1.pem")
    203      };
    204 
    205      subtest 'verifying resp2 against wrong req1 should fail' => sub {
    206          verify_fail("req1.tsq", "resp2.tsr", "tsa_cert1.pem", "tsaca.pem")
    207      };
    208 
    209      subtest 'verifying resp1 against wrong req2 should fail' => sub {
    210          verify_fail("req2.tsq", "resp1.tsr", "tsa_cert1.pem", "tsaca.pem")
    211      };
    212 
    213      subtest 'verifying resp1 using wrong untrusted should fail' => sub {
    214          verify_fail("req2.tsq", "resp2.tsr", "tsa_cert2.pem", "tsaca.pem")
    215      };
    216 
    217      subtest 'verifying resp1 using wrong root should fail' => sub {
    218          verify_fail("req1.tsq", "resp1.tsr", "tsa_cert1.pem", "tsa_cert1.pem")
    219      };
    220 
    221      skip "failure", 2
    222          unless ok(run(app([@QUERY, "-data", $CAtsa,
    223                             "-no_nonce", "-out", "req3.tsq"])),
    224                    "creating req3.req time stamp request for file CAtsa.cnf");
    225 
    226      ok(run(app([@QUERY, "-in", "req3.tsq", "-text"])),
    227         'printing req3.req');
    228 
    229      subtest 'verifying resp1 against wrong req3 should fail' => sub {
    230          verify_fail("req3.tsq", "resp1.tsr", "tsa_cert1.pem", "tsaca.pem")
    231      };
    232     }
    233 
    234     # verifying response with two ESSCertIDs, referring to leaf cert
    235     # "sectigo-signer.pem" and intermediate cert "sectigo-time-stamping-ca.pem"
    236     # 1. validation chain contains these certs and root "user-trust-ca.pem"
    237     ok(run(app([@VERIFY, "-no_check_time",
    238                 "-queryfile", data_file("all-zero.tsq"),
    239                 "-in", data_file("sectigo-all-zero.tsr"),
    240                 "-CAfile", data_file("user-trust-ca.pem")])),
    241      "validation with two ESSCertIDs and 3-element chain");
    242     # 2. validation chain contains these certs, a cross-cert, and different root
    243     ok(run(app([@VERIFY, "-no_check_time",
    244                 "-queryfile", data_file("all-zero.tsq"),
    245                 "-in", data_file("sectigo-all-zero.tsr"),
    246                 "-untrusted", data_file("user-trust-ca-aaa.pem"),
    247                 "-CAfile", data_file("comodo-aaa.pem")])),
    248      "validation with two ESSCertIDs and 4-element chain");
    249 
    250 }, create => 1, cleanup => 1
    251