PKI Test Framework is a dockerized test PKI generator, with a built-in HTTP/S certificate server.
PKI Test Framework is designed to produce X509 material useful for CI/CD integration testing.
On build, PKI Test Framework will generate a multi-organization PKI identity tree, then launch a web server to serve the certificates. The certificates are available over HTTPS, so TLS certificates are generated as well.
Clone from GitHub:
git clone https://github.com/merlincinematic/pki-test-framework.git
cd pki-test-framework
Build and run:
docker compose build --no-cache --build-arg "DAYS=300"
docker compose up
Bootstrap root TLS:
docker compose exec identity /root.sh -t > root.pem
Download a certificate
curl --cacert root.pem https://identity.vandelaybank.com:4443/certificates/[email protected]
Optionally, install PKI identities locally for file access:
mkdir -p target
cd target
curl --cacert ../root.pem https://identity.ciph.xxx:4443/certificates/identity.tar.gz |
tar xzv -
AIA_URL_SERVER_PORT
- when generating the PKI identity tree, use this port for AIA URLs. It should match the port the certificate server is running on.DAYS
- sets the expiration validity date n days from the current time, for all certificates. Defaults to 300. The CA/Browser Forum recommends that TLS certificates expire after 398 days. As a result of the recommendation, most browsers will reject certificates with a longer lifespan.
The DAYS
build argument is relative, so building with --no-cache
is recommended if images are not tagged. Otherwise, a version of the image with expired certificates will be pulled from the Docker cache.
The tls-password.txt
and tls-ca-password.txt
files hold the passwords for encrypting the TLS keys used for the server certificates.
PKI Test Framework builds three fictional organizations:
- biffgroup.com
- bluthdigital.com
- vandelaybank.com
Each organization has its own root authority. All certificates contain an AIA extension, which links to where its issuer certificate can be accessed from certificate server.
bluthdigital.com and vandelaybank.com are cross-signed with the biffgroup.com bridge authority.
Path Validation Example
Root name: CN=biffgroup.com
Certificate server base URL: https://identity.biffgroup.com:4443/certificates/
biffgroup.com is a bridge authority. It issues cross-signed two certificates:
- bridge.biffgroup.com <-> id.bluthdigital.com
- bridge.biffgroup.com <-> id.vandelaybank.com
Root name: CN=bluthdigital.com
Certificate server base URL: https://identity.bluthdigital.com:4443/certificates/
bluthdigital.com is a member of the biffgroup.com bridge. It issues a crossed-signed certificate for bridge.biffgroup.com.
Root name: CN=vandelaybank.com
Certificate server base URL: https://identity.vandelaybank.com:4443/certificates/
vandelaybank.com is a member of the biffgroup.com bridge. It issues a crossed-signed certificate for bridge.biffgroup.com.
Every certificate is encoded multiple times in the formats listed below. The format be identified by the filename extension:
.cer
- single DER-encoded certificate.pem
- single PEM-encoded certificate.p7c
- DER-encoded PKCS7 certificate bundle of the complete certificate chain, excluding root-fullchain.pem
- PEM encoded stack of the complete certificate chain, excluding root
The certificate server has real DNS entries, with an A
record that resolves to 127.0.0.1
. Each organization in the identity tree has its own domain. The URL pattern is:
https://identity.{organization-name}/certificates/{certificate-name}.{format-extension}
Example:
For the organization vandelaybank.com, the certificate named [email protected] can be downloaded in PEM
format from:
https://identity.vandelaybank.com:4443/certificates/[email protected]
On build, TLS certificates are generated for each organization, with a single root authority used to sign all certificates. The root can be bootstrapped as follows:
- Extract the root from a running container:
docker compose exec identity /root.sh -t > root.pem
- Install the root into your trusted certificate store. Curl example:
curl --cacert root.pem {url}