diff --git a/src/main/java/com/netspi/awssigner/signing/ParsedAuthHeader.java b/src/main/java/com/netspi/awssigner/signing/ParsedAuthHeader.java index 816d14d..c5b5d0d 100644 --- a/src/main/java/com/netspi/awssigner/signing/ParsedAuthHeader.java +++ b/src/main/java/com/netspi/awssigner/signing/ParsedAuthHeader.java @@ -15,7 +15,7 @@ public class ParsedAuthHeader { private static final String AUTH_HEADER_PATTERN_SERVICE_GROUP = "service"; private static final String AUTH_HEADER_PATTERN_SIGNED_HEADERS_GROUP = "signedheaders"; private static final String AUTH_HEADER_PATTERN_SIGNATURE_GROUP = "signature"; - private static final Pattern AUTH_HEADER_PATTERN = Pattern.compile("Authorization:\\s*(?<" + AUTH_HEADER_PATTERN_ALGORITHM_GROUP + ">AWS4-(?:HMAC|ECDSA-P256)-SHA256)\\s*Credential=(?<" + AUTH_HEADER_PATTERN_ACCESS_KEY_GROUP + ">[\\w-]{1,128})\\/(?<" + AUTH_HEADER_PATTERN_DATE_GROUP + ">\\d{8})\\/(?:(?<" + AUTH_HEADER_PATTERN_REGION_GROUP + ">[\\w-]{0,64})\\/)?(?<" + AUTH_HEADER_PATTERN_SERVICE_GROUP + ">\\S{0,128})\\/aws4_request(,|\\s)+SignedHeaders=(?<" + AUTH_HEADER_PATTERN_SIGNED_HEADERS_GROUP + ">\\S+)(,|\\s)+Signature=(?<" + AUTH_HEADER_PATTERN_SIGNATURE_GROUP + ">[a-fA-F\\d]{1,256})", Pattern.CASE_INSENSITIVE); + private static final Pattern AUTH_HEADER_PATTERN = Pattern.compile("Authorization:\\s*(?<" + AUTH_HEADER_PATTERN_ALGORITHM_GROUP + ">AWS4-(?:HMAC|ECDSA-P256)-SHA256)\\s*Credential=(?<" + AUTH_HEADER_PATTERN_ACCESS_KEY_GROUP + ">[\\w-]{1,128})\\/(?<" + AUTH_HEADER_PATTERN_DATE_GROUP + ">\\d{8})\\/(?:(?<" + AUTH_HEADER_PATTERN_REGION_GROUP + ">[\\w-]{0,64})\\/)?(?<" + AUTH_HEADER_PATTERN_SERVICE_GROUP + ">\\S{0,128})\\/aws4_request[,\\s]+SignedHeaders=(?<" + AUTH_HEADER_PATTERN_SIGNED_HEADERS_GROUP + ">\\S+?)[,\\s]+Signature=(?<" + AUTH_HEADER_PATTERN_SIGNATURE_GROUP + ">[a-fA-F\\d]{1,256})", Pattern.CASE_INSENSITIVE); private final SigningAlgorithm algorithm; private final String accessKey; diff --git a/src/test/java/com/netspi/awssigner/signing/ParsedAuthHeaderTest.java b/src/test/java/com/netspi/awssigner/signing/ParsedAuthHeaderTest.java new file mode 100644 index 0000000..fc5cc7b --- /dev/null +++ b/src/test/java/com/netspi/awssigner/signing/ParsedAuthHeaderTest.java @@ -0,0 +1,108 @@ +package com.netspi.awssigner.signing; + +import java.util.Optional; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class ParsedAuthHeaderTest { + + @Test + public void testTypical1CommaAnd1Space() { + String testHeader = "Authorization: AWS4-HMAC-SHA256 Credential=ASIAXXXXXXXXXXXXXXXX/20230901/us-east-1/XXXX/aws4_request SignedHeaders=content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target, Signature=64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464"; + //Parse the header + Optional result = ParsedAuthHeader.parseFromAuthorizationHeader(testHeader); + //Ensure it parsed successfully. + assertTrue(result.isPresent()); + //Extract the result + ParsedAuthHeader parsedHeader = result.get(); + + //Ensure all fields were extracted properly. + assertEquals(SigningAlgorithm.SIGV4,parsedHeader.getAlgorithm()); + assertEquals("ASIAXXXXXXXXXXXXXXXX",parsedHeader.getAccessKey()); + assertEquals("20230901",parsedHeader.getDate()); + assertEquals("us-east-1",parsedHeader.getRegion().get()); + assertEquals("XXXX",parsedHeader.getService()); + assertEquals("content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target",parsedHeader.getSignedHeaders()); + assertEquals("64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464",parsedHeader.getSignature()); + } + + @Test + public void testNoCommaAnd1Space() { + String testHeader = "Authorization: AWS4-HMAC-SHA256 Credential=ASIAXXXXXXXXXXXXXXXX/20230901/us-east-1/XXXX/aws4_request SignedHeaders=content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target Signature=64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464"; + //Parse the header + Optional result = ParsedAuthHeader.parseFromAuthorizationHeader(testHeader); + //Ensure it parsed successfully. + assertTrue(result.isPresent()); + //Extract the result + ParsedAuthHeader parsedHeader = result.get(); + + //Ensure all fields were extracted properly. + assertEquals(SigningAlgorithm.SIGV4,parsedHeader.getAlgorithm()); + assertEquals("ASIAXXXXXXXXXXXXXXXX",parsedHeader.getAccessKey()); + assertEquals("20230901",parsedHeader.getDate()); + assertEquals("us-east-1",parsedHeader.getRegion().get()); + assertEquals("XXXX",parsedHeader.getService()); + assertEquals("content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target",parsedHeader.getSignedHeaders()); + assertEquals("64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464",parsedHeader.getSignature()); + } + + @Test + public void test1CommaAndNoSpace() { + String testHeader = "Authorization: AWS4-HMAC-SHA256 Credential=ASIAXXXXXXXXXXXXXXXX/20230901/us-east-1/XXXX/aws4_request SignedHeaders=content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target,Signature=64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464"; + //Parse the header + Optional result = ParsedAuthHeader.parseFromAuthorizationHeader(testHeader); + //Ensure it parsed successfully. + assertTrue(result.isPresent()); + //Extract the result + ParsedAuthHeader parsedHeader = result.get(); + + //Ensure all fields were extracted properly. + assertEquals(SigningAlgorithm.SIGV4,parsedHeader.getAlgorithm()); + assertEquals("ASIAXXXXXXXXXXXXXXXX",parsedHeader.getAccessKey()); + assertEquals("20230901",parsedHeader.getDate()); + assertEquals("us-east-1",parsedHeader.getRegion().get()); + assertEquals("XXXX",parsedHeader.getService()); + assertEquals("content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target",parsedHeader.getSignedHeaders()); + assertEquals("64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464",parsedHeader.getSignature()); + } + @Test + public void testManyCommasAnd1Space() { + String testHeader = "Authorization: AWS4-HMAC-SHA256 Credential=ASIAXXXXXXXXXXXXXXXX/20230901/us-east-1/XXXX/aws4_request SignedHeaders=content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target,,,,,,,,,,,,, Signature=64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464"; + //Parse the header + Optional result = ParsedAuthHeader.parseFromAuthorizationHeader(testHeader); + //Ensure it parsed successfully. + assertTrue(result.isPresent()); + //Extract the result + ParsedAuthHeader parsedHeader = result.get(); + + //Ensure all fields were extracted properly. + assertEquals(SigningAlgorithm.SIGV4,parsedHeader.getAlgorithm()); + assertEquals("ASIAXXXXXXXXXXXXXXXX",parsedHeader.getAccessKey()); + assertEquals("20230901",parsedHeader.getDate()); + assertEquals("us-east-1",parsedHeader.getRegion().get()); + assertEquals("XXXX",parsedHeader.getService()); + assertEquals("content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target",parsedHeader.getSignedHeaders()); + assertEquals("64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464",parsedHeader.getSignature()); + } + @Test + public void testManyCommasAndNoSpace() { + String testHeader = "Authorization: AWS4-HMAC-SHA256 Credential=ASIAXXXXXXXXXXXXXXXX/20230901/us-east-1/XXXX/aws4_request SignedHeaders=content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target,,,,,,,,,,,,,Signature=64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464"; + //Parse the header + Optional result = ParsedAuthHeader.parseFromAuthorizationHeader(testHeader); + //Ensure it parsed successfully. + assertTrue(result.isPresent()); + //Extract the result + ParsedAuthHeader parsedHeader = result.get(); + + //Ensure all fields were extracted properly. + assertEquals(SigningAlgorithm.SIGV4,parsedHeader.getAlgorithm()); + assertEquals("ASIAXXXXXXXXXXXXXXXX",parsedHeader.getAccessKey()); + assertEquals("20230901",parsedHeader.getDate()); + assertEquals("us-east-1",parsedHeader.getRegion().get()); + assertEquals("XXXX",parsedHeader.getService()); + assertEquals("content-encoding;host;x-amz-date;x-amz-requestsupertrace;x-amz-target",parsedHeader.getSignedHeaders()); + assertEquals("64ed7bf1ee17050e2a38b4c878ca6471c341b78cdb428bcec52cc6b58f1a8464",parsedHeader.getSignature()); + } + + +}