TS ESS: Let TS_RESP_verify_signature() make use of untrusted certs also from token response

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14504)
This commit is contained in:
Dr. David von Oheimb 2021-03-10 17:21:37 +01:00 committed by Dr. David von Oheimb
parent 234261f3a1
commit c89fd035d5
3 changed files with 42 additions and 34 deletions

View File

@ -89,6 +89,7 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
{ {
STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
PKCS7_SIGNER_INFO *si; PKCS7_SIGNER_INFO *si;
STACK_OF(X509) *untrusted = NULL;
STACK_OF(X509) *signers = NULL; STACK_OF(X509) *signers = NULL;
X509 *signer; X509 *signer;
STACK_OF(X509) *chain = NULL; STACK_OF(X509) *chain = NULL;
@ -125,7 +126,13 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
goto err; goto err;
signer = sk_X509_value(signers, 0); signer = sk_X509_value(signers, 0);
if (!ts_verify_cert(store, certs, signer, &chain)) untrusted = sk_X509_new_reserve(NULL, sk_X509_num(certs)
+ sk_X509_num(token->d.sign->cert));
if (untrusted == NULL
|| !X509_add_certs(untrusted, certs, 0)
|| !X509_add_certs(untrusted, token->d.sign->cert, 0))
goto err;
if (!ts_verify_cert(store, untrusted, signer, &chain))
goto err; goto err;
if (!ts_check_signing_certs(si, chain)) if (!ts_check_signing_certs(si, chain))
goto err; goto err;
@ -149,6 +156,7 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
err: err:
BIO_free_all(p7bio); BIO_free_all(p7bio);
sk_X509_free(untrusted);
sk_X509_pop_free(chain, X509_free); sk_X509_pop_free(chain, X509_free);
sk_X509_free(signers); sk_X509_free(signers);

View File

@ -326,12 +326,12 @@ This flag can be used together with the B<-in> option and indicates
that the input is a DER encoded timestamp token (ContentInfo) instead that the input is a DER encoded timestamp token (ContentInfo) instead
of a timestamp response (TimeStampResp). (Optional) of a timestamp response (TimeStampResp). (Optional)
=item B<-untrusted> I<cert_file.pem> =item B<-untrusted> I<file>
Set of additional untrusted certificates in PEM format which may be A set of additional untrusted certificates which may be
needed when building the certificate chain for the TSA's signing needed when building the certificate chain for the TSA's signing certificate.
certificate. This file must contain the TSA signing certificate and These do not need to contain the TSA signing certificate and intermediate CA
all intermediate CA certificates unless the response includes them. certificates as far as the response already includes them.
(Optional) (Optional)
=item B<-CAfile> I<file>, B<-CApath> I<dir>, B<-CAstore> I<uri> =item B<-CAfile> I<file>, B<-CApath> I<dir>, B<-CAstore> I<uri>

View File

@ -1,5 +1,5 @@
#! /usr/bin/env perl #! /usr/bin/env perl
# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
# #
# Licensed under the Apache License 2.0 (the "License"). You may not use # 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 # this file except in compliance with the License. You can obtain a copy
@ -13,7 +13,7 @@ use warnings;
use POSIX; use POSIX;
use File::Spec::Functions qw/splitdir curdir catfile/; use File::Spec::Functions qw/splitdir curdir catfile/;
use File::Compare; use File::Compare;
use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file/; use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file data_file/;
use OpenSSL::Test::Utils; use OpenSSL::Test::Utils;
setup("test_tsa"); setup("test_tsa");
@ -26,7 +26,9 @@ plan skip_all => "TS is not supported by this OpenSSL build"
my $openssl_conf; my $openssl_conf;
my $testtsa; my $testtsa;
my $CAtsa; my $CAtsa;
my @RUN; my @QUERY = ("openssl", "ts", "-query");
my @REPLY;
my @VERIFY = ("openssl", "ts", "-verify");
sub create_tsa_cert { sub create_tsa_cert {
my $INDEX = shift; my $INDEX = shift;
@ -51,7 +53,7 @@ sub create_time_stamp_response {
my $outputfile = shift; my $outputfile = shift;
my $datafile = shift; my $datafile = shift;
ok(run(app([@RUN, "-reply", "-section", "$datafile", ok(run(app([@REPLY, "-section", "$datafile",
"-queryfile", "$queryfile", "-out", "$outputfile"]))); "-queryfile", "$queryfile", "-out", "$outputfile"])));
} }
@ -60,10 +62,10 @@ sub verify_time_stamp_response {
my $inputfile = shift; my $inputfile = shift;
my $datafile = shift; my $datafile = shift;
ok(run(app([@RUN, "-verify", "-queryfile", "$queryfile", ok(run(app([@VERIFY, "-queryfile", "$queryfile",
"-in", "$inputfile", "-CAfile", "tsaca.pem", "-in", "$inputfile", "-CAfile", "tsaca.pem",
"-untrusted", "tsa_cert1.pem"]))); "-untrusted", "tsa_cert1.pem"])));
ok(run(app([@RUN, "-verify", "-data", "$datafile", ok(run(app([@VERIFY, "-data", "$datafile",
"-in", "$inputfile", "-CAfile", "tsaca.pem", "-in", "$inputfile", "-CAfile", "tsaca.pem",
"-untrusted", "tsa_cert1.pem"]))); "-untrusted", "tsa_cert1.pem"])));
} }
@ -72,7 +74,7 @@ sub verify_time_stamp_response_fail {
my $queryfile = shift; my $queryfile = shift;
my $inputfile = shift; my $inputfile = shift;
ok(!run(app([@RUN, "-verify", "-queryfile", "$queryfile", ok(!run(app([@VERIFY, "-queryfile", "$queryfile",
"-in", "$inputfile", "-CAfile", "tsaca.pem", "-in", "$inputfile", "-CAfile", "tsaca.pem",
"-untrusted", "tsa_cert1.pem"]))); "-untrusted", "tsa_cert1.pem"])));
} }
@ -87,7 +89,7 @@ indir "tsa" => sub
$openssl_conf = srctop_file("test", "CAtsa.cnf"); $openssl_conf = srctop_file("test", "CAtsa.cnf");
$testtsa = srctop_file("test", "recipes", "80-test_tsa.t"); $testtsa = srctop_file("test", "recipes", "80-test_tsa.t");
$CAtsa = srctop_file("test", "CAtsa.cnf"); $CAtsa = srctop_file("test", "CAtsa.cnf");
@RUN = ("openssl", "ts", "-config", $openssl_conf); @REPLY = ("openssl", "ts", "-config", $openssl_conf, "-reply");
# ../apps/CA.pl needs these # ../apps/CA.pl needs these
$ENV{OPENSSL_CONFIG} = "-config $openssl_conf"; $ENV{OPENSSL_CONFIG} = "-config $openssl_conf";
@ -112,19 +114,19 @@ indir "tsa" => sub
}; };
skip "failed", 16 skip "failed", 16
unless ok(run(app([@RUN, "-query", "-data", $testtsa, unless ok(run(app([@QUERY, "-data", $testtsa,
"-tspolicy", "tsa_policy1", "-cert", "-tspolicy", "tsa_policy1", "-cert",
"-out", "req1.tsq"])), "-out", "req1.tsq"])),
'creating req1.req time stamp request for file testtsa'); 'creating req1.req time stamp request for file testtsa');
ok(run(app([@RUN, "-query", "-in", "req1.tsq", "-text"])), ok(run(app([@QUERY, "-in", "req1.tsq", "-text"])),
'printing req1.req'); 'printing req1.req');
subtest 'generating valid response for req1.req' => sub { subtest 'generating valid response for req1.req' => sub {
create_time_stamp_response("req1.tsq", "resp1.tsr", "tsa_config1") create_time_stamp_response("req1.tsq", "resp1.tsr", "tsa_config1")
}; };
ok(run(app([@RUN, "-reply", "-in", "resp1.tsr", "-text"])), ok(run(app([@REPLY, "-in", "resp1.tsr", "-text"])),
'printing response'); 'printing response');
subtest 'verifying valid response' => sub { subtest 'verifying valid response' => sub {
@ -133,25 +135,23 @@ indir "tsa" => sub
skip "failed", 11 skip "failed", 11
unless subtest 'verifying valid token' => sub { unless subtest 'verifying valid token' => sub {
ok(run(app([@RUN, "-reply", "-in", "resp1.tsr", ok(run(app([@REPLY, "-in", "resp1.tsr",
"-out", "resp1.tsr.token", "-token_out"]))); "-out", "resp1.tsr.token", "-token_out"])));
ok(run(app([@RUN, "-verify", "-queryfile", "req1.tsq", ok(run(app([@VERIFY, "-queryfile", "req1.tsq",
"-in", "resp1.tsr.token", "-token_in", "-in", "resp1.tsr.token", "-token_in",
"-CAfile", "tsaca.pem", "-CAfile", "tsaca.pem"])));
"-untrusted", "tsa_cert1.pem"]))); ok(run(app([@VERIFY, "-data", $testtsa,
ok(run(app([@RUN, "-verify", "-data", $testtsa,
"-in", "resp1.tsr.token", "-token_in", "-in", "resp1.tsr.token", "-token_in",
"-CAfile", "tsaca.pem", "-CAfile", "tsaca.pem"])));
"-untrusted", "tsa_cert1.pem"])));
}; };
skip "failed", 10 skip "failed", 10
unless ok(run(app([@RUN, "-query", "-data", $testtsa, unless ok(run(app([@QUERY, "-data", $testtsa,
"-tspolicy", "tsa_policy2", "-no_nonce", "-tspolicy", "tsa_policy2", "-no_nonce",
"-out", "req2.tsq"])), "-out", "req2.tsq"])),
'creating req2.req time stamp request for file testtsa'); 'creating req2.req time stamp request for file testtsa');
ok(run(app([@RUN, "-query", "-in", "req2.tsq", "-text"])), ok(run(app([@QUERY, "-in", "req2.tsq", "-text"])),
'printing req2.req'); 'printing req2.req');
skip "failed", 8 skip "failed", 8
@ -164,20 +164,20 @@ indir "tsa" => sub
my $RESPONSE2="resp2.tsr.copy.tsr"; my $RESPONSE2="resp2.tsr.copy.tsr";
my $TOKEN_DER="resp2.tsr.token.der"; my $TOKEN_DER="resp2.tsr.token.der";
ok(run(app([@RUN, "-reply", "-in", "resp2.tsr", ok(run(app([@REPLY, "-in", "resp2.tsr",
"-out", "$TOKEN_DER", "-token_out"]))); "-out", "$TOKEN_DER", "-token_out"])));
ok(run(app([@RUN, "-reply", "-in", "$TOKEN_DER", ok(run(app([@REPLY, "-in", "$TOKEN_DER",
"-token_in", "-out", "$RESPONSE2"]))); "-token_in", "-out", "$RESPONSE2"])));
is(compare($RESPONSE2, "resp2.tsr"), 0); is(compare($RESPONSE2, "resp2.tsr"), 0);
ok(run(app([@RUN, "-reply", "-in", "resp2.tsr", ok(run(app([@REPLY, "-in", "resp2.tsr",
"-text", "-token_out"]))); "-text", "-token_out"])));
ok(run(app([@RUN, "-reply", "-in", "$TOKEN_DER", ok(run(app([@REPLY, "-in", "$TOKEN_DER",
"-token_in", "-text", "-token_out"]))); "-token_in", "-text", "-token_out"])));
ok(run(app([@RUN, "-reply", "-queryfile", "req2.tsq", ok(run(app([@REPLY, "-queryfile", "req2.tsq",
"-text", "-token_out"]))); "-text", "-token_out"])));
}; };
ok(run(app([@RUN, "-reply", "-in", "resp2.tsr", "-text"])), ok(run(app([@REPLY, "-in", "resp2.tsr", "-text"])),
'printing response'); 'printing response');
subtest 'verifying valid response' => sub { subtest 'verifying valid response' => sub {
@ -193,11 +193,11 @@ indir "tsa" => sub
}; };
skip "failure", 2 skip "failure", 2
unless ok(run(app([@RUN, "-query", "-data", $CAtsa, unless ok(run(app([@QUERY, "-data", $CAtsa,
"-no_nonce", "-out", "req3.tsq"])), "-no_nonce", "-out", "req3.tsq"])),
"creating req3.req time stamp request for file CAtsa.cnf"); "creating req3.req time stamp request for file CAtsa.cnf");
ok(run(app([@RUN, "-query", "-in", "req3.tsq", "-text"])), ok(run(app([@QUERY, "-in", "req3.tsq", "-text"])),
'printing req3.req'); 'printing req3.req');
subtest 'verifying response against wrong request, it should fail' => sub { subtest 'verifying response against wrong request, it should fail' => sub {