Skip to content

Commit 08a7ef8

Browse files
committed
Add SigV4aSignatureCalculatorTest
1 parent 29b34aa commit 08a7ef8

File tree

423 files changed

+2239
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

423 files changed

+2239
-0
lines changed

runtime/auth/aws-signing-default/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ kotlin {
1818
dependencies {
1919
implementation(project(":runtime:auth:aws-signing-tests"))
2020
implementation(libs.kotlinx.coroutines.test)
21+
implementation(libs.kotlinx.serialization.json)
2122
}
2223
}
2324

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package aws.smithy.kotlin.runtime.auth.awssigning
6+
7+
import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials
8+
import aws.smithy.kotlin.runtime.time.Instant
9+
import aws.smithy.kotlin.runtime.util.PlatformProvider
10+
import kotlinx.coroutines.test.runTest
11+
import kotlinx.serialization.json.Json
12+
import kotlinx.serialization.json.JsonObject
13+
import kotlinx.serialization.json.jsonObject
14+
import kotlin.test.Test
15+
import kotlin.test.assertEquals
16+
import kotlin.test.assertTrue
17+
18+
private const val SIGV4A_RESOURCES_BASE = "common/test/resources/sigv4a"
19+
20+
/**
21+
* Tests which are defined in resources/sigv4a
22+
*/
23+
private val TESTS = listOf(
24+
"get-header-key-duplicate",
25+
"get-header-value-multiline",
26+
"get-header-value-order",
27+
"get-header-value-trim",
28+
"get-relative-normalized",
29+
"get-relative-relative-normalized",
30+
"get-relative-relative-unnormalized",
31+
"get-relative-unnormalized",
32+
"get-slash-dot-slash-normalized",
33+
"get-slash-dot-slash-unnormalized",
34+
"get-slash-normalized",
35+
"get-slash-pointless-dot-normalized",
36+
"get-slash-pointless-dot-unnormalized",
37+
"get-slash-unnormalized",
38+
"get-slashes-normalized",
39+
"get-slashes-unnormalized",
40+
"get-space-normalized",
41+
"get-space-unnormalized",
42+
"get-unreserved",
43+
"get-utf8",
44+
"get-vanilla",
45+
"get-vanilla-empty-query-key",
46+
"get-vanilla-query",
47+
"get-vanilla-query-order-encoded",
48+
"get-vanilla-query-order-key-case",
49+
"get-vanilla-query-unreserved",
50+
"get-vanilla-utf8-query",
51+
"get-vanilla-with-session-token",
52+
"post-header-key-case",
53+
"post-header-key-sort",
54+
"post-header-value-case",
55+
"post-sts-header-after",
56+
"post-sts-header-before",
57+
"post-vanilla",
58+
"post-vanilla-empty-query-value",
59+
"post-vanilla-query",
60+
"post-x-www-form-urlencoded",
61+
"post-x-www-form-urlencoded-parameters",
62+
)
63+
64+
class SigV4aSignatureCalculatorTest {
65+
@Test
66+
fun testStringToSign() = TESTS.forEach { testId ->
67+
runTest {
68+
val testDir = "$SIGV4A_RESOURCES_BASE/$testId/"
69+
assertTrue(PlatformProvider.System.fileExists(testDir), "Failed to find test directory for $testId")
70+
71+
val context = Json.parseToJsonElement(testDir.fileContents("context.json")).jsonObject
72+
val signingConfig = context.parseAwsSigningConfig()
73+
74+
val expectedStringToSign = testDir.fileContents("header-string-to-sign.txt")
75+
val canonicalRequest = testDir.fileContents("header-canonical-request.txt")
76+
val actualStringToSign = SignatureCalculator.SigV4a.stringToSign(canonicalRequest, signingConfig)
77+
78+
assertEquals(expectedStringToSign, actualStringToSign)
79+
}
80+
}
81+
82+
private fun JsonObject.parseAwsSigningConfig(): AwsSigningConfig {
83+
fun JsonObject.getStringValue(key: String): String {
84+
val value = checkNotNull(get(key)) { "Failed to find key $key in JSON object $this" }
85+
return value.toString().replace("\"", "")
86+
}
87+
88+
val contextCredentials = checkNotNull(get("credentials")?.jsonObject) { "credentials unexpectedly null" }
89+
90+
val credentials = Credentials(
91+
contextCredentials.getStringValue("access_key_id"),
92+
contextCredentials.getStringValue("secret_access_key"),
93+
)
94+
95+
val region = getStringValue("region")
96+
val service = getStringValue("service")
97+
val signingDate = Instant.fromIso8601(getStringValue("timestamp"))
98+
99+
return AwsSigningConfig {
100+
algorithm = AwsSigningAlgorithm.SIGV4_ASYMMETRIC
101+
this.credentials = credentials
102+
this.region = region
103+
this.service = service
104+
this.signingDate = signingDate
105+
}
106+
}
107+
108+
private suspend fun String.fileContents(path: String): String = checkNotNull(PlatformProvider.System.readFileOrNull(this + path)?.decodeToString()) {
109+
"Unable to read contents at ${this + path}"
110+
}
111+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Copied directly from https://github.com/awslabs/aws-c-auth/tree/e8360a65e0f3337d4ac827945e00c3b55a641a5f/tests/aws-signing-test-suite/v4a.
2+
get-vanilla-query-order-key and get-vanilla-query-order-value were deleted since they are not complete tests.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"credentials": {
3+
"access_key_id": "AKIDEXAMPLE",
4+
"secret_access_key": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"
5+
},
6+
"expiration_in_seconds": 3600,
7+
"normalize": true,
8+
"region": "us-east-1",
9+
"service": "service",
10+
"sign_body": false,
11+
"timestamp": "2015-08-30T12:36:00Z"
12+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
GET
2+
/
3+
4+
host:example.amazonaws.com
5+
my-header1:value2,value2,value1
6+
x-amz-date:20150830T123600Z
7+
x-amz-region-set:us-east-1
8+
9+
host;my-header1;x-amz-date;x-amz-region-set
10+
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
304502204862ad283a21f883fc12f1156a6f3fcdbba13d1847e58aa5eb37c666477ea06b022100ee439fac0a975c9a6605b1fa44ad7b654a1f8ac6e868e4e1069a1b3aa35d8113
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
GET / HTTP/1.1
2+
Host:example.amazonaws.com
3+
My-Header1:value2
4+
My-Header1:value2
5+
My-Header1:value1
6+
X-Amz-Date:20150830T123600Z
7+
X-Amz-Region-Set:us-east-1
8+
Authorization:AWS4-ECDSA-P256-SHA256 Credential=AKIDEXAMPLE/20150830/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date;x-amz-region-set, Signature=30450220331da6dfebb0d19e5e161b1efa389ccb83cadb60bc71f6791ef71ac6054c44de0221008588b7d5c9f7a79ca9c02a02efbd0f540cda242a64ca1452aa914e050b517724
9+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
AWS4-ECDSA-P256-SHA256
2+
20150830T123600Z
3+
20150830/service/aws4_request
4+
30f1f7b639b7fd5982a0f700e6d23bf7bb24f2f1d9e1314005bf22130da61cdf
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"X":"b6618f6a65740a99e650b33b6b4b5bd0d43b176d721a3edfea7e7d2d56d936b1",
3+
"Y":"865ed22a7eadc9c5cb9d2cbaca1b3699139fedc5043dc6661864218330c8e518"
4+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
GET
2+
/
3+
X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-Expires=3600&X-Amz-Region-Set=us-east-1&X-Amz-SignedHeaders=host%3Bmy-header1
4+
host:example.amazonaws.com
5+
my-header1:value2,value2,value1
6+
7+
host;my-header1
8+
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

0 commit comments

Comments
 (0)