Beispiel #1
0
 /// <summary>
 /// Constructs the token for validating an incoming request.
 /// </summary>
 public HttpSignatureSecurityToken(string rawDigest, string rawSignature)
 {
     RawDigest    = rawDigest;
     RawSignature = rawSignature;
     Digest       = HttpDigest.Parse(rawDigest);
     Signature    = HttpSignature.Parse(rawSignature);
 }
Beispiel #2
0
 /// <summary>
 /// constructs the token for sending a request with http signature.
 /// </summary>
 /// <param name="signingCredentials"></param>
 /// <param name="requestBody"></param>
 /// <param name="includedHeaders"></param>
 /// <param name="createdDate"></param>
 /// <param name="expirationDate"></param>
 public HttpSignatureSecurityToken(SigningCredentials signingCredentials, byte[] requestBody, IDictionary <string, string> includedHeaders, DateTime?createdDate = null, DateTime?expirationDate = null)
 {
     Digest = new HttpDigest(signingCredentials.Algorithm, requestBody);
     includedHeaders.Add(HttpDigest.HTTPHeaderName, Digest.ToString());
     Signature = new HttpSignature(signingCredentials, includedHeaders, createdDate, expirationDate);
     RequestId = includedHeaders["X-Request-Id"];
 }
Beispiel #3
0
        /// <summary>
        /// Parses the header value string into an <see cref="HttpDigest"/> instance.
        /// </summary>
        /// <param name="headerValue"></param>
        /// <returns></returns>
        public static HttpDigest Parse(string headerValue)
        {
            var equalsSignPosition = headerValue.IndexOf('='); // do not use split because base64 uses the equals sign.

            if (equalsSignPosition < 0)
            {
                throw new FormatException($"Cannot parse HttpDigest from raw value {headerValue}");
            }
            var digest = new HttpDigest {
                Algorithm = headerValue.Substring(0, equalsSignPosition),
                Output    = headerValue.Substring(equalsSignPosition + 1),
            };

            return(digest);
        }
Beispiel #4
0
        private async Task ValidateResponse(HttpRequestMessage request, HttpResponseMessage response)
        {
            if (IgnoreResponseValidation)
            {
                return;
            }
            if (StringExtensions.IsIgnoredPath(IgnoredPaths, request.RequestUri.AbsolutePath, request.Method.Method))
            {
                return;
            }
            if (!response.Headers.TryGetValues(HttpSignature.HTTPHeaderName, out var signatureValues) || signatureValues.Count() == 0)
            {
                return;
            }
            if (!response.Headers.TryGetValues(ResponseSignatureCertificateHeaderName, out var certValues) || certValues.Count() == 0)
            {
                var error = $"Missing certificate in HTTP header '{ResponseSignatureCertificateHeaderName}'. Cannot validate signature.";
                throw new Exception(error);
            }
            var rawSignature   = signatureValues.First();
            var rawCertificate = certValues.First();

            Debug.WriteLine($"{nameof(HttpSignatureDelegatingHandler)}: Raw Signature: {rawSignature}");
            Debug.WriteLine($"{nameof(HttpSignatureDelegatingHandler)}: Raw Certificate: {rawCertificate}");
            X509Certificate2 certificate;

            try {
                certificate = new X509Certificate2(Convert.FromBase64String(rawCertificate));
            } catch (Exception inner) {
                var error = $"Signature Certificate not in a valid format. Expected a base64 encoded x509.";
                throw new Exception(error, inner);
            }
            var validationKey = new X509SecurityKey(certificate);

            Debug.WriteLine($"{nameof(HttpSignatureDelegatingHandler)}: Validation Key: {validationKey.KeyId}");
            var httpSignature = HttpSignature.Parse(rawSignature);

            if (response.Headers.TryGetValues(HttpDigest.HTTPHeaderName, out var digestValues) && digestValues.Count() > 0)
            {
                var rawDigest = digestValues.First();
                Debug.WriteLine($"{nameof(HttpSignatureDelegatingHandler)}: Raw Digest: {rawDigest}");
                var httpDigest = HttpDigest.Parse(rawDigest);
                Debug.WriteLine($"{nameof(HttpSignatureDelegatingHandler)}: Validated Token Digest: {httpDigest}");
                var responseBody = await response.Content.ReadAsByteArrayAsync();

                // Validate the request.
                var disgestIsValid = httpDigest.Validate(responseBody);
                if (!disgestIsValid)
                {
                    var error = $"Response digest validation failed.";
                    throw new Exception(error);
                }
            }
            response.Headers.TryGetValues(ResponseCreatedHeaderName, out var createdFieldValue);
            var signatureIsValid = httpSignature.Validate(validationKey, request.RequestUri, request.Method.Method, createdFieldValue.First(), response.Headers);

            if (!signatureIsValid)
            {
                var error = $"Response signature validation failed.";
                throw new Exception(error);
            }
        }