Commit Graph

501 Commits

Author SHA1 Message Date
Aaron Gable 7f49867ae9
Truncate ocsp thisUpdate to the minute, not the hour (#7191)
Truncating to the hour does not provide any meaningful protection
against signature preimage attacks, and can cause the thisUpdate and
producedAt fields to differ by up to 59 minutes from each other.
Instead, truncate to the minute, to match how x/crypto/ocsp sets the
producedAt field.

Fixes https://github.com/letsencrypt/boulder/issues/7190
2023-12-08 11:48:14 -08:00
Phil Porada 6925fad324
Finish migration from int64 timestamps to timestamppb (#7142)
This is a cleanup PR finishing the migration from int64 timestamps to
protobuf `*timestamppb.Timestamps` by removing all usage of the old
int64 fields. In the previous PR
https://github.com/letsencrypt/boulder/pull/7121 all fields were
switched to read from the protobuf timestamppb fields.

Adds a new case to `core.IsAnyNilOrZero` to check various properties of
a `*timestamppb.Timestamp` reducing the visual complexity for receivers.

Fixes https://github.com/letsencrypt/boulder/issues/7060
2023-11-27 13:37:31 -08:00
Phil Porada 000cd05d54
Remove config live reloader package (#7112)
The CA, RA, and tools importing the PA (policy authority) will no longer
be able to live reload specific config files. Each location is now
responsible for loading the config file.

* Removed the reloader package
* Removed unused `ecdsa_allow_list_status` metric from the CA
* Removed mutex from all ratelimit `limitsImpl` methods

Fixes https://github.com/letsencrypt/boulder/issues/7111

---------

Co-authored-by: Samantha <hello@entropy.cat>
Co-authored-by: Aaron Gable <aaron@letsencrypt.org>
2023-10-26 16:06:31 -04:00
Phil Porada a5c2772004
Add and populate new protobuf Timestamp fields (#7070)
* Adds new `google.protobuf.Timestamp` fields to each .proto file where
we had been using `int64` fields as a timestamp.
* Updates relevant gRPC messages to populate the new
`google.protobuf.Timestamp` fields in addition to the old `int64`
timestamp fields.
* Added tests for each `<x>ToPB` and `PBto<x>` functions to ensure that
new fields passed into a gRPC message arrive as intended.
* Removed an unused error return from `PBToCert` and `PBToCertStatus`
and cleaned up each call site.

Built on-top of https://github.com/letsencrypt/boulder/pull/7069
Part 2 of 4 related to
https://github.com/letsencrypt/boulder/issues/7060
2023-10-11 12:12:12 -04:00
Aaron Gable cb28a001e9
Unfork crl x509 (#7078)
Delete our forked version of the x509 library, and update all call-sites
to use the version that we upstreamed and got released in go1.21. This
requires making a few changes to calling code:
- replace crl_x509.RevokedCertificate with x509.RevocationListEntry
- replace RevocationList.RevokedCertificates with
RevocationList.RevokedCertificateEntries
- make RevocationListEntry.ReasonCode a non-pointer integer

Our lints cannot yet be updated to use the new types and fields, because
those improvements have not yet been adopted by the zcrypto/x509 package
used by the linting framework.

Fixes https://github.com/letsencrypt/boulder/issues/6741
2023-09-15 20:25:13 -07:00
Phil Porada 034316ef6a
Rename int64 timestamp related protobuf fields to <fieldname>NS (#7069)
Rename all of int64 timestamp fields to `<fieldname>NS` to indicate they
are Unix nanosecond timestamps.

Part 1 of 4 related to
https://github.com/letsencrypt/boulder/issues/7060
2023-09-15 13:49:07 -04:00
Jacob Hoffman-Andrews 725f190c01
ca: remove orphan queue code (#7025)
The `orphanQueueDir` config field is no longer used anywhere.

Fixes #6551
2023-08-02 16:04:28 -07:00
Aaron Gable 158f62bd0c
Remove policy qualifiers from all issuance paths (#6980)
The inclusion of Policy Qualifiers inside Policy Information elements of
a Certificate Policies extension is now NOT RECOMMENDED by the Baseline
Requirements. We have already removed these fields from all of our
Boulder configuration, and ceased issuing certificates with Policy
Qualifiers.

Remove all support for configuring and including Policy Qualifiers in
our certificates, both in Boulder's main issuance path and in our
ceremony tool. Switch from using the policyasn1 library to manually
encode these extensions, to using the crypto/x509's
Certificate.PolicyIdentifiers field. Delete the policyasn1 package as it
is no longer necessary.

Fixes https://github.com/letsencrypt/boulder/issues/6880
2023-07-13 10:37:05 -07:00
Aaron Gable 92d75a9445
Improve core.PublicKeysEqual (#6996)
Rather than marshalling and comparing the bytes of each key, simply use
the .Equal() method provided by all go stdlib types that implement the
crypto.PublicKey interface.
2023-07-13 10:01:42 -07:00
cui fliter 45fa658086
fix function name in comment (#6984)
Signed-off-by: cui fliter <imcusg@gmail.com>
2023-07-07 13:12:39 -04:00
Jacob Hoffman-Andrews cd24b9db20
ca: deprecate StoreLintingCertificateInsteadOfPrecertificate (#6970)
And turn off the orphan queue in config-next.
2023-07-05 10:44:08 -07:00
Jacob Hoffman-Andrews 8dcbc4c92f
Add must.Do utility function (#6955)
This can take two values (typically the return values of a two-value
function) and panic if the error is non-nil, returning the interesting
value. This is particularly useful for cases where we statically know
the call will succeed.

Thanks to @mcpherrinm for the idea!
2023-06-26 14:43:30 -07:00
Jacob Hoffman-Andrews 1c7e0fd1d8
Store linting certificate instead of precertificate (#6807)
In order to get rid of the orphan queue, we want to make sure that
before we sign a precertificate, we have enough data in the database
that we can fulfill our revocation-checking obligations even if storing
that precertificate in the database fails. That means:

- We should have a row in the certificateStatus table for the serial.
- But we should not serve "good" for that serial until we are positive
the precertificate was issued (BRs 4.9.10).
- We should have a record in the live DB of the proposed certificate's
public key, so the bad-key-revoker can mark it revoked.
- We should have a record in the live DB of the proposed certificate's
names, so it can be revoked if we are required to revoke based on names.

The SA.AddPrecertificate method already achieves these goals for
precertificates by writing to the various metadata tables. This PR
repurposes the SA.AddPrecertificate method to write "proposed
precertificates" instead.

We already create a linting certificate before the precertificate, and
that linting certificate is identical to the precertificate that will be
issued except for the private key used to sign it (and the AKID). So for
instance it contains the right pubkey and SANs, and the Issuer name is
the same as the Issuer name that will be used. So we'll use the linting
certificate as the "proposed precertificate" and store it to the DB,
along with appropriate metadata.

In the new code path, rather than writing "good" for the new
certificateStatus row, we write a new, fake OCSP status string "wait".
This will cause us to return internalServerError to OCSP requests for
that serial (but we won't get such requests because the serial has not
yet been published). After we finish precertificate issuance, we update
the status to "good" with SA.SetCertificateStatusReady.

Part of #6665
2023-04-26 13:54:24 -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
Samantha 914e971f15
CA: Emit count of precertificate lint failures (#6839)
Fixes #6825
2023-04-21 17:00:27 -04:00
Aaron Gable 45329c9472
Deprecate ROCSPStage7 flag (#6804)
Deprecate the ROCSPStage7 feature flag, which caused the RA and CA to
stop generating OCSP responses when issuing new certs and when revoking
certs. (That functionality is now handled just-in-time by the
ocsp-responder.) Delete the old OCSP-generating codepaths from the RA
and CA. Remove the CA's internal reference to an OCSP implementation,
because it no longer needs it.

Additionally, remove the SA's "Issuers" config field, which was never
used.

Fixes #6285
2023-04-12 17:03:06 -07:00
Aaron Gable e55a276efe
CA: Remove deprecated config stanzas (#6595)
These config stanzas have been removed in staging and prod. They used to
configure the separate OCSP and CRL gRPC services provided by the CA
process, but the CA now provides those services on the same port as the
main CA gRPC service.

Fixes #6448
2023-04-07 09:37:34 -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 9262ca6e3f
Add grpc implementation tests to all services (#6782)
As a follow-up to #6780, add the same style of implementation test to
all of our other gRPC services. This was not included in that PR just to
keep it small and single-purpose.
2023-03-31 09:52:26 -07:00
Aaron Gable 6d6f3632da
Change SetCommonName to RequireCommonName (#6749)
Change the SetCommonName flag, introduced in #6706, to
RequireCommonName. Rather than having the flag control both whether or
not a name is hoisted from the SANs into the CN *and* whether or not the
CA is willing to issue certs with no CN, this updated flag now only
controls the latter. By default, the new flag is true, and continues our
current behavior of failing issuance if we cannot set a CN in the cert.
When the flag is set to false, then we are willing to issue certificates
for which the CSR contains no CN and there is no SAN short enough to be
hoisted into the CN field.

When we have rolled out this change, we can move on to the next flag in
this series: HoistCommonName, which will control whether or not a SAN is
hoisted at all, effectively giving the CSRs (and therefore the clients)
full control over whether their certificate contains a SAN.

This change is safe because no environment explicitly sets the
SetCommonName flag to false yet.

Fixes #5112
2023-03-21 11:07:06 -07:00
Phil Porada b9f0fe030a
CA: Fail construction if no issuers are provided (#6736)
If a CA config is created with an empty `issuers[]` json, then the CA
should fail to start up. With no issuers present, the integration tests
fail with the following error truncated for readability.
```
boulder-ra [AUDIT] Certificate request - error 
Error":"issuing precertificate: no issuer found for public key algorithm RSA"
```

Fixes https://github.com/letsencrypt/boulder/issues/6735
2023-03-09 18:34:38 -05:00
Aaron Gable 9af4871e59
Add SetCommonName feature flag (#6706)
Add a new feature flag, `SetCommonName`, which defaults to `true`. In
this default state, no behavior changes.

When set to `false` on the CA, this flag will cause the CA to leave the
Subject commonName field of the certificate blank, as is recommended by
the Baseline Requirements Section 7.1.4.2.2(a).

Also slightly modify the behavior of the RA's `matchesCSR()` function,
to allow for both certificates that have a CN and certificates that
don't. It is not feasible to put this behavior behind the same
SetCommonName flag, because that would require an atomic deploy of both
the RA and the CA.

Obsoletes #5112
2023-03-09 13:31:55 -05:00
Jacob Hoffman-Andrews 85fd3ed8b7
sa: remove GetPrecertificate (#6692)
This was mostly unused. The only caller was orphan-finder, which used it
to determine if a certificate was already in the database. But this is
not particularly important functionality, so I've removed it.
2023-03-01 11:30:51 -08:00
Matthew McPherrin 391a59921b
Move cmd.ConfigDuration to config.Duration (#6705)
We rely on the ratelimit/ package in CI to validate our ratelimit
configurations. However, because that package relies on cmd/ just for
cmd.ConfigDuration, many additional dependencies get pulled in.

This refactors just that struct to a separate config package. This was
done using Goland's automatic refactoring tooling, which also organized
a few imports while it was touching them, keeping standard library,
internal and external dependencies grouped.
2023-02-28 08:11:49 -08:00
Jacob Hoffman-Andrews d9872dbe41
sa: rename AddPrecertificateRequest.IssuerID (#6689)
sa: rename AddPrecertificateRequest.IssuerID
to IssuerNameID. This is in preparation for adding a similarly-named
field to AddSerialRequest.

Part of #5152.
2023-02-27 17:21:00 -05:00
Aaron Gable 5ce4b5a6d4
Use time format constants (#6694)
Use constants from the go stdlib time package, such as time.DateTime and
time.RFC3339, when parsing and formatting timestamps. Additionally,
simplify or remove some of our uses of parsing timestamps, such as to
set fake clocks in tests.
2023-02-24 11:22:23 -08:00
Aaron Gable 427bced0cd
Remove OCSP and CRL methods from CA gRPC service (#6474)
Remove the GenerateOCSP and GenerateCRL methods from the
CertificateAuthority gRPC service. These methods are no longer called by
any clients; all clients use their respective OCSPGenerator and
CRLGenerator gRPC services instead.

In addition, remove the CRLGeneratorServer field from the caImpl, as it
no longer needs it to serve as a backing implementation for the
GenerateCRL pass-through method. Unfortunately, we can't remove the
OCSPGeneratorServer field until after ROCSPStage7 is complete, and the
CA is no longer generating an OCSP response during initial certificate
issuance.

Part of #6448
2023-02-23 14:42:14 -08:00
Phil Porada d3845f25c6
Strict YAML parsing (#6652)
Adds a custom YAML unmarshaller in the `//strictyaml` package based on
`go-yaml/yaml v3` with unique key detection enabled and ensures that
target struct is able to contain all target fields.

Fixes https://github.com/letsencrypt/boulder/issues/3344.
2023-02-22 14:56:26 -05:00
Phil Porada 9390c0e5f5
Put errors at end of log lines (#6627)
For consistency, put the error field at the end of unstructured log
lines to make them more ... structured.

Adds the `issuerID` field to "orphaning certificate" log line in the CA
to match the "orphaning precertificate" log line.

Fixes broken tests as a result of the CA and bdns log line change.

Fixes #5457
2023-02-03 11:28:38 -05:00
Aaron Gable b7e4e9d0ce
SA: Remove AddCertificate's unused return value (#6532)
The `digest` value in AddCertificate's response message is never used by
any callers. Remove it, replacing the whole response message with
google.protobuf.Empty, to mirror the AddPrecertificate method.

This swap is safe, because message names are not sent on the network,
and empty message fields are omitted from the wire format entirely, so
sending the predefined Empty message is identical to sending an empty
AddCertificateResponse message. Since no client is inspecting the
response to access the digest field, sending an empty response will not
break any clients.

Fixes #6498
2022-11-30 13:00:56 -08:00
Aaron Gable 4f473edfa8
Deprecate 10 feature flags (#6502)
Deprecate these feature flags, which are consistently set in both prod
and staging and which we do not expect to change the value of ever
again:
- AllowReRevocation
- AllowV1Registration
- CheckFailedAuthorizationsFirst
- FasterNewOrdersRateLimit
- GetAuthzReadOnly
- GetAuthzUseIndex
- MozRevocationReasons
- RejectDuplicateCSRExtensions
- RestrictRSAKeySizes
- SHA1CSRs

Move each feature flag to the "deprecated" section of features.go.
Remove all references to these feature flags from Boulder application
code, and make the code they were guarding the only path. Deduplicate
tests which were testing both the feature-enabled and feature-disabled
code paths. Remove the flags from all config-next JSON configs (but
leave them in config ones until they're fully deleted, not just
deprecated). Finally, replace a few testdata CSRs used in CA tests,
because they had SHA1WithRSAEncryption signatures that are now rejected.

Fixes #5171 
Fixes #6476
Part of #5997
2022-11-14 09:24:50 -08:00
Aaron Gable 2af11e425c
CA: Add configs to disable each gRPC service (#6473)
Add three new boolean config keys to the CA's config json:
- DisableCertService
- DisableOCSPService
- DisableCRLService

Setting any one of these flags to True and restarting the CA causes the
corresponding gRPC service (CertificateAuthority, OCSPGenerator, or
CRLGenerator, respectively) to not be started. The implementation is not
instantiated, the port is not opened, and no requests will be listened
for. All clients will receive failures to connect.

Also, create two temporary "dummy" implementations of the CRL and OCSP
services (and an interface for the fake OCSP service to meet), These are
necessary because the CertificateAuthority gRPC service currently
contains wrapper methods which replicate the methods of the OCSP and CRL
services, and which pass through calls to underlying implementation
objects. These objects must be replaced with fake objects which always
return an error when the service is disabled.

Fixes #6452
2022-11-01 10:00:37 -07:00
Aaron Gable 868214b85e
CRLs: include IssuingDistributionPoint extension (#6412)
Add the Issuing Distribution Point extension to all of our end-entity
CRLs. The extension contains the Distribution Point, the URL from
which this CRL is meant to be downloaded. Because our CRLs are
sharded, this URL prevents an on-path attacker from substituting a
different shard than the client expected in order to hide a revocation.
The extension also contains the OnlyContainsUserCerts boolean,
because our CRLs only contain end-entity certificates.

The Distribution Point url is constructed from a configurable base URI,
the issuer's NameID, the shard index, and the suffix ".crl". The base
URI must use the "http://" scheme and must not end with a slash.

openssl displays the IDP extension as:
```
X509v3 Issuing Distribution Point: critical
  Full Name:
    URI:http://c.boulder.test/66283756913588288/0.crl                Only User Certificates
```

Fixes #6410
2022-10-24 11:21:55 -07:00
Aaron Gable ab4b1eb3e1
Add ROCSPStage7 flag to disable OCSP calls (#6461)
Rather than simply refusing to write OCSP Response bytes to the
database (which is what ROCSP Stage 6 did), Stage 7 refuses to
even generate those bytes in the first place. We obviously can't
disable OCSP Response generation in the CA, since it still needs to
be usable by the ocsp-responder's live-signing path, so instead we
disable it in all of the non-live-signing codepaths (orphan finder,
issue precertificate, revoke certificate, and re-revoke certificate)
which have previously called GenerateOCSP.

Part of #6285
2022-10-21 17:24:19 -07:00
Aaron Gable 89f7fb1636
Clean up go1.19 TODOs (#6464)
Clean up several spots where we were behaving differently on
go1.18 and go1.19, now that we're using go1.19 everywhere. Also
re-enable the lint and generate tests, and fix the various places where
the two versions disagreed on how comments should be formatted.

Also clean up the OldTLS codepaths, now that both go1.19 and our
own feature flags have forbidden TLS < 1.2 everywhere.

Fixes #6011
2022-10-21 15:54:18 -07:00
Aaron Gable 02432fcd51
RA: Use OCSPGenerator gRPC service (#6453)
When the RA is generating OCSP (as part of new issuance, revocation,
or when its own GenerateOCSP method is called by the ocsp-responder)
have it use the CA's dedicated OCSPGenerator service, rather than
calling the method exposed by the CA's catch-all CertificateAuthority
service. To facilitate this, add a new GRPCClientConfig stanza to the
RA.

This change will allow us to remove the GenerateOCSP and GenerateCRL
methods from the catch-all CertificateAuthority service, allowing us to
independently control which kinds of objects the CA is willing to sign
by turning off individual service interfaces. The RA's new config stanza
will need to be populated in prod before further changes are possible.

Fixes #6451
2022-10-21 15:37:01 -07:00
Jacob Hoffman-Andrews ad840b4410
reloader: log reload events directly (#6398)
Previously, the reloader relied on user code to log errors and changes.
But this led to gaps (for instance the RA not logging reloads of the rate
limit file). Instead, make the reloader responsible for this.

This allowed removing the error callback, at the minor cost of removing
the status gauge for the ECDSA allowlist.
2022-09-23 14:41:54 -07:00
Jacob Hoffman-Andrews dd1c52573e
log: allow logging to stdout/stderr instead of syslog (#6307)
Right now, Boulder expects to be able to connect to syslog, and panics
if it's not available. We'd like to be able to log to stdout/stderr as a
replacement for syslog.

- Add a detailed timestamp (down to microseconds, same as we collect in
prod via syslog).
- Remove the escape codes for colorizing output.
- Report the severity level numerically rather than with a letter prefix.

Add locking for stdout/stderr and syslog logs. Neither the [syslog] package
nor the [os] package document concurrency-safety, and the Go rule is: if
it's not documented to be concurrent-safe, it's not. Notably the [log.Logger]
package is documented to be concurrent-safe, and a look at its implementation
shows it uses a Mutex internally.

Remove places that use the singleton `blog.Get()`, and instead pass through
a logger from main in all the places that need it.

[syslog]: https://pkg.go.dev/log/syslog
[os]: https://pkg.go.dev/os
[log.Logger]: https://pkg.go.dev/log#Logger
2022-08-29 06:19:22 -07:00
Aaron Gable 0340b574d9
Add unparam linter to CI (#6312)
Enable the "unparam" linter, which checks for unused function
parameters, unused function return values, and parameters and
return values that always have the same value every time they
are used.

In addition, fix many instances where the unparam linter complains
about our existing codebase. Remove error return values from a
number of functions that never return an error, remove or use
context and test parameters that were previously unused, and
simplify a number of (mostly test-only) functions that always take the
same value for their parameter. Most notably, remove the ability to
customize the RSA Public Exponent from the ceremony tooling,
since it should always be 65537 anyway.

Fixes #6104
2022-08-23 12:37:24 -07:00
Samantha 7ed4cd992e
CRL: Improve shard identification in error messages (#6306)
- Create new package `crl`
- Add a common unique CRL identifier `crl.id` with constructor `crl.Id()`
- Replace `shardIdx` with `crl.Id` in `storer` and `updater` errors
- Add a common type for the `CRLNumber` field `crl.number` with constructor
  `crl.Number()`
- Replace `CRLNumber` construction in CA and CRL package with `crl.Number()`

Resolves #6261
2022-08-23 12:35:00 -07:00
Aaron Gable 4ad66729d2
Tests: use reflect.IsNil() to avoid boxed nil issues (#6305)
Add a new `test.AssertNil()` helper to facilitate asserting that a given
unit test result is a non-boxed nil. Update `test.AssertNotNil()` to use
the reflect package's `.IsNil()` method to catch boxed nils.

In Go, variables whose type is constrained to be an interface type (e.g.
a function parameter which takes an interface, or the return value of a
function which returns `error`, itself an interface type) should
actually be thought of as a (T, V) tuple, where T is their underlying
concrete type and V is their underlying value. Thus, there are two ways
for such a variable to be nil-like: it can be truly nil where T=nil and
V is uninitialized, or it can be a "boxed nil" where T is a nillable
type such as a pointer or a slice and V=nil.

Unfortunately, only the former of these is == nil. The latter is the
cause of frequent bugs, programmer frustration, a whole entry in the Go
FAQ, and considerable design effort to remove from Go 2.

Therefore these two test helpers both call `t.Fatal()` when passed a
boxed nil. We want to avoid passing around boxed nils whenever possible,
and having our tests fail whenever we do is a good way to enforce good
nil hygiene.

Fixes #3279
2022-08-19 14:47:34 -07:00
Aaron Gable 9c197e1f43
Use io and os instead of deprecated ioutil (#6286)
The iotuil package has been deprecated since go1.16; the various
functions it provided now exist in the os and io packages. Replace all
instances of ioutil with either io or os, as appropriate.
2022-08-10 13:30:17 -07:00
Aaron Gable 6a9bb399f7
Create new crl-storer service (#6264)
Create a new crl-storer service, which receives CRL shards via gRPC and
uploads them to an S3 bucket. It ignores AWS SDK configuration in the
usual places, in favor of configuration from our standard JSON service
config files. It ensures that the CRLs it receives parse and are signed
by the appropriate issuer before uploading them.

Integrate crl-updater with the new service. It streams bytes to the
crl-storer as it receives them from the CA, without performing any
checking at the same time. This new functionality is disabled if the
crl-updater does not have a config stanza instructing it how to connect
to the crl-storer.

Finally, add a new test component, the s3-test-srv. This acts similarly
to the existing mail-test-srv: it receives requests, stores information
about them, and exposes that information for later querying by the
integration test. The integration test uses this to ensure that a
newly-revoked certificate does show up in the next generation of CRLs
produced.

Fixes #6162
2022-08-08 16:22:48 -07:00
Aaron Gable 733bcec941
Standardize on 'shardIdx' to identify crl shards (#6263)
Realized that "ShardID" is a bad name, because a real unique
identifier of a shard would include the issuer, crl number, and
shard number. Switching to "ShardIdx" makes it clearer that
shards within a full and complete CRL are identified by a
zero-indexed integer.
2022-08-02 13:21:26 -07:00
Nina cdf1d321a5
ocsp: log revocation reason code (#6228)
In the CA, rather than logging just the revocation status (0 for Good,
1 for Revoked), begin logging the integer revocation reason (0 for
Unspecified, 1 for KeyCompromise, etc). For OCSP responses with the Good
status, log an underscore ("_") indicating that the revocation reason is
inapplicable.

This brings the OCSP audit logging in line with the new CRL logging,
which logs the reason for each serial included in a CRL.

Fixes #6214
2022-08-01 12:53:17 -07:00
Aaron Gable f5f6f378a7
Fix CA CRL log lines (#6249)
Add a closing bracket both when ending a line due to max log length
and when ending a line due to the end of the entry list. Change the
max log length check to a greater-than to prevent it from incorrectly
firing every time.
2022-07-25 13:20:03 -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 436061fb35
CRL: Create crl-updater service (#6212)
Create a new service named crl-updater. It is responsible for
maintaining the full set of CRLs we issue: one "full and complete" CRL
for each currently-active Issuer, split into a number of "shards" which
are essentially CRLs with arbitrary scopes.

The crl-updater is modeled after the ocsp-updater: it is a long-running
standalone service that wakes up periodically, does a large amount of
work in parallel, and then sleeps. The period at which it wakes to do
work is configurable. Unlike the ocsp-responder, it does all of its work
every time it wakes, so we expect to set the update frequency at 6-24
hours.

Maintaining CRL scopes is done statelessly. Every certificate belongs to
a specific "bucket", given its notAfter date. This mapping is generally
unchanging over the life of the certificate, so revoked certificate
entries will not be moving between shards upon every update. The only
exception is if we change the number of shards, in which case all of the
bucket boundaries will be recomputed. For more details, see the comment
on `getShardBoundaries`.

It uses the new SA.GetRevokedCerts method to collect all of the revoked
certificates whose notAfter timestamps fall within the boundaries of
each shard's time-bucket. It uses the new CA.GenerateCRL method to sign
the CRLs. In the future, it will send signed CRLs to the crl-storer to
be persisted outside our infrastructure.

Fixes #6163
2022-07-08 09:34:51 -07:00
Aaron Gable 74e914e8e7
Disallow affiliationChanged revocation reason (#6217)
The `affiliationChanged` revocation reason is only relevant
to certificates which contain Subject Identity Information.
As we only issue DV certificates, which cannot contain such
information, our certificates should not be able to be revoked
for this reason.

See https://groups.google.com/a/mozilla.org/g/dev-security-policy/c/m3-XPcVcJ9M
2022-07-07 10:45:36 -07:00
Nina 6986f0d756
ca: avoid ocsp.ResponseStatus (#6213) 2022-07-05 15:43:06 -07:00
Aaron Gable 63f7936ea2
Use forked crl x509 (#6204)
Use the new //crl/x509 library in the CA, to make handling the
ReasonCode of each CRL entry significantly easier. This also
allows us to log the reason code along with each serial in the
CRL.

Also, make a couple tiny tweaks to the //crl/x509 package that
were discovered to be useful while writing this change. These
include moving it to a //crl/crl_x509 directory so that it doesn't
have to be aliased at import time.

Fixes #6199
2022-07-01 11:27:32 -07:00
Aaron Gable e13918b50e
CA: Add GenerateCRL gRPC method (#6187)
Add a new CA gRPC method named `GenerateCRL`. In the
style of the existing `GenerateOCSP` method, this new endpoint
is implemented as a separate service, for which the CA binary
spins up an additional gRPC service.

This method uses gRPC streaming for both its input and output.
For input, the stream must contain exactly one metadata message
identifying the crl number, issuer, and timestamp, and then any
number of messages identifying a single certificate which should
be included in the CRL. For output, it simply streams chunks of
bytes.

Fixes #6161
2022-06-29 11:03:12 -07:00
Aaron Gable 1a6f7154d8
Update yaml from v2.4.0 to v3.0.1 (#6146)
The gopkg.in/yaml.v2 package has a potential crash when
parsing malicious input. Although we only use the yaml
package to parse trusted configuration, update to v3 anyway.
2022-06-14 13:53:58 -07:00
Aaron Gable 9b4ca235dd
Update boulder-tools dependencies (#6129)
Update:
- golangci-lint from v1.42.1 to v1.46.2
- protoc from v3.15.6 to v3.20.1
- protoc-gen-go from v1.26.0 to v1.28.0
- protoc-gen-go-grpc from v1.1.0 to v1.2.0
- fpm from v1.14.0 to v1.14.2

Also remove a reference to go1.17.9 from one last place.

This does result in updating all of our generated .pb.go files, but only
to update the version number embedded in each file's header.

Fixes #6123
2022-05-20 14:24:01 -07:00
Aaron Gable 50f6a6b84f
Speed up ca unit tests by 10x (#6128)
Profiling showed that the unit tests were spending almost all of
their time in key generation, because the tests were generating
new fake keys for the linter with every call to `setup()`. Instead,
create the linters just once at startup time.

This decreases the runtime of `go test ./ca/...` from ~9.7s to less
than one second.
2022-05-18 13:16:04 -07:00
Aaron Gable 238c309088
Reduce redundant audit logging of CSR (#6113)
Stop logging the full CSR bytes at the WFE; we log these bytes in the
CA immediately before attempting to sign a precertificate anyway.

Also unify the way we log precertificate and final certificate signing
events in the CA: an Info containing the request prior to signing, and
then either an Info or an Error containing the result afterwards.

Fixes #6088
2022-05-16 14:33:33 -07:00
Aaron Gable 8cb01a0c34
Enable additional linters (#6106)
These new linters are almost all part of golangci-lint's collection
of default linters, that would all be running if we weren't setting
`disable-all: true`. By adding them, we now have parity with the
default configuration, as well as the additional linters we like.

Adds the following linters:
* unconvert
* deadcode
* structcheck
* typecheck
* varcheck
* wastedassign
2022-05-11 13:58:58 -07:00
Jacob Hoffman-Andrews dd8be8d7b0
Add regID to signing log messages (#6014) 2022-03-22 10:32:23 -07:00
Eng Zer Jun f6db0fe0a3
test: use `T.TempDir` to create temporary test directory (#5930)
Use the T.TempDir method from the testing package to create temporary
directories for tests. Directories created by T.TempDir are automatically
removed when tests complete.
2022-02-07 12:41:28 -08:00
Aaron Gable 305ef9cce9
Improve error checking paradigm (#5920)
We have decided that we don't like the if err := call(); err != nil
syntax, because it creates confusing scopes, but we have not cleaned up
all existing instances of that syntax. However, we have now found a
case where that syntax enables a bug: It caused readers to believe that
a later err = call() statement was assigning to an already-declared err
in the local scope, when in fact it was assigning to an
already-declared err in the parent scope of a closure. This caused our
ineffassign and staticcheck linters to be unable to analyze the
lifetime of the err variable, and so they did not complain when we
never checked the actual value of that error.

This change standardizes on the two-line error checking syntax
everywhere, so that we can more easily ensure that our linters are
correctly analyzing all error assignments.
2022-02-01 14:42:43 -07:00
Aaron Gable ab79f96d7b
Fixup staticcheck and stylecheck, and violations thereof (#5897)
Add `stylecheck` to our list of lints, since it got separated out from
`staticcheck`. Fix the way we configure both to be clearer and not
rely on regexes.

Additionally fix a number of easy-to-change `staticcheck` and
`stylecheck` violations, allowing us to reduce our number of ignored
checks.

Part of #5681
2022-01-20 16:22:30 -08:00
Andrew Gabbitas 8ffae7d316
Create precert ocsp before precert issuance (#5890)
Move the precertificate ocsp response creation to happen before the
precertificate is issued to avoid a case where a precertificate is issued
but an OCSP response generation error could cause the precertificate to
not be stored in the database.

Fixes #5887
2022-01-20 12:00:13 -07:00
Aaron Gable 8da52f74c3
Remove v1 `NewCertificate` code path from WFE and RA (#5842)
The NewCertificate codepath was the ACME v1 API's equivalent of
the modern Finalize endpoint. Remove the bodies of the WFE's and
the RA's `NewCertificate` functions. Remove the functions which were
called only from those functions. One of the removed functions is the
old `checkAuthorizations`, so update some tests which were calling
that directly to instead use different entry points.

Part of #5681
2021-12-13 17:45:45 -08:00
Jacob Hoffman-Andrews 6ffbd32dc8
Remove unused testdata files (#5804) 2021-11-17 17:12:25 -08:00
Aaron Gable a57d97c6e5
CA: Store IssuerNameID in certStatus table (#5593)
Finally, the second-to-last step of switching from IssuerIDs to
IssuerNameIDs: have the CA store the IssuerNameID in the
certStatus database when first issuing precertificates and final
certificates.

This is the change we can't come back from: once this is deployed,
we've effectively changed our database schema (by changing
the semantic meaning of the certStatus table's "IssuerID" column).
Although it can be rolled back and no harm should come to anything,
rolling back (e.g. because some component actually *doesn't* handle
this gracefully) will not remove the data that was written while it
was deployed.

Part of #5152
2021-10-26 16:17:58 -07:00
Aaron Gable 4c2b07004c
Compute OCSP validity interval correctly (#5680)
Like certificates, the validity of an OCSP response is measured
inclusive of its final second. Ensure that we set the `nextUpdate`
timestamp taking this into account.

Fixes #5667
2021-09-30 11:00:24 -07:00
Aaron Gable bab688b98f
Remove sa-wrappers.go (#5663)
Remove the last of the gRPC wrapper files. In order to do so:

- Remove the `core.StorageGetter` interface. Replace it with a new
  interface (whose methods include the `...grpc.CallOption` arg)
  inside the `sa/proto/` package.
- Remove the `core.StorageAdder` interface. There's no real use-case
  for having a write-only interface.
- Remove the `core.StorageAuthority` interface, as it is now redundant
  with the autogenerated `sapb.StorageAuthorityClient` interface.
- Replace the `certificateStorage` interface (which appears in two
  different places) with a single unified interface also in `sa/proto/`.
- Update all test mocks to include the `_ ...grpc.CallOption` arg in
  their method signatures so they match the gRPC client interface.
- Delete many methods from mocks which are no longer necessary (mostly
  because they're mocking old authz1 methods that no longer exist).
- Move the two `test/inmem/` wrappers into their own sub-packages to
  avoid an import cycle.
- Simplify the `satest` package to satisfy one of its TODOs and to
  avoid an import cycle.
- Add many methods to the `test/inmem/sa/` wrapper, to accommodate all
  of the methods which are called in unittests.

Fixes #5600
2021-09-27 13:25:41 -07:00
Aaron Gable 2fe12cdf20
Unwrap SA Add/Revoke Certificate methods (#5598)
Make the gRPC wrappers for the SA's `AddCertificate`,
`AddPrecertificate`, `AddSerial`, and `RevokeCertificate`
methods simple pass-throughs.

Fixup a couple tests that were passing only because their
requests to in-memory SA objects were not passing through
the wrapper's consistency checks.

Part of #5532
2021-08-25 15:54:25 -07:00
Aaron Gable f454892dd1
Unwrap SA Get[Pre]Certificate methods (#5588)
Make the gRPC wrappers for sa.GetCertificate and
sa.GetPrecertificate bare passthroughs. The latter of
these already took and returned appropriate protobufs,
so this change mostly just makes the former look like the
latter.

Part of #5532
2021-08-19 15:43:48 -07:00
Aaron Gable 3492a996ab
Update TODOs for Issue #5152 (#5591)
Changing how we're going to finally handle #5152: rather
than changing everything to use IssuerNameIDs, we're going
to change the meaning of IssuerID. This will allow us to avoid
renaming database columns and protobuf message fields.
2021-08-19 14:31:09 -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
Aaron Gable 2723a9b0b5
Allow IssuerID or IssuerNameID in OCSP requests (#5515)
Have the OCSP component of the CA keep track of both the (old-style)
IssuerID and the (new-style) IssuerNameID of all issuer certificates
loaded by its config. When receiving a requests to generate an OCSP
response, check the ID contained in that request against both lists,
preferring the IssuerNameID list.

This allows us to have GenerateOCSP clients (the RA and ocsp-updater)
begin specifying IssuerNameIDs in their requests, so that we can get
rid of the old IssuerID entirely.

Part of #5152
2021-07-09 10:20:59 -07:00
Aaron Gable 20f1bf1d0d
Compute validity periods inclusive of notAfter second (#5494)
In the CA, compute the notAfter timestamp such that the cert is actually
valid for the intended duration, not for one second longer. In the
Issuance library, compute the validity period by including the full
length of the final second indicated by the notAfter date when
determining if the certificate request matches our profile. Update tests
and config files to match.

Fixes #5473
2021-06-24 13:17:29 -07:00
Samantha d574b50c41
CA: Deprecate field ECDSAAllowedAccounts (#5477)
- Remove field `ECDSAAllowedAccounts` from CA
- Remove `ECDSAAllowedAccounts` from CA tests
- Replace `ECDSAAllowedAccounts` with `ECDSAAllowListFilename` in
  `test/config/ca-a.json` and `test/config/ca-b.json`
- Add YAML allow list file at `test/config/ecdsaAllowList.yml`

Fixes #5394
2021-06-11 12:13:01 -07:00
Aaron Gable 64c9ec350d
Unify protobuf generation (#5458)
Create script which finds every .proto file in the repo and correctly
invokes `protoc` for each. Create a single file with a `//go:generate`
directive to invoke the new script. Delete all of the other generate.go
files, so that our proto generation is unified in one place.

Fixes #5453
2021-06-07 08:49:15 -07:00
Aaron Gable 8be32d3312
Use google.protobuf.Empty instead of core.Empty (#5454)
Replace `core.Empty` with `google.protobuf.Empty` in all of our gRPC
methods which consume or return an empty protobuf. The golang core
proto libraries provide an empty message type, so there is no need
for us to reinvent the wheel.

This change is backwards-compatible and does not require a special
deploy. The protobuf message descriptions of `core.Empty` and
`google.protobuf.Empty` are identical, so their wire-formats are
indistinguishable and therefore interoperable / cross-compatible.

Fixes #5443
2021-06-03 14:17:41 -07:00
Samantha 1f19eee55b
CA: Fix startup bug caused by ECDSA allow list reloader (#5412)
Solve a nil pointer dereference of `ecdsaAllowList` in `boulder-ca` by
calling `reloader.New()` in constructor `ca.NewECDSAAllowListFromFile`
instead.

- Add missing entry `ECDSAAllowListFilename` to
  `test/config-next/ca-a.json` and `test/config-next/ca-b.json`
- Add missing file ecdsaAllowList.yml to `test/config-next`
- Add missing entry `ECDSAAllowedAccounts` to `test/config/ca-a.json`
  and `test/config/ca-b.json`
- Move creation of the reloader to `NewECDSAAllowListFromFile`

Fixes #5414
2021-05-17 14:41:15 -07:00
Samantha 8912c7c24d
CA: Load and reload ECDSA allow list from a file (#5392)
- Add field `ECDSAAllowListFilename` to `config.CA`
- Move ECDSA allow list logic from `boulder-ca/main.go` to new file
  `ca/ecdsa_allow_list.go`
- Add field `ecdsaAllowList` to `certificateAuthorityImpl`
- Update units test to account for changes to `certificateAuthorityImpl`
- Move previous allow list unit tests to `TestDeprecatedECDSAAllowList`
- Add `TestECDSAAllowList` units tests

Fixes #5361
2021-05-10 13:19:46 -07:00
Aaron Gable 7bf854fe03
Move OCSP gRPC service to separate file and struct (#5402)
Create a new `ocspImpl` struct which satisfies the interface required
by the `OCSPGenerator` gRPC service. Move the `GenerateOCSP`
method from the `certificateAuthorityImpl` to this new type. To support
existing gRPC clients, keep a reference to the new OCSP service in
the CA impl, and maintain a pass-through `GenerateOCSP` method.
Simplify some of the CA setup code, and make the CA implementation
non-exported because it doesn't need to be.

In order to maintain our existing signature and sign error metrics,
they now need to be initialized outside the CA and OCSP constructors.
This complicates the tests slightly, but seems like a worthwhile
tradeoff.

Fixes #5226
Fixes #5086
2021-04-29 14:20:39 -07:00
Aaron Gable 30a516737c
Remove CertDER from GenerateOCSPRequest proto (#5388)
No clients nor servers use this field anymore, so it can safely
be removed without breaking deployability.

Fixes #5079
2021-04-20 10:13:51 -07:00
Aaron Gable b246d9cc45
Remove certDER OCSP generation code path from CA (#5117)
Only process OCSP generation requests which are identified
by the certificate's serial number and the ID (not NameID,
unfortunately) of its issuer. Delete the code path which handled
OCSP generation for requests identified by the full DER of
the certificate in question.

Update existing tests to use serial+id to request OCSP, and
move test cases from the old `TestGenerateOCSPWithIssuerID`
into the default test method.

Part of #5079
2021-04-09 16:08:05 -07:00
Jacob Hoffman-Andrews 7194624191
Update grpc and protobuf to latest. (#5369)
protoc now generates grpc code in a separate file from protobuf code.
Also, grpc servers are now required to embed an "unimplemented"
interface from the generated .pb.go file, which provides forward
compatibility.

Update the generate.go files since the invocation for protoc has changed
with the split into .pb.org and _grpc.pb.go.

Fixes #5368
2021-04-01 17:18:15 -07:00
Aaron Gable ef1d3c4cde
Standardize on `AssertMetricWithLabelsEquals` (#5371)
Update all of our tests to use `AssertMetricWithLabelsEquals`
instead of combinations of the older `CountFoo` helpers with
simple asserts. This coalesces all of our prometheus inspection
logic into a single function, allowing the deletion of four separate
helper functions.
2021-04-01 15:20:43 -07:00
Aaron Gable b4da43ea74
CA: add "issuer" label to signatureCount metric (#5370)
Add a new label, "issuer", to the `signatureCount` prometheus metric
which is exported by the CA. This allows us to separately monitor
signatures by the R3 and E1 intermediates, for all three kinds of
issuance we perform: precertificate, certificate, and ocsp. Add the
appropriate label value when incrementing this metric.

Also add a new `AssertMetricWithLabelsEquals` method to our test
helpers. This allows us to make assertions about the total value of
all metrics with a particular subset of labels set, rather than only
being able to make assertions about metrics which are parameterized by
only a single label. A follow-up change will migrate our usages of
CountCounterVec, CountCounter, and GaugeValueWithLabels to use this new
helper instead.

Fixes #5354
2021-04-01 11:00:30 -07:00
Andrew Gabbitas a718a9349d
Add waiting mock log writer (#5359)
Add a mock log buffer that is able to wait for a regex match in the
log buffer or timeout and error.

Fixes #5310
2021-04-01 10:53:21 -07:00
Aaron Gable 54b697d51b
Remove CFSSL helpers and dependency (#5349)
Replace the few instances where we were relying on CFSSL utilities: for
OIDs and "helper" methods (parsing private keys and parsing SCT lists)
with our own code. Then delete all vendored CFSSL code.

Based on #5347
Fixes #5115
2021-03-18 17:28:00 -07:00
Aaron Gable bfd3f83717
Remove CFSSL issuance path (#5347)
Make the `NonCFSSLSigner` code path the only code path through the CA.
Remove all code related to the old, CFSSL-based code path. Update tests
to supply (or mock) issuers of the new kind. Remove or simplify a few
tests that were testing for behavior only exhibited by the old code
path, such as incrementing certain metrics. Remove code from `//cmd/`
for initializing the CFSSL library. Finally, mark the `NonCFSSLSigner`
feature flag itself as deprecated.

Delete the portions of the vendored CFSSL code which were only used
by these deleted code paths. This does not remove the CFSSL library
entirely, the rest of the cleanup will follow shortly.

Part of #5115
2021-03-18 16:39:52 -07:00
Aaron Gable 68c393b081
CA: Create ECDSA issuance allowlist (#5258)
Currently, the CA is configured with a set of `internalIssuer`s,
and a mapping of public key algorithms (e.g. `x509.RSA`) to which
internalIssuer to use. In operation today, we use the same issuer
for all kinds of public key algorithms. In the future, we will use
different issuers for different algorithms (in particular, we will
use R3 to issue for RSA keys, and E1 to issue for ECDSA keys). But
we want to roll that out slowly, continuing to use our RSA issuer
to issue for all types of public keys, except for ECDSA keys which
are presented by a specific set of allowed accounts.

This change adds a new config field to the CA, which lets us specify
a small list of registration IDs which are allowed to have issuance
from our ECDSA issuer. If the config list is empty, then all accounts
are allowed. The CA checks to see if the key being issued for is
ECDSA: if it is, it then checks to make sure that the associated
registration ID is in the allowlist. If the account is not allowed,
it then overrides the issuance algorithm to use RSA instead,
mimicking our old behavior. It also adds a new feature flag, which
can be enabled to skip the allowlist entirely (effectively allowing
all registered accounts). This feature flag will be enabled when
we're done with our testing and confident in our ECDSA issuance.

Fixes #5259
2021-02-01 09:11:38 -08:00
Aaron Gable 400bf3a02a
Allow WFEv1 to specify which issuer to use (#5222)
We intend to delete the v1 API (i.e. `wfe` and its associated codepaths)
in the near future, and as such are not giving it new features or
capabilities. However, before then we intend to allow the v2 API to
provide issuance both from our RSA and from our ECDSA intermediates.
The v1 API cannot gain such capability at the same time.

The CA doesn't know which frontend originated any given issuance
request, so we can't simply gate the single- or double-issuer behavior
based on that. Instead, this change introduces the ability for the
WFE (and the RA, which sits between the WFE and the CA) to request
issuance from a specific intermediate. If the specified intermediate is
not available in the CA, issuance will fail. If no intermediate is
specified (as is the case in requests coming from wfe2), it falls back
to selecting the issuer based on the algorithm of the public key to
be signed.

Fixes #5216
2021-01-20 09:22:03 -08:00
Jacob Hoffman-Andrews 9464d025d1
Fix OCSP log queue blocking when maxLogLen = 0. (#5230)
Move responsibility for handling the default path (maxLogLen = 0)
from the ocspLogQueue component to CertificateAuthorityImpl. Now the
ocspLogQueue isn't constructed at all unless we configure it to be used.

Also, remove buffer from OCSP audit log chan. The bug this fixes was
hidden by the large buffer, and on reconsideration the large buffer was
unnecessary.

Verified that with the buffer removed, the integration test fails. Then
adding the fixes to the maxLogLen = 0 case fixes the integration test.

Fixes #5228
2021-01-15 11:32:00 -08:00
Jacob Hoffman-Andrews 8b9145838d
Add logging of OCSP generation events (#5223)
This adds a new component to the CA, ocspLogQueue, which batches up
OCSP generation events for audit logging. It will log accumulated
events when it reaches a certain line length, or when a maximum amount
of times has passed.
2021-01-12 15:31:49 -08:00
Aaron Gable f5982c6d44
Use IssuerNameID to get issuer from precertificate (#5217)
Today, when issuing a certificate based on a precertificate, we choose
the issuer based on algorithm: we find the precert's algorithm, look
it up in our table mapping algs to issuers, and then issue the final
cert from that issuer.

It is therefore hypothetically possible for the precertificate and
final certificate to be issued from different issuers, if the mapping
of algs to issuers were updated between precert and final cert issuance.
We don't expect this to be possible given Boulder's architecture, but
it could become possible given sufficient refactoring.

This change updates the lookup method to be based on the IssuerNameID,
which is a truncated hash computed across the whole Name field of the
issuer certificate (or equivalently across the Issuer field of the
issued precertificate). This ensures that final issuance will fail,
rather than have different issuers for the precert and final cert.

Part of #5216
2021-01-07 11:03:31 -08:00
Aaron Gable 294d1c31d7
Use error wrapping for berrors and tests (#5169)
This change adds two new test assertion helpers, `AssertErrorIs`
and `AssertErrorWraps`. The former is a wrapper around `errors.Is`,
and asserts that the error's wrapping chain contains a specific (i.e.
singleton) error. The latter is a wrapper around `errors.As`, and
asserts that the error's wrapping chain contains any error which is
of the given type; it also has the same unwrapping side effect as
`errors.As`, which can be useful for further assertions about the
contents of the error.

It also makes two small changes to our `berrors` package, namely
making `berrors.ErrorType` itself an error rather than just an int,
and giving `berrors.BoulderError` an `Unwrap()` method which
exposes that inner `ErrorType`. This allows us to use the two new
helpers above to make assertions about berrors, rather than
having to hand-roll equality assertions about their types.

Finally, it takes advantage of the two changes above to greatly
simplify many of the assertions in our tests, removing conditional
checks and replacing them with simple assertions.
2020-11-06 13:17:11 -08:00
Samantha 0f7a5121ed
ca: replacing error assertions with errors.As (#5134)
errors.As checks for a specific error in a wrapped error chain
(see https://golang.org/pkg/errors/#As) as opposed to asserting
that an error is of a specific type.

Part of #5010
2020-10-19 13:49:34 -07:00
Jacob Hoffman-Andrews cfe943fea5
Factor out idForIssuer. (#5102)
This was already part done: There is an ID() method in issuance. This
change extends that by:
 - Defining a type alias indicating something is an IssuerID.
 - Defining issuance.Certificate, which also has an ID() method,
   so that components that aren't the CA can load certificates and
   use the type system to mark them as issuers (and get their IDs).
 - Converting akamai-purger and ca to use the new types.
 - Removing idForIssuer from ca.go.
2020-10-06 15:04:43 -07:00
Aaron Gable 17e9e7fbb7
SA: Ensure that IssuerID is set when adding precertificates (#5099)
This change adds `req.IssuerID` to the set of fields that the SA's
`AddPrecertificate` method requires be non-zero.

As a result, this also updates many tests, both unit and integration,
to ensure that they supply a value (usually just 1) for that field. The
most complex part of the test changes is a slight refactoring to the
orphan-finder code, which makes it easier to reason about the
separation between log line parsing and building and sending the
request.

Based on #5096
Fixes #5097
2020-09-23 16:45:19 -07:00
Jacob Hoffman-Andrews 6f14be824d
ca: return better error on bad cert parse. (#5090)
Fixes #5078
2020-09-15 08:51:43 -07:00
Aaron Gable 2d10cce1a3
Refactor CA configs for more modularity (#5087)
The CA is the only service which still defines its json config format
in the package itself, rather than in its corresponding boulder-ca cmd
package. This has allowed the CA's constructor interface to hide
arbitrary complexity inside its first argument, the whole config blob.

This change moves the CA's config to boulder-ca/main.go, to match
the other Boulder components. In the process, it makes a host of
other improvements:

It refactors the issuance package to have a cleaner configuration
interface. It also separates the config into a high-level profile (which
applies equally to all issuers), and issuer-level profiles (which apply
only to a single issuer). This does involve some code duplication,
but that will be removed when CFSSL goes away.

It adds helper functions to the issuance package to make it easier
to construct a new issuer, and takes advantage of these in the
boulder-ca package. As a result, the CA now receives fully-formed
Issuers at construction time, rather than constructing them from
nearly-complete configs during its own initialization.

It adds a Linter struct to the lint package, so that an issuer can
simply carry around a Linter, rather than a separate lint signing
key and registry of lints to run.

It makes CFSSL-specific code more clearly marked as such,
making future removal easier and cleaner.

Fixes #5070
Fixes #5076
2020-09-14 18:38:12 -07:00
Aaron Gable d8a786ea08
Unify usage of 'issuer' and 'signer' as nouns (#5085)
We define a "signer" to be a private key, or something that satisfies the
crypto.Signer interface. We define an "issuer" to be an object which has
both a signer (so it can sign things) and a certificate (so that the things
it signs can have appropriate issuer fields set).

As a result, this change:
- moves the new "signer" library to be called "issuance" instead
- renames several "signers" to instead be "issuers", as defined above
- renames several "issuers" to instead be "certs", to reduce confusion more

There are some further cleanups which could be made, but most of them
will be made irrelevant by the removal of the CFSSL code, so I'm leaving
them be for now.
2020-09-10 17:18:42 -07:00
Aaron Gable 86c49278ac
CA: Set IssuerID when integrating orphaned certs (#5083)
There are two code paths which end up calling the SA's AddPrecertificate
RPC: one "normal" path from inside the CA's IssuePrecertificate
method, and one "exceptional" path from inside the orphan-integration
path which only gets executed if the initial attempt to store the cert
failed for some reason.

The first of these paths always sets the IssuerID in the RPC's
AddCertificateRequest. The latter of these paths never does.
Historically, this has been fine, as the SA has stored NULL in the
certificateStatus table when given a nil IssuerID, which matches the
behavior prior to the StoreIssuerInfo flag (when the IssuerID was
always nil, and cert status was tracked by full cert DER instead).

However, with the switch to proto3, the SA now interprets a nil
IssuerID as a 0, and stores that value in the table instead. The
ocsp-updater code which consumes rows of the certificateStatus table
is not able to properly handle IssuerIDs of 0, leading to fun times.

This change ensures that the orphan handling code also sets the
IssuerID when asking the SA to create a new certificateStatus row,
so we should stop producing new rows with a 0 IssuerID.
2020-09-09 09:51:31 -07:00