PIV/CAC support for login.gov.
- Ruby 3.2
- OpenSSL 1.1 (see troubleshooting notes)
- PostgreSQL
- Nginx
Run the following command to set up your local environment:
$ make setup
The first time, it will prompt for a passphrase for the root certificate. You can put anything as long as you remember it, it's just for development. You will also want to make sure to trust the root SSL certificate
Run the app server with:
$ make run
Most of the root certificate management is handled by bin/setup
but there are some manual steps
-
Open the Keychain Access app
-
Within your default keychain, search for the certificate "identity-pki Development Certificate"
-
Double-click the certificate to view its details
-
Expand the "Trust" section and select "Always Trust" for the top-level "When using this certificate" dropdown
-
Close the details to save your changes. You'll be prompted to enter your password or PIN to confirm the changes.
Errors commonly occur due to a mismatch in the expected version of OpenSSL:
- Trying to register or authenticate with your PIV locally produces errors saying your certificate is invalid
- Running certificate Rake tasks produces Ruby errors
If you encounter errors, ensure that you have OpenSSL 1.1 installed, including bindings for your Ruby installation.
To check, run: ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
If the version is anything other than OpenSSL 1.1, you will need to install OpenSSL 1.1 and reinstall Ruby with the OpenSSL directory pointing to the correct version.
If you have Homebrew available and use rbenv
to manage your Ruby installation, you can run the following command to reinstall the project's version of Ruby with OpenSSL 1.1:
RUBY_CONFIGURE_OPTS=--with-openssl-dir=$(brew --prefix openssl@1.1) rbenv install
- Delete the certificate files:
pushd config/local-certs/
make clean
popd
- Open Keychain Access and delete the certificate named "identity-pki Development Certificate"
-
Download, install, and launch Docker.
-
Build the Docker containers:
docker-compose build
-
Run
make docker_setup
to copy configuration files and bootstrap the database. -
Start the Docker containers
docker-compose up
andopen https://localhost:8443
(If you see an SSL error, check Trust the root SSL certificate instructions)
The PIV/CAC service relies on having all of the certificate authorities (issuing certificates). If a certificate authority is missing, then any client certificates signed by that authority will not be recognized as valid.
All certificates have to link back to a trusted root. Trusted roots are implicitly trusted as long as they aren't expired. Any certificate authority that can't be traced back to a trusted root will be ignored.
Certificate authorities are made trusted roots by listing their key id in the
config/application.yml
. The trusted_ca_root_identifiers
configuration attribute
is a comma-delimited list of key ids.
OCSP is a real-time revocation status protocol for certificates. We contact the OCSP server when we check the validity of a certificate rather than relying on a periodic refresh of CRLs. CRLs become a fall-back if we aren't able to contact the OCSP server.
If we have a OCSP URL on record for an issuing certificate, we use that. Otherwise, we find the OCSP URL in the certificate we're verifying. If we are not able to get a response from the OCSP server, we fall back to the CRL information we've cached.
If we get a "revoked" status from the OCSP server, we record that for future checks so we don't have to go back to the OCSP server.
Once a certificate is marked as revoked, we don't "unrevoke." We will always refuse to accept the certificate as valid unless the revocation status is removed from the database.
The application does not download CRLs. Instead, it expects revoked serial numbers to
be listed in the certificate_revocations
table.
Use the rake crls:load
command to load a CSV of CRL metadata into the database. This
command takes an optional filename argument if you aren't providing the CSV on STDIN.
The CSV has the following columns:
- certificate authority key id
- valid not before date/time
- valid not after date/time
- certificate authority subject
- CRL HTTP URL
Use the rake crls:dump
command to dump a CSV of CRL metadata from the database. This
command takes an optional filename argument if you aren't wanting the CSV on STDOUT.
The CSV has the same columns as for crls:load
.
Use the rake crls:update
command to fetch the CRLs of configured certificate authorities
and add any serial numbers to the database.
N.B.: Because of the CRL security model, the command will not fetch or update CRLs for certificate authorities that aren't linked to a trusted root. Make sure your trusted roots are configured if you aren't seeing CRLs fetched as you expect.