Commit Graph

12 Commits

Author SHA1 Message Date
Aaron Gable f7b79d07e5
Generate self-signed lint certs when linting roots (#6994)
Our linting system uses a throwaway key to sign an untrusted version of
the to-be-signed cert, then runs the lints over that. But this means
that, when linting a self-signed cert, the signature no longer matches
the embedded public key. This in turn causes a bunch of zlint's checks
to think they're linting a Subordinate CA cert, rather than a Root CA
cert.

Change our linting system to make the lint cert appear self-signed when
the input cert is intended to be self-signed.
2023-07-13 12:29:12 -07:00
Aaron Gable b090ffbd2e
Use zlint to check our CRLs (#6972)
Update zlint to v3.5.0, which introduces scaffolding for running lints
over CRLs.

Convert all of our existing CRL checks to structs which match the zlint
interface, and add them to the registry. Then change our linter's
CheckCRL function, and crl-checker's Validate function, to run all lints
in the zlint registry.

Finally, update the ceremony tool to run these lints as well.

This change touches a lot of files, but involves almost no logic
changes. It's all just infrastructure, changing the way our lints and
their tests are shaped, and moving test files into new homes.

Fixes https://github.com/letsencrypt/boulder/issues/6934
Fixes https://github.com/letsencrypt/boulder/issues/6979
2023-07-11 15:39:05 -07:00
Aaron Gable c46f19faed
Simplify custom lint directory structure (#6971)
The upstream zlint lints are organized not by what kind of certificate
they apply to, but what source they are from. This change rearranges
(and slightly renames) our custom lints to match the same structure.
This will make it easier for us to temporarily add lints (e.g. for our
CRLs) which we intend to upstream to zlint later.

Part of https://github.com/letsencrypt/boulder/issues/6934
2023-07-05 13:29:30 -07:00
Samantha 43bb293d6f
CA: Only increment lintErrorCount for true lint violations (#6843)
Return the sentinel error indicative of lint violation from
`linter.ProcessResultSet()` instead of `issuance`. This removes a
potential source of false-positives.
2023-04-24 14:30:50 -07:00
Jacob Hoffman-Andrews b4bdd035ad
issuance: split linting and issuing (#6788)
It's useful to be able to get a copy of the linting certificate out of
the process, so we can store it in the database for use by processes
that want a certificate-shaped object (for instance, scanning
possibly-issued public keys for a newly discovered weakness in key
generation).

To do this, while still ensuring that it's impossible to issue a
certificate without linting it, return an IssuanceToken from the linting
process. The IssuanceToken has a private field containing the template
that was used for linting. To issue a final certificate, the
IssuanceToken has to be redeemed, and only the template stored in it can
be used.
2023-04-06 13:24:19 -07:00
Aaron Gable aed604294e
crl-checker: a simple tool to validate public CRLs (#6381)
Add crl-checker, a simple tool which downloads, parses, lints,
and validates signatures on a list of CRLs. It takes its input in
the form of a JSON Array of Sharded CRL URLs, the exact
same format as we will be disclosing in CCADB.

We can add additional checks -- such as ensuring that a set of
known-revoked serials are present, or checking that all of the
downloaded CRLs are "recent enough" -- over time.
2022-09-14 16:41:51 -07:00
Aaron Gable c7014dfd29
Add CRL linting framework and first few lints (#6205)
Add a collection of lints (structured similarly, but not identically,
to zlint's certificate lints) which check a variety of requirements
based on RFC 5280, the Baseline Requirements, and the Mozilla
Root Store Policy.

Add a method to lint CRLs to the existing linter package which
uses its fake issuer to sign the CRL, calls all of the above lints,
and returns all of their findings. Call this new method from within
the CA's new GenerateCRL method immediately before signing
the real CRL using the real issuer.

Fixes #6188
2022-07-08 12:22:44 -07:00
Aaron Gable 11544756bb
Support new Google CT Policy (#6082)
Add a new code path to the ctpolicy package which enforces Chrome's new
CT Policy, which requires that SCTs come from logs run by two different
operators, rather than one Google and one non-Google log. To achieve
this, invert the "race" logic: rather than assuming we always have two
groups, and racing the logs within each group against each other, we now
race the various groups against each other, and pick just one arbitrary
log from each group to attempt submission to.

Ensure that the new code path does the right thing by adding a new zlint
which checks that the two SCTs embedded in a certificate come from logs
run by different operators. To support this lint, which needs to have a
canonical mapping from logs to their operators, import the Chrome CT Log
List JSON Schema and autogenerate Go structs from it so that we can
parse a real CT Log List. Also add flags to all services which run these
lints (the CA and cert-checker) to let them load a CT Log List from disk
and provide it to the lint.

Finally, since we now have the ability to load a CT Log List file
anyway, use this capability to simplify configuration of the RA. Rather
than listing all of the details for each log we're willing to submit to,
simply list the names (technically, Descriptions) of each log, and look
up the rest of the details from the log list file.

To support this change, SRE will need to deploy log list files (the real
Chrome log list for prod, and a custom log list for staging) and then
update the configuration of the RA, CA, and cert-checker. Once that
transition is complete, the deletion TODOs left behind by this change
will be able to be completed, removing the old RA configuration and old
ctpolicy race logic.

Part of #5938
2022-05-25 15:14:57 -07:00
Aaron Gable 9ac85891bb
lint: check that cert doesn't have extra +1s (#5677)
Add a new lint, which applies to all certs, not just one kind of
root/intermediate/subscriber cert, which checks that the validity
period is a round number of minutes; i.e. that it doesn't have an
extra second of validity, like 90d+1s.

In general, if all certs are issued with validities much less than
the limits imposed by root program requirements, being off by one
second one way or another shouldn't matter much. But since it is
easy to mistakenly configure a cert to have notBefore and notAfter
timestamps with the exact same second value, this lint will force
people configuring profiles to think critically about their cert
lifetimes.

Fixes #5669
2021-09-30 11:00:56 -07:00
Aaron Gable 0be4679a9b
Remove debugging prints from linter (#5547) 2021-07-26 12:53:03 -07:00
Aaron Gable bb210a2a28
Add lints for our own CPS requirements (#5512)
Add a collection of custom lints to enforce that our issuance of
Subscriber (via normal Boulder operation) and Root and Intermediate CA
Certificates (via the Ceremony tool) abides by the requirements we
place on ourselves via our CPS. Provide a small collection of useful
constants for these lints to share. Import all of these lints from our
lint package, so that they are automatically registered with zlint's
`GlobalRegistry` and are automatically included in all of our lint
checks.

At this time, only three lints are included, checking that the validity
periods of our various certificate types do not exceed their CPS-set
maximums. Additional lints for key sizes, distinguished names, key
usages, policy OIDs, AIA URLs, and more will be added in the future.

Part of #5492
2021-07-13 10:16:15 -07:00
Aaron Gable d405f9e616
Refactor lint library for go1.17 support (#5513)
In go1.17, the `x509.CreateCertificate()` method fails if the provided
Signer (private key) and Parent (cert with public key) do not match.
This change both updates the lint library to create and use an issuer
cert whose public key matches the throwaway private key used for lint
signatures, and overhauls its public interface for readability and
simplicity.

Rename the `lint` library to `linter`, to allow other methods to be
renamed to reduce word repetition. Reduce the linter library interface
to three functions: `Check()`, `New()`, and `Linter.Check()` by making
all helper functions private. Refactor the top-level `Check()` method to
rely on `New()` and `Linter.Check()` behind the scenes. Finally, create
a new helper method for creating a lint issuer certificate, call this
new method from `New()`, and store the result in the `Linter` struct.

Part of #5480
2021-07-09 10:29:10 -07:00