Skip to content

Commit 56db341

Browse files
committed
Cache SigV4a key in the ImmutableCredentials object.
1 parent f6c7cbe commit 56db341

File tree

4 files changed

+28
-20
lines changed

4 files changed

+28
-20
lines changed

sdk/src/Core/Amazon.Runtime/Credentials/ImmutableCredentials.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using Amazon.Runtime.Internal.Util;
1616
using Amazon.Util;
1717
using System;
18+
using System.Security.Cryptography;
1819

1920
namespace Amazon.Runtime
2021
{
@@ -55,6 +56,14 @@ public class ImmutableCredentials
5556
/// Account-based endpoints take the form https://accountid.ddb.region.amazonaws.com
5657
/// </summary>
5758
public string AccountId { get; private set; }
59+
60+
/// <summary>
61+
/// Gets a cached AWS4a signing key for the current credentials.
62+
/// </summary>
63+
/// <remarks>
64+
/// The key must not be disposed, and must not be returned to the user.
65+
/// </remarks>
66+
internal ECDsa AWS4aSigningKey { get; set; }
5867
#endregion
5968

6069

sdk/src/Core/Amazon.Runtime/Internal/Auth/AWS4aSigner.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,8 @@ public static AWS4aSigningResult ComputeSignature(ImmutableCredentials credentia
250250

251251
metrics?.AddProperty(Metric.StringToSign, stringToSignBuilder);
252252

253-
using var key = ComputeSigningKey(credentials);
254-
255253
var stringToSign = stringToSignBuilder.ToString();
256-
var signature = AWSSDKUtils.ToHex(SignBlob(key, stringToSign), true);
254+
var signature = AWSSDKUtils.ToHex(SignBlob(credentials, stringToSign), true);
257255
return new AWS4aSigningResult(credentials.AccessKey, signedAt, signedHeaders, scope, regionSet, signature, service, "", credentials);
258256
}
259257

@@ -309,9 +307,10 @@ private static int CompareConstantTime(byte[] lhs, byte[] rhs)
309307
/// <summary>
310308
/// Compute and return the signing key for the request.
311309
/// </summary>
312-
/// <param name="credentials">The credentials.</param>
310+
/// <param name="awsAccessKey">Access key credential.</param>
311+
/// <param name="awsSecretAccessKey">Secret access key credential.</param>
313312
/// <returns>Computed signing key</returns>
314-
public static ECDsa ComputeSigningKey(ImmutableCredentials credentials)
313+
public static ECDsa ComputeSigningKey(string awsAccessKey, string awsSecretAccessKey)
315314
{
316315
byte[] kvalue = null;
317316
byte[] ksecret = null;
@@ -328,7 +327,7 @@ public static ECDsa ComputeSigningKey(ImmutableCredentials credentials)
328327
idx += 4;
329328
idx += Encoding.UTF8.GetBytes(AWS4aAlgorithmTag, 0, AWS4aAlgorithmTag.Length, kvalue, idx);
330329
idx++;
331-
idx += Encoding.UTF8.GetBytes(credentials.AccessKey, 0, credentials.AccessKey.Length, kvalue, idx);
330+
idx += Encoding.UTF8.GetBytes(awsAccessKey, 0, awsAccessKey.Length, kvalue, idx);
332331
ref byte counterValue = ref kvalue[idx++];
333332
kvalue[idx + 2] = 1;
334333

@@ -366,22 +365,23 @@ public static ECDsa ComputeSigningKey(ImmutableCredentials credentials)
366365
}
367366

368367
/// <summary>
369-
/// Returns the ECDSA signature for an arbitrary blob using the specified key
368+
/// Returns the ECDSA signature for an arbitrary blob using the specified credentials.
370369
/// </summary>
371-
/// <param name="key">The key to use.</param>
370+
/// <param name="credentials">The credentials to use.</param>
372371
/// <param name="data">The data to sign.</param>
373-
public static byte[] SignBlob(ECDsa key, string data)
372+
public static byte[] SignBlob(ImmutableCredentials credentials, string data)
374373
{
375-
return SignBlob(key, Encoding.UTF8.GetBytes(data));
374+
return SignBlob(credentials, Encoding.UTF8.GetBytes(data));
376375
}
377376

378377
/// <summary>
379-
/// Returns the ECDSA signature for an arbitrary blob using the specified key
378+
/// Returns the ECDSA signature for an arbitrary blob using the specified credentials.
380379
/// </summary>
381-
/// <param name="key">The key to use.</param>
380+
/// <param name="credentials">The credentials to use.</param>
382381
/// <param name="data">The data to sign.</param>
383-
public static byte[] SignBlob(ECDsa key, byte[] data)
382+
public static byte[] SignBlob(ImmutableCredentials credentials, byte[] data)
384383
{
384+
var key = credentials.AWS4aSigningKey ??= ComputeSigningKey(credentials.AccessKey, credentials.SecretKey);
385385
return key.SignData(data, HashAlgorithmName.SHA256);
386386
}
387387
#endregion

sdk/src/Core/Amazon.Runtime/Internal/Util/ChunkedUploadWrapperStream.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,7 @@ private void ConstructOutputBufferChunk(int dataLen)
318318
string chunkSignature = "";
319319
if (HeaderSigningResult is AWS4aSigningResult v4aHeaderSigningResult)
320320
{
321-
using var signingKey = AWS4aSigner.ComputeSigningKey(v4aHeaderSigningResult.Credentials);
322-
chunkSignature = AWSSDKUtils.ToHex(AWS4aSigner.SignBlob(signingKey, chunkStringToSign), true);
321+
chunkSignature = AWSSDKUtils.ToHex(AWS4aSigner.SignBlob(v4aHeaderSigningResult.Credentials, chunkStringToSign), true);
323322
}
324323
else if (HeaderSigningResult is AWS4SigningResult v4HeaderSingingResult) // SigV4
325324
{
@@ -404,14 +403,14 @@ private string ConstructSignedTrailersChunk()
404403
AWSSDKUtils.ToHex(AWS4Signer.ComputeHash(canonicalizedTrailingHeaders), true);
405404

406405
string chunkSignature;
407-
if (HeaderSigningResult is AWS4SigningResult result)
406+
if (HeaderSigningResult is AWS4SigningResult aws4Result)
408407
{
409-
chunkSignature = AWSSDKUtils.ToHex(AWS4Signer.SignBlob(result.GetSigningKey(), chunkStringToSign), true);
408+
chunkSignature = AWSSDKUtils.ToHex(AWS4Signer.SignBlob(aws4Result.GetSigningKey(), chunkStringToSign), true);
410409
}
411410
else // SigV4a
412411
{
413-
using var signingKey = AWS4aSigner.ComputeSigningKey(((AWS4aSigningResult)HeaderSigningResult).Credentials);
414-
chunkSignature = AWSSDKUtils.ToHex(AWS4aSigner.SignBlob(signingKey, chunkStringToSign), true).PadRight(V4A_SIGNATURE_LENGTH, '*');
412+
var aws4aResult = (AWS4aSigningResult)HeaderSigningResult;
413+
chunkSignature = AWSSDKUtils.ToHex(AWS4aSigner.SignBlob(aws4aResult.Credentials, chunkStringToSign), true).PadRight(V4A_SIGNATURE_LENGTH, '*');
415414
}
416415

417416
var chunk = new StringBuilder();

sdk/src/Core/Amazon.Runtime/SharedInterfaces/IAWSSigV4aProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License").

0 commit comments

Comments
 (0)