public void CanonicalHeadersOrdinalCaseOrderedTest() { var signer = new AwsSigner(); var inputHeaders = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"), new KeyValuePair <string, string>("host", "iam.amazonaws.com"), new KeyValuePair <string, string>("X-AMZ-Date", "20150830T123600Z"), new KeyValuePair <string, string>("my-header1", "a b c"), new KeyValuePair <string, string>("My-header1", "\"a b c\"") }; var expectedBuilder = new StringBuilder(); expectedBuilder.Append("content-type:application/x-www-form-urlencoded; charset=utf-8\n"); expectedBuilder.Append("my-header1:\"a b c\"\n"); expectedBuilder.Append("x-amz-date:20150830T123600Z\n"); expectedBuilder.Append("host:iam.amazonaws.com\n"); expectedBuilder.Append("my-header1:a b c\n"); var expected = expectedBuilder.ToString(); var output = signer.BuildCanonicalHeaders(inputHeaders); Assert.AreEqual(expected, output, "Header builder failed"); }
public async Task CanonicalRequestCreatedHasherTest() { var signer = new AwsSigner(); var request = Helpers.CreateExampleRequest(); var inputBuilder = new StringBuilder(); inputBuilder.Append("GET\n"); inputBuilder.Append("/\n"); inputBuilder.Append("Action=ListUsers&Version=2010-05-08\n"); inputBuilder.Append("content-type:application/x-www-form-urlencoded; charset=utf-8\n"); inputBuilder.Append("host:iam.amazonaws.com\n"); inputBuilder.Append("x-amz-date:20150830T123600Z\n"); inputBuilder.Append("\n"); inputBuilder.Append("content-type;host;x-amz-date\n"); inputBuilder.Append("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); var canonicalRequest = await signer.BuildCanonicalRequest(request); Assert.AreEqual(inputBuilder.ToString(), canonicalRequest, "Request are not equal"); var output = signer.HashText(canonicalRequest); const string expected = "f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59"; Assert.AreEqual(expected, output, "Hash content failed"); }
public async Task CanonicalRequestBuilderTest() { var signer = new AwsSigner(); var request = Helpers.CreateExampleRequest(); request.Headers.Add("DifficultContent", "This & That + Something = the rest"); var canonicalRequest = await signer.BuildCanonicalRequest(request); var expectedBuilder = new StringBuilder(); expectedBuilder.Append("GET\n"); expectedBuilder.Append("/\n"); expectedBuilder.Append("Action=ListUsers&Version=2010-05-08\n"); expectedBuilder.Append("content-type:application/x-www-form-urlencoded; charset=utf-8\n"); // The names should be lower cased and then ordered so DifficultContent should be second expectedBuilder.Append("difficultcontent:This & That + Something = the rest\n"); expectedBuilder.Append("host:iam.amazonaws.com\n"); expectedBuilder.Append("x-amz-date:20150830T123600Z\n"); expectedBuilder.Append("\n"); expectedBuilder.Append("content-type;difficultcontent;host;x-amz-date\n"); expectedBuilder.Append("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); var expected = expectedBuilder.ToString(); Assert.AreEqual(expected, canonicalRequest); }
private static void Send() { var config = new AwsConfig { Region = "eu-west-1", Service = "ses", AccessId = "<ACCESSID>", Secret = "<SECRET>" }; var from = "*****@*****.**"; var to = "*****@*****.**"; var request = new HttpRequestMessage { Method = HttpMethod.Get, // Optional content //Content = new StringContent(string.Empty, Encoding.UTF8, "application/x-www-form-urlencoded"), RequestUri = new Uri($"https://email.eu-west-1.amazonaws.com?Action=SendEmail&Source={from}&Destination.ToAddresses.member.1={to}&Message.Subject.Data=AmazonMail&Message.Body.Text.Data=SigningTest&ConfigurationSetName=ExtraInfo") }; AwsSigner.SignRequest(config, request).GetAwaiter().GetResult(); var client = new HttpClient(); var result = client.SendAsync(request).GetAwaiter().GetResult(); result.EnsureSuccessStatusCode(); Console.WriteLine("All good"); }
public void SignCanonicalRequestByHeaders() { var config = BuildBaseSigningConfig(); config.SignedBodyHeader = AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA256; config.SignatureType = AwsSignatureType.CANONICAL_REQUEST_VIA_HEADERS; var canonicalRequest = String.Join("\n", "POST", "/", "", "content-length:13", "content-type:application/x-www-form-urlencoded", "host:example.amazonaws.com", "x-amz-content-sha256:9095672bbd1f56dfc5b65f3e153adc8731a4a654192329106275f4c7b24d0b6e", "x-amz-date:20150830T123600Z", "", "content-length;content-type;host;x-amz-content-sha256;x-amz-date", "9095672bbd1f56dfc5b65f3e153adc8731a4a654192329106275f4c7b24d0b6e"); CrtResult <String> result = AwsSigner.SignCanonicalRequest(canonicalRequest, config); String signatureValue = result.Get(); Assert.Equal("d3875051da38690788ef43de4db0d8f280229d82040bfac253562e56c3f20e0b", signatureValue); }
public void TestChunkedRequest() { var signer = new CrtAWS4aSigner(); var request = BuildMockChunkedRequest(); var clientConfig = BuildSigningClientConfig(SigningTestService); var headerResult = signer.SignRequest(request, clientConfig, null, SigningTestCredentials); var config = BuildDefaultSigningConfig(SigningTestService); config.SignatureType = AwsSignatureType.CANONICAL_REQUEST_VIA_HEADERS; config.SignedBodyValue = AWS4Signer.V4aStreamingBodySha256; Assert.True(AwsSigner.VerifyV4aCanonicalSigning(GetExpectedCanonicalRequestForChunkedSigningTest(), config, headerResult.Signature, SigningTestEccPubX, SigningTestEccPubY)); var chunk1Result = signer.SignChunk(CreateChunkStream(Chunk1Size), headerResult.Signature, headerResult); Assert.True(AwsSigner.VerifyV4aSignature(BuildV4aChunkedStringToSignHelper(headerResult, headerResult.Signature, Chunk1Size), Encoding.ASCII.GetBytes(chunk1Result), SigningTestEccPubX, SigningTestEccPubY)); var chunk2Result = signer.SignChunk(CreateChunkStream(Chunk2Size), chunk1Result, headerResult); Assert.True(AwsSigner.VerifyV4aSignature(BuildV4aChunkedStringToSignHelper(headerResult, chunk1Result, Chunk2Size), Encoding.ASCII.GetBytes(chunk2Result), SigningTestEccPubX, SigningTestEccPubY)); var chunk3Result = signer.SignChunk(null, chunk2Result, headerResult); Assert.True(AwsSigner.VerifyV4aSignature(BuildV4aChunkedStringToSignHelper(headerResult, chunk2Result, 0), Encoding.ASCII.GetBytes(chunk3Result), SigningTestEccPubX, SigningTestEccPubY)); }
public void CanonicalQueryStringBuilderEncodingTest() { const string input = "[email protected]&Version=2010-05-08&Action=ListUsers&bA=ab"; const string expected = "Action=ListUsers&Email=thomas.bruggink%40infosupport.com&Version=2010-05-08&bA=ab"; var signer = new AwsSigner(); var output = signer.BuildCanonicalQueryString(input); Assert.AreEqual(expected, output, "Query String builder failed"); }
public void CanonicalQueryStringBuilderOrdinalTest() { const string input = "Version=2010-05-08&Action=ListUsers&bA=ab"; const string expected = "Action=ListUsers&Version=2010-05-08&bA=ab"; var signer = new AwsSigner(); var output = signer.BuildCanonicalQueryString(input); Assert.AreEqual(expected, output, "Query String builder failed"); }
public void CanonicalUriBuilderTest() { var signer = new AwsSigner(); var request = Helpers.CreateExampleRequest(); const string expected = "/api/documents%20and%20settings"; request.RequestUri = new Uri("https://myhost.com/api/documents and settings?query=path"); var output = signer.BuildCanonicalUri(request); Assert.AreEqual(expected, output, "Uri builder failed"); }
public async Task PayloadHashContentTest() { var signer = new AwsSigner(); var content = new StringContent("Hello World!", Encoding.UTF8, "text/plain"); const string expected = "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"; var output = await signer.HashPayload(content); Assert.AreEqual(expected, output, "Payload hash failed"); }
public void CreateSigningKey() { var signer = new AwsSigner(); var config = Helpers.CreateExampleConfig(); const string expected = "c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9"; var dateTime = DateTimeOffset.Parse("2015-08-30T12:36:00Z"); var result = signer.CreateSigningKey(config.Secret, dateTime, config.Region, config.Service); // Convert the result to hex string just to compare // In the actual world this stays a byte array Assert.AreEqual(expected, signer.ToHexString(result), "Create signing key failed"); }
public void PayloadHashTest() { var signer = new AwsSigner(); var inputBuilder = new StringBuilder(); inputBuilder.Append(""); const string expected = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; var output = signer.HashText(inputBuilder.ToString()); Assert.AreEqual(expected, output, "Payload hash failed"); }
/// <summary> /// Signs one chunk of a request when transferring a payload using multiple chunks /// </summary> /// <param name="chunkBody">Content of the current chunk to sign</param> /// <param name="previousSignature">Signature of the previously signed chunk</param> /// <param name="headerSigningResult">Signing result for the "seed" signature consisting of headers</param> /// <returns>Signature of the current chunk</returns> public string SignChunk(Stream chunkBody, string previousSignature, AWS4aSigningResult headerSigningResult) { var signingConfig = PrepareCRTSigningConfig(AwsSignatureType.HTTP_REQUEST_CHUNK, headerSigningResult); signingConfig.SignedBodyHeader = AwsSignedBodyHeaderType.NONE; // The previous signature may be padded with '*' up to 144 characters, which is used // when actually sending a chunk but not when calculating the next chunk's signature. previousSignature = previousSignature.TrimEnd('*'); var signingResult = AwsSigner.SignChunk(chunkBody, Encoding.UTF8.GetBytes(previousSignature), signingConfig); return(Encoding.UTF8.GetString(signingResult.Get().Signature)); }
public void SignBodylessRequestByHeaders() { var config = BuildBaseSigningConfig(); var request = BuildTestSuiteRequestWithoutBody(); CrtResult <HttpRequest> result = AwsSigner.SignHttpRequest(request, config); HttpRequest signedRequest = result.Get(); Assert.Equal("GET", signedRequest.Method); Assert.Equal("/?Param-3=Value3&Param=Value2&%E1%88%B4=Value1", signedRequest.Uri); Assert.Equal(3, signedRequest.Headers.Length); Assert.True(HasHeader(signedRequest, "Host", "example.amazonaws.com")); Assert.True(HasHeader(signedRequest, "X-Amz-Date", "20150830T123600Z")); Assert.True(HasHeader(signedRequest, "Authorization", "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=371d3713e185cc334048618a97f809c9ffe339c62934c032af5a0e595648fcac")); }
public async Task CreateAuthorizationHeader() { var signer = new AwsSigner(); var config = Helpers.CreateExampleConfig(); var request = Helpers.CreateExampleRequest(); var dateTime = DateTimeOffset.Parse("2015-08-30T12:36:00Z"); var signedHeaders = signer.BuildSignedHeaders(signer.BuildCanonicalHeaders(request)); const string expected = "Credential=AKIDEXAMPLE/20150830/us-east-1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7"; var signature = await signer.CreateSignature(config, request, dateTime); var result = signer.CreateAuthorizationHeader(config.AccessId, dateTime, config.Region, config.Service, signedHeaders, signature); Assert.AreEqual(expected, result, "Authorization string creation failed"); }
public async Task CreateSignature() { var signer = new AwsSigner(); var config = Helpers.CreateExampleConfig(); var request = Helpers.CreateExampleRequest(); const string expected = "5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7"; var dateTime = DateTimeOffset.Parse("2015-08-30T12:36:00Z"); var signingKey = signer.CreateSigningKey(config.Secret, dateTime, config.Region, config.Service); var signString = await signer.CreateSignString(config.Region, config.Service, request, dateTime); var result = signer.CreateSignature(signingKey, signString); Assert.AreEqual(expected, result, "Create signature failed"); }
/// <summary> /// Signs the final chunk containing trailing headers /// </summary> /// <param name="trailingHeaders">Trailing header keys and values</param> /// <param name="previousSignature">Signature of the previously signed chunk</param> /// <param name="headerSigningResult">Signing result for the "seed" signature consisting of headers</param> /// <returns>Signature of the trailing header chunk</returns> public string SignTrailingHeaderChunk(IDictionary <string, string> trailingHeaders, string previousSignature, AWS4aSigningResult headerSigningResult) { var signingConfig = PrepareCRTSigningConfig(AwsSignatureType.HTTP_REQUEST_TRAILING_HEADERS, headerSigningResult); signingConfig.SignedBodyHeader = AwsSignedBodyHeaderType.NONE; var headerArray = trailingHeaders.Select(kvp => new HttpHeader(kvp.Key, kvp.Value)).ToArray(); // The previous signature may be padded with '*' up to 144 characters, which is used // when actually sending a chunk but not when calculating the next chunk's signature. previousSignature = previousSignature.TrimEnd('*'); var signingResult = AwsSigner.SignTrailingHeaders(headerArray, Encoding.UTF8.GetBytes(previousSignature), signingConfig); return(Encoding.UTF8.GetString(signingResult.Get().Signature)); }
/// /// <summary> /// Calculates the signature for the specified request using the Asymmetric SigV4 /// signing protocol in preparation for generating a presigned URL. /// </summary> /// <param name="request"> /// The request to compute the signature for. Additional headers mandated by the /// SigV4a protocol will be added to the request before signing. /// </param> /// <param name="clientConfig"> /// Client configuration data encompassing the service call (notably authentication /// region, endpoint and service name). /// </param> /// <param name="metrics">Metrics for the request</param> /// <param name="credentials">The AWS credentials for the account making the service call</param> /// <param name="service">Service to sign the request for</param> /// <param name="overrideSigningRegion">Region to sign the request for</param> /// <returns>AWS4aSigningResult for the given request</returns> public AWS4aSigningResult Presign4a(IRequest request, IClientConfig clientConfig, RequestMetrics metrics, ImmutableCredentials credentials, string service, string overrideSigningRegion) { var signedAt = AWS4Signer.InitializeHeaders(request.Headers, request.Endpoint); var regionSet = overrideSigningRegion ?? AWS4Signer.DetermineSigningRegion(clientConfig, service, request.AlternateEndpoint, request); var signingConfig = PrepareCRTSigningConfig(AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS, regionSet, service, signedAt, credentials); if (AWS4PreSignedUrlSigner.ServicesUsingUnsignedPayload.Contains(service)) { signingConfig.SignedBodyValue = AWS4Signer.UnsignedPayload; } else { signingConfig.SignedBodyValue = AWS4Signer.EmptyBodySha256; } // The expiration may have already be set in a header when marshalling the GetPreSignedUrlRequest -> IRequest if (request.Parameters != null && request.Parameters.ContainsKey(HeaderKeys.XAmzExpires)) { signingConfig.ExpirationInSeconds = Convert.ToUInt64(request.Parameters[HeaderKeys.XAmzExpires]); } var crtRequest = CrtHttpRequestConverter.ConvertToCrtRequest(request); var signingResult = AwsSigner.SignHttpRequest(crtRequest, signingConfig); string authorizationValue = Encoding.Default.GetString(signingResult.Get().Signature); var dateStamp = AWS4Signer.FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateFormat); var scope = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}", dateStamp, service, AWS4Signer.Terminator); AWS4aSigningResult result = new AWS4aSigningResult( credentials.AccessKey, signedAt, CrtHttpRequestConverter.ExtractSignedHeaders(signingResult.Get().SignedRequest), scope, regionSet, authorizationValue, service, signingResult.Get().SignedRequest.Uri, credentials); return(result); }
public void SignBodylessRequestByQuery() { var config = BuildBaseSigningConfig(); config.SignatureType = AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS; config.ExpirationInSeconds = 3600; var request = BuildTestSuiteRequestWithoutBody(); CrtResult <HttpRequest> result = AwsSigner.SignHttpRequest(request, config); HttpRequest signedRequest = result.Get(); Assert.Equal("GET", signedRequest.Method); Assert.Equal("/?Param-3=Value3&Param=Value2&%E1%88%B4=Value1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fus-east-1%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=c5f1848ceec943ac2ca68ee720460c23aaae30a2300586597ada94c4a65e4787", signedRequest.Uri); Assert.Equal(1, signedRequest.Headers.Length); Assert.True(HasHeader(signedRequest, "Host", "example.amazonaws.com")); }
/// <summary> /// Calculates the signature for the specified request using the Asymmetric SigV4 signing protocol /// </summary> /// <param name="request"> /// The request to compute the signature for. Additional headers mandated by the /// SigV4a protocol will be added to the request before signing. /// </param> /// <param name="clientConfig"> /// Client configuration data encompassing the service call (notably authentication /// region, endpoint and service name). /// </param> /// <param name="metrics">Metrics for the request</param> /// <param name="credentials">The AWS credentials for the account making the service call</param> /// <returns>AWS4aSigningResult for the given request</returns> public AWS4aSigningResult SignRequest(IRequest request, IClientConfig clientConfig, RequestMetrics metrics, ImmutableCredentials credentials) { var signedAt = AWS4Signer.InitializeHeaders(request.Headers, request.Endpoint); var serviceSigningName = !string.IsNullOrEmpty(request.OverrideSigningServiceName) ? request.OverrideSigningServiceName : AWS4Signer.DetermineService(clientConfig); var regionSet = AWS4Signer.DetermineSigningRegion(clientConfig, clientConfig.RegionEndpointServiceName, request.AlternateEndpoint, request); request.DeterminedSigningRegion = regionSet; AWS4Signer.SetXAmzTrailerHeader(request.Headers, request.TrailingHeaders); var signingConfig = PrepareCRTSigningConfig(AwsSignatureType.HTTP_REQUEST_VIA_HEADERS, regionSet, serviceSigningName, signedAt, credentials); // If the request should use a fixed x-amz-content-sha256 header value, determine the appropriate one var fixedBodyHash = request.TrailingHeaders?.Count > 0 ? AWS4Signer.V4aStreamingBodySha256WithTrailer : AWS4Signer.V4aStreamingBodySha256; signingConfig.SignedBodyValue = AWS4Signer.SetRequestBodyHash(request, SignPayload, fixedBodyHash, ChunkedUploadWrapperStream.V4A_SIGNATURE_LENGTH); var crtRequest = CrtHttpRequestConverter.ConvertToCrtRequest(request); var signingResult = AwsSigner.SignHttpRequest(crtRequest, signingConfig); var authorizationValue = Encoding.Default.GetString(signingResult.Get().Signature); var signedCrtRequest = signingResult.Get().SignedRequest; CrtHttpRequestConverter.CopyHeadersFromCrtRequest(request, signedCrtRequest); var dateStamp = AWS4Signer.FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateFormat); var scope = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}", dateStamp, serviceSigningName, AWS4Signer.Terminator); AWS4aSigningResult result = new AWS4aSigningResult( credentials.AccessKey, signedAt, CrtHttpRequestConverter.ExtractSignedHeaders(signedCrtRequest), scope, regionSet, authorizationValue, serviceSigningName, "", credentials); return(result); }
public void SignedHeadersBuilderTest() { var signer = new AwsSigner(); var inputBuilder = new StringBuilder(); inputBuilder.Append("content-type:application/x-www-form-urlencoded; charset=utf-8\n"); inputBuilder.Append("host:iam.amazonaws.com\n"); inputBuilder.Append("my-header1:a b c\n"); inputBuilder.Append("my-header1:\"a b c\"\n"); inputBuilder.Append("x-amz-date:20150830T123600Z\n"); var expected = "content-type;host;my-header1;my-header1;x-amz-date"; var output = signer.BuildSignedHeaders(inputBuilder.ToString()); Assert.AreEqual(expected, output, "Signed headers builder failed"); }
[InlineData("s3", "my-object//example//photo.user", "/my-object//example//photo.user")] // should not normalize public void SignRequestViaHeadersWithSigv4a(string service, string resourcePath, string canonicalizedResourcePath) { var signer = new CrtAWS4aSigner(); var request = BuildHeaderRequestToSign(resourcePath); var clientConfig = BuildSigningClientConfig(service); var result = signer.SignRequest(request, clientConfig, null, SigningTestCredentials); string signatureValue = result.Signature; var canonicalRequest = GetExpectedCanonicalRequestForHeaderSigningTest(canonicalizedResourcePath); var config = BuildDefaultSigningConfig(service); config.SignatureType = AwsSignatureType.CANONICAL_REQUEST_VIA_HEADERS; Assert.True(AwsSigner.VerifyV4aCanonicalSigning(canonicalRequest, config, signatureValue, SigningTestEccPubX, SigningTestEccPubY)); }
public void SignRequestViaQueryParamsWithSigv4a() { var signer = new CrtAWS4aSigner(); var request = BuildQueryParamRequestToSign(); var clientConfig = BuildSigningClientConfig("service"); var result = signer.Presign4a(request, clientConfig, null, SigningTestCredentials, "service", SigningTestRegion); var signatureValue = result.Signature; var canonicalRequest = GetExpectedCanonicalRequestForQueryParamSigningTest(); var config = BuildDefaultSigningConfig("service"); config.SignatureType = AwsSignatureType.CANONICAL_REQUEST_VIA_QUERY_PARAMS; Assert.True(AwsSigner.VerifyV4aCanonicalSigning(canonicalRequest, config, signatureValue, SigningTestEccPubX, SigningTestEccPubY)); }
public async Task CreateSignString() { var signer = new AwsSigner(); var request = Helpers.CreateExampleRequest(); var region = "us-east-1"; var service = "iam"; var dateTime = DateTimeOffset.Parse("2015-08-30T12:36:00Z"); var expectedBuilder = new StringBuilder(); expectedBuilder.Append("AWS4-HMAC-SHA256\n"); expectedBuilder.Append("20150830T123600Z\n"); expectedBuilder.Append("20150830/us-east-1/iam/aws4_request\n"); expectedBuilder.Append("f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59"); var output = await signer.CreateSignString(region, service, request, dateTime); Assert.AreEqual(expectedBuilder.ToString(), output, "Create Sign string failed"); }
public void SignBodyRequestByHeaders() { var config = BuildBaseSigningConfig(); config.SignedBodyHeader = AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA256; var request = BuildTestSuiteRequestWithBody(); CrtResult <HttpRequest> result = AwsSigner.SignHttpRequest(request, config); HttpRequest signedRequest = result.Get(); Assert.Equal("POST", signedRequest.Method); Assert.Equal("/", signedRequest.Uri); Assert.Equal(6, signedRequest.Headers.Length); Assert.True(HasHeader(signedRequest, "Host", "example.amazonaws.com")); Assert.True(HasHeader(signedRequest, "X-Amz-Date", "20150830T123600Z")); Assert.True(HasHeader(signedRequest, "Authorization", "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-content-sha256;x-amz-date, Signature=d3875051da38690788ef43de4db0d8f280229d82040bfac253562e56c3f20e0b")); Assert.True(HasHeader(signedRequest, "Content-Type", "application/x-www-form-urlencoded")); Assert.True(HasHeader(signedRequest, "x-amz-content-sha256", "9095672bbd1f56dfc5b65f3e153adc8731a4a654192329106275f4c7b24d0b6e")); Assert.True(HasHeader(signedRequest, "Content-Length", "13")); }
public async Task SignRequest() { var signer = new AwsSigner(); var config = Helpers.CreateExampleConfig(); var expectedRequest = Helpers.CreateExampleRequest(); var request = Helpers.CreateExampleRequest(); //Remove the X-Amz-Date header since the authorize method should do this request.Headers.Remove("X-Amz-Date"); var expectedDateTime = DateTimeOffset.Parse("2015-08-30T12:36:00Z"); await AwsSigner.SignRequest(config, request, expectedDateTime); var signature = await signer.CreateSignature(config, expectedRequest, expectedDateTime); var expectedScheme = "AWS4-HMAC-SHA256"; var expectedContent = $"Credential=AKIDEXAMPLE/{expectedDateTime:yyyyMMdd}/us-east-1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature={signature}"; Assert.AreEqual(expectedScheme, request.Headers.Authorization.Scheme, "Authorization scheme does not match"); Assert.AreEqual(expectedContent, request.Headers.Authorization.Parameter, "Authorization content does not match"); }
public void SignRequestFailureIllegalHeader() { var config = BuildBaseSigningConfig(); var request = BuildRequestWithIllegalHeader(); CrtResult <HttpRequest> result = AwsSigner.SignHttpRequest(request, config); Assert.Throws <CrtException>(() => result.Get()); int crtErrorCode = 0; try { HttpRequest req = result.Get(); } catch (CrtException e) { crtErrorCode = e.ErrorCode; } /* AWS_AUTH_SIGNING_ILLEGAL_REQUEST_HEADER */ Assert.Equal(1024 * 6 + 6, crtErrorCode); }
public void CanonicalHeadersFromNullContentTest() { var signer = new AwsSigner(); var request = Helpers.CreateExampleRequest(); request.Content = null; request.Headers.Add("My-header1", "a b c"); request.Headers.Add("My-header1", "\"a b c\""); var expectedBuilder = new StringBuilder(); expectedBuilder.Append("host:iam.amazonaws.com\n"); expectedBuilder.Append("my-header1:a b c\n"); expectedBuilder.Append("my-header1:\"a b c\"\n"); expectedBuilder.Append("x-amz-date:20150830T123600Z\n"); var expected = expectedBuilder.ToString(); var output = signer.BuildCanonicalHeaders(request); Assert.AreEqual(expected, output, "Header builder failed"); }
/// <summary> /// Calculates the signature for the specified request using the Asymmetric SigV4 signing protocol /// </summary> /// <param name="request"> /// The request to compute the signature for. Additional headers mandated by the /// SigV4a protocol will be added to the request before signing. /// </param> /// <param name="clientConfig"> /// Client configuration data encompassing the service call (notably authentication /// region, endpoint and service name). /// </param> /// <param name="metrics">Metrics for the request</param> /// <param name="credentials">The AWS credentials for the account making the service call</param> /// <returns>AWS4aSigningResult for the given request</returns> public AWS4aSigningResult SignRequest(IRequest request, IClientConfig clientConfig, RequestMetrics metrics, ImmutableCredentials credentials) { var signedAt = AWS4Signer.InitializeHeaders(request.Headers, request.Endpoint); var service = !string.IsNullOrEmpty(request.OverrideSigningServiceName) ? request.OverrideSigningServiceName : AWS4Signer.DetermineService(clientConfig); var regionSet = AWS4Signer.DetermineSigningRegion(clientConfig, service, request.AlternateEndpoint, request); request.DeterminedSigningRegion = regionSet; var signingConfig = PrepareCRTSigningConfig(AwsSignatureType.HTTP_REQUEST_VIA_HEADERS, regionSet, service, signedAt, credentials); // Compute here rather than CRT to support the fixed value for header of a chunked request signingConfig.SignedBodyValue = AWS4Signer.SetRequestBodyHash(request, SignPayload, AWS4Signer.V4aStreamingBodySha256, ChunkedUploadWrapperStream.V4A_SIGNATURE_LENGTH); var crtRequest = CrtHttpRequestConverter.ConvertToCrtRequest(request); var signingResult = AwsSigner.SignHttpRequest(crtRequest, signingConfig); var authorizationValue = Encoding.Default.GetString(signingResult.Get().Signature); var signedCrtRequest = signingResult.Get().SignedRequest; CrtHttpRequestConverter.CopyHeadersFromCrtRequest(request, signedCrtRequest); var dateStamp = AWS4Signer.FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateFormat); var scope = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}", dateStamp, service, AWS4Signer.Terminator); AWS4aSigningResult result = new AWS4aSigningResult( credentials.AccessKey, signedAt, CrtHttpRequestConverter.ExtractSignedHeaders(signedCrtRequest), scope, regionSet, authorizationValue, service, "", credentials); return(result); }
public void SignRequestFailureNoCredentials() { var config = BuildBaseSigningConfig(); config.Credentials = null; var request = BuildTestSuiteRequestWithoutBody(); CrtResult <HttpRequest> result = AwsSigner.SignHttpRequest(request, config); Assert.Throws <CrtException>(() => result.Get()); int crtErrorCode = 0; try { HttpRequest req = result.Get(); } catch (CrtException e) { crtErrorCode = e.ErrorCode; } /* AWS_AUTH_SIGNING_INVALID_CONFIGURATION */ Assert.Equal(1024 * 6 + 7, crtErrorCode); }