Skip to content

Commit

Permalink
Fix new reg GetRegistrationByKey error check (letsencrypt#3895)
Browse files Browse the repository at this point in the history
  • Loading branch information
Roland Bracewell Shoemaker authored and cpu committed Oct 22, 2018
1 parent 48103af commit c47993f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
10 changes: 6 additions & 4 deletions wfe/wfe.go
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,6 @@ func link(url, relation string) string {

// NewRegistration is used by clients to submit a new registration/account
func (wfe *WebFrontEndImpl) NewRegistration(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {

body, key, _, prob := wfe.verifyPOST(ctx, logEvent, request, false, core.ResourceNewReg)
addRequesterHeader(response, logEvent.Requester)
if prob != nil {
Expand All @@ -579,15 +578,18 @@ func (wfe *WebFrontEndImpl) NewRegistration(ctx context.Context, logEvent *web.R
return
}

if existingReg, err := wfe.SA.GetRegistrationByKey(ctx, key); err == nil {
existingReg, err := wfe.SA.GetRegistrationByKey(ctx, key)
if err != nil && !berrors.Is(err, berrors.NotFound) {
wfe.sendError(response, logEvent, probs.ServerInternal("couldn't retrieve the registration"), err)
return
} else if err == nil || !berrors.Is(err, berrors.NotFound) {
response.Header().Set("Location", web.RelativeEndpoint(request, fmt.Sprintf("%s%d", regPath, existingReg.ID)))
// TODO(#595): check for missing registration err
wfe.sendError(response, logEvent, probs.Conflict("Registration key is already in use"), err)
return
}

var init core.Registration
err := json.Unmarshal(body, &init)
err = json.Unmarshal(body, &init)
if err != nil {
wfe.sendError(response, logEvent, probs.Malformed("Error unmarshaling JSON"), err)
return
Expand Down
32 changes: 32 additions & 0 deletions wfe/wfe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -2499,3 +2500,34 @@ func TestNewCertificateSCTError(t *testing.T) {
responseWriter.Body.String(),
`{"type":"`+probs.V1ErrorNS+`serverInternal","detail":"Error creating new cert :: Unable to meet CA SCT embedding requirements","status":500}`)
}

type mockSAGetRegByKeyNotFoundAfterVerify struct {
core.StorageGetter
verified bool
}

func (sa *mockSAGetRegByKeyNotFoundAfterVerify) GetRegistrationByKey(ctx context.Context, jwk *jose.JSONWebKey) (core.Registration, error) {
if !sa.verified {
sa.verified = true
return sa.StorageGetter.GetRegistrationByKey(ctx, jwk)
}
return core.Registration{}, errors.New("broke")
}

// If GetRegistrationByKey returns a non berrors.NotFound error NewRegistration should fail
// out with an internal server error instead of continuing on and attempting to create a new
// account.
func TestNewRegistrationGetKeyBroken(t *testing.T) {
wfe, fc := setupWFE(t)
wfe.SA = &mockSAGetRegByKeyNotFoundAfterVerify{mocks.NewStorageAuthority(fc), false}
payload := `{"resource":"new-reg","contact":["mailto:[email protected]"],"agreement":"` + agreementURL + `"}`
responseWriter := httptest.NewRecorder()
wfe.NewRegistration(ctx, newRequestEvent(), responseWriter,
makePostRequest(signRequest(t, payload, wfe.nonceService)))
var prob probs.ProblemDetails
err := json.Unmarshal(responseWriter.Body.Bytes(), &prob)
test.AssertNotError(t, err, "unmarshalling response")
if prob.Type != probs.V1ErrorNS+probs.ServerInternalProblem {
t.Errorf("Wrong type for returned problem: %#v", prob.Type)
}
}

0 comments on commit c47993f

Please sign in to comment.