Skip to content

Commit

Permalink
Fix for latest protobuf changes
Browse files Browse the repository at this point in the history
  • Loading branch information
pgporada committed Mar 4, 2024
1 parent b0ed65a commit 5204681
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 85 deletions.
85 changes: 37 additions & 48 deletions ca/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,21 +273,15 @@ func (ca *certificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
return nil, berrors.InternalServerError("Incomplete issue certificate request")
}

// TODO(#6966): Remove the outer nil check and assignment of
// *capb.CertificateProfile after the RA plumbs the certificate profile name
// from the WFE and SA.
if issueReq.CertProfile == nil {
// The CA must check if it is capable of issuing for the given
// certificate profile name. The name is checked here instead of the
// hash because the RA is unaware of what certificate profiles exist.
profileHashBytes, err := ca.certificateProfileNameExists(issuance.DefaultCertProfileName)
if err != nil {
return nil, err
}
issueReq.CertProfile = &capb.CertificateProfile{
Name: issuance.DefaultCertProfileName,
Hash: profileHashBytes[:],
}
// The CA must check if it is capable of issuing for the given
// certificate profile name. The name is checked here instead of the
// hash because the RA is unaware of what certificate profiles exist.
if issueReq.CertProfileName == "" {
issueReq.CertProfileName = issuance.DefaultCertProfileName
}
profileHashBytes, err := ca.certificateProfileNameExists(issueReq.CertProfileName)
if err != nil {
return nil, err
}

serialBigInt, validity, err := ca.generateSerialNumberAndValidity()
Expand Down Expand Up @@ -318,8 +312,8 @@ func (ca *certificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
}

return &capb.IssuePrecertificateResponse{
DER: precertDER,
CertProfile: issueReq.CertProfile,
DER: precertDER,
CertProfileHash: profileHashBytes[:],
}, nil
}

Expand Down Expand Up @@ -351,24 +345,21 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
return nil, berrors.InternalServerError("Incomplete cert for precertificate request")
}

// TODO(#6966): Remove this section after the RA plumbs the certificate
// profile name from the WFE and SA.
if req.CertProfile == nil {
// TODO(#6966): Remove this section after the RA passes the certificate
// profile hash in.
if req.CertProfileHash == nil {
profileHashBytes, err := ca.certificateProfileNameExists(issuance.DefaultCertProfileName)
if err != nil {
return nil, err
}
req.CertProfile = &capb.CertificateProfile{
Name: issuance.DefaultCertProfileName,
Hash: profileHashBytes[:],
}
req.CertProfileHash = profileHashBytes[:]
}

// The certificate profile hash is checked here instead of the name because
// the hash is over the entire contents of a *ProfileConfig which includes
// the name giving more assurance that the certificate profile has remained
// the name giving assurance that the certificate profile has remained
// unchanged during the roundtrip from a CA, to the RA, then back to a CA.
certProfile, err := ca.certificateProfileHashExists([32]byte(req.CertProfile.Hash))
certProfile, err := ca.certificateProfileHashExists([32]byte(req.CertProfileHash))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -407,16 +398,16 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
}

names := strings.Join(issuanceReq.DNSNames, ", ")
certProfileCountLabels := prometheus.Labels{"purpose": string(certType), "profile": req.CertProfile.Name, "hash": hex.EncodeToString(req.CertProfile.Hash)}
certProfileCountLabels := prometheus.Labels{"purpose": string(certType), "profile": certProfile.Name, "hash": hex.EncodeToString(req.CertProfileHash)}

ca.log.AuditInfof("Signing cert: serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%s] precert=[%s]",
serialHex, req.RegistrationID, names, req.CertProfile.Name, hex.EncodeToString(req.CertProfile.Hash), hex.EncodeToString(precert.Raw))
serialHex, req.RegistrationID, names, certProfile.Name, hex.EncodeToString(req.CertProfileHash), hex.EncodeToString(precert.Raw))

_, issuanceToken, err := issuer.Prepare(certProfile, issuanceReq)
if err != nil {
ca.certProfileCount.MustCurryWith(certProfileCountLabels).With(prometheus.Labels{"status": "preparation failure"}).Inc()
ca.log.AuditErrf("Preparing cert failed: serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%s] err=[%v]",
serialHex, req.RegistrationID, names, req.CertProfile.Name, hex.EncodeToString(req.CertProfile.Hash), err)
serialHex, req.RegistrationID, names, certProfile.Name, hex.EncodeToString(req.CertProfileHash), err)
return nil, berrors.InternalServerError("failed to prepare certificate signing: %s", err)
}

Expand All @@ -425,14 +416,14 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
ca.noteSignError(err)
ca.certProfileCount.MustCurryWith(certProfileCountLabels).With(prometheus.Labels{"status": "signing failure"}).Inc()
ca.log.AuditErrf("Signing cert failed: serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%s] err=[%v]",
serialHex, req.RegistrationID, names, req.CertProfile.Name, hex.EncodeToString(req.CertProfile.Hash), err)
serialHex, req.RegistrationID, names, certProfile.Name, hex.EncodeToString(req.CertProfileHash), err)
return nil, berrors.InternalServerError("failed to sign certificate: %s", err)
}

ca.certProfileCount.MustCurryWith(certProfileCountLabels).With(prometheus.Labels{"status": "success"}).Inc()
ca.signatureCount.With(prometheus.Labels{"purpose": string(certType), "issuer": issuer.Name()}).Inc()
ca.log.AuditInfof("Signing cert success: serial=[%s] regID=[%d] names=[%s] certificate=[%s] certProfileName=[%s] certProfileHash=[%s]",
serialHex, req.RegistrationID, names, hex.EncodeToString(certDER), req.CertProfile.Name, hex.EncodeToString(req.CertProfile.Hash))
serialHex, req.RegistrationID, names, hex.EncodeToString(certDER), certProfile.Name, hex.EncodeToString(req.CertProfileHash))

_, err = ca.sa.AddCertificate(ctx, &sapb.AddCertificateRequest{
Der: certDER,
Expand All @@ -441,7 +432,7 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
})
if err != nil {
ca.log.AuditErrf("Failed RPC to store at SA: serial=[%s] cert=[%s] issuerID=[%d] regID=[%d] orderID=[%d] certProfileName=[%s] certProfileHash=[%s] err=[%v]",
serialHex, hex.EncodeToString(certDER), issuer.NameID(), req.RegistrationID, req.OrderID, req.CertProfile.Name, hex.EncodeToString(req.CertProfile.Hash), err)
serialHex, hex.EncodeToString(certDER), issuer.NameID(), req.RegistrationID, req.OrderID, certProfile.Name, hex.EncodeToString(req.CertProfileHash), err)
return nil, err
}

Expand Down Expand Up @@ -507,17 +498,15 @@ func generateSKID(pk crypto.PublicKey) ([]byte, error) {
}

func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context, issueReq *capb.IssueCertificateRequest, serialBigInt *big.Int, validity validity) ([]byte, *issuance.Issuer, error) {
// TODO(#6966): Remove this section after the RA plumbs the certificate
// profile name from the WFE and SA.
if issueReq.CertProfile == nil {
profileHashBytes, err := ca.certificateProfileNameExists(issuance.DefaultCertProfileName)
if err != nil {
return nil, nil, err
}
issueReq.CertProfile = &capb.CertificateProfile{
Name: issuance.DefaultCertProfileName,
Hash: profileHashBytes[:],
}
// The CA must check if it is capable of issuing for the given
// certificate profile name. The name is checked here instead of the
// hash because the RA is unaware of what certificate profiles exist.
if issueReq.CertProfileName == "" {
issueReq.CertProfileName = issuance.DefaultCertProfileName
}
profileHashBytes, err := ca.certificateProfileNameExists(issueReq.CertProfileName)
if err != nil {
return nil, nil, err
}

csr, err := x509.ParseCertificateRequest(issueReq.Csr)
Expand Down Expand Up @@ -587,12 +576,12 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
// the hash is over the entire contents of a *ProfileConfig which includes
// the name giving more assurance that the certificate profile has remained
// unchanged during the roundtrip from a CA, to the RA, then back to a CA.
lintCertBytes, issuanceToken, err := issuer.Prepare(ca.certProfiles.byHash[[32]byte(issueReq.CertProfile.Hash)], req)
certProfileCountLabels := prometheus.Labels{"purpose": string(precertType), "profile": issueReq.CertProfile.Name, "hash": hex.EncodeToString(issueReq.CertProfile.Hash)}
lintCertBytes, issuanceToken, err := issuer.Prepare(ca.certProfiles.byHash[profileHashBytes], req)
certProfileCountLabels := prometheus.Labels{"purpose": string(precertType), "profile": issueReq.CertProfileName, "hash": hex.EncodeToString(profileHashBytes[:])}
if err != nil {
ca.certProfileCount.MustCurryWith(certProfileCountLabels).With(prometheus.Labels{"status": "preparation failure"}).Inc()
ca.log.AuditErrf("Preparing precert failed: serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%s] err=[%v]",
serialHex, issueReq.RegistrationID, strings.Join(csr.DNSNames, ", "), issueReq.CertProfile.Name, hex.EncodeToString(issueReq.CertProfile.Hash), err)
serialHex, issueReq.RegistrationID, strings.Join(csr.DNSNames, ", "), issueReq.CertProfileName, hex.EncodeToString(profileHashBytes[:]), err)
if errors.Is(err, linter.ErrLinting) {
ca.lintErrorCount.Inc()
}
Expand All @@ -615,14 +604,14 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
ca.noteSignError(err)
ca.certProfileCount.MustCurryWith(certProfileCountLabels).With(prometheus.Labels{"status": "signing failure"}).Inc()
ca.log.AuditErrf("Signing precert failed: serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%s] err=[%v]",
serialHex, issueReq.RegistrationID, strings.Join(csr.DNSNames, ", "), issueReq.CertProfile.Name, hex.EncodeToString(issueReq.CertProfile.Hash), err)
serialHex, issueReq.RegistrationID, strings.Join(csr.DNSNames, ", "), issueReq.CertProfileName, hex.EncodeToString(profileHashBytes[:]), err)
return nil, nil, berrors.InternalServerError("failed to sign precertificate: %s", err)
}

ca.signatureCount.With(prometheus.Labels{"purpose": string(precertType), "issuer": issuer.Name()}).Inc()
ca.certProfileCount.MustCurryWith(certProfileCountLabels).With(prometheus.Labels{"status": "success"}).Inc()
ca.log.AuditInfof("Signing precert success: serial=[%s] regID=[%d] names=[%s] precertificate=[%s] certProfileName=[%s] certProfileHash=[%s]",
serialHex, issueReq.RegistrationID, strings.Join(csr.DNSNames, ", "), hex.EncodeToString(certDER), issueReq.CertProfile.Name, hex.EncodeToString(issueReq.CertProfile.Hash))
serialHex, issueReq.RegistrationID, strings.Join(csr.DNSNames, ", "), hex.EncodeToString(certDER), issueReq.CertProfileName, hex.EncodeToString(profileHashBytes[:]))

return certDER, issuer, nil
}
69 changes: 32 additions & 37 deletions ca/ca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,23 +491,28 @@ func TestMultipleIssuers(t *testing.T) {
testCtx.fc)
test.AssertNotError(t, err, "Failed to remake CA")

selectedProfile := issuance.DefaultCertProfileName
certProfileHash, err := ca.certificateProfileNameExists(selectedProfile)
hexHash := hex.EncodeToString(certProfileHash[:])
test.AssertNotError(t, err, "Certificate profile was expected to exist")

// Test that an RSA CSR gets issuance from the RSA issuer.
issuedCert, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID})
issuedCert, err := ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, CertProfileName: selectedProfile})
test.AssertNotError(t, err, "Failed to issue certificate")
cert, err := x509.ParseCertificate(issuedCert.DER)
test.AssertNotError(t, err, "Certificate failed to parse")
err = cert.CheckSignatureFrom(testCtx.boulderIssuers[1].Cert.Certificate)
test.AssertNotError(t, err, "Certificate failed signature validation")
test.AssertMetricWithLabelsEquals(t, ca.certProfileCount, prometheus.Labels{"purpose": "precertificate", "profile": issuance.DefaultCertProfileName, "hash": "4598ba97d7b278a8ecf37eaf2416635cf32eab1616c8b4a2d612e2c30378a44b", "status": "success"}, 1)
test.AssertMetricWithLabelsEquals(t, ca.certProfileCount, prometheus.Labels{"purpose": "precertificate", "profile": selectedProfile, "hash": hexHash, "status": "success"}, 1)

// Test that an ECDSA CSR gets issuance from the ECDSA issuer.
issuedCert, err = ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID})
issuedCert, err = ca.IssuePrecertificate(ctx, &capb.IssueCertificateRequest{Csr: ECDSACSR, RegistrationID: arbitraryRegID, CertProfileName: selectedProfile})
test.AssertNotError(t, err, "Failed to issue certificate")
cert, err = x509.ParseCertificate(issuedCert.DER)
test.AssertNotError(t, err, "Certificate failed to parse")
err = cert.CheckSignatureFrom(testCtx.boulderIssuers[0].Cert.Certificate)
test.AssertNotError(t, err, "Certificate failed signature validation")
test.AssertMetricWithLabelsEquals(t, ca.certProfileCount, prometheus.Labels{"purpose": "precertificate", "profile": issuance.DefaultCertProfileName, "hash": "4598ba97d7b278a8ecf37eaf2416635cf32eab1616c8b4a2d612e2c30378a44b", "status": "success"}, 2)
test.AssertMetricWithLabelsEquals(t, ca.certProfileCount, prometheus.Labels{"purpose": "precertificate", "profile": selectedProfile, "hash": hexHash, "status": "success"}, 2)
}

func TestProfiles(t *testing.T) {
Expand Down Expand Up @@ -1012,20 +1017,15 @@ func TestIssueCertificateForPrecertificateWithSpecificCertificateProfile(t *test
test.AssertNotError(t, err, "Failed to create CA")

selectedProfile := "longerLived"
hash, err := ca.certificateProfileNameExists(selectedProfile)
hexHash := hex.EncodeToString(hash[:])
certProfileHash, err := ca.certificateProfileNameExists(selectedProfile)
hexHash := hex.EncodeToString(certProfileHash[:])
test.AssertNotError(t, err, "Certificate profile was expected to exist")

certProfile := &capb.CertificateProfile{
Name: selectedProfile,
Hash: hash[:],
}

issueReq := capb.IssueCertificateRequest{
Csr: CNandSANCSR,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfile: certProfile,
Csr: CNandSANCSR,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfileName: selectedProfile,
}
precert, err := ca.IssuePrecertificate(ctx, &issueReq)
test.AssertNotError(t, err, "Failed to issue precert")
Expand All @@ -1047,11 +1047,11 @@ func TestIssueCertificateForPrecertificateWithSpecificCertificateProfile(t *test

test.AssertNotError(t, err, "Failed to marshal SCT")
cert, err := ca.IssueCertificateForPrecertificate(ctx, &capb.IssueCertificateForPrecertificateRequest{
DER: precert.DER,
SCTs: sctBytes,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfile: certProfile,
DER: precert.DER,
SCTs: sctBytes,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfileHash: certProfileHash[:],
})
test.AssertNotError(t, err, "Failed to issue cert from precert")
parsedCert, err := x509.ParseCertificate(cert.Der)
Expand Down Expand Up @@ -1143,25 +1143,20 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
}

selectedProfile := issuance.DefaultCertProfileName
hash, err := ca.certificateProfileNameExists(selectedProfile)
hexHash := hex.EncodeToString(hash[:])
certProfileHash, err := ca.certificateProfileNameExists(selectedProfile)
hexHash := hex.EncodeToString(certProfileHash[:])
test.AssertNotError(t, err, "Certificate profile was expected to exist")

certProfile := &capb.CertificateProfile{
Name: selectedProfile,
Hash: hash[:],
}

issueReq := capb.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: arbitraryRegID, OrderID: 0}
precert, err := ca.IssuePrecertificate(ctx, &issueReq)
test.AssertNotError(t, err, "Failed to issue precert")
test.AssertMetricWithLabelsEquals(t, ca.certProfileCount, prometheus.Labels{"purpose": "precertificate", "profile": selectedProfile, "hash": hexHash, "status": "success"}, 1)
_, err = ca.IssueCertificateForPrecertificate(ctx, &capb.IssueCertificateForPrecertificateRequest{
DER: precert.DER,
SCTs: sctBytes,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfile: certProfile,
DER: precert.DER,
SCTs: sctBytes,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfileHash: certProfileHash[:],
})
if err == nil {
t.Error("Expected error issuing duplicate serial but got none.")
Expand Down Expand Up @@ -1196,11 +1191,11 @@ func TestIssueCertificateForPrecertificateDuplicateSerial(t *testing.T) {
test.AssertNotError(t, err, "Failed to create CA")

_, err = errorca.IssueCertificateForPrecertificate(ctx, &capb.IssueCertificateForPrecertificateRequest{
DER: precert.DER,
SCTs: sctBytes,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfile: certProfile,
DER: precert.DER,
SCTs: sctBytes,
RegistrationID: arbitraryRegID,
OrderID: 0,
CertProfileHash: certProfileHash[:],
})
if err == nil {
t.Fatal("Expected error issuing duplicate serial but got none.")
Expand Down

0 comments on commit 5204681

Please sign in to comment.