CA: Fix multi-profile deployability bug (#7422)

When https://github.com/letsencrypt/boulder/pull/7325 was deployed to
staging, the CA threw "Incomplete cert for precertificate request"
errors. Even though the RA was forwarding the CertProfileHash in all
IssueCertificateForPrecertificate requests to updated CA instances, it
can't do that if the IssuePrecertificate request was handled by a
non-updated CA instance that didn't yet know to return the hash.

This PR should be landed, tagged with a release, and then immediately
reverted for inclusion in the next release.

Part of https://github.com/letsencrypt/boulder/issues/6966
This commit is contained in:
Aaron Gable 2024-04-09 15:41:46 -07:00 committed by GitHub
parent 327f96d281
commit ebdabe693b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 13 additions and 1 deletions

View File

@ -346,10 +346,22 @@ func (ca *certificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
// serial number at the same time.
func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx context.Context, req *capb.IssueCertificateForPrecertificateRequest) (*corepb.Certificate, error) {
// issueReq.orderID may be zero, for ACMEv1 requests.
if core.IsAnyNilOrZero(req, req.DER, req.SCTs, req.RegistrationID, req.CertProfileHash) {
if core.IsAnyNilOrZero(req, req.DER, req.SCTs, req.RegistrationID) {
return nil, berrors.InternalServerError("Incomplete cert for precertificate request")
}
// The RA already provides the CertProfileHash to all
// IssueCertificateForPrecertificate calls... but it can only do that if the
// CA itself provided the hash in the IssuePrecertificate response. Therefore
// there can be a short period during the deploy where updated CAs which
// expect a profile hash aren't being provided with one.
if len(req.CertProfileHash) == 0 {
// This lookup will succeed because makeCertificateProfilesMap guarantees
// that the default name has a corresponding profile.
profile := ca.certProfiles.profileByName[ca.certProfiles.defaultName]
req.CertProfileHash = profile.hash[:]
}
// The certificate profile hash is checked here instead of the name because
// the hash is over the entire contents of a *ProfileConfig giving assurance
// that the certificate profile has remained unchanged during the roundtrip