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