diff --git a/s3api/utils/utils.go b/s3api/utils/utils.go index 77723f3..7c5fd59 100644 --- a/s3api/utils/utils.go +++ b/s3api/utils/utils.go @@ -224,24 +224,17 @@ func IsBigDataAction(ctx *fiber.Ctx) bool { return false } +// expiration time window +// https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationTimeStamp +const timeExpirationSec = 15 * 60 + func ValidateDate(date time.Time) error { now := time.Now().UTC() diff := date.Unix() - now.Unix() - // Checks the dates difference to be less than a minute - if diff > 60 { - return s3err.APIError{ - Code: "SignatureDoesNotMatch", - Description: fmt.Sprintf("Signature not yet current: %s is still later than %s", date.Format(iso8601Format), now.Format(iso8601Format)), - HTTPStatusCode: http.StatusForbidden, - } - } - if diff < -60 { - return s3err.APIError{ - Code: "SignatureDoesNotMatch", - Description: fmt.Sprintf("Signature expired: %s is now earlier than %s", date.Format(iso8601Format), now.Format(iso8601Format)), - HTTPStatusCode: http.StatusForbidden, - } + // Checks the dates difference to be within allotted window + if diff > timeExpirationSec || diff < -timeExpirationSec { + return s3err.GetAPIError(s3err.ErrRequestTimeTooSkewed) } return nil diff --git a/s3err/s3err.go b/s3err/s3err.go index 35b7676..954904e 100644 --- a/s3err/s3err.go +++ b/s3err/s3err.go @@ -116,6 +116,7 @@ const ( ErrInvalidBucketObjectLockConfiguration ErrObjectLocked ErrPastObjectLockRetainDate + ErrRequestTimeTooSkewed // Non-AWS errors ErrExistingObjectIsDirectory @@ -430,6 +431,13 @@ var errorCodeResponse = map[ErrorCode]APIError{ Description: "the retain until date must be in the future", HTTPStatusCode: http.StatusBadRequest, }, + ErrRequestTimeTooSkewed: { + Code: "RequestTimeTooSkewed", + Description: "The difference between the request time and the server's time is too large.", + HTTPStatusCode: http.StatusForbidden, + }, + + // non aws errors ErrExistingObjectIsDirectory: { Code: "ExistingObjectIsDirectory", Description: "Existing Object is a directory.", diff --git a/tests/integration/tests.go b/tests/integration/tests.go index 56093e4..5d4111b 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -339,11 +339,8 @@ func Authentication_credentials_future_date(s *S3Conf) error { if resp.StatusCode != http.StatusForbidden { return fmt.Errorf("expected response status code to be %v, instead got %v", http.StatusForbidden, resp.StatusCode) } - if errResp.Code != "SignatureDoesNotMatch" { - return fmt.Errorf("expected error code to be %v, instead got %v", "SignatureDoesNotMatch", errResp.Code) - } - if !strings.Contains(errResp.Message, "Signature not yet current:") { - return fmt.Errorf("expected future date error message, instead got %v", errResp.Message) + if errResp.Code != "RequestTimeTooSkewed" { + return fmt.Errorf("expected error code to be %v, instead got %v", "RequestTimeTooSkewed", errResp.Code) } return nil @@ -383,11 +380,8 @@ func Authentication_credentials_past_date(s *S3Conf) error { if resp.StatusCode != http.StatusForbidden { return fmt.Errorf("expected response status code to be %v, instead got %v", http.StatusForbidden, resp.StatusCode) } - if errResp.Code != "SignatureDoesNotMatch" { - return fmt.Errorf("expected error code to be %v, instead got %v", "SignatureDoesNotMatch", errResp.Code) - } - if !strings.Contains(errResp.Message, "Signature expired:") { - return fmt.Errorf("expected past date error message, instead got %v", errResp.Message) + if errResp.Code != "RequestTimeTooSkewed" { + return fmt.Errorf("expected error code to be %v, instead got %v", "RequestTimeTooSkewed", errResp.Code) } return nil