public void CopyHeadersFromCrtRequestTest() { var crtRequest = new Aws.Crt.Http.HttpRequest { Headers = new[] { new Aws.Crt.Http.HttpHeader("a", "a"), new Aws.Crt.Http.HttpHeader("b", "b") } }; var mock = new Mock <IRequest>(); mock.SetupAllProperties(); mock.SetupGet(x => x.Headers).Returns(new Dictionary <string, string> { { "c", "c" }, // this is only on the SDK request so we expect it to be replaced by "a" and "b" from CRT }); var sdkRequest = mock.Object; CrtHttpRequestConverter.CopyHeadersFromCrtRequest(sdkRequest, crtRequest); // Verify that we've replaced the SDK request's headers with all of the CRT request's headers Assert.Equal(2, sdkRequest.Headers.Count); Assert.True(sdkRequest.Headers.ContainsKey("a")); Assert.True(sdkRequest.Headers.ContainsKey("b")); Assert.Equal("a", sdkRequest.Headers["a"]); Assert.Equal("b", sdkRequest.Headers["b"]); }
public void ConvertToCrtRequestTest() { var mock = new Mock <IRequest>(); mock.SetupAllProperties(); mock.SetupGet(x => x.Headers).Returns(new Dictionary <string, string> { { HeaderKeys.ContentLengthHeader, "13" }, { HeaderKeys.ContentTypeHeader, "application/x-www-form-urlencoded" }, { HeaderKeys.XAmzRegionSetHeader, "us-east-1" }, // should not be passed into CRT { HeaderKeys.XAmzSecurityTokenHeader, "token" } // should not be passed into CRT }); var sdkRequest = mock.Object; sdkRequest.HttpMethod = "POST"; sdkRequest.ResourcePath = "/resource"; sdkRequest.Content = Encoding.ASCII.GetBytes("Param1=value1"); sdkRequest.Endpoint = new Uri("https://amazonaws.com/"); var crtRequest = CrtHttpRequestConverter.ConvertToCrtRequest(sdkRequest); // Verify that all expected properties made it to the CRT request Assert.Equal("https://amazonaws.com/resource", crtRequest.Uri); Assert.Equal("POST", crtRequest.Method); Assert.Equal("Param1=value1", new StreamReader(crtRequest.BodyStream).ReadToEnd()); // Verify that we're correctly stripping CRT-managed headers Assert.Equal(2, crtRequest.Headers.Length); Assert.Equal(HeaderKeys.ContentLengthHeader, crtRequest.Headers[0].Name); Assert.Equal("13", crtRequest.Headers[0].Value); Assert.Equal(HeaderKeys.ContentTypeHeader, crtRequest.Headers[1].Name); Assert.Equal("application/x-www-form-urlencoded", crtRequest.Headers[1].Value); }
/// /// <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); }
/// <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 ExtractSignedHeadersTest() { var crtRequest = new Aws.Crt.Http.HttpRequest(); crtRequest.Headers = new Aws.Crt.Http.HttpHeader[] { new Aws.Crt.Http.HttpHeader("a", "a"), new Aws.Crt.Http.HttpHeader("Authorization", "AWS4-ECDSA-P256-SHA256 Credential=accesskey/20210101/s3/aws4_request, " + "SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-region-set;x-amz-security-token, Signature=signature"), new Aws.Crt.Http.HttpHeader("b", "b"), }; var signedHeaders = CrtHttpRequestConverter.ExtractSignedHeaders(crtRequest); // Verify that we can extract the signed headers out of the CRT's 'Authorization' header, // since we may use them directly later in the SDK Assert.Equal("host;x-amz-content-sha256;x-amz-date;x-amz-region-set;x-amz-security-token", signedHeaders); }
/// <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); }