diff --git a/acme/api/eab.go b/acme/api/eab.go index 81af66060..8026ae829 100644 --- a/acme/api/eab.go +++ b/acme/api/eab.go @@ -57,21 +57,21 @@ func validateExternalAccountBinding(ctx context.Context, nar *NewAccountRequest) if errors.As(err, &ae) { return nil, acme.WrapError(acme.ErrorUnauthorizedType, err, "the field 'kid' references an unknown key") } - return nil, acme.WrapErrorISE(err, "error retrieving external account key") + return nil, acme.NewError(acme.ErrorEabDoesNotExistType, "error retrieving external account key") } if externalAccountKey == nil { return nil, acme.NewError(acme.ErrorUnauthorizedType, "the field 'kid' references an unknown key") } - if len(externalAccountKey.HmacKey) == 0 { - return nil, acme.NewError(acme.ErrorServerInternalType, "external account binding key with id '%s' does not have secret bytes", keyID) - } - if externalAccountKey.AlreadyBound() { return nil, acme.NewError(acme.ErrorUnauthorizedType, "external account binding key with id '%s' was already bound to account '%s' on %s", keyID, externalAccountKey.AccountID, externalAccountKey.BoundAt) } + if len(externalAccountKey.HmacKey) == 0 { + return nil, acme.NewError(acme.ErrorEabAlreadyUsedType, "external account binding key with id '%s' does not have secret bytes", keyID) + } + payload, err := eabJWS.Verify(externalAccountKey.HmacKey) if err != nil { return nil, acme.WrapErrorISE(err, "error verifying externalAccountBinding signature") diff --git a/acme/api/eab_test.go b/acme/api/eab_test.go index 14dbdad1f..ec1906dcd 100644 --- a/acme/api/eab_test.go +++ b/acme/api/eab_test.go @@ -312,7 +312,7 @@ func TestHandler_validateExternalAccountBinding(t *testing.T) { ExternalAccountBinding: eab, }, eak: nil, - err: acme.NewErrorISE("error retrieving external account key"), + err: acme.NewError(acme.ErrorEabDoesNotExistType, "error retrieving external account key"), } }, "fail/db.GetExternalAccountKey-not-found": func(t *testing.T) test { @@ -361,7 +361,7 @@ func TestHandler_validateExternalAccountBinding(t *testing.T) { ExternalAccountBinding: eab, }, eak: nil, - err: acme.NewErrorISE("error retrieving external account key"), + err: acme.NewError(acme.ErrorEabDoesNotExistType, "error retrieving external account key"), } }, "fail/db.GetExternalAccountKey-error": func(t *testing.T) test { @@ -410,7 +410,7 @@ func TestHandler_validateExternalAccountBinding(t *testing.T) { ExternalAccountBinding: eab, }, eak: nil, - err: acme.NewErrorISE("error retrieving external account key"), + err: acme.NewError(acme.ErrorEabDoesNotExistType, "error retrieving external account key"), } }, "fail/db.GetExternalAccountKey-nil": func(t *testing.T) test { @@ -516,7 +516,7 @@ func TestHandler_validateExternalAccountBinding(t *testing.T) { ExternalAccountBinding: eab, }, eak: nil, - err: acme.NewError(acme.ErrorServerInternalType, "external account binding key with id 'eakID' does not have secret bytes"), + err: acme.NewError(acme.ErrorEabAlreadyUsedType, "external account binding key with id 'eakID' does not have secret bytes"), } }, "fail/db.GetExternalAccountKey-wrong-provisioner": func(t *testing.T) test { diff --git a/acme/errors.go b/acme/errors.go index 658ec6e0c..ebd71e65b 100644 --- a/acme/errors.go +++ b/acme/errors.go @@ -65,6 +65,10 @@ const ( ErrorUserActionRequiredType // ErrorNotImplementedType operation is not implemented ErrorNotImplementedType + // ErrorEabAlreadyUsedType the external account binding has already been used + ErrorEabAlreadyUsedType + // ErrorEabDoesNotExistType the external account binding does not exist + ErrorEabDoesNotExistType ) // String returns the string representation of the acme problem type, @@ -121,6 +125,10 @@ func (ap ProblemType) String() string { return "userActionRequired" case ErrorNotImplementedType: return "notImplemented" + case ErrorEabAlreadyUsedType: + return "eabAlreadyUsed" + case ErrorEabDoesNotExistType: + return "eabDoesNotExist" default: return fmt.Sprintf("unsupported type ACME error type '%d'", int(ap)) } @@ -141,6 +149,16 @@ var ( status: 500, } errorMap = map[ProblemType]errorMetadata{ + ErrorEabAlreadyUsedType: { + typ: officialACMEPrefix + ErrorExternalAccountRequiredType.String(), + details: "The external account binding has already been used", + status: 400, + }, + ErrorEabDoesNotExistType: { + typ: officialACMEPrefix + ErrorExternalAccountRequiredType.String(), + details: "The used external account binding key id does not exist", + status: 400, + }, ErrorAccountDoesNotExistType: { typ: officialACMEPrefix + ErrorAccountDoesNotExistType.String(), details: "Account does not exist",