Created
December 31, 2019 08:23
-
-
Save dirkx/e4dc43ebcea0b3f372f5d6a3dce302e5 to your computer and use it in GitHub Desktop.
updated example - more in line with other tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Note -- this assumes bash - not the bourne shell. | |
# | |
import ../nixpkgs-test/nixos/tests/make-test-python.nix ({ pkgs, ... }: | |
let | |
tsWebRoot = "/data/http/ts"; | |
in | |
{ | |
name = "redwax"; | |
meta = with pkgs.stdenv.lib.maintainers; { | |
maintainers = [ dirkx ]; | |
}; | |
machine = | |
{ config, ... }: | |
{ networking.firewall.enable = true; | |
networking.firewall.rejectPackets = true; | |
networking.firewall.allowPing = true; | |
networking.firewall.allowedTCPPorts = [ 443 ]; | |
networking.extraHosts = '' | |
${config.networking.primaryIPAddress} tts.local | |
''; | |
services.httpd = { | |
enable = true; | |
adminAddr = "admin@tts.local"; | |
extraModules = [ | |
{ name = "ca"; path = "${pkgs.apacheHttpdPackages.mod_ca}/modules/mod_ca.so"; } | |
{ name = "ca_simple"; path = "${pkgs.apacheHttpdPackages.mod_ca}/modules/mod_ca_simple.so"; } | |
{ name = "timestamp"; path = "${pkgs.apacheHttpdPackages.mod_timestamp}/modules/mod_timestamp.so"; } | |
]; | |
virtualHosts = { | |
"tts.local" = { | |
documentRoot = tsWebRoot; | |
forceSSL = true; | |
sslServerKey = "${tsWebRoot}/keys/server.key"; | |
sslServerCert = "${tsWebRoot}/keys/server.pem"; | |
extraConfig = '' | |
Header always set Strict-Transport-Security "max-age=15552000" | |
# backend configuration: | |
# | |
<IfModule mod_ca_simple.c> | |
# use system clock as the time source | |
CASimpleTime on | |
# assign a random serial number | |
CASimpleSerialRandom on | |
</IfModule> | |
# frontend configuration | |
<IfModule mod_timestamp.c> | |
<Location /timestamp> | |
SetHandler timestamp | |
TimestampSigningCertificate "${tsWebRoot}/keys/ts-service.pem" | |
TimestampSigningKey "${tsWebRoot}/keys/ts-service.key" | |
TimestampDigest SHA256 | |
TimestampDefaultPolicy 1.2.3.4.5 | |
Require all granted | |
</Location> | |
</IfModule> | |
''; | |
}; | |
}; | |
}; | |
environment.systemPackages = [ pkgs.openssl ]; | |
system.activationScripts.createDummyKey = '' | |
set -xe | |
dir="${tsWebRoot}/keys" | |
mkdir -m 0700 -p $dir | |
# We need to construct two certificates; one for the web server (optional; http fine too) | |
# and one for the time stamping sevice. See section 2.1/#11 of RFC 3161 for the rationale | |
# behind separate keys/certs ((https://tools.ietf.org/html/rfc3161). | |
# Generating CA - and use that to sign a server and service cert. | |
# | |
${pkgs.openssl}/bin/openssl req -new -x509 -nodes -newkey rsa:1024 \ | |
-extensions v3_ca \ | |
-subj "/C=NL/ST=Zuid-Holland/L=Leiden/O=Koelie-Kerk/CN=CA" \ | |
-out $dir/ca.pem -keyout $dir/ca.key | |
# Generating key for server. We are a bit pedantic about subjectAltNames as | |
# some enterprise tools that use time-stamping severs seem to be strict on this. | |
# | |
${pkgs.openssl}/bin/openssl req -new -nodes -newkey rsa:1024 -keyout $dir/server.key \ | |
-subj "/C=NL/ST=Zuid-Holland/L=Leiden/O=Koelie-Kerk/CN=tts.local" \ | |
-extensions v3_req \ | |
-addext subjectAltName=DNS:tts.local \ | |
-out $dir/temp.csr | |
# We're generating a v3 cert (as we need subjectAltName); which does | |
# not have the requered extension block in the default openssl.cnf. So | |
# we generate one. | |
# | |
cat > $dir/extfile.cnf <<EOM | |
authorityKeyIdentifier=keyid,issuer | |
basicConstraints=CA:FALSE | |
keyUsage = digitalSignature, keyEncipherment | |
EOM | |
${pkgs.openssl}/bin/openssl x509 -req -days 14 -set_serial 2 \ | |
-CA $dir/ca.pem -CAkey $dir/ca.key \ | |
-extension usr_cert \ | |
-extfile $dir/extfile.cnf \ | |
-in $dir/temp.csr \ | |
-out $dir/server.pem | |
rm $dir/temp.csr $dir/extfile.cnf | |
# Generating key for service | |
# | |
${pkgs.openssl}/bin/openssl req -new -nodes -newkey rsa:1024 -keyout $dir/ts-service.key \ | |
-subj "/C=NL/ST=Zuid-Holland/L=Leiden/O=Koelie-Kerk/CN=Grote klokken doen bim-bam - timestamps service" \ | |
-out $dir/temp.csr | |
# The signed cert needs timestamping as a critical usage extension. | |
# | |
echo extendedKeyUsage=critical,timeStamping > $dir/extfile.cnf | |
${pkgs.openssl}/bin/openssl x509 -req -days 14 -set_serial 3 \ | |
-CA $dir/ca.pem -CAkey $dir/ca.key \ | |
-extfile $dir/extfile.cnf \ | |
-in $dir/temp.csr \ | |
-in $dir/temp.csr \ | |
-out $dir/ts-service.pem | |
rm $dir/temp.csr $dir/extfile.cnf | |
# CA key not needed from this point onwards. | |
# | |
rm $dir/ca.key | |
# We need a chain to verify the signature on the timestamp. | |
# | |
cat $dir/ts-service.pem $dir/ca.pem > $dir/fullchain-ts-service.pem | |
''; | |
}; | |
testScript = '' | |
start_all() | |
machine.wait_for_unit("httpd.service") | |
# generate a file to sign | |
machine.succeed("dd if=/dev/urandom of=data.raw count=1 bs=1024") | |
# create a signing request for this file | |
machine.succeed( | |
"openssl ts -query -data data.raw -cert -sha256 -no_nonce -out request.tsq" | |
) | |
# offer it to the signing server | |
machine.succeed( | |
"curl --cacert ${tsWebRoot}/keys/ca.pem -H Content-type:application/timestamp-query --data-binary @request.tsq https://tts.local/timestamp > reply.tsq" | |
) | |
# dump the content of the reply. | |
# | |
machine.succeed("openssl ts -reply -text -in reply.tsq") | |
# verify that it is actually signed & valid - and matches the hash of our file | |
# | |
machine.succeed( | |
"openssl ts -verify -in reply.tsq -data data.raw -CAfile ${tsWebRoot}/keys/fullchain-ts-service.pem" | |
) | |
# In this simple, cannonical case - we can also check straight against the CA - as there | |
# is nothing in between. | |
# | |
machine.succeed( | |
"openssl ts -verify -in reply.tsq -data data.raw -CAfile ${tsWebRoot}/keys/ca.pem" | |
) | |
''; | |
}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment