예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        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));
        }
예제 #4
0
        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));
        }
예제 #5
0
        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));
        }
예제 #6
0
        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());
        }
예제 #7
0
        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());
        }
예제 #8
0
        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());
        }
예제 #9
0
        /// <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));
        }