xref: /freebsd/crypto/openssl/test/recipes/82-test_ocsp_cert_chain.t (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery#! /usr/bin/env perl
2*e7be843bSPierre Pronchery# Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery#
4*e7be843bSPierre Pronchery# Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery# this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery# in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery# https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery
9*e7be843bSPierre Proncheryuse strict;
10*e7be843bSPierre Proncheryuse warnings;
11*e7be843bSPierre Pronchery
12*e7be843bSPierre Proncheryuse IPC::Open3;
13*e7be843bSPierre Proncheryuse OpenSSL::Test qw/:DEFAULT srctop_file bldtop_file/;
14*e7be843bSPierre Proncheryuse OpenSSL::Test::Utils;
15*e7be843bSPierre Proncheryuse Symbol 'gensym';
16*e7be843bSPierre Pronchery
17*e7be843bSPierre Proncherymy $test_name = "test_ocsp_cert_chain";
18*e7be843bSPierre Proncherysetup($test_name);
19*e7be843bSPierre Pronchery
20*e7be843bSPierre Proncheryplan skip_all => "$test_name requires OCSP support"
21*e7be843bSPierre Pronchery    if disabled("ocsp");
22*e7be843bSPierre Proncheryplan skip_all => "$test_name requires EC cryptography"
23*e7be843bSPierre Pronchery    if disabled("ec");
24*e7be843bSPierre Proncheryplan skip_all => "$test_name requires sock enabled"
25*e7be843bSPierre Pronchery    if disabled("sock");
26*e7be843bSPierre Proncheryplan skip_all => "$test_name requires TLS enabled"
27*e7be843bSPierre Pronchery    if alldisabled(available_protocols("tls"));
28*e7be843bSPierre Proncheryplan skip_all => "$test_name is not available Windows or VMS"
29*e7be843bSPierre Pronchery    if $^O =~ /^(VMS|MSWin32|msys)$/;
30*e7be843bSPierre Pronchery
31*e7be843bSPierre Proncheryplan tests => 3;
32*e7be843bSPierre Pronchery
33*e7be843bSPierre Proncherymy $shlib_wrap   = bldtop_file("util", "shlib_wrap.sh");
34*e7be843bSPierre Proncherymy $apps_openssl = bldtop_file("apps", "openssl");
35*e7be843bSPierre Pronchery
36*e7be843bSPierre Proncherymy $index_txt             = srctop_file("test", "ocsp-tests", "index.txt");
37*e7be843bSPierre Proncherymy $ocsp_pem              = srctop_file("test", "ocsp-tests", "ocsp.pem");
38*e7be843bSPierre Proncherymy $intermediate_cert_pem = srctop_file("test", "ocsp-tests", "intermediate-cert.pem");
39*e7be843bSPierre Pronchery
40*e7be843bSPierre Proncherymy $server_pem            = srctop_file("test", "ocsp-tests", "server.pem");
41*e7be843bSPierre Pronchery
42*e7be843bSPierre Proncherysub run_test {
43*e7be843bSPierre Pronchery
44*e7be843bSPierre Pronchery    # this test starts two servers that listen on respective ports.
45*e7be843bSPierre Pronchery    # that can be problematic since the ports may not be available
46*e7be843bSPierre Pronchery    # (e.g. when multiple instances of the test are run on the same
47*e7be843bSPierre Pronchery    # machine).
48*e7be843bSPierre Pronchery
49*e7be843bSPierre Pronchery    # to avoid this, we specify port 0 when staring each server, which
50*e7be843bSPierre Pronchery    # causes the OS to provide a random unused port.
51*e7be843bSPierre Pronchery
52*e7be843bSPierre Pronchery    # using a random port with s_server is straightforward.  doing so
53*e7be843bSPierre Pronchery    # with the ocsp responder required some investigation because the
54*e7be843bSPierre Pronchery    # url for the ocsp responder is usually included in the server's
55*e7be843bSPierre Pronchery    # cert (normally, in the authority-information-access extension,
56*e7be843bSPierre Pronchery    # and it would be complicated to change that when the test
57*e7be843bSPierre Pronchery    # executes).  however, s_server has an option "-status_url" that
58*e7be843bSPierre Pronchery    # can be used to specify a fallback url when no url is specified
59*e7be843bSPierre Pronchery    # in the cert.  that is what we do here.
60*e7be843bSPierre Pronchery
61*e7be843bSPierre Pronchery    # openssl ocsp -port 0 -index index.txt -rsigner ocsp.pem -CA intermediate-cert.pem
62*e7be843bSPierre Pronchery    my @ocsp_cmd = ("ocsp", "-port", "0", "-index", $index_txt, "-rsigner", $ocsp_pem, "-CA", $intermediate_cert_pem);
63*e7be843bSPierre Pronchery    my $ocsp_pid = open3(my $ocsp_i, my $ocsp_o, my $ocsp_e = gensym, $shlib_wrap, $apps_openssl, @ocsp_cmd);
64*e7be843bSPierre Pronchery
65*e7be843bSPierre Pronchery    ## ipv4
66*e7be843bSPierre Pronchery    # ACCEPT 0.0.0.0:19254 PID=620007
67*e7be843bSPierre Pronchery    ## ipv6
68*e7be843bSPierre Pronchery    # ACCEPT [::]:19254 PID=620007
69*e7be843bSPierre Pronchery    my $port = "0";
70*e7be843bSPierre Pronchery    while (<$ocsp_o>) {
71*e7be843bSPierre Pronchery        print($_);
72*e7be843bSPierre Pronchery        chomp;
73*e7be843bSPierre Pronchery        if (/^ACCEPT 0.0.0.0:(\d+)/) {
74*e7be843bSPierre Pronchery            $port = $1;
75*e7be843bSPierre Pronchery            last;
76*e7be843bSPierre Pronchery        } elsif (/^ACCEPT \[::\]:(\d+)/) {
77*e7be843bSPierre Pronchery            $port = $1;
78*e7be843bSPierre Pronchery            last;
79*e7be843bSPierre Pronchery        } else {
80*e7be843bSPierre Pronchery            last;
81*e7be843bSPierre Pronchery        }
82*e7be843bSPierre Pronchery    }
83*e7be843bSPierre Pronchery    ok($port ne "0", "ocsp server port check");
84*e7be843bSPierre Pronchery    my $ocsp_port = $port;
85*e7be843bSPierre Pronchery
86*e7be843bSPierre Pronchery    print("ocsp server ready, listening on port $ocsp_port\n");
87*e7be843bSPierre Pronchery
88*e7be843bSPierre Pronchery    # openssl s_server -accept 0 -naccept 1 \
89*e7be843bSPierre Pronchery    #                  -cert server.pem -cert_chain intermediate-cert.pem \
90*e7be843bSPierre Pronchery    #                  -status_verbose -status_url http://localhost:19254/ocsp
91*e7be843bSPierre Pronchery    my @s_server_cmd = ("s_server", "-accept", "0", "-naccept", "1",
92*e7be843bSPierre Pronchery                        "-cert", $server_pem, "-cert_chain", $intermediate_cert_pem,
93*e7be843bSPierre Pronchery                        "-status_verbose", "-status_url", "http://localhost:${ocsp_port}/ocsp");
94*e7be843bSPierre Pronchery    my $s_server_pid = open3(my $s_server_i, my $s_server_o, my $s_server_e = gensym, $shlib_wrap, $apps_openssl, @s_server_cmd);
95*e7be843bSPierre Pronchery
96*e7be843bSPierre Pronchery    # ACCEPT 0.0.0.0:45921
97*e7be843bSPierre Pronchery    # ACCEPT [::]:45921
98*e7be843bSPierre Pronchery    $port = "0";
99*e7be843bSPierre Pronchery    while (<$s_server_o>) {
100*e7be843bSPierre Pronchery        print($_);
101*e7be843bSPierre Pronchery        chomp;
102*e7be843bSPierre Pronchery        if (/^ACCEPT 0.0.0.0:(\d+)/) {
103*e7be843bSPierre Pronchery            $port = $1;
104*e7be843bSPierre Pronchery            last;
105*e7be843bSPierre Pronchery        } elsif (/^ACCEPT \[::\]:(\d+)/) {
106*e7be843bSPierre Pronchery            $port = $1;
107*e7be843bSPierre Pronchery            last;
108*e7be843bSPierre Pronchery        } elsif (/^Using default/) {
109*e7be843bSPierre Pronchery            ;
110*e7be843bSPierre Pronchery        } else {
111*e7be843bSPierre Pronchery            last;
112*e7be843bSPierre Pronchery        }
113*e7be843bSPierre Pronchery    }
114*e7be843bSPierre Pronchery    ok($port ne "0", "s_server port check");
115*e7be843bSPierre Pronchery    my $server_port = $port;
116*e7be843bSPierre Pronchery
117*e7be843bSPierre Pronchery    print("s_server ready, listening on port $server_port\n");
118*e7be843bSPierre Pronchery
119*e7be843bSPierre Pronchery    # openssl s_client -connect localhost:45921 -status -verify_return_error
120*e7be843bSPierre Pronchery    my @s_client_cmd = ("s_client", "-connect", "localhost:$server_port", "-status", "-verify_return_error");
121*e7be843bSPierre Pronchery    my $s_client_pid = open3(my $s_client_i, my $s_client_o, my $s_client_e = gensym, $shlib_wrap, $apps_openssl, @s_client_cmd);
122*e7be843bSPierre Pronchery
123*e7be843bSPierre Pronchery    waitpid($s_client_pid, 0);
124*e7be843bSPierre Pronchery    kill 'HUP', $s_server_pid, $ocsp_pid;
125*e7be843bSPierre Pronchery
126*e7be843bSPierre Pronchery    ### the output from s_server that we want to check is written to its stderr
127*e7be843bSPierre Pronchery    ###    cert_status: ocsp response sent:
128*e7be843bSPierre Pronchery
129*e7be843bSPierre Pronchery    my $resp = 0;
130*e7be843bSPierre Pronchery    while (<$s_server_e>) {
131*e7be843bSPierre Pronchery        print($_);
132*e7be843bSPierre Pronchery        chomp;
133*e7be843bSPierre Pronchery        if (/^cert_status: ocsp response sent:/) {
134*e7be843bSPierre Pronchery            $resp = 1;
135*e7be843bSPierre Pronchery            last;
136*e7be843bSPierre Pronchery        }
137*e7be843bSPierre Pronchery    }
138*e7be843bSPierre Pronchery    ok($resp == 1, "check s_server sent ocsp response");
139*e7be843bSPierre Pronchery}
140*e7be843bSPierre Pronchery
141*e7be843bSPierre Proncheryrun_test();
142