Commit f9796787f5 for openssl.org

commit f9796787f5189a23242f95d081c871d8bca479b2
Author: skaiea13-ai <246881935+skaiea13-ai@users.noreply.github.com>
Date:   Sun Aug 30 14:12:36 2026 +0900

    apps/ocsp.c: fail on invalid response times

    Propagate OCSP_check_validity() failures through print_ocsp_summary(),
    so the command returns a nonzero exit status for stale responses.

    Add a request-aware regression test using the existing signed fixtures.

    Resolves: https://github.com/openssl/openssl/issues/32367
    References: 639bb581ce5b "apps/ocsp: Return non zero exit code with invalid certID"
    References: https://github.com/openssl/openssl/issues/7151
    Co-Authored-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    Assisted-by: OpenAI Codex:GPT-5
    Assisted-by: OpenAI Codex:GPT-6
    Reviewed-by: Frederik Wedel-Heinen <fwh.openssl@gmail.com>
    Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    Merge-date: Mon Oct 19 13:41:13 2026
    Merged-from: https://github.com/openssl/openssl/pull/32600

diff --git a/apps/ocsp.c b/apps/ocsp.c
index e302c1cf6b..c4c82efbc1 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -1059,6 +1059,7 @@ static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
         if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) {
             BIO_puts(out, "WARNING: Status times invalid.\n");
             ERR_print_errors(out);
+            ret = 0;
         }
         BIO_printf(out, "%s\n"
                         "\tThis Update: ",
diff --git a/test/recipes/80-test_ocsp.t b/test/recipes/80-test_ocsp.t
index cec3d7d64a..fc7f6971d8 100644
--- a/test/recipes/80-test_ocsp.t
+++ b/test/recipes/80-test_ocsp.t
@@ -38,23 +38,40 @@ sub test_ocsp {
     my $expected_exit = shift;
     my $nochecks = shift;
     my $opt_untrusted = shift // "-verify_other";
+    my $certfile = shift;
     my $outputfile = basename($inputfile, '.ors') . '.dat';
+    my %appopts = defined($certfile)
+        ? (stdout => "$outputfile.out", stderr => "$outputfile.err") : ();

     run(app(["openssl", "base64", "-d",
              "-in", catfile($ocspdir,$inputfile),
              "-out", $outputfile]));
     my @certopt = ($opt_untrusted, catfile($ocspdir, $untrusted));
+    my @requestopt = defined($certfile)
+        ? ("-issuer", catfile($ocspdir, $CAfile),
+           "-cert", catfile($ocspdir, $certfile), "-no_nonce")
+        : ();
     with({ exit_checker => sub { return shift == $expected_exit; } },
          sub { ok(run(app(["openssl", "ocsp", "-respin", $outputfile,
+                           @requestopt,
                            "-partial_chain", @check_time,
                            "-CAfile", catfile($ocspdir, $CAfile),
                            @certopt,
                            "-no-CApath", "-no-CAstore",
-                           $nochecks ? "-no_cert_checks" : ()])),
+                           $nochecks ? "-no_cert_checks" : ()], %appopts)),
                   $title); });
+
+    return unless defined($certfile);
+    my $output = '';
+    foreach my $suffix (qw(out err)) {
+        open my $fh, '<', "$outputfile.$suffix"
+            or die "Cannot open $outputfile.$suffix: $!";
+        $output .= join('', <$fh>);
+    }
+    return $output;
 }

-plan tests => 15;
+plan tests => 16;

 subtest "=== VALID OCSP RESPONSES ===" => sub {
     plan tests => 7;
@@ -75,6 +92,20 @@ subtest "=== VALID OCSP RESPONSES ===" => sub {
               "D3.ors", "D3_Issuer_Root.pem", "", 0, 0);
 };

+subtest "=== INVALID OCSP RESPONSE TIMES ===" => sub {
+    plan tests => 3;
+
+    my $output = test_ocsp("NON-DELEGATED; expired response",
+                          "ND1.ors", "ND1_Issuer_ICA.pem", "", 1, 0, undef,
+                          "ND1_Cert_EE.pem");
+    like($output, qr/Response verify OK/, "response signature verified");
+    SKIP: {
+        skip "Error strings disabled", 1
+            if disabled("err") || disabled("autoerrinit");
+        like($output, qr/status expired/, "response status expired");
+    }
+};
+
 subtest "=== INVALID SIGNATURE on the OCSP RESPONSE ===" => sub {
     plan tests => 6;