Skip to content
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
53af9e2
EventLoopGroup
lauzadis Mar 1, 2024
10ab3c9
HostResolver
lauzadis Mar 1, 2024
9578b5b
ClientBootstrap
lauzadis Mar 1, 2024
c4e8b45
TlsContext
lauzadis Mar 1, 2024
5ad6270
.api
lauzadis Mar 1, 2024
4a3a139
Fix iOS linker errors
lauzadis Mar 1, 2024
7e83d28
Replace `runSuspendTest` with kotlinx coroutines `runTest`
lauzadis Mar 1, 2024
b7a09f9
String utils
lauzadis Mar 1, 2024
e2ac2cd
parseUri
lauzadis Mar 1, 2024
2b765e1
MutableBuffer
lauzadis Mar 4, 2024
5bac472
ktlint
lauzadis Mar 4, 2024
4e36539
close buffer
lauzadis Mar 4, 2024
7d33185
Remove common test
lauzadis Mar 4, 2024
2cdc67c
Fix compilation error
lauzadis Mar 4, 2024
ed53650
.api
lauzadis Mar 4, 2024
038269a
Disable native builds on Windows JVM CI
lauzadis Mar 4, 2024
2fec6ca
Correct flag
lauzadis Mar 4, 2024
a1f40f3
Try remove quotes
lauzadis Mar 4, 2024
fc15cf5
Revert flag to disable Kotlin Native on Windows CI (not respected)
lauzadis Mar 4, 2024
d992a8e
Remove "failed" from exception message
lauzadis Mar 4, 2024
3e9c435
Fix buffer clean up
lauzadis Mar 4, 2024
d0108ca
Write `minOf(length, writeRemaining)`
lauzadis Mar 4, 2024
fdd7092
Fill in `waitForShutdown`
lauzadis Mar 4, 2024
a00256b
remove println
lauzadis Mar 4, 2024
ded1b81
Lift return
lauzadis Mar 5, 2024
0c8422c
Merge branch 'kn-main' of github.com:awslabs/aws-crt-kotlin into kn-auth
lauzadis Mar 5, 2024
b759fb0
Push latest changes
lauzadis Mar 6, 2024
f01df1b
Push latest changes
lauzadis Mar 6, 2024
9ebeec0
Add `initFromCursor`
lauzadis Mar 7, 2024
52c1afb
latest commit
lauzadis Mar 12, 2024
6f28b9b
building
lauzadis Mar 12, 2024
8a297ed
Merge branch 'kn-main' of github.com:awslabs/aws-crt-kotlin into kn-auth
lauzadis Mar 12, 2024
fd959d8
remove my initFromCursor
lauzadis Mar 12, 2024
633a9d1
latest changes
lauzadis Mar 13, 2024
5058165
latest
lauzadis Mar 20, 2024
00460a6
latest
lauzadis Mar 25, 2024
66f3b3e
Merge branch 'kn-main' of github.com:awslabs/aws-crt-kotlin into kn-auth
lauzadis Apr 4, 2024
d9da555
revert native credentials providers
lauzadis Apr 4, 2024
c142899
also remove tests
lauzadis Apr 4, 2024
dfcca49
copy `toNativeCredentials`
lauzadis Apr 4, 2024
339494e
Replace use of `byValue`
lauzadis Apr 22, 2024
bdefe2d
latest signing
lauzadis Apr 24, 2024
d0f96e1
Parallelize Cmake builds
lauzadis Apr 25, 2024
535653e
aws_auth_library_init!!!
lauzadis Apr 25, 2024
3c49521
Set `bodyDone` to `true` after the body is successfully sent
lauzadis Apr 25, 2024
889bd1b
Latest signing tests based off kn-main
lauzadis Apr 25, 2024
9de307a
Native request `toHttpRequest`
lauzadis Apr 25, 2024
b279627
Native signer
lauzadis Apr 25, 2024
263bb84
Merge branch 'kn-main' of github.com:awslabs/aws-crt-kotlin into kn-auth
lauzadis Apr 25, 2024
d52605c
Replace newlines at end of file
lauzadis Apr 25, 2024
8182695
remove debug code
lauzadis Apr 25, 2024
8c80cfc
clean up
lauzadis Apr 25, 2024
5fde345
Remove flaky `lastError` test since it returns the latest error code …
lauzadis Apr 25, 2024
821fc4f
remove newline
lauzadis Apr 25, 2024
49918bc
Add cal.h and initialize the library
lauzadis Apr 25, 2024
f15aff6
remove debug comments
lauzadis Apr 25, 2024
c8a1b02
aws_cal_library_clean_up
lauzadis Apr 25, 2024
90e3c87
ktlint
lauzadis Apr 25, 2024
4666f24
Add a linting workflow
lauzadis Apr 25, 2024
b86d611
Create credentials once at initialization
lauzadis Apr 26, 2024
8f2ef4a
Remove unnecessary runBlocking
lauzadis Apr 26, 2024
59c9cc9
apiDump
lauzadis Apr 26, 2024
0f5a4f2
apiDump
lauzadis Apr 26, 2024
738217a
apiDump
lauzadis Apr 26, 2024
f4c6550
Add support for should_sign_header
lauzadis Apr 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
package aws.sdk.kotlin.crt.auth.signing

import aws.sdk.kotlin.crt.*
import aws.sdk.kotlin.crt.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.crt.auth.credentials.build
import aws.sdk.kotlin.crt.auth.credentials.Credentials
import aws.sdk.kotlin.crt.http.Headers
import aws.sdk.kotlin.crt.http.HttpRequest
import aws.sdk.kotlin.crt.http.HttpRequestBodyStream
Expand Down Expand Up @@ -55,182 +54,142 @@ class SigningTest : CrtTest() {
headers.append("Authorization", "example.amazonaws.com")
}

@Ignore // FIXME Enable when Kotlin/Native implementation is complete
@Test
fun testSigningSuccess() = runTest {
StaticCredentialsProvider.build {
accessKeyId = TEST_ACCESS_KEY_ID
secretAccessKey = TEST_SECRET_ACCESS_KEY
}.use { provider ->
val request = createSimpleRequest("https://www.example.com", "POST", "/derp", "<body>Hello</body>")
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = Platform.epochMilliNow()
credentialsProvider = provider
shouldSignHeader = { it != "bad-param" }
useDoubleUriEncode = true
normalizeUriPath = true
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)
assertTrue(signedRequest.headers.contains("X-Amz-Date"))
assertTrue(signedRequest.headers.contains("Authorization"))
val request = createSimpleRequest("https://www.example.com", "POST", "/derp", "<body>Hello</body>")
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = Platform.epochMilliNow()
credentials = Credentials(TEST_ACCESS_KEY_ID, TEST_SECRET_ACCESS_KEY, null)
shouldSignHeader = { it != "bad-param" }
useDoubleUriEncode = true
normalizeUriPath = true
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)
assertTrue(signedRequest.headers.contains("X-Amz-Date"))
assertTrue(signedRequest.headers.contains("Authorization"))
}

@Ignore // FIXME Enable when Kotlin/Native implementation is complete
@Test
fun testQuerySigningSuccess() = runTest {
StaticCredentialsProvider.build {
accessKeyId = TEST_ACCESS_KEY_ID
secretAccessKey = TEST_SECRET_ACCESS_KEY
}.use { provider ->
val request = createSigV4TestSuiteRequest()
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS
region = "us-east-1"
service = "service"
date = TEST_DATE_EPOCH_MILLI
credentialsProvider = provider
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
expirationInSeconds = 60
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)

val path = signedRequest.encodedPath
assertTrue(path.contains("X-Amz-Signature="), "`$path` did not contain expected signature")
assertTrue(path.contains("X-Amz-SignedHeaders=host"), "`$path` did not contain expected host")
assertTrue(path.contains("X-Amz-Credential=AKIDEXAMPLE%2F20150830%2F"), "`$path` did not contain expected credentials")
assertTrue(path.contains("X-Amz-Algorithm=AWS4-HMAC-SHA256"), "`$path` did not contain expected algorithm")
assertTrue(path.contains("X-Amz-Expires=60"), "`$path` did not contain expected expiration")
val request = createSigV4TestSuiteRequest()
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS
region = "us-east-1"
service = "service"
date = TEST_DATE_EPOCH_MILLI
credentials = Credentials(TEST_ACCESS_KEY_ID, TEST_SECRET_ACCESS_KEY, null)
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
expirationInSeconds = 60
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)

val path = signedRequest.encodedPath
assertTrue(path.contains("X-Amz-Signature="), "`$path` did not contain expected signature")
assertTrue(path.contains("X-Amz-SignedHeaders=host"), "`$path` did not contain expected host")
assertTrue(path.contains("X-Amz-Credential=AKIDEXAMPLE%2F20150830%2F"), "`$path` did not contain expected credentials")
assertTrue(path.contains("X-Amz-Algorithm=AWS4-HMAC-SHA256"), "`$path` did not contain expected algorithm")
assertTrue(path.contains("X-Amz-Expires=60"), "`$path` did not contain expected expiration")
}

@Ignore // FIXME Enable when Kotlin/Native implementation is complete
@Test
fun testSigningBasicSigV4() = runTest {
StaticCredentialsProvider.build {
accessKeyId = TEST_ACCESS_KEY_ID
secretAccessKey = TEST_SECRET_ACCESS_KEY
}.use { provider ->
val request = createSigV4TestSuiteRequest()
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = TEST_DATE_EPOCH_MILLI
credentialsProvider = provider
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
expirationInSeconds = 60
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)
assertTrue(signedRequest.headers.contains("X-Amz-Date", "20150830T123600Z"), "${signedRequest.headers}")
assertTrue(
signedRequest.headers.contains(
"Authorization",
"AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=28038455d6de14eafc1f9222cf5aa6f1a96197d7deb8263271d420d138af7f11",
),
"sigv4 authorization not equal: " + signedRequest.headers["Authorization"],
)
val request = createSigV4TestSuiteRequest()
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = TEST_DATE_EPOCH_MILLI
credentials = Credentials(TEST_ACCESS_KEY_ID, TEST_SECRET_ACCESS_KEY, null)
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
expirationInSeconds = 60
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)
assertTrue(signedRequest.headers.contains("X-Amz-Date", "20150830T123600Z"), "${signedRequest.headers}")
assertTrue(
signedRequest.headers.contains(
"Authorization",
"AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=28038455d6de14eafc1f9222cf5aa6f1a96197d7deb8263271d420d138af7f11",
),
"sigv4 authorization not equal: " + signedRequest.headers["Authorization"],
)
}

@Ignore // FIXME Enable when Kotlin/Native implementation is complete
@Test
fun testSigningFailureBadRequest() = runTest {
StaticCredentialsProvider.build {
accessKeyId = TEST_ACCESS_KEY_ID
secretAccessKey = TEST_SECRET_ACCESS_KEY
}.use { provider ->
val request = createUnsignableRequest("POST", "/bad")
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = Platform.epochMilliNow()
credentialsProvider = provider
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
}

val ex = assertFailsWith<CrtRuntimeException> {
AwsSigner.signRequest(request, signingConfig)
}
assertEquals("AWS_AUTH_SIGNING_ILLEGAL_REQUEST_HEADER", ex.errorName)
val request = createUnsignableRequest("POST", "/bad")
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = Platform.epochMilliNow()
credentials = Credentials(TEST_ACCESS_KEY_ID, TEST_SECRET_ACCESS_KEY, null)
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
}

val ex = assertFailsWith<CrtRuntimeException> {
AwsSigner.signRequest(request, signingConfig)
}
assertEquals("AWS_AUTH_SIGNING_ILLEGAL_REQUEST_HEADER", ex.errorName)
}

@Ignore // FIXME Enable when Kotlin/Native implementation is complete
@Test
fun testSigningSigV4Asymmetric() = runTest {
StaticCredentialsProvider.build {
accessKeyId = TEST_ACCESS_KEY_ID
secretAccessKey = TEST_SECRET_ACCESS_KEY
}.use { provider ->
val request = createSigV4TestSuiteRequest()
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4_ASYMMETRIC
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = TEST_DATE_EPOCH_MILLI
credentialsProvider = provider
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
expirationInSeconds = 60
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)
assertTrue(signedRequest.headers.contains("X-Amz-Date", "20150830T123600Z"), "${signedRequest.headers}")
val prefix = "AWS4-ECDSA-P256-SHA256 Credential=AKIDEXAMPLE/20150830/service/aws4_request, SignedHeaders=host;x-amz-date;x-amz-region-set, Signature="
assertTrue(signedRequest.headers["Authorization"]!!.contains(prefix), signedRequest.headers["Authorization"])
val request = createSigV4TestSuiteRequest()
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4_ASYMMETRIC
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS
region = "us-east-1"
service = "service"
date = TEST_DATE_EPOCH_MILLI
credentials = Credentials(TEST_ACCESS_KEY_ID, TEST_SECRET_ACCESS_KEY, null)
useDoubleUriEncode = true
normalizeUriPath = true
signedBodyValue = AwsSignedBodyValue.EMPTY_SHA256
expirationInSeconds = 60
}

val signedRequest = AwsSigner.signRequest(request, signingConfig)
assertTrue(signedRequest.headers.contains("X-Amz-Date", "20150830T123600Z"), "${signedRequest.headers}")
val prefix = "AWS4-ECDSA-P256-SHA256 Credential=AKIDEXAMPLE/20150830/service/aws4_request, SignedHeaders=host;x-amz-date;x-amz-region-set, Signature="
assertTrue(signedRequest.headers["Authorization"]!!.contains(prefix), signedRequest.headers["Authorization"])
}

@Ignore // FIXME Enable when Kotlin/Native implementation is complete
@Test
fun testSigningChunkTrailingHeaders() = runTest {
StaticCredentialsProvider.build {
accessKeyId = "AKID"
secretAccessKey = "SECRET"
}.use { provider ->

val creds = provider.getCredentials()

val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_TRAILING_HEADERS
region = "foo"
service = "bar"
date = 1651022625000
credentialsProvider = provider
credentials = creds
}

val trailingHeaders = Headers.build {
append("x-amz-checksum-crc32", "AAAAAA==")
append("x-amz-arbitrary-header-with-value", "test")
}

val previousSignature = "106d0654706e3e8dde144d69ca9882ea38d4d72576056c724ba763f8ed3074f3".encodeToByteArray()

val signature = AwsSigner.signChunkTrailer(trailingHeaders, previousSignature, signingConfig).signature.decodeToString()
val expectedSignature = "24f8ed01c7add645b75e65d2382fae5233b97526fdd1a2c4094933b93f6a08bf" // validated using DefaultAwsSigner
assertEquals(expectedSignature, signature)
val signingConfig = AwsSigningConfig.build {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_TRAILING_HEADERS
region = "foo"
service = "bar"
date = 1651022625000
credentials = Credentials(TEST_ACCESS_KEY_ID, TEST_SECRET_ACCESS_KEY, null)
}

val trailingHeaders = Headers.build {
append("x-amz-checksum-crc32", "AAAAAA==")
append("x-amz-arbitrary-header-with-value", "test")
}

val previousSignature = "106d0654706e3e8dde144d69ca9882ea38d4d72576056c724ba763f8ed3074f3".encodeToByteArray()

val signature = AwsSigner.signChunkTrailer(trailingHeaders, previousSignature, signingConfig).signature.decodeToString()
val expectedSignature = "8b578658fa1705d62bf26aa73e764ac4b705e6d9efd223a2d9e156580f085de4" // validated using DefaultAwsSigner
Copy link
Member Author

@lauzadis lauzadis Apr 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the expected signature changed due to different credentials being used, but I did check again with DefaultAwsSigner to ensure correctness

assertEquals(expectedSignature, signature)
}
}
}
9 changes: 8 additions & 1 deletion aws-crt-kotlin/native/interop/crt.def
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ headers = aws/common/allocator.h \
aws/http/request_response.h \
aws/http/proxy.h \
aws/compression/compression.h \
aws/auth/credentials.h \
aws/auth/signing.h \
aws/auth/signing_config.h \
aws/auth/signable.h \
aws/auth/signing_result.h \
aws/compression/compression.h \
aws/cal/hash.h \
aws/cal/cal.h \
aws/checksums/crc.h
headerFilter = aws/common/* aws/io/* aws/http/* aws/compression/* aws/cal/* aws/checksums/*
headerFilter = aws/common/* aws/io/* aws/http/* aws/compression/* aws/auth/* aws/checksums/* aws/cal/*

linkerOpts.osx = -framework Security
linkerOpts.ios = -framework Security
Expand Down
3 changes: 3 additions & 0 deletions aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/CRTNative.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public actual object CRT {
aws_compression_library_init(Allocator.Default)
aws_io_library_init(Allocator.Default)
aws_http_library_init(Allocator.Default)
aws_auth_library_init(Allocator.Default)
aws_cal_library_init(Allocator.Default)

Logging.initialize(config)
aws_register_log_subject_info_list(s_crt_log_subject_list.ptr)
Expand Down Expand Up @@ -110,6 +112,7 @@ private fun cleanup() {
aws_compression_library_clean_up()
aws_io_library_clean_up()
aws_common_library_clean_up()
aws_auth_library_clean_up()

s_crt_kotlin_clean_up()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,10 @@ package aws.sdk.kotlin.crt.auth.credentials
/**
* A credentials provider for a fixed set of credentials
*/
public actual class StaticCredentialsProvider internal actual constructor(builder: StaticCredentialsProviderBuilder) :
CredentialsProvider {
public actual class StaticCredentialsProvider internal actual constructor(private val builder: StaticCredentialsProviderBuilder) : CredentialsProvider {
public actual companion object {}

override suspend fun getCredentials(): Credentials {
TODO("Not yet implemented")
}

override fun close() {
TODO("Not yet implemented")
}

override suspend fun waitForShutdown() {
TODO("Not yet implemented")
}
override suspend fun getCredentials(): Credentials =
Credentials(builder.accessKeyId!!, builder.secretAccessKey!!, builder.sessionToken)
override fun close() { }
override suspend fun waitForShutdown() { }
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness: Typically, retaining a reference to a mutable builder is a bad idea since it means the values used by your supposedly-static provider can be changed after the fact:

val builder = StaticCredentialsProviderBuilder().apply {
    accessKeyId = "foo"
    secretAccessKey = "bar"
}
val built = builder.build()
println(built.getCredentials()) // foo/bar

builder.secretAccessKey = "baz"
println(built.getCredentials()) // foo/baz

We should either create the credentials once at initialization time or copy the builder values to local private members.

Loading