Inheritance: IRequestMetrics
Esempio n. 1
0
 /// <summary>
 /// Determines the appropriate signer and signs the request.
 /// </summary>
 /// <param name="awsAccessKeyId">The AWS public key</param>
 /// <param name="awsSecretAccessKey">The AWS secret key used to sign the request in clear text</param>
 /// <param name="metrics">Request metrics</param>
 /// <param name="clientConfig">The configuration that specifies which hashing algorithm to use</param>
 /// <param name="request">The request to have the signature compute for</param>
 /// <exception cref="Amazon.Runtime.SignatureException">If any problems are encountered while signing the request</exception>
 public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
 {
     var aws4Signer = SelectSigner(clientConfig) as AWS4Signer;
     if (aws4Signer != null)
         aws4Signer.Sign(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
     else
         base.Sign(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
 }
Esempio n. 2
0
 /// <summary>
 /// Calculates and signs the specified request using the AWS4 signing protocol by using the
 /// AWS account credentials given in the method parameters. The resulting signature is added
 /// to the request headers as 'Authorization'. Parameters supplied in the request, either in
 /// the resource path as a query string or in the Parameters collection must not have been
 /// uri encoded. If they have, use the SignRequest method to obtain a signature.
 /// </summary>
 /// <param name="request">
 /// The request to compute the signature for. Additional headers mandated by the AWS4 protocol 
 /// ('host' and 'x-amz-date') 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="awsAccessKeyId">
 /// The AWS public key for the account making the service call.
 /// </param>
 /// <param name="awsSecretAccessKey">
 /// The AWS secret key for the account making the call, in clear text.
 /// </param>
 /// <exception cref="Amazon.Runtime.SignatureException">
 /// If any problems are encountered while signing the request.
 /// </exception>
 public override void Sign(IRequest request, 
                           ClientConfig clientConfig, 
                           RequestMetrics metrics, 
                           string awsAccessKeyId, 
                           string awsSecretAccessKey)
 {
     var signingResult = SignRequest(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
     request.Headers[HeaderKeys.AuthorizationHeader] = signingResult.ForAuthorizationHeader;
 }
Esempio n. 3
0
        public override UnmarshallerContext CreateContext(IWebResponseData response, bool readEntireResponse, Stream stream, RequestMetrics metrics)
        {
            if (response.IsHeaderPresent(HeaderKeys.XAmzId2Header))
                metrics.AddProperty(Metric.AmzId2, response.GetHeaderValue(HeaderKeys.XAmzId2Header));

            if (response.IsHeaderPresent(HeaderKeys.XAmzCloudFrontIdHeader))
                metrics.AddProperty(Metric.AmzCfId, response.GetHeaderValue(HeaderKeys.XAmzCloudFrontIdHeader));

            return base.CreateContext(response, readEntireResponse, stream, metrics);
        }
Esempio n. 4
0
        internal void SignRequest(IRequest request, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
        {
            request.Headers[HeaderKeys.XAmzDateHeader] = AWSSDKUtils.FormattedCurrentTimestampRFC822;

            var stringToSign = BuildStringToSign(request);
            metrics.AddProperty(Metric.StringToSign, stringToSign);
            var auth = CryptoUtilFactory.CryptoInstance.HMACSign(stringToSign, awsSecretAccessKey, SigningAlgorithm.HmacSHA1);
            var authorization = string.Concat("AWS ", awsAccessKeyId, ":", auth);
            request.Headers[HeaderKeys.AuthorizationHeader] = authorization;
        }
Esempio n. 5
0
        public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
        {
            request.Headers["x-amz-date"] = AWSSDKUtils.FormattedCurrentTimestampRFC822;

            string toSign = buildSigningString(request.HttpMethod, request.CanonicalResource, request.Parameters, request.Headers);
            metrics.AddProperty(Metric.StringToSign, toSign);
            string auth = CryptoUtilFactory.CryptoInstance.HMACSign(toSign, awsSecretAccessKey, SigningAlgorithm.HmacSHA1);
            string authorization = string.Concat("AWS ", awsAccessKeyId, ":", auth);
            request.Headers[S3QueryParameter.Authorization.ToString()] = authorization;
        }
Esempio n. 6
0
        /// <summary>
        /// Calculates and signs the specified request using the AWS4 signing protocol by using the
        /// AWS account credentials given in the method parameters.
        /// </summary>
        /// <param name="awsAccessKeyId">The AWS public key</param>
        /// <param name="awsSecretAccessKey">The AWS secret key used to sign the request in clear text</param>
        /// <param name="metrics">Request metrics</param>
        /// <param name="clientConfig">The configuration that specifies which hashing algorithm to use</param>
        /// <param name="request">The request to have the signature compute for</param>
        /// <exception cref="Amazon.Runtime.SignatureException">If any problems are encountered while signing the request</exception>
        public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
        {
            // clean up request from previous execution
            request.Headers.Remove("Authorization");

            SigningAlgorithm signingAlgorithm = SigningAlgorithm.HmacSHA256;

            DateTime dt = DateTime.UtcNow;
            string dateTime = dt.ToString(AWSSDKUtils.ISO8601BasicDateTimeFormat, CultureInfo.InvariantCulture);
            string dateStamp = dt.ToString("yyyyMMdd", CultureInfo.InvariantCulture);

            string region = DetermineRegion(clientConfig);
            string service = DetermineService(clientConfig);

            if (!request.Headers.ContainsKey("Host"))
            {
                string hostHeader = request.Endpoint.Host;
                if (!request.Endpoint.IsDefaultPort)
                    hostHeader += ":" + request.Endpoint.Port;
                request.Headers.Add("Host", hostHeader);
            }
            request.Headers["X-Amz-Date"] = dateTime;

            string scope = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}", dateStamp, region, service, TERMINATOR);
            List<string> headersToSign = GetHeadersForSigning(request.Headers);

            var queryString = request.UseQueryString ? AWSSDKUtils.GetParametersAsString(request.Parameters) : "";

            string canonicalRequest = GetCanonicalRequest(headersToSign,
                                                          new Uri(request.Endpoint, request.ResourcePath),
                                                          queryString,
                                                          request.Headers,
                                                          request.UseQueryString ? "" : GetRequestPayload(request),
                                                          request.ContentStreamHash,
                                                          request.HttpMethod);

            StringBuilder stringToSignBuilder = new StringBuilder();
            stringToSignBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}-{1}\n{2}\n{3}\n", SCHEME, ALGORITHM, dateTime, scope);

            byte[] canonicalRequestHashBytes = CryptoUtilFactory.CryptoInstance.ComputeSHA256Hash(Encoding.UTF8.GetBytes(canonicalRequest));
            stringToSignBuilder.Append(AWSSDKUtils.ToHex(canonicalRequestHashBytes, true));

            byte[] hashKey = ComposeSigningKey(signingAlgorithm, awsSecretAccessKey, region, dateStamp, service);
            string stringToSign = stringToSignBuilder.ToString();
            metrics.AddProperty(Metric.StringToSign, stringToSign);
            byte[] signature = CryptoUtilFactory.CryptoInstance.HMACSignBinary(Encoding.UTF8.GetBytes(stringToSign), hashKey, SigningAlgorithm.HmacSHA256);

            StringBuilder authorizationHeader = new StringBuilder();
            authorizationHeader.AppendFormat("{0}-{1} ", SCHEME, ALGORITHM);
            authorizationHeader.AppendFormat("Credential={0}/{1}, ", awsAccessKeyId, scope);
            authorizationHeader.AppendFormat("SignedHeaders={0}, ", GetSignedHeaders(headersToSign));
            authorizationHeader.AppendFormat("Signature={0}", AWSSDKUtils.ToHex(signature, true));

            request.Headers["Authorization"] = authorizationHeader.ToString();
        }
Esempio n. 7
0
 /// <summary>
 /// Signs the specified request with the AWS3 signing protocol by using the
 /// AWS account credentials given in the method parameters.
 /// </summary>
 /// <param name="awsAccessKeyId">The AWS public key</param>
 /// <param name="awsSecretAccessKey">The AWS secret key used to sign the request in clear text</param>
 /// <param name="metrics">Request metrics</param>
 /// <param name="clientConfig">The configuration that specifies which hashing algorithm to use</param>
 /// <param name="request">The request to have the signature compute for</param>
 /// <exception cref="Amazon.Runtime.SignatureException">If any problems are encountered while signing the request</exception>
 public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey) 
 {
     if (UseAws3Https)
     {
         SignHttps(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
     }
     else
     {
         SignHttp(request, metrics, awsAccessKeyId, awsSecretAccessKey);
     }
 }
Esempio n. 8
0
 public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
 {
     var aws4Signer = SelectSigner(clientConfig) as AWS4Signer;
     if (aws4Signer != null)
     {
         var signingResult = aws4Signer.SignRequest(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
         request.Headers[HeaderKeys.AuthorizationHeader] = signingResult.ForAuthorizationHeader;
         if (request.UseChunkEncoding)
             request.AWS4SignerResult = signingResult;
     }
     else
         SignRequest(request, metrics, awsAccessKeyId, awsSecretAccessKey);
 }
Esempio n. 9
0
        public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
        {
            if (String.IsNullOrEmpty(awsAccessKeyId))
            {
                throw new ArgumentOutOfRangeException("awsAccessKeyId", "The AWS Access Key ID cannot be NULL or a Zero length string");
            }

            string dateTime = AWSSDKUtils.GetFormattedTimestampRFC822(0);
            request.Headers.Add(HeaderKeys.XAmzDateHeader, dateTime);

            string signature = ComputeHash(dateTime, awsSecretAccessKey, SigningAlgorithm.HmacSHA1);

            request.Headers.Add(HeaderKeys.AuthorizationHeader, "AWS " + awsAccessKeyId + ":" + signature);
        }
Esempio n. 10
0
        /// <summary>
        /// Determines the appropriate signer and signs the request.
        /// </summary>
        /// <param name="awsAccessKeyId">The AWS public key</param>
        /// <param name="awsSecretAccessKey">The AWS secret key used to sign the request in clear text</param>
        /// <param name="metrics">Request metrics</param>
        /// <param name="clientConfig">The configuration that specifies which hashing algorithm to use</param>
        /// <param name="request">The request to have the signature compute for</param>
        /// <exception cref="Amazon.Runtime.SignatureException">If any problems are encountered while signing the request</exception>
        public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
        {
            var signer = SelectSigner(querySigner, _useSigV4, request, clientConfig);
            var useV4 = signer is AWS4Signer;

            if (useV4)
            {
                if (request.Parameters.ContainsKey("SecurityToken"))
                {
                    var token = request.Parameters["SecurityToken"];
                    request.Parameters.Remove("SecurityToken");

                    request.Headers[HeaderKeys.XAmzSecurityTokenHeader] = token;
                }
            }

            signer.Sign(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
        }
Esempio n. 11
0
        /// <summary>
        /// Signs the specified request with the AWS3 signing protocol by using the
        /// AWS account credentials given in the method parameters.
        /// </summary>
        /// <param name="awsAccessKeyId">The AWS public key</param>
        /// <param name="awsSecretAccessKey">The AWS secret key used to sign the request in clear text</param>
        /// <param name="metrics">Request metrics</param>
        /// <param name="clientConfig">The configuration that specifies which hashing algorithm to use</param>
        /// <param name="request">The request to have the signature compute for</param>
        /// <exception cref="Amazon.Runtime.SignatureException">If any problems are encountered while signing the request</exception>
        public override void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey) 
        {
            var signer = SelectSigner(request, clientConfig);
            var useV4 = signer is AWS4Signer;

            if (useV4)
                signer.Sign(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
            else
            {
                if (UseAws3Https)
                {
                    SignHttps(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey);
                }
                else
                {
                    SignHttp(request, metrics, awsAccessKeyId, awsSecretAccessKey);
                }
            }
        }
Esempio n. 12
0
        private static void SignHttps(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
        {
            string nonce = Guid.NewGuid().ToString();
            string date = AWSSDKUtils.FormattedCurrentTimestampRFC822;
            string stringToSign;

            stringToSign = date + nonce;
            metrics.AddProperty(Metric.StringToSign, stringToSign);

            string signature = ComputeHash(stringToSign, awsSecretAccessKey, clientConfig.SignatureMethod);

            StringBuilder builder = new StringBuilder();
            builder.Append(HTTPS_SCHEME).Append(" ");
            builder.Append("AWSAccessKeyId=" + awsAccessKeyId + ",");
            builder.Append("Algorithm=" + clientConfig.SignatureMethod.ToString() + ",");
            builder.Append("SignedHeaders=x-amz-date;x-amz-nonce,");
            builder.Append("Signature=" + signature);

            request.Headers[HeaderKeys.XAmzAuthorizationHeader] = builder.ToString();
            request.Headers[HeaderKeys.XAmzNonceHeader] = nonce;
            request.Headers[HeaderKeys.XAmzDateHeader] = date;
        }
Esempio n. 13
0
 internal TimingEvent(RequestMetrics metrics, Metric metric)
 {
     this.metrics = metrics;
     this.metric  = metric;
 }
Esempio n. 14
0
 internal TimingEvent(RequestMetrics metrics, Metric metric)
 {
     this.metrics = metrics;
     this.metric = metric;
 }
Esempio n. 15
0
 public abstract void Sign(IRequest request, ClientConfig clientConfig, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey);
        /// <summary>
        /// Calculates the AWS4 signature for a presigned url.
        /// </summary>
        /// <param name="request">
        /// The request to compute the signature for. Additional headers mandated by the AWS4 protocol 
        /// ('host' and 'x-amz-date') will be added to the request before signing. If the Expires parameter
        /// is present, it is renamed to 'X-Amz-Expires' before signing.
        /// </param>
        /// <param name="clientConfig">
        /// Adding supporting data for the service call required by the signer (notably authentication
        /// region, endpoint and service name).
        /// </param>
        /// <param name="metrics">
        /// Metrics for the request
        /// </param>
        /// <param name="awsAccessKeyId">
        /// The AWS public key for the account making the service call.
        /// </param>
        /// <param name="awsSecretAccessKey">
        /// The AWS secret key for the account making the call, in clear text
        /// </param>
        /// <param name="service">
        /// The service to sign for
        /// </param>
        /// <param name="overrideSigningRegion">
        /// The region to sign to, if null then the region the client is configured for will be used.
        /// </param>
        /// <exception cref="Amazon.Runtime.SignatureException">
        /// If any problems are encountered while signing the request.
        /// </exception>
        /// <remarks>
        /// Parameters passed as part of the resource path should be uri-encoded prior to
        /// entry to the signer. Parameters passed in the request.Parameters collection should
        /// be not be encoded; encoding will be done for these parameters as part of the 
        /// construction of the canonical request.
        /// </remarks>
        public static AWS4SigningResult SignRequest(IRequest request,
                                                 ClientConfig clientConfig,
                                                 RequestMetrics metrics,
                                                 string awsAccessKeyId,
                                                 string awsSecretAccessKey,
                                                 string service,
                                                 string overrideSigningRegion)
        {
            // clean up any prior signature in the headers if resigning
            request.Headers.Remove(HeaderKeys.AuthorizationHeader);
            if (!request.Headers.ContainsKey(HeaderKeys.HostHeader))
            {
                var hostHeader = request.Endpoint.Host;
                if (!request.Endpoint.IsDefaultPort)
                    hostHeader += ":" + request.Endpoint.Port;
                request.Headers.Add(HeaderKeys.HostHeader, hostHeader);
            }

            var signedAt = AWSSDKUtils.CorrectedUtcNow;
            var region = overrideSigningRegion ?? DetermineSigningRegion(clientConfig, service, request.AlternateEndpoint, request);

            // AWS4 presigned urls got S3 are expected to contain a 'UNSIGNED-PAYLOAD' magic string
            // during signing (other services use the empty-body sha)
            if (request.Headers.ContainsKey(HeaderKeys.XAmzContentSha256Header))
                request.Headers.Remove(HeaderKeys.XAmzContentSha256Header);

            var sortedHeaders = SortHeaders(request.Headers);
            var canonicalizedHeaderNames = CanonicalizeHeaderNames(sortedHeaders);

            var parametersToCanonicalize = GetParametersToCanonicalize(request);
            parametersToCanonicalize.Add(XAmzAlgorithm, AWS4AlgorithmTag);
            parametersToCanonicalize.Add(XAmzCredential,
                                         string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}/{4}",
                                                       awsAccessKeyId,
                                                       FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateFormat),
                                                       region,
                                                       service,
                                                       Terminator));

            parametersToCanonicalize.Add(HeaderKeys.XAmzDateHeader, FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateTimeFormat));
            parametersToCanonicalize.Add(HeaderKeys.XAmzSignedHeadersHeader, canonicalizedHeaderNames);

            var canonicalQueryParams = CanonicalizeQueryParameters(parametersToCanonicalize);

            var canonicalRequest = CanonicalizeRequest(request.ResourcePath,
                                                       request.HttpMethod,
                                                       sortedHeaders,
                                                       canonicalQueryParams,
                                                       service == "s3" ? UnsignedPayload : EmptyBodySha256);
            if (metrics != null)
                metrics.AddProperty(Metric.CanonicalRequest, canonicalRequest);

            return ComputeSignature(awsAccessKeyId,
                                    awsSecretAccessKey,
                                    region,
                                    signedAt,
                                    service,
                                    canonicalizedHeaderNames,
                                    canonicalRequest,
                                    metrics);
        }
 /// <summary>
 /// Calculates the AWS4 signature for a presigned url.
 /// </summary>
 /// <param name="request">
 /// The request to compute the signature for. Additional headers mandated by the AWS4 protocol 
 /// ('host' and 'x-amz-date') will be added to the request before signing. If the Expires parameter
 /// is present, it is renamed to 'X-Amz-Expires' before signing.
 /// </param>
 /// <param name="clientConfig">
 /// Adding supporting data for the service call required by the signer (notably authentication
 /// region, endpoint and service name).
 /// </param>
 /// <param name="metrics">
 /// Metrics for the request
 /// </param>
 /// <param name="awsAccessKeyId">
 /// The AWS public key for the account making the service call.
 /// </param>
 /// <param name="awsSecretAccessKey">
 /// The AWS secret key for the account making the call, in clear text
 /// </param>
 /// <exception cref="Amazon.Runtime.SignatureException">
 /// If any problems are encountered while signing the request.
 /// </exception>
 /// <remarks>
 /// Parameters passed as part of the resource path should be uri-encoded prior to
 /// entry to the signer. Parameters passed in the request.Parameters collection should
 /// be not be encoded; encoding will be done for these parameters as part of the 
 /// construction of the canonical request.
 /// </remarks>
 public new AWS4SigningResult SignRequest(IRequest request,
                                          ClientConfig clientConfig,
                                          RequestMetrics metrics,
                                          string awsAccessKeyId,
                                          string awsSecretAccessKey)
 {
     return SignRequest(request, clientConfig, metrics, awsAccessKeyId, awsSecretAccessKey, "s3", null);
 }
 /// <summary>
 /// Calculates and signs the specified request using the AWS4 signing protocol by using the
 /// AWS account credentials given in the method parameters. The resulting signature is added
 /// to the request headers as 'Authorization'.
 /// </summary>
 /// <param name="request">
 /// The request to compute the signature for. Additional headers mandated by the AWS4 protocol 
 /// ('host' and 'x-amz-date') will be added to the request before signing.
 /// </param>
 /// <param name="clientConfig">
 /// Adding supporting data for the service call required by the signer (notably authentication
 /// region, endpoint and service name).
 /// </param>
 /// <param name="metrics">
 /// Metrics for the request
 /// </param>
 /// <param name="awsAccessKeyId">
 /// The AWS public key for the account making the service call.
 /// </param>
 /// <param name="awsSecretAccessKey">
 /// The AWS secret key for the account making the call, in clear text
 /// </param>
 /// <exception cref="Amazon.Runtime.SignatureException">
 /// If any problems are encountered while signing the request.
 /// </exception>
 public override void Sign(IRequest request,
                           ClientConfig clientConfig,
                           RequestMetrics metrics,
                           string awsAccessKeyId,
                           string awsSecretAccessKey)
 {
     throw new InvalidOperationException("PreSignedUrl signature computation is not supported by this method; use SignRequest instead.");
 }
        /// <summary>
        /// Computes and returns an AWS4 signature for the specified canonicalized request
        /// </summary>
        /// <param name="awsAccessKey"></param>
        /// <param name="awsSecretAccessKey"></param>
        /// <param name="region"></param>
        /// <param name="signedAt"></param>
        /// <param name="service"></param>
        /// <param name="signedHeaders"></param>
        /// <param name="canonicalRequest"></param>
        /// <param name="metrics"></param>
        /// <returns></returns>
        public static AWS4SigningResult ComputeSignature(string awsAccessKey,
                                                         string awsSecretAccessKey,
                                                         string region,
                                                         DateTime signedAt,
                                                         string service,
                                                         string signedHeaders,
                                                         string canonicalRequest,
                                                         RequestMetrics metrics)
        {
            var dateStamp = FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateFormat);
            var scope = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}", dateStamp, region, service, Terminator);

            var stringToSignBuilder = new StringBuilder();
            stringToSignBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}-{1}\n{2}\n{3}\n",
                                      Scheme,
                                      Algorithm,
                                      FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateTimeFormat),
                                      scope);

            var canonicalRequestHashBytes = ComputeHash(canonicalRequest);
            stringToSignBuilder.Append(AWSSDKUtils.ToHex(canonicalRequestHashBytes, true));

            if (metrics != null)
                metrics.AddProperty(Metric.StringToSign, stringToSignBuilder);

            var key = ComposeSigningKey(awsSecretAccessKey,
                                        region,
                                        dateStamp,
                                        service);

            var stringToSign = stringToSignBuilder.ToString();
            var signature = ComputeKeyedHash(SignerAlgorithm, key, stringToSign);
            return new AWS4SigningResult(awsAccessKey, signedAt, signedHeaders, scope, key, signature);
        }
        /// <summary>
        /// Calculates and signs the specified request using the AWS4 signing protocol by using the
        /// AWS account credentials given in the method parameters.
        /// </summary>
        /// <param name="request">
        /// The request to compute the signature for. Additional headers mandated by the AWS4 protocol 
        /// ('host' and 'x-amz-date') 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="awsAccessKeyId">
        /// The AWS public key for the account making the service call.
        /// </param>
        /// <param name="awsSecretAccessKey">
        /// The AWS secret key for the account making the call, in clear text.
        /// </param>
        /// <exception cref="Amazon.Runtime.SignatureException">
        /// If any problems are encountered while signing the request.
        /// </exception>
        /// <remarks>
        /// Parameters passed as part of the resource path should be uri-encoded prior to
        /// entry to the signer. Parameters passed in the request.Parameters collection should
        /// be not be encoded; encoding will be done for these parameters as part of the 
        /// construction of the canonical request.
        /// </remarks>
        public AWS4SigningResult SignRequest(IRequest request,
                                             ClientConfig clientConfig,
                                             RequestMetrics metrics,
                                             string awsAccessKeyId,
                                             string awsSecretAccessKey)
        {
            var signedAt = InitializeHeaders(request.Headers, request.Endpoint);
            var service = DetermineService(clientConfig);
            var region = DetermineSigningRegion(clientConfig, service, request.AlternateEndpoint, request);

            var parametersToCanonicalize = GetParametersToCanonicalize(request);
            var canonicalParameters = CanonicalizeQueryParameters(parametersToCanonicalize);
            var bodyHash = SetRequestBodyHash(request);
            var sortedHeaders = SortHeaders(request.Headers);
            
            var canonicalRequest = CanonicalizeRequest(request.ResourcePath,
                                                       request.HttpMethod,
                                                       sortedHeaders,
                                                       canonicalParameters,
                                                       bodyHash);
            if (metrics != null)
                metrics.AddProperty(Metric.CanonicalRequest, canonicalRequest);

            return ComputeSignature(awsAccessKeyId,
                                    awsSecretAccessKey,
                                    region,
                                    signedAt,
                                    service,
                                    CanonicalizeHeaderNames(sortedHeaders),
                                    canonicalRequest,
                                    metrics);
        }
Esempio n. 21
0
        private static void SignHttp(IRequest request, RequestMetrics metrics, string awsAccessKeyId, string awsSecretAccessKey)
        {
            SigningAlgorithm algorithm = SigningAlgorithm.HmacSHA256;
            string nonce = Guid.NewGuid().ToString();
            string date = AWSSDKUtils.FormattedCurrentTimestampRFC822;
            bool isHttps = IsHttpsRequest(request);

            // Temporarily disabling the AWS3 HTTPS signing scheme and only using AWS3 HTTP
            isHttps = false;

            request.Headers[HeaderKeys.DateHeader] = date;
            request.Headers[HeaderKeys.XAmzDateHeader] = date;

            // Clear out existing auth header (can be there if retry)
            request.Headers.Remove(HeaderKeys.XAmzAuthorizationHeader);

            // AWS3 HTTP requires that we sign the Host header
            // so we have to have it in the request by the time we sign.
            string hostHeader = request.Endpoint.Host;
            if (!request.Endpoint.IsDefaultPort)
                hostHeader += ":" + request.Endpoint.Port;
            request.Headers[HeaderKeys.HostHeader] = hostHeader;

            byte[] bytesToSign = null;
            string stringToSign;
            if (isHttps)
            {
                request.Headers[HeaderKeys.XAmzNonceHeader] = nonce;
                stringToSign = date + nonce;
                bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
            }
            else
            {
                Uri url = request.Endpoint;
                if (!string.IsNullOrEmpty(request.ResourcePath))
                    url = new Uri(request.Endpoint, request.ResourcePath);

                stringToSign = request.HttpMethod + "\n"
                    + GetCanonicalizedResourcePath(url) + "\n"
                    + GetCanonicalizedQueryString(request.Parameters) + "\n"
                    + GetCanonicalizedHeadersForStringToSign(request) + "\n"
                    + GetRequestPayload(request);

                bytesToSign = CryptoUtilFactory.CryptoInstance.ComputeSHA256Hash(Encoding.UTF8.GetBytes(stringToSign));
            }

            metrics.AddProperty(Metric.StringToSign, stringToSign);
            string signature = ComputeHash(bytesToSign, awsSecretAccessKey, algorithm);

            StringBuilder builder = new StringBuilder();
            builder.Append(isHttps ? HTTPS_SCHEME : HTTP_SCHEME);
            builder.Append(" ");
            builder.Append("AWSAccessKeyId=" + awsAccessKeyId + ",");
            builder.Append("Algorithm=" + algorithm.ToString() + ",");

            if (!isHttps)
            {
                builder.Append(GetSignedHeadersComponent(request) + ",");
            }

            builder.Append("Signature=" + signature);
            string authorizationHeader = builder.ToString();
            request.Headers[HeaderKeys.XAmzAuthorizationHeader] = authorizationHeader;
        }
Esempio n. 22
0
        /// <summary>
        /// Calculates the AWS4 signature for a presigned url.
        /// </summary>
        /// <param name="request">
        /// The request to compute the signature for. Additional headers mandated by the AWS4 protocol 
        /// ('host' and 'x-amz-date') will be added to the request before signing. If the Expires parameter
        /// is present, it is renamed to 'X-Amz-Expires' before signing.
        /// </param>
        /// <param name="clientConfig">
        /// Adding supporting data for the service call required by the signer (notably authentication
        /// region, endpoint and service name).
        /// </param>
        /// <param name="metrics">
        /// Metrics for the request
        /// </param>
        /// <param name="awsAccessKeyId">
        /// The AWS public key for the account making the service call.
        /// </param>
        /// <param name="awsSecretAccessKey">
        /// The AWS secret key for the account making the call, in clear text
        /// </param>
        /// <param name="service">
        /// The service to sign for
        /// </param>
        /// <param name="overrideSigningRegion">
        /// The region to sign to, if null then the region the client is configured for will be used.
        /// </param>
        /// <exception cref="Amazon.Runtime.SignatureException">
        /// If any problems are encountered while signing the request.
        /// </exception>
        /// <remarks>
        /// Parameters passed as part of the resource path should be uri-encoded prior to
        /// entry to the signer. Parameters passed in the request.Parameters collection should
        /// be not be encoded; encoding will be done for these parameters as part of the 
        /// construction of the canonical request.
        /// </remarks>
        public static AWS4SigningResult SignRequest(IRequest request,
                                                 ClientConfig clientConfig,
                                                 RequestMetrics metrics,
                                                 string awsAccessKeyId,
                                                 string awsSecretAccessKey,
                                                 string service,
                                                 string overrideSigningRegion)
        {
            // clean up any prior signature in the headers if resigning
            request.Headers.Remove(AuthorizationHeader);
            if (!request.Headers.ContainsKey(HostHeader))
            {
                var hostHeader = request.Endpoint.Host;
                if (!request.Endpoint.IsDefaultPort)
                    hostHeader += ":" + request.Endpoint.Port;
                request.Headers.Add(HostHeader, hostHeader);
            }

            var signedAt = DateTime.UtcNow;
            var region = overrideSigningRegion == null ? DetermineSigningRegion(clientConfig, service) : overrideSigningRegion;

            // remove any hash supplied in headers in favor of the 'unsigned-payload' expected by AWS4
            if (request.Headers.ContainsKey(XAmzContentSha256))
                request.Headers.Remove(XAmzContentSha256);
            var sortedHeaders = SortHeaders(request.Headers);
            var canonicalizedHeaderNames = CanonicalizeHeaderNames(sortedHeaders);

            // add the auth parameters for canonicalization to a copy of the parameters so we don't
            // end up adding url encoded data to the url subsquently
            var copiedParameters = new Dictionary<string, string>(request.Parameters)
                {
                    {XAmzAlgorithm, string.Format(CultureInfo.InvariantCulture, "{0}-{1}", Scheme, Algorithm)},
                    {
                        XAmzCredential, string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}/{4}",
                                                      awsAccessKeyId,
                                                      FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateFormat),
                                                      region,
                                                      service,
                                                      Terminator)
                    },
                    {XAmzDate, FormatDateTime(signedAt, AWSSDKUtils.ISO8601BasicDateTimeFormat)},
                    {XAmzSignedHeaders, canonicalizedHeaderNames}
                };

            var canonicalQueryParams = CanonicalizeQueryParameters(copiedParameters);

            var canonicalRequest = CanonicalizeRequest(request.ResourcePath,
                                                       request.HttpMethod,
                                                       sortedHeaders,
                                                       canonicalQueryParams,
                                                       service == "s3" ? UnsignedPayload : EmptyBodySha256);
            if (metrics != null)
                metrics.AddProperty(Metric.CanonicalRequest, canonicalRequest);

            return ComputeSignature(awsAccessKeyId,
                                    awsSecretAccessKey,
                                    region,
                                    signedAt,
                                    service,
                                    canonicalizedHeaderNames,
                                    canonicalRequest,
                                    metrics);
        }
Esempio n. 23
0
        /// <summary>
        /// Calculates and signs the specified request using the AWS4 signing protocol by using the
        /// AWS account credentials given in the method parameters.
        /// </summary>
        /// <param name="request">
        /// The request to compute the signature for. Additional headers mandated by the AWS4 protocol 
        /// ('host' and 'x-amz-date') 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="awsAccessKeyId">
        /// The AWS public key for the account making the service call.
        /// </param>
        /// <param name="awsSecretAccessKey">
        /// The AWS secret key for the account making the call, in clear text.
        /// </param>
        /// <exception cref="Amazon.Runtime.SignatureException">
        /// If any problems are encountered while signing the request.
        /// </exception>
        /// <remarks>
        /// Parameters passed as part of the resource path should be uri-encoded prior to
        /// entry to the signer. Parameters passed in the request.Parameters collection should
        /// be not be encoded; encoding will be done for these parameters as part of the 
        /// construction of the canonical request.
        /// </remarks>
        public AWS4SigningResult SignRequest(IRequest request,
                                             ClientConfig clientConfig,
                                             RequestMetrics metrics,
                                             string awsAccessKeyId,
                                             string awsSecretAccessKey)
        {
            var signedAt = InitializeHeaders(request.Headers, request.Endpoint);
            var service = DetermineService(clientConfig);
            var region = DetermineSigningRegion(clientConfig, service);
            
            var resourcePathParamStart = -1;
            var resourcePath = string.Empty;

            // Extract the true resource path, less any query parameters or sub resource
            if (!string.IsNullOrEmpty(request.ResourcePath))
            {
                resourcePathParamStart = request.ResourcePath.IndexOf('?');
                resourcePath = resourcePathParamStart == -1 ? request.ResourcePath : request.ResourcePath.Substring(0, resourcePathParamStart);
            }

            // if UseQueryString is indicated and Parameters are present, canonicalize those (including uri encoding them)
            // otherwise if we spotted parameters in the resource path, canonicalize those instead (which should be encoded
            // already)
            var canonicalQueryParams = string.Empty;
            if (request.UseQueryString && request.Parameters.Count > 0)
                canonicalQueryParams = CanonicalizeQueryParameters(request.Parameters);
            else if (resourcePathParamStart != -1)
                canonicalQueryParams = CanonicalizeQueryParameters(request.ResourcePath.Substring(resourcePathParamStart + 1), false);

            var bodyHash = SetRequestBodyHash(request);
            var sortedHeaders = SortHeaders(request.Headers);
            var canonicalRequest = CanonicalizeRequest(resourcePath,
                                                       request.HttpMethod,
                                                       sortedHeaders,
                                                       canonicalQueryParams,
                                                       bodyHash);
            if (metrics != null)
                metrics.AddProperty(Metric.CanonicalRequest, canonicalRequest);

            return ComputeSignature(awsAccessKeyId,
                                    awsSecretAccessKey,
                                    region,
                                    signedAt,
                                    service,
                                    CanonicalizeHeaderNames(sortedHeaders),
                                    canonicalRequest,
                                    metrics);
        }