/// <summary> /// Signs the request and adds the authentication headers (Authentication & x-amz-date). /// </summary> /// <param name="request"> /// the request to sign. /// </param> /// <param name="credential"> /// the credential to use when signing. /// </param> public void Sign(IDTARequest request, Credential credential) { DateTime now = clock.Now(); string date = now.ToString(ISO8601Date); string dateTime = now.ToString(ISO8601DateTime); request.Headers[XAmzDateHeader] = dateTime; var headersToSign = request.Headers.OrderBy(kv => kv.Key).ToArray(); string signedHeaders = GetSignedHeaders(headersToSign); string canonicalHeaders = GetCanonicalHeaders(headersToSign); string canonicalRequest = GetCanonicalRequest( request.HttpMethod.ToUpperInvariant(), request.Uri.AbsolutePath, string.Empty, canonicalHeaders, signedHeaders, HexEncodedHash(request.Body ?? "")); string authorizationString = GetStringToSign( AlgorithmHeader, dateTime, string.Empty, HexEncodedHash(canonicalRequest)); byte[] timedKey = Sign(date, credential.SecretKey); string signature = Sign(authorizationString, timedKey).HexEncode(); request.Headers[AuthorizationHeader] = GetAuthorizationHeader(signedHeaders, credential, date, signature); }
/// <summary> /// Verifies the request against a credential. /// </summary> /// <param name="request"> /// the request to verify. /// </param> /// <param name="credential"> /// the credential used to verify the request. /// </param> /// <returns> /// true if the request validates. false for any other reason except a SigningException. /// </returns> public bool Verify(IDTARequest request, Credential credential) { CredentialStore store = new CredentialStore(); store.Add(credential); return(Verify(request, store)); }
public void verifyNoDate() { Credential credential = new Credential("SECRETKEY", "KEYID"); Signer signer = new Signer(); var mockDTARequest = createRequestMock("http://amazon.com", "GET", "application/json"); IDTARequest request = mockDTARequest.Object; request.Headers[AUTHORIZATION_HEADER] = string.Empty; Assert.IsFalse(signer.Verify(request, credential)); }
public void verifyNoAuthorization() { Credential credential = new Credential("SECRETKEY", "KEYID"); Signer signer = new Signer(); var mockDTARequest = createRequestMock("http://amazon.com", "GET", "application/json"); IDTARequest request = mockDTARequest.Object; request.Headers[X_AMZ_DATE_HEADER] = "20110909T233600Z"; Assert.IsFalse(signer.Verify(request, credential)); }
public void before15MinuteWindowFailsValidation() { Mock <Clock> clock = new Mock <Clock>(); Signer signer = new Signer(new AuthenticationHeaderParser(), clock.Object); DateTime mockDate = getDate(2011, 9, 9, 23, 36 - 16, 59); // Go 15 Minutes Before clock.Setup(Clock => Clock.Now()).Returns(() => mockDate); Credential credential = new Credential("SECRETKEY", "KEYID"); var mockDTARequest = createRequestMock("http://amazon.com", "GET", "application/json", "body"); IDTARequest request = mockDTARequest.Object; request.Headers["aaa"] = "aaa"; request.Headers["zzz"] = "zzz"; request.Headers[X_AMZ_DATE_HEADER] = "20110909T233600Z"; request.Headers[AUTHORIZATION_HEADER] = "DTA1-HMAC-SHA256 SignedHeaders=aaa;content-type;x-amz-date;zzz, Credential=KEYID/20110909, Signature=16ec5ffa0e33e8ec8f87f14bb5fd8a03545dbffe99eb3a89f5de450e791ef262"; Assert.IsFalse(signer.Verify(request, credential)); }
public void validSignatureNullBody() { Mock <Clock> clock = new Mock <Clock>(); DateTime mockDate = getDate(2011, 9, 9, 23, 36, 0); clock.Setup(Clock => Clock.Now()).Returns(() => mockDate); Signer signer = new Signer(new AuthenticationHeaderParser(), clock.Object); Credential credential = new Credential("SECRETKEY", "KEYID"); var mockDTARequest = createRequestMock("http://amazon.com", "GET", "application/json"); IDTARequest request = mockDTARequest.Object; signer.Sign(request, credential); Assert.AreEqual("20110909T233600Z", request.Headers["x-amz-date"].ToString()); Assert.AreEqual("DTA1-HMAC-SHA256 SignedHeaders=content-type;x-amz-date, Credential=KEYID/20110909, " + "Signature=d3042ffc41e6456535558faa130655a1c957263467e78d4485e70884b49ea52b", request.Headers["Authorization"].ToString()); }
public void validSignature() { Mock <Clock> clock = new Mock <Clock>(); DateTime mockDate = getDate(2011, 9, 9, 23, 36, 0); clock.Setup(Clock => Clock.Now()).Returns(mockDate); Signer signer = new Signer(new AuthenticationHeaderParser(), clock.Object); Credential credential = new Credential("SECRETKEY", "KEYID"); Mock <IDTARequest> mockDTARequest = createRequestMock("http://amazon.com", "GET", "application/json", "body"); IDTARequest dtaRequestMock = mockDTARequest.Object; signer.Sign(dtaRequestMock, credential); Assert.AreEqual("20110909T233600Z", dtaRequestMock.Headers["x-amz-date"].ToString()); Assert.AreEqual("DTA1-HMAC-SHA256 SignedHeaders=content-type;x-amz-date, Credential=KEYID/20110909, " + "Signature=4d2f81ea2cf8d6963f8176a22eec4c65ae95c63502326a7c148686da7d50f47e", dtaRequestMock.Headers["Authorization"].ToString()); }
public void additionalHeadersAreSigned() { Mock <Clock> clock = new Mock <Clock>(); DateTime mockDate = getDate(2011, 9, 9, 23, 36, 0); clock.Setup(Clock => Clock.Now()).Returns(() => mockDate); Signer signer = new Signer(new AuthenticationHeaderParser(), clock.Object); Credential credential = new Credential("SECRETKEY", "KEYID"); var mockDTARequest = createRequestMock("http://amazon.com", "GET", "application/json", "body"); IDTARequest request = mockDTARequest.Object; request.Headers["aaa"] = "aaa"; request.Headers["zzz"] = "zzz"; signer.Sign(request, credential); Assert.AreEqual("20110909T233600Z", request.Headers["x-amz-date"].ToString()); Assert.AreEqual("DTA1-HMAC-SHA256 SignedHeaders=aaa;content-type;x-amz-date;zzz, Credential=KEYID/20110909, " + "Signature=16ec5ffa0e33e8ec8f87f14bb5fd8a03545dbffe99eb3a89f5de450e791ef262", request.Headers["Authorization"].ToString()); }
/// <summary> /// Verifies the request against a credential store. /// </summary> /// <param name="request"> /// The request to verify. /// </param> /// <param name="credentialStore"> /// The credential store used to verify the request. /// </param> /// <returns> /// true if the request validates. false for any other reason except a SigningException. /// </returns> public bool Verify(IDTARequest request, CredentialStore credentialStore) { if (!TryGetRequestDate(request.Headers, out DateTime amznAuthDateTime)) { return(false); } if (!request.Headers.TryGetValue(AuthorizationHeader, out var requestAuthorization)) { return(false); } if (!authenticationHeaderParser.TryParse(requestAuthorization, out var authenticationHeader)) { return(false); } // The credential info should follow this pattern: KEYID/DATE string[] credentialInfo = authenticationHeader.Credential.Split('/'); if (credentialInfo.Length < 2) { return(false); } if (!credentialStore.TryGetValue(credentialInfo[0], out var credential)) { return(false); } string signedHeaders = authenticationHeader.SignedHeaders; string[] signedHeadersList = signedHeaders.Split(';'); if (!TryGetHeadersToSign(signedHeadersList, request.Headers, out var headersToSign)) { return(false); } string date = amznAuthDateTime.ToString(ISO8601Date); string dateTime = amznAuthDateTime.ToString(ISO8601DateTime); string canonicalHeaders = GetCanonicalHeaders(headersToSign); string canonicalRequest = GetCanonicalRequest( request.HttpMethod.ToUpperInvariant(), request.Uri.AbsolutePath, string.Empty, canonicalHeaders, signedHeaders, HexEncodedHash(request.Body ?? "")); string stringToSign = GetStringToSign( AlgorithmHeader, dateTime, string.Empty, HexEncodedHash(canonicalRequest)); byte[] timedKey = Sign(date, credential.SecretKey); string signature = Sign(stringToSign, timedKey).HexEncode(); string computedAuthorization = GetAuthorizationHeader(signedHeaders, credential, date, signature); return(computedAuthorization.Equals(requestAuthorization)); }