Skip to content

Add managed SigV4a signer. #3923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
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
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ You can find the archive for _**legacy**_ Unity support at https://github.com/aw

This SDK has optional functionality that requires the [AWS Common Runtime (CRT)](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html)
bindings to be included as a dependency with your application. This functionality includes:
* [Amazon S3 Multi-Region Access Points](https://docs.aws.amazon.com/AmazonS3/latest/userguide/MultiRegionAccessPoints.html)
* [Amazon S3 Object Integrity](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html)
* Amazon EventBridge Global Endpoints

If the required AWS Common Runtime components are not installed you will receive an error like `Attempting to make a request that requires an implementation of AWS Signature V4a. Add a reference to the AWSSDK.Extensions.CrtIntegration NuGet package to your project to include the AWS Signature V4a signer.`,
If the required AWS Common Runtime components are not installed you will receive an error like `Attempting to handle a request that requires additional checksums. Add a reference to the AWSSDK.Extensions.CrtIntegration NuGet package to your project to include the AWS Common Runtime checksum implementation.`,
indicating that the required dependency is missing to use the associated functionality. To install this dependency follow
the provided [instructions](#installing-the-aws-common-runtime-crt-dependency).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using AWSSDK.Extensions.CrtIntegration;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
Expand All @@ -34,6 +35,7 @@ namespace Amazon.Extensions.CrtIntegration
/// <summary>
/// Asymmetric Sigv4 (SigV4a) protocol signer using the implementation provided by Aws.Crt.Auth
/// </summary>
[Obsolete("Use Amazon.Runtime.Internal.Auth.AWS4aSigner instead."), EditorBrowsable(EditorBrowsableState.Never)]
public class CrtAWS4aSigner : IAWSSigV4aProvider
{
/// <summary>
Expand Down
10 changes: 10 additions & 0 deletions generator/.DevConfigs/b495f893-31aa-4e17-866c-af78e4da6e8b.json
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might need to be updated to account for the fact that the S3 library needs a newer Core version. How to write this?

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"core": {
"updateMinimum": false,
"type": "patch",
"changeLogMessages": [
"Added AWS4aSigner class that implements SigV4a signing in managed code. AWS CRT is no longer used by the SDK for this purpose, and the related APIs were deprecated.",
"The AWS4aSigningResult.PresignedUri property was deprecated and will always be empty in objects returned by AWS4aSigner. Use the ForQueryParameters property instead, to get the query parameters for a presigned URL."
]
}
}
1 change: 1 addition & 0 deletions sdk/src/Core/AWSSDK.Core.NetFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@

<ItemGroup>
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.Formats.Asn1" Version="6.0.1" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<!-- Powershell (pwsh) will have a preloaded version of System.Text.Json that is older than
the version we will ship in core nuget packages and dlls, so we compile with an older version of STJ
Expand Down
7 changes: 6 additions & 1 deletion sdk/src/Core/AWSSDK.Core.NetStandard.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@
an older version of System.Text.Json. -->
<PackageReference Include="System.Text.Json" Version="6.0.11" />
</ItemGroup>
<Import Project="overrides.targets"/>
<ItemGroup Condition="'$(TargetFramework)' != 'net8.0'">
<!-- Version 8.x emits a warning about being unsupported on .NET Core 3.1, so we use 6.x.
Also, 6.0.0 has a vulnerability. -->
<PackageReference Include="System.Formats.Asn1" Version="6.0.1" />
</ItemGroup>
<Import Project="overrides.targets" />

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Amazon.Runtime.Internal.Util;
using Amazon.Util;
using System;
using System.Security.Cryptography;

namespace Amazon.Runtime
{
Expand Down Expand Up @@ -55,6 +56,14 @@ public class ImmutableCredentials
/// Account-based endpoints take the form https://accountid.ddb.region.amazonaws.com
/// </summary>
public string AccountId { get; private set; }

/// <summary>
/// Gets a cached AWS4a signing key for the current credentials.
/// </summary>
/// <remarks>
/// The key must not be disposed, and must not be returned to the user.
/// </remarks>
internal ECDsa AWS4aSigningKey { get; set; }
#endregion


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
* permissions and limitations under the License.
*/

using System.Threading;
using Amazon.Runtime.Identity;
using Amazon.Runtime.Internal.Auth;

Expand All @@ -25,7 +24,7 @@ namespace Amazon.Runtime.Credentials.Internal
/// </summary>
public class AwsV4aAuthScheme : IAuthScheme<AWSCredentials>
{
private static ISigner _signer;
private static readonly ISigner _signer = new AWS4aSigner();

/// <inheritdoc/>
public string SchemeId => AuthSchemeOption.SigV4A;
Expand All @@ -35,14 +34,6 @@ public IIdentityResolver GetIdentityResolver(IIdentityResolverConfiguration conf
=> configuration.GetIdentityResolver<AWSCredentials>();

/// <inheritdoc/>
public ISigner Signer()
{
if (_signer == null)
{
Interlocked.Exchange(ref _signer, new AWS4aSignerCRTWrapper());
}

return _signer;
}
public ISigner Signer() => _signer;
}
}
19 changes: 9 additions & 10 deletions sdk/src/Core/Amazon.Runtime/Internal/Auth/AWS4Signer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
Expand Down Expand Up @@ -31,7 +31,6 @@ namespace Amazon.Runtime.Internal.Auth
/// </summary>
public class AWS4Signer : AbstractAWSSigner
{

public const string Scheme = "AWS4";
public const string Algorithm = "HMAC-SHA256";
public const string Sigv4aAlgorithm = "ECDSA-P256-SHA256";
Expand Down Expand Up @@ -299,7 +298,7 @@ private static void CleanHeaders(IDictionary<string, string> headers)
}
}

private static void ValidateRequest(IRequest request)
internal static void ValidateRequest(IRequest request)
{
Uri url = request.Endpoint;

Expand Down Expand Up @@ -630,7 +629,7 @@ public static byte[] ComputeHash(byte[] data)
#endregion

#region Private Signing Helpers
static string SetPayloadSignatureHeader(IRequest request, string payloadHash)
internal static string SetPayloadSignatureHeader(IRequest request, string payloadHash)
{
if (request.Headers.ContainsKey(HeaderKeys.XAmzContentSha256Header))
request.Headers[HeaderKeys.XAmzContentSha256Header] = payloadHash;
Expand Down Expand Up @@ -704,7 +703,7 @@ public static string DetermineService(IClientConfig clientConfig, IRequest reque
/// will look for the hash as a header on the request.
/// </param>
/// <returns>Canonicalised request as a string</returns>
protected static string CanonicalizeRequest(Uri endpoint,
protected internal static string CanonicalizeRequest(Uri endpoint,
string resourcePath,
string httpMethod,
IDictionary<string, string> sortedHeaders,
Expand All @@ -728,7 +727,7 @@ protected static string CanonicalizeRequest(Uri endpoint,
/// will look for the hash as a header on the request.
/// </param>
/// <returns>Canonicalised request as a string</returns>
protected static string CanonicalizeRequest(Uri endpoint,
protected internal static string CanonicalizeRequest(Uri endpoint,
string resourcePath,
string httpMethod,
IDictionary<string, string> sortedHeaders,
Expand Down Expand Up @@ -761,7 +760,7 @@ protected static string CanonicalizeRequest(Uri endpoint,
/// </param>
/// <param name="doubleEncode">Encode "/" when canonicalize resource path</param>
/// <returns>Canonicalised request as a string</returns>
protected static string CanonicalizeRequest(Uri endpoint,
protected internal static string CanonicalizeRequest(Uri endpoint,
string resourcePath,
string httpMethod,
IDictionary<string, string> sortedHeaders,
Expand Down Expand Up @@ -866,7 +865,7 @@ protected internal static string CanonicalizeHeaders(IEnumerable<KeyValuePair<st
/// </summary>
/// <param name="sortedHeaders">The headers included in the signature</param>
/// <returns>Formatted string of header names</returns>
protected static string CanonicalizeHeaderNames(IEnumerable<KeyValuePair<string, string>> sortedHeaders)
protected internal static string CanonicalizeHeaderNames(IEnumerable<KeyValuePair<string, string>> sortedHeaders)
{
var builder = new ValueStringBuilder(512);

Expand All @@ -886,7 +885,7 @@ protected static string CanonicalizeHeaderNames(IEnumerable<KeyValuePair<string,
/// </summary>
/// <param name="request">The in-flight request being signed</param>
/// <returns>The fused set of parameters</returns>
protected static List<KeyValuePair<string, string>> GetParametersToCanonicalize(IRequest request)
protected internal static List<KeyValuePair<string, string>> GetParametersToCanonicalize(IRequest request)
{
var parametersToCanonicalize = new List<KeyValuePair<string, string>>();

Expand Down Expand Up @@ -968,7 +967,7 @@ protected static string CanonicalizeQueryParameters(string queryString, bool uri
return CanonicalizeQueryParameters(queryParams, uriEncodeParameters: uriEncodeParameters);
}

protected static string CanonicalizeQueryParameters(IEnumerable<KeyValuePair<string, string>> parameters)
protected internal static string CanonicalizeQueryParameters(IEnumerable<KeyValuePair<string, string>> parameters)
{
return CanonicalizeQueryParameters(parameters, true);
}
Expand Down
Loading