commit df27e4a27da2c2761c667fcbe775b77fadf25cfe Author: Jacob Champion Date: Fri Jul 30 10:55:10 2021 -0400 squash! test/ssl: rework the sslfiles Makefile target Feedback: - don't use .SECONDARYEXPANSION; unroll recipes for each CA - don't fail tests if openssl isn't functional on the PATH Also add a dependency on cas.config for the recipes that use it. diff --git a/src/test/ssl/Makefile b/src/test/ssl/Makefile index 6e67013f61..458520dc6d 100644 --- a/src/test/ssl/Makefile +++ b/src/test/ssl/Makefile @@ -132,24 +132,29 @@ $(STANDARD_KEYS): # Standard certificates # +CA_CERTS := ssl/server_ca.crt ssl/client_ca.crt SERVER_CERTS := $(SERVERS:%=ssl/%.crt) CLIENT_CERTS := $(CLIENTS:%=ssl/%.crt) -ssl/server_ca.crt ssl/client_ca.crt: ca := root_ca -$(SERVER_CERTS): ca := server_ca -$(CLIENT_CERTS): ca := client_ca +# See the "CA State" section below. +root_ca_state_files := ssl/root_ca-certindex ssl/root_ca-certindex.attr ssl/root_ca.srl +server_ca_state_files := ssl/server_ca-certindex ssl/server_ca-certindex.attr ssl/server_ca.srl +client_ca_state_files := ssl/client_ca-certindex ssl/client_ca-certindex.attr ssl/client_ca.srl -ca_state_files = ssl/$(ca)-certindex ssl/$(ca)-certindex.attr ssl/$(ca).srl - -# This is the workhorse recipe. `openssl ca` can't be safely run from parallel -# processes, so we must mark the entire Makefile .NOTPARALLEL. Enable -# .SECONDEXPANSION so that the correct dependencies are determined by the value -# of $(ca). +# These are the workhorse recipes. `openssl ca` can't be safely run from +# parallel processes, so we must mark the entire Makefile .NOTPARALLEL. .NOTPARALLEL: -.SECONDEXPANSION: $(STANDARD_CERTS) -ssl/%.crt: ssl/%.csr %.config ssl/$$(ca).crt | ssl/new_certs_dir $$(ca_state_files) - openssl ca -batch -config cas.config -name $(ca) -notext -in $< -out $@ +$(CA_CERTS): ssl/%.crt: ssl/%.csr %.config cas.config ssl/root_ca.crt | ssl/new_certs_dir $(root_ca_state_files) + openssl ca -batch -config cas.config -name root_ca -notext -in $< -out $@ + +$(SERVER_CERTS): ssl/%.crt: ssl/%.csr %.config cas.config ssl/server_ca.crt | ssl/new_certs_dir $(server_ca_state_files) + openssl ca -batch -config cas.config -name server_ca -notext -in $< -out $@ + +$(CLIENT_CERTS): ssl/%.crt: ssl/%.csr %.config cas.config ssl/client_ca.crt | ssl/new_certs_dir $(client_ca_state_files) + openssl ca -batch -config cas.config -name client_ca -notext -in $< -out $@ +# The CSRs don't need to persist after a build. +.INTERMEDIATE: $(CERTIFICATES:%=ssl/%.csr) ssl/%.csr: ssl/%.key %.config openssl req -new -key $< -out $@ -config $*.config @@ -157,12 +162,13 @@ ssl/%.csr: ssl/%.key %.config # CA State # # All of these are intended to be order-only dependencies; additionally, the -# pattern recipes are intended to be intermediates, so do not name them -# explicitly somewhere else in the Makefile. The goal is for Make to create the -# state files once for each CA, allow them to accumulate whatever state is -# needed, and then automatically remove them at the end of the run. +# pattern recipes are marked as explicit intermediates. The goal is for Make to +# create the state files once for each CA, allow them to accumulate whatever +# state is needed, and then automatically remove them at the end of the run. # +.INTERMEDIATE: $(root_ca_state_files) $(server_ca_state_files) $(client_ca_state_files) + # OpenSSL requires a directory to put all generated certificates in. We don't # use this for anything, but we need a location. ssl/new_certs_dir: @@ -183,19 +189,16 @@ ssl/%.srl: # CRLs # -ssl/root.crl: revoked := -ssl/root.crl: ca := root_ca - -ssl/client.crl: revoked := ssl/client-revoked.crt -ssl/client.crl: ca := client_ca +ssl/root.crl: ssl/root_ca.crt | $(root_ca_state_files) + openssl ca -config cas.config -name root_ca -gencrl -out $@ -ssl/server.crl: revoked := ssl/server-revoked.crt -ssl/server.crl: ca := server_ca +ssl/server.crl: ssl/server-revoked.crt ssl/server_ca.crt | $(server_ca_state_files) + openssl ca -config cas.config -name server_ca -revoke $< + openssl ca -config cas.config -name server_ca -gencrl -out $@ -.SECONDEXPANSION: $(CRLS) -ssl/%.crl: ssl/$$(ca).crt $$(revoked) | $$(ca_state_files) - $(foreach cert,$(revoked),openssl ca -config cas.config -name $(ca) -revoke $(cert) &&) true - openssl ca -config cas.config -name $(ca) -gencrl -out $@ +ssl/client.crl: ssl/client-revoked.crt ssl/client_ca.crt | $(client_ca_state_files) + openssl ca -config cas.config -name client_ca -revoke $< + openssl ca -config cas.config -name client_ca -gencrl -out $@ # # CRL hash directories diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl index 0ff3564742..4d8fdd7620 100644 --- a/src/test/ssl/t/001_ssltests.pl +++ b/src/test/ssl/t/001_ssltests.pl @@ -487,8 +487,18 @@ TODO: # pg_stat_ssl my $serialno = `openssl x509 -serial -noout -in ssl/client.crt`; -$serialno =~ s/^serial=//; -$serialno = hex($serialno); # OpenSSL prints serial numbers in hexadecimal +if ($? == 0) +{ + $serialno =~ s/^serial=//; + $serialno = hex($serialno); # OpenSSL prints serial numbers in hexadecimal +} +else +{ + # OpenSSL isn't functioning on the user's PATH. This probably isn't worth + # skipping the test over, so just fall back to a generic integer match. + warn 'couldn\'t run `openssl x509` to get client cert serialno'; + $serialno = '\d+'; +} command_like( [