private static string CalculateCanonicalRequestHash(string httpMethod, string url, IDictionary <string, string> httpHeaders, out string signedHeaders) { var httpMethodToUpper = httpMethod.ToUpper(); var isGet = httpMethodToUpper == "GET"; var uri = new Uri(url); var queryStringCollection = uri.ParseQueryString(); var canonicalUri = uri.AbsolutePath; var queryString = ( from string parameter in queryStringCollection select new KeyValuePair <string, string>(parameter, queryStringCollection.Get(parameter)) ); var canonicalQueryString = queryString .OrderBy(x => x.Key) .Aggregate(string.Empty, (current, parameter) => current + string.Format("{0}={1}&", parameter.Key.ToLower(), parameter.Value.Trim())); if (canonicalQueryString.EndsWith("&")) { canonicalQueryString = canonicalQueryString.Substring(0, canonicalQueryString.Length - 1); } var headers = httpHeaders .Where(x => isGet == false || x.Key.StartsWith("Date", StringComparison.InvariantCultureIgnoreCase) == false) .OrderBy(x => x.Key); var canonicalHeaders = headers .Aggregate(string.Empty, (current, parameter) => current + string.Format("{0}:{1}\n", parameter.Key.ToLower(), parameter.Value.Trim())); signedHeaders = headers .Aggregate(string.Empty, (current, parameter) => current + parameter.Key.ToLower() + ";"); if (signedHeaders.EndsWith(";")) { signedHeaders = signedHeaders.Substring(0, signedHeaders.Length - 1); } using (var hash = SHA256.Create()) { var hashedPayload = httpHeaders["x-amz-content-sha256"]; var canonicalRequest = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}", httpMethodToUpper, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders, hashedPayload); return(RavenAwsHelper.ConvertToHex(hash.ComputeHash(Encoding.UTF8.GetBytes(canonicalRequest)))); } }
public AuthenticationHeaderValue CalculateAuthorizationHeaderValue(string httpMethod, string url, DateTime date, IDictionary <string, string> httpHeaders) { string signedHeaders; var canonicalRequestHash = CalculateCanonicalRequestHash(httpMethod, url, httpHeaders, out signedHeaders); var signingKey = CalculateSigningKey(date, ServiceName); using (var hash = new HMACSHA256(signingKey)) { var scope = string.Format("{0}/{1}/{2}/aws4_request", date.ToString("yyyyMMdd"), AwsRegion, ServiceName); var stringToHash = string.Format("AWS4-HMAC-SHA256\n{0}\n{1}\n{2}", RavenAwsHelper.ConvertToString(date), scope, canonicalRequestHash); var hashedString = hash.ComputeHash(Encoding.UTF8.GetBytes(stringToHash)); var signature = RavenAwsHelper.ConvertToHex(hashedString); var credentials = string.Format("{0}/{1}/{2}/{3}/aws4_request", awsAccessKey, date.ToString("yyyyMMdd"), AwsRegion, ServiceName); return(new AuthenticationHeaderValue("AWS4-HMAC-SHA256", string.Format("Credential={0},SignedHeaders={1},Signature={2}", credentials, signedHeaders, signature))); } }
public Blob GetObject(string bucketName, string key) { var url = GetUrl(bucketName) + "/" + key; var now = SystemTime.UtcNow; var payloadHash = RavenAwsHelper.CalculatePayloadHash(null); var requestMessage = new HttpRequestMessage(HttpMethod.Get, url) { Headers = { { "x-amz-date", RavenAwsHelper.ConvertToString(now) }, { "x-amz-content-sha256", payloadHash } } }; var headers = ConvertToHeaders(bucketName, requestMessage.Headers); var client = GetClient(); client.DefaultRequestHeaders.Authorization = CalculateAuthorizationHeaderValue("GET", url, now, headers); var response = AsyncHelpers.RunSync(() => client.SendAsync(requestMessage)); if (response.StatusCode == HttpStatusCode.NotFound) { return(null); } if (response.IsSuccessStatusCode == false) { throw ErrorResponseException.FromResponseMessage(response); } var data = AsyncHelpers.RunSync(() => response.Content.ReadAsStreamAsync()); var metadataHeaders = response.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault()); return(new Blob(data, metadataHeaders)); }
public void PutObject(string bucketName, string key, Stream stream, Dictionary <string, string> metadata, int timeoutInSeconds) { var url = GetUrl(bucketName) + "/" + key; var now = SystemTime.UtcNow; var payloadHash = RavenAwsHelper.CalculatePayloadHash(stream); var content = new StreamContent(stream) { Headers = { { "x-amz-date", RavenAwsHelper.ConvertToString(now) }, { "x-amz-content-sha256", payloadHash } } }; foreach (var metadataKey in metadata.Keys) { content.Headers.Add("x-amz-meta-" + metadataKey.ToLower(), metadata[metadataKey]); } var headers = ConvertToHeaders(bucketName, content.Headers); var client = GetClient(TimeSpan.FromSeconds(timeoutInSeconds)); var authorizationHeaderValue = CalculateAuthorizationHeaderValue("PUT", url, now, headers); client.DefaultRequestHeaders.Authorization = authorizationHeaderValue; var response = AsyncHelpers.RunSync(() => client.PutAsync(url, content)); if (response.IsSuccessStatusCode) { return; } throw ErrorResponseException.FromResponseMessage(response); }
public string UploadArchive(string glacierVaultName, Stream stream, string archiveDescription, int timeoutInSeconds) { var url = string.Format("{0}/-/vaults/{1}/archives", GetUrl(null), glacierVaultName); var now = SystemTime.UtcNow; var payloadHash = RavenAwsHelper.CalculatePayloadHash(stream); var payloadTreeHash = RavenAwsHelper.CalculatePayloadTreeHash(stream); var content = new StreamContent(stream) { Headers = { { "x-amz-glacier-version", "2012-06-01" }, { "x-amz-date", RavenAwsHelper.ConvertToString(now) }, { "x-amz-content-sha256", payloadHash }, { "x-amz-sha256-tree-hash", payloadTreeHash }, { "x-amz-archive-description", archiveDescription } } }; var headers = ConvertToHeaders(glacierVaultName, content.Headers); var client = GetClient(TimeSpan.FromSeconds(timeoutInSeconds)); var authorizationHeaderValue = CalculateAuthorizationHeaderValue("POST", url, now, headers); client.DefaultRequestHeaders.Authorization = authorizationHeaderValue; var response = AsyncHelpers.RunSync(() => client.PostAsync(url, content)); if (response.IsSuccessStatusCode) { return(ReadArchiveId(response)); } throw ErrorResponseException.FromResponseMessage(response); }