Skip to content

Commit

Permalink
wfe: remove authz-v3 and chall-v3 paths (#7904)
Browse files Browse the repository at this point in the history
This removes the `handlerPath` parameter to various calls, which was
used solely to distinguish the `-v3`-style paths from the `WithAccount`
paths.

Also, this removes `WithAccount` from all names that had it. The fact
that these URLS include an account ID is now implicit.
  • Loading branch information
jsha authored Dec 19, 2024
1 parent d42865c commit e8a49c5
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 466 deletions.
116 changes: 35 additions & 81 deletions wfe2/wfe.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,31 +50,24 @@ import (
// lowercase plus hyphens. If you violate that assumption you should update
// measured_http.
const (
directoryPath = "/directory"
newAcctPath = "/acme/new-acct"
acctPath = "/acme/acct/"
// When we moved to authzv2, we used a "-v3" suffix to avoid confusion
// regarding ACMEv2. More recently we moved back to using plain `/acme/authz/`
// and `/acme/chall/`, so the `-v3` paths are deprecated.
// TODO(#7683): Remove authz-v3 and chall-v3 once the new paths have been
// the default in prod for 30 days.
deprecatedAuthzPath = "/acme/authz-v3/"
authzPathWithAcct = "/acme/authz/"
deprecatedChallengePath = "/acme/chall-v3/"
challengePathWithAcct = "/acme/chall/"
certPath = "/acme/cert/"
revokeCertPath = "/acme/revoke-cert"
buildIDPath = "/build"
rolloverPath = "/acme/key-change"
newNoncePath = "/acme/new-nonce"
newOrderPath = "/acme/new-order"
orderPath = "/acme/order/"
finalizeOrderPath = "/acme/finalize/"
directoryPath = "/directory"
newAcctPath = "/acme/new-acct"
acctPath = "/acme/acct/"
authzPath = "/acme/authz/"
challengePath = "/acme/chall/"
certPath = "/acme/cert/"
revokeCertPath = "/acme/revoke-cert"
buildIDPath = "/build"
rolloverPath = "/acme/key-change"
newNoncePath = "/acme/new-nonce"
newOrderPath = "/acme/new-order"
orderPath = "/acme/order/"
finalizeOrderPath = "/acme/finalize/"

getAPIPrefix = "/get/"
getOrderPath = getAPIPrefix + "order/"
getAuthzPath = getAPIPrefix + "authz-v3/"
getChallengePath = getAPIPrefix + "chall-v3/"
getAuthzPath = getAPIPrefix + "authz/"
getChallengePath = getAPIPrefix + "chall/"
getCertPath = getAPIPrefix + "cert/"

// Draft or likely-to-change paths
Expand Down Expand Up @@ -435,15 +428,13 @@ func (wfe *WebFrontEndImpl) Handler(stats prometheus.Registerer, oTelHTTPOptions
// TODO(@cpu): After November 1st, 2020 support for "GET" to the following
// endpoints will be removed, leaving only POST-as-GET support.
wfe.HandleFunc(m, orderPath, wfe.GetOrder, "GET", "POST")
wfe.HandleFunc(m, deprecatedAuthzPath, wfe.DeprecatedAuthorizationHandler, "GET", "POST")
wfe.HandleFunc(m, authzPathWithAcct, wfe.AuthorizationHandler, "GET", "POST")
wfe.HandleFunc(m, deprecatedChallengePath, wfe.DeprecatedChallengeHandler, "GET", "POST")
wfe.HandleFunc(m, challengePathWithAcct, wfe.ChallengeHandler, "GET", "POST")
wfe.HandleFunc(m, authzPath, wfe.AuthorizationHandler, "GET", "POST")
wfe.HandleFunc(m, challengePath, wfe.ChallengeHandler, "GET", "POST")
wfe.HandleFunc(m, certPath, wfe.Certificate, "GET", "POST")
// Boulder-specific GET-able resource endpoints
wfe.HandleFunc(m, getOrderPath, wfe.GetOrder, "GET")
wfe.HandleFunc(m, getAuthzPath, wfe.DeprecatedAuthorizationHandler, "GET")
wfe.HandleFunc(m, getChallengePath, wfe.DeprecatedChallengeHandler, "GET")
wfe.HandleFunc(m, getAuthzPath, wfe.AuthorizationHandler, "GET")
wfe.HandleFunc(m, getChallengePath, wfe.ChallengeHandler, "GET")
wfe.HandleFunc(m, getCertPath, wfe.Certificate, "GET")

// Endpoint for draft-ietf-acme-ari
Expand Down Expand Up @@ -1089,22 +1080,6 @@ func (wfe *WebFrontEndImpl) RevokeCertificate(
response.WriteHeader(http.StatusOK)
}

// DeprecatedChallengeHandler handles POST requests to challenge URLs of the form /acme/chall-v3/<authorizationID>/<challengeID>.
// Such requests are clients' responses to the server's challenges.
func (wfe *WebFrontEndImpl) DeprecatedChallengeHandler(
ctx context.Context,
logEvent *web.RequestEvent,
response http.ResponseWriter,
request *http.Request) {
slug := strings.Split(request.URL.Path, "/")
if len(slug) != 2 {
wfe.sendError(response, logEvent, probs.NotFound("No such challenge"), nil)
return
}

wfe.Challenge(ctx, logEvent, deprecatedChallengePath, response, request, slug[0], slug[1])
}

// ChallengeHandler handles POST requests to challenge URLs of the form /acme/chall/{regID}/{authzID}/{challID}.
func (wfe *WebFrontEndImpl) ChallengeHandler(
ctx context.Context,
Expand All @@ -1117,14 +1092,13 @@ func (wfe *WebFrontEndImpl) ChallengeHandler(
return
}
// TODO(#7683): the regID is currently ignored.
wfe.Challenge(ctx, logEvent, challengePathWithAcct, response, request, slug[1], slug[2])
wfe.Challenge(ctx, logEvent, response, request, slug[1], slug[2])
}

// Challenge handles POSTS to both formats of challenge URLs.
func (wfe *WebFrontEndImpl) Challenge(
ctx context.Context,
logEvent *web.RequestEvent,
handlerPath string,
response http.ResponseWriter,
request *http.Request,
authorizationIDStr string,
Expand Down Expand Up @@ -1182,11 +1156,11 @@ func (wfe *WebFrontEndImpl) Challenge(
challenge := authz.Challenges[challengeIndex]
switch request.Method {
case "GET", "HEAD":
wfe.getChallenge(handlerPath, response, request, authz, &challenge, logEvent)
wfe.getChallenge(response, request, authz, &challenge, logEvent)

case "POST":
logEvent.ChallengeType = string(challenge.Type)
wfe.postChallenge(ctx, handlerPath, response, request, authz, challengeIndex, logEvent)
wfe.postChallenge(ctx, response, request, authz, challengeIndex, logEvent)
}
}

Expand All @@ -1212,16 +1186,12 @@ func prepAccountForDisplay(acct *core.Registration) {
// the client by filling in its URL field and clearing several unnecessary
// fields.
func (wfe *WebFrontEndImpl) prepChallengeForDisplay(
handlerPath string,
request *http.Request,
authz core.Authorization,
challenge *core.Challenge,
) {
// Update the challenge URL to be relative to the HTTP request Host
challenge.URL = web.RelativeEndpoint(request, fmt.Sprintf("%s%s/%s", deprecatedChallengePath, authz.ID, challenge.StringID()))
if handlerPath == challengePathWithAcct || handlerPath == authzPathWithAcct {
challenge.URL = web.RelativeEndpoint(request, fmt.Sprintf("%s%d/%s/%s", challengePathWithAcct, authz.RegistrationID, authz.ID, challenge.StringID()))
}
challenge.URL = web.RelativeEndpoint(request, fmt.Sprintf("%s%d/%s/%s", challengePath, authz.RegistrationID, authz.ID, challenge.StringID()))

// Internally, we store challenge error problems with just the short form
// (e.g. "CAA") of the problem type. But for external display, we need to
Expand All @@ -1244,9 +1214,9 @@ func (wfe *WebFrontEndImpl) prepChallengeForDisplay(

// prepAuthorizationForDisplay takes a core.Authorization and prepares it for
// display to the client by preparing all its challenges.
func (wfe *WebFrontEndImpl) prepAuthorizationForDisplay(handlerPath string, request *http.Request, authz *core.Authorization) {
func (wfe *WebFrontEndImpl) prepAuthorizationForDisplay(request *http.Request, authz *core.Authorization) {
for i := range authz.Challenges {
wfe.prepChallengeForDisplay(handlerPath, request, *authz, &authz.Challenges[i])
wfe.prepChallengeForDisplay(request, *authz, &authz.Challenges[i])
}

// Shuffle the challenges so no one relies on their order.
Expand All @@ -1268,15 +1238,14 @@ func (wfe *WebFrontEndImpl) prepAuthorizationForDisplay(handlerPath string, requ
}

func (wfe *WebFrontEndImpl) getChallenge(
handlerPath string,
response http.ResponseWriter,
request *http.Request,
authz core.Authorization,
challenge *core.Challenge,
logEvent *web.RequestEvent) {
wfe.prepChallengeForDisplay(handlerPath, request, authz, challenge)
wfe.prepChallengeForDisplay(request, authz, challenge)

authzURL := urlForAuthz(handlerPath, authz, request)
authzURL := urlForAuthz(authz, request)
response.Header().Add("Location", challenge.URL)
response.Header().Add("Link", link(authzURL, "up"))

Expand All @@ -1291,7 +1260,6 @@ func (wfe *WebFrontEndImpl) getChallenge(

func (wfe *WebFrontEndImpl) postChallenge(
ctx context.Context,
handlerPath string,
response http.ResponseWriter,
request *http.Request,
authz core.Authorization,
Expand Down Expand Up @@ -1320,7 +1288,7 @@ func (wfe *WebFrontEndImpl) postChallenge(
// challenge details, not a POST to initiate a challenge
if string(body) == "" {
challenge := authz.Challenges[challengeIndex]
wfe.getChallenge(handlerPath, response, request, authz, &challenge, logEvent)
wfe.getChallenge(response, request, authz, &challenge, logEvent)
return
}

Expand Down Expand Up @@ -1370,9 +1338,9 @@ func (wfe *WebFrontEndImpl) postChallenge(

// assumption: PerformValidation does not modify order of challenges
challenge := returnAuthz.Challenges[challengeIndex]
wfe.prepChallengeForDisplay(handlerPath, request, authz, &challenge)
wfe.prepChallengeForDisplay(request, authz, &challenge)

authzURL := urlForAuthz(handlerPath, authz, request)
authzURL := urlForAuthz(authz, request)
response.Header().Add("Location", challenge.URL)
response.Header().Add("Link", link(authzURL, "up"))

Expand Down Expand Up @@ -1538,15 +1506,6 @@ func (wfe *WebFrontEndImpl) deactivateAuthorization(
return true
}

// DeprecatedAuthorizationHandler handles requests to authorization URLs of the form /acme/authz/{authzID}.
func (wfe *WebFrontEndImpl) DeprecatedAuthorizationHandler(
ctx context.Context,
logEvent *web.RequestEvent,
response http.ResponseWriter,
request *http.Request) {
wfe.Authorization(ctx, deprecatedAuthzPath, logEvent, response, request, request.URL.Path)
}

// AuthorizationHandler handles requests to authorization URLs of the form /acme/authz/{regID}/{authzID}.
func (wfe *WebFrontEndImpl) AuthorizationHandler(
ctx context.Context,
Expand All @@ -1559,14 +1518,13 @@ func (wfe *WebFrontEndImpl) AuthorizationHandler(
return
}
// TODO(#7683): The regID is currently ignored.
wfe.Authorization(ctx, authzPathWithAcct, logEvent, response, request, slug[1])
wfe.Authorization(ctx, logEvent, response, request, slug[1])
}

// Authorization handles both `/acme/authz/{authzID}` and `/acme/authz/{regID}/{authzID}` requests,
// after the calling function has parsed out the authzID.
func (wfe *WebFrontEndImpl) Authorization(
ctx context.Context,
handlerPath string,
logEvent *web.RequestEvent,
response http.ResponseWriter,
request *http.Request,
Expand Down Expand Up @@ -1657,7 +1615,7 @@ func (wfe *WebFrontEndImpl) Authorization(
return
}

wfe.prepAuthorizationForDisplay(handlerPath, request, &authz)
wfe.prepAuthorizationForDisplay(request, &authz)

err = wfe.writeJsonResponse(response, logEvent, http.StatusOK, authz)
if err != nil {
Expand Down Expand Up @@ -2050,7 +2008,7 @@ func (wfe *WebFrontEndImpl) orderToOrderJSON(request *http.Request, order *corep
respObj.Error.Type = probs.ErrorNS + respObj.Error.Type
}
for _, v2ID := range order.V2Authorizations {
respObj.Authorizations = append(respObj.Authorizations, web.RelativeEndpoint(request, fmt.Sprintf("%s%d/%d", authzPathWithAcct, order.RegistrationID, v2ID)))
respObj.Authorizations = append(respObj.Authorizations, web.RelativeEndpoint(request, fmt.Sprintf("%s%d/%d", authzPath, order.RegistrationID, v2ID)))
}
if respObj.Status == core.StatusValid {
certURL := web.RelativeEndpoint(request,
Expand Down Expand Up @@ -2766,10 +2724,6 @@ func extractRequesterIP(req *http.Request) (net.IP, error) {
return net.ParseIP(host), nil
}

func urlForAuthz(handlerPath string, authz core.Authorization, request *http.Request) string {
if handlerPath == challengePathWithAcct || handlerPath == authzPathWithAcct {
return web.RelativeEndpoint(request, fmt.Sprintf("%s%d/%s", authzPathWithAcct, authz.RegistrationID, authz.ID))
}

return web.RelativeEndpoint(request, deprecatedAuthzPath+authz.ID)
func urlForAuthz(authz core.Authorization, request *http.Request) string {
return web.RelativeEndpoint(request, fmt.Sprintf("%s%d/%s", authzPath, authz.RegistrationID, authz.ID))
}
Loading

0 comments on commit e8a49c5

Please sign in to comment.