/// <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)); }
/// <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(Request request, CredentialStore credentialStore) { DateTime now = Clock.Now(); string strDate = now.ToString(DateStampFormat); string dateTime = request.GetHeader(XAmzDateHeader); if (dateTime == null) { return(false); } // Fail if the Authentication header is not found string actualAuthorization = request.GetHeader(AuthorizationHeader); if (string.IsNullOrEmpty(actualAuthorization)) { return(false); } request.RemoveHeader(AuthorizationHeader); // Clear any header that isn't in the list of signed signedHeaders AuthenticationHeader authenticationHeader = AuthenticationHeaderParser.Parse(actualAuthorization); if (authenticationHeader == null) { return(false); } string[] signedHeaders = authenticationHeader.SignedHeaders.Split(';'); RemoveUnsignedHeaders(request, signedHeaders); DateTime dateOfRequest; if (!DateTime.TryParseExact(dateTime, DateTimeFormat, null, DateTimeStyles.None, out dateOfRequest)) { return(false); } TimeSpan timeSpan = now - dateOfRequest; if (Math.Abs(timeSpan.TotalMilliseconds) > TimeToleranceInMilliseconds) { return(false); } // The credential info should follow this pattern: KEYID/DATE string[] credentialInfo = authenticationHeader.Credential.Split('/'); if (credentialInfo.GetLength(0) < 2) { return(false); } Credential credential; try { credential = credentialStore.Get(credentialInfo[0]); } catch (CredentialNotFoundException) { return(false); } byte[] timedKey = Sign(strDate, credential.SecretKey); string canonicalRequest = GetCanonicalRequest(request); string stringToSign = GetStringToSign(AlgorithmHeader, dateTime, EmptyScope, canonicalRequest); string signature = BitConverter.ToString(Sign(stringToSign, timedKey)).Replace("-", "").ToLower(); string computedAuthorization = GetAuthorizatioinHeader(request, credential, strDate, signature); return(computedAuthorization.Equals(actualAuthorization)); }