blob: a8cffbe55b55df058c4df349d089f5e08c97ccc6 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.ozone.s3.header;
import org.apache.hadoop.ozone.s3.exception.OS3Exception;
import org.apache.hadoop.test.LambdaTestUtils;
import org.junit.Before;
import org.junit.Test;
import java.time.LocalDate;
import static java.time.temporal.ChronoUnit.DAYS;
import static org.apache.hadoop.ozone.s3.AWSV4AuthParser.DATE_FORMATTER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* This class tests Authorization header format v2.
*/
public class TestAuthorizationHeaderV4 {
private String curDate;
@Before
public void setup() {
LocalDate now = LocalDate.now();
curDate = DATE_FORMATTER.format(now);
}
@Test
public void testV4HeaderWellFormed() throws Exception {
String auth = "AWS4-HMAC-SHA256 " +
"Credential=ozone/" + curDate + "/us-east-1/s3/aws4_request, " +
"SignedHeaders=host;range;x-amz-date, " +
"Signature=fe5f80f77d5fa3beca038a248ff027";
AuthorizationHeaderV4 v4 = new AuthorizationHeaderV4(auth);
assertEquals("AWS4-HMAC-SHA256", v4.getAlgorithm());
assertEquals("ozone", v4.getAccessKeyID());
assertEquals(curDate, v4.getDate());
assertEquals("us-east-1", v4.getAwsRegion());
assertEquals("aws4_request", v4.getAwsRequest());
assertEquals("host;range;x-amz-date", v4.getSignedHeaderString());
assertEquals("fe5f80f77d5fa3beca038a248ff027", v4.getSignature());
}
@Test
public void testV4HeaderMissingParts() {
try {
String auth = "AWS4-HMAC-SHA256 " +
"Credential=ozone/" + curDate + "/us-east-1/s3/aws4_request, " +
"SignedHeaders=host;range;x-amz-date,";
AuthorizationHeaderV4 v4 = new AuthorizationHeaderV4(auth);
fail("Exception is expected in case of malformed header");
} catch (OS3Exception ex) {
assertEquals("AuthorizationHeaderMalformed", ex.getCode());
}
}
@Test
public void testV4HeaderInvalidCredential() {
try {
String auth = "AWS4-HMAC-SHA256 " +
"Credential=" + curDate + "/us-east-1/s3/aws4_request, " +
"SignedHeaders=host;range;x-amz-date, " +
"Signature=fe5f80f77d5fa3beca038a248ff027";
AuthorizationHeaderV4 v4 = new AuthorizationHeaderV4(auth);
fail("Exception is expected in case of malformed header");
} catch (OS3Exception ex) {
assertEquals("AuthorizationHeaderMalformed", ex.getCode());
}
}
@Test
public void testV4HeaderWithoutSpace() throws OS3Exception {
String auth =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
AuthorizationHeaderV4 v4 = new AuthorizationHeaderV4(auth);
assertEquals("AWS4-HMAC-SHA256", v4.getAlgorithm());
assertEquals("ozone", v4.getAccessKeyID());
assertEquals(curDate, v4.getDate());
assertEquals("us-east-1", v4.getAwsRegion());
assertEquals("aws4_request", v4.getAwsRequest());
assertEquals("host;x-amz-content-sha256;x-amz-date",
v4.getSignedHeaderString());
assertEquals("fe5f80f77d5fa3beca038a248ff027", v4.getSignature());
}
@Test
public void testV4HeaderDateValidationSuccess() throws OS3Exception {
// Case 1: valid date within range.
LocalDate now = LocalDate.now();
String dateStr = DATE_FORMATTER.format(now);
validateResponse(dateStr);
// Case 2: Valid date with in range.
dateStr = DATE_FORMATTER.format(now.plus(1, DAYS));
validateResponse(dateStr);
// Case 3: Valid date with in range.
dateStr = DATE_FORMATTER.format(now.minus(1, DAYS));
validateResponse(dateStr);
}
@Test
public void testV4HeaderDateValidationFailure() throws Exception {
// Case 1: Empty date.
LocalDate now = LocalDate.now();
String dateStr = "";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> validateResponse(dateStr));
// Case 2: Date after yesterday.
String dateStr2 = DATE_FORMATTER.format(now.plus(2, DAYS));
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> validateResponse(dateStr2));
// Case 3: Date before yesterday.
String dateStr3 = DATE_FORMATTER.format(now.minus(2, DAYS));
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> validateResponse(dateStr3));
}
private void validateResponse(String dateStr) throws OS3Exception {
String auth =
"AWS4-HMAC-SHA256 Credential=ozone/" + dateStr + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
AuthorizationHeaderV4 v4 = new AuthorizationHeaderV4(auth);
assertEquals("AWS4-HMAC-SHA256", v4.getAlgorithm());
assertEquals("ozone", v4.getAccessKeyID());
assertEquals(dateStr, v4.getDate());
assertEquals("us-east-1", v4.getAwsRegion());
assertEquals("aws4_request", v4.getAwsRequest());
assertEquals("host;x-amz-content-sha256;x-amz-date",
v4.getSignedHeaderString());
assertEquals("fe5f80f77d5fa3beca038a248ff027", v4.getSignature());
}
@Test
public void testV4HeaderRegionValidationFailure() throws Exception {
String auth =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "//s3/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027%";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth));
String auth2 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "s3/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027%";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth2));
}
@Test
public void testV4HeaderServiceValidationFailure() throws Exception {
String auth =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1" +
"//aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth));
String auth2 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth2));
}
@Test
public void testV4HeaderRequestValidationFailure() throws Exception {
String auth =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/ ,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth));
String auth2 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth2));
String auth3 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
","
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth3));
}
@Test
public void testV4HeaderSignedHeaderValidationFailure() throws Exception {
String auth =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=;;,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth));
String auth2 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth2));
String auth3 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "=x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth3));
String auth4 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "=,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth4));
}
@Test
public void testV4HeaderSignatureValidationFailure() throws Exception {
String auth =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027%";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth));
String auth2 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth2));
String auth3 =
"AWS4-HMAC-SHA256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ ""
+ "=";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth3));
}
@Test
public void testV4HeaderHashAlgoValidationFailure() throws Exception {
String auth =
"AWS4-HMAC-SHA Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth));
String auth2 =
"SHA-256 Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth2));
String auth3 =
" Credential=ozone/" + curDate + "/us-east-1/s3" +
"/aws4_request,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth3));
}
@Test
public void testV4HeaderCredentialValidationFailure() throws Exception {
String auth =
"AWS4-HMAC-SHA Credential=/" + curDate + "//" +
"/,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth));
String auth2 =
"AWS4-HMAC-SHA =/" + curDate + "//" +
"/,"
+ "SignedHeaders=host;x-amz-content-sha256;x-amz-date,"
+ "Signature"
+ "=fe5f80f77d5fa3beca038a248ff027";
LambdaTestUtils.intercept(OS3Exception.class, "",
() -> new AuthorizationHeaderV4(auth2));
}
}