Skip to content

Commit f71d2ea

Browse files
authored
WFE: Return err instead of prob from parseRevocation helper (#8076)
Change the wfe.parseRevocation function to return `error` instead of `probs.ProblemDetails`. This slightly changes some of our user-facing error messages to be more complete and verbose, thanks to how ProblemDetailsForError works. This is a building block towards making the probs.ProblemDetails type not implement the Error interface, and only be used when rendering errors to the user (i.e. not within Boulder logic itself). Part of #4980
1 parent d3669eb commit f71d2ea

File tree

2 files changed

+20
-28
lines changed

2 files changed

+20
-28
lines changed

wfe2/wfe.go

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -871,21 +871,21 @@ func (wfe *WebFrontEndImpl) NewAccount(
871871
// or revocation reason don't pass simple static checks. Also populates some
872872
// metadata fields on the given logEvent.
873873
func (wfe *WebFrontEndImpl) parseRevocation(
874-
jwsBody []byte, logEvent *web.RequestEvent) (*x509.Certificate, revocation.Reason, *probs.ProblemDetails) {
874+
jwsBody []byte, logEvent *web.RequestEvent) (*x509.Certificate, revocation.Reason, error) {
875875
// Read the revoke request from the JWS payload
876876
var revokeRequest struct {
877877
CertificateDER core.JSONBuffer `json:"certificate"`
878878
Reason *revocation.Reason `json:"reason"`
879879
}
880880
err := json.Unmarshal(jwsBody, &revokeRequest)
881881
if err != nil {
882-
return nil, 0, probs.Malformed("Unable to JSON parse revoke request")
882+
return nil, 0, berrors.MalformedError("Unable to JSON parse revoke request")
883883
}
884884

885885
// Parse the provided certificate
886886
parsedCertificate, err := x509.ParseCertificate(revokeRequest.CertificateDER)
887887
if err != nil {
888-
return nil, 0, probs.Malformed("Unable to parse certificate DER")
888+
return nil, 0, berrors.MalformedError("Unable to parse certificate DER")
889889
}
890890

891891
// Compute and record the serial number of the provided certificate
@@ -899,31 +899,23 @@ func (wfe *WebFrontEndImpl) parseRevocation(
899899
// issuer certificate.
900900
issuerCert, ok := wfe.issuerCertificates[issuance.IssuerNameID(parsedCertificate)]
901901
if !ok || issuerCert == nil {
902-
return nil, 0, probs.NotFound("Certificate from unrecognized issuer")
902+
return nil, 0, berrors.NotFoundError("Certificate from unrecognized issuer")
903903
}
904904
err = parsedCertificate.CheckSignatureFrom(issuerCert.Certificate)
905905
if err != nil {
906-
return nil, 0, probs.NotFound("No such certificate")
906+
return nil, 0, berrors.NotFoundError("No such certificate")
907907
}
908908
logEvent.DNSNames = parsedCertificate.DNSNames
909909

910910
if parsedCertificate.NotAfter.Before(wfe.clk.Now()) {
911-
return nil, 0, probs.Unauthorized("Certificate is expired")
911+
return nil, 0, berrors.UnauthorizedError("Certificate is expired")
912912
}
913913

914914
// Verify the revocation reason supplied is allowed
915915
reason := revocation.Reason(0)
916916
if revokeRequest.Reason != nil {
917917
if _, present := revocation.UserAllowedReasons[*revokeRequest.Reason]; !present {
918-
reasonStr, ok := revocation.ReasonToString[*revokeRequest.Reason]
919-
if !ok {
920-
reasonStr = "unknown"
921-
}
922-
return nil, 0, probs.BadRevocationReason(fmt.Sprintf(
923-
"unsupported revocation reason code provided: %s (%d). Supported reasons: %s",
924-
reasonStr,
925-
*revokeRequest.Reason,
926-
revocation.UserAllowedReasonsMessage))
918+
return nil, 0, berrors.BadRevocationReasonError(int64(*revokeRequest.Reason))
927919
}
928920
reason = *revokeRequest.Reason
929921
}
@@ -952,9 +944,9 @@ func (wfe *WebFrontEndImpl) revokeCertBySubscriberKey(
952944
return prob
953945
}
954946

955-
cert, reason, prob := wfe.parseRevocation(jwsBody, logEvent)
956-
if prob != nil {
957-
return prob
947+
cert, reason, err := wfe.parseRevocation(jwsBody, logEvent)
948+
if err != nil {
949+
return err
958950
}
959951

960952
wfe.log.AuditObject("Authenticated revocation", revocationEvidence{
@@ -967,7 +959,7 @@ func (wfe *WebFrontEndImpl) revokeCertBySubscriberKey(
967959
// The RA will confirm that the authenticated account either originally
968960
// issued the certificate, or has demonstrated control over all identifiers
969961
// in the certificate.
970-
_, err := wfe.ra.RevokeCertByApplicant(ctx, &rapb.RevokeCertByApplicantRequest{
962+
_, err = wfe.ra.RevokeCertByApplicant(ctx, &rapb.RevokeCertByApplicantRequest{
971963
Cert: cert.Raw,
972964
Code: int64(reason),
973965
RegID: acct.ID,
@@ -997,9 +989,9 @@ func (wfe *WebFrontEndImpl) revokeCertByCertKey(
997989
return prob
998990
}
999991

1000-
cert, reason, prob := wfe.parseRevocation(jwsBody, logEvent)
1001-
if prob != nil {
1002-
return prob
992+
cert, reason, err := wfe.parseRevocation(jwsBody, logEvent)
993+
if err != nil {
994+
return err
1003995
}
1004996

1005997
// For embedded JWK revocations we decide if a requester is able to revoke a specific
@@ -1019,7 +1011,7 @@ func (wfe *WebFrontEndImpl) revokeCertByCertKey(
10191011

10201012
// The RA assumes here that the WFE2 has validated the JWS as proving
10211013
// control of the private key corresponding to this certificate.
1022-
_, err := wfe.ra.RevokeCertByKey(ctx, &rapb.RevokeCertByKeyRequest{
1014+
_, err = wfe.ra.RevokeCertByKey(ctx, &rapb.RevokeCertByKeyRequest{
10231015
Cert: cert.Raw,
10241016
})
10251017
if err != nil {
@@ -1071,7 +1063,7 @@ func (wfe *WebFrontEndImpl) RevokeCertificate(
10711063
err = berrors.MalformedError("Malformed JWS, no KeyID or embedded JWK")
10721064
}
10731065
if err != nil {
1074-
wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "unable to revoke"), nil)
1066+
wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "Unable to revoke"), nil)
10751067
return
10761068
}
10771069

wfe2/wfe_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3246,7 +3246,7 @@ func TestRevokeCertificateNotIssued(t *testing.T) {
32463246
makePostRequestWithPath("revoke-cert", jwsBody))
32473247
// It should result in a 404 response with a problem body
32483248
test.AssertEquals(t, responseWriter.Code, 404)
3249-
test.AssertEquals(t, responseWriter.Body.String(), "{\n \"type\": \"urn:ietf:params:acme:error:malformed\",\n \"detail\": \"Certificate from unrecognized issuer\",\n \"status\": 404\n}")
3249+
test.AssertEquals(t, responseWriter.Body.String(), "{\n \"type\": \"urn:ietf:params:acme:error:malformed\",\n \"detail\": \"Unable to revoke :: Certificate from unrecognized issuer\",\n \"status\": 404\n}")
32503250
}
32513251

32523252
func TestRevokeCertificateExpired(t *testing.T) {
@@ -3271,7 +3271,7 @@ func TestRevokeCertificateExpired(t *testing.T) {
32713271
wfe.RevokeCertificate(ctx, newRequestEvent(), responseWriter,
32723272
makePostRequestWithPath("revoke-cert", jwsBody))
32733273
test.AssertEquals(t, responseWriter.Code, 403)
3274-
test.AssertEquals(t, responseWriter.Body.String(), "{\n \"type\": \"urn:ietf:params:acme:error:unauthorized\",\n \"detail\": \"Certificate is expired\",\n \"status\": 403\n}")
3274+
test.AssertEquals(t, responseWriter.Body.String(), "{\n \"type\": \"urn:ietf:params:acme:error:unauthorized\",\n \"detail\": \"Unable to revoke :: Certificate is expired\",\n \"status\": 403\n}")
32753275
}
32763276

32773277
func TestRevokeCertificateReasons(t *testing.T) {
@@ -3306,13 +3306,13 @@ func TestRevokeCertificateReasons(t *testing.T) {
33063306
Name: "Unsupported reason",
33073307
Reason: &reason2,
33083308
ExpectedHTTPCode: http.StatusBadRequest,
3309-
ExpectedBody: `{"type":"` + probs.ErrorNS + `badRevocationReason","detail":"unsupported revocation reason code provided: cACompromise (2). Supported reasons: unspecified (0), keyCompromise (1), superseded (4), cessationOfOperation (5)","status":400}`,
3309+
ExpectedBody: `{"type":"` + probs.ErrorNS + `badRevocationReason","detail":"Unable to revoke :: disallowed revocation reason: 2","status":400}`,
33103310
},
33113311
{
33123312
Name: "Non-existent reason",
33133313
Reason: &reason100,
33143314
ExpectedHTTPCode: http.StatusBadRequest,
3315-
ExpectedBody: `{"type":"` + probs.ErrorNS + `badRevocationReason","detail":"unsupported revocation reason code provided: unknown (100). Supported reasons: unspecified (0), keyCompromise (1), superseded (4), cessationOfOperation (5)","status":400}`,
3315+
ExpectedBody: `{"type":"` + probs.ErrorNS + `badRevocationReason","detail":"Unable to revoke :: disallowed revocation reason: 100","status":400}`,
33163316
},
33173317
}
33183318

0 commit comments

Comments
 (0)