Exemplo n.º 1
0
        /// <summary>
        /// Gets the return to signature.
        /// </summary>
        /// <param name="returnTo">The return to.</param>
        /// <returns>The generated signature.</returns>
        /// <remarks>
        /// Only the parameters in the return_to URI are signed, rather than the base URI
        /// itself, in order that OPs that might change the return_to's implicit port :80 part
        /// or other minor changes do not invalidate the signature.
        /// </remarks>
        private string GetReturnToSignature(Uri returnTo)
        {
            Contract.Requires <ArgumentNullException>(returnTo != null);

            // Assemble the dictionary to sign, taking care to remove the signature itself
            // in order to accurately reproduce the original signature (which of course didn't include
            // the signature).
            // Also we need to sort the dictionary's keys so that we sign in the same order as we did
            // the last time.
            var returnToParameters = HttpUtility.ParseQueryString(returnTo.Query);

            returnToParameters.Remove(ReturnToSignatureParameterName);
            var sortedReturnToParameters = new SortedDictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (string key in returnToParameters)
            {
                sortedReturnToParameters.Add(key, returnToParameters[key]);
            }

            Logger.Bindings.DebugFormat("ReturnTo signed data: {0}{1}", Environment.NewLine, sortedReturnToParameters.ToStringDeferred());

            // Sign the parameters.
            byte[] bytesToSign = KeyValueFormEncoding.GetBytes(sortedReturnToParameters);
            byte[] signature;
            try {
                signature = this.secretManager.Sign(bytesToSign, returnToParameters[ReturnToSignatureHandleParameterName]);
            } catch (ProtocolException ex) {
                throw ErrorUtilities.Wrap(ex, OpenIdStrings.MaximumAuthenticationTimeExpired);
            }
            string signatureBase64 = Convert.ToBase64String(signature);

            return(signatureBase64);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Calculates the signature for a given message.
        /// </summary>
        /// <param name="signedMessage">The message to sign or verify.</param>
        /// <param name="association">The association to use to sign the message.</param>
        /// <returns>The calculated signature of the method.</returns>
        protected string GetSignature(ITamperResistantOpenIdMessage signedMessage, Association association)
        {
            Requires.NotNull(signedMessage, "signedMessage");
            Requires.That(!string.IsNullOrEmpty(signedMessage.SignedParameterOrder), "signedMessage", "SignedParameterOrder must not be null or empty.");
            Requires.NotNull(association, "association");

            // Prepare the parts to sign, taking care to replace an openid.mode value
            // of check_authentication with its original id_res so the signature matches.
            MessageDictionary dictionary = this.Channel.MessageDescriptions.GetAccessor(signedMessage);
            var parametersToSign         = from name in signedMessage.SignedParameterOrder.Split(',')
                                           let prefixedName = Protocol.V20.openid.Prefix + name
                                                              select new KeyValuePair <string, string>(name, dictionary.GetValueOrThrow(prefixedName, signedMessage));

            byte[] dataToSign = KeyValueFormEncoding.GetBytes(parametersToSign);
            string signature  = Convert.ToBase64String(association.Sign(dataToSign));

            if (Logger.Signatures.IsDebugEnabled)
            {
                Logger.Signatures.DebugFormat(
                    "Signing these message parts: {0}{1}{0}Base64 representation of signed data: {2}{0}Signature: {3}",
                    Environment.NewLine,
                    parametersToSign.ToStringDeferred(),
                    Convert.ToBase64String(dataToSign),
                    signature);
            }

            return(signature);
        }
        /// <summary>
        /// Calculates the signature for a given message.
        /// </summary>
        /// <param name="signedMessage">The message to sign or verify.</param>
        /// <param name="association">The association to use to sign the message.</param>
        /// <returns>The calculated signature of the method.</returns>
        private static string GetSignature(ITamperResistantOpenIdMessage signedMessage, Association association)
        {
            ErrorUtilities.VerifyArgumentNotNull(signedMessage, "signedMessage");
            ErrorUtilities.VerifyNonZeroLength(signedMessage.SignedParameterOrder, "signedMessage.SignedParameterOrder");
            ErrorUtilities.VerifyArgumentNotNull(association, "association");

            // Prepare the parts to sign, taking care to replace an openid.mode value
            // of check_authentication with its original id_res so the signature matches.
            MessageDictionary dictionary = new MessageDictionary(signedMessage);
            var parametersToSign         = from name in signedMessage.SignedParameterOrder.Split(',')
                                           let prefixedName = Protocol.V20.openid.Prefix + name
                                                              select new KeyValuePair <string, string>(name, dictionary[prefixedName]);

            byte[] dataToSign = KeyValueFormEncoding.GetBytes(parametersToSign);
            string signature  = Convert.ToBase64String(association.Sign(dataToSign));

            if (signingLogger.IsDebugEnabled)
            {
                signingLogger.DebugFormat(
                    CultureInfo.InvariantCulture,
                    "Signing these message parts: {0}{1}{0}Base64 representation of signed data: {2}{0}Signature: {3}",
                    Environment.NewLine,
                    parametersToSign.ToStringDeferred(),
                    Convert.ToBase64String(dataToSign),
                    signature);
            }

            return(signature);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the return to signature.
        /// </summary>
        /// <param name="returnTo">The return to.</param>
        /// <param name="cryptoKey">The crypto key.</param>
        /// <returns>
        /// The generated signature.
        /// </returns>
        /// <remarks>
        /// Only the parameters in the return_to URI are signed, rather than the base URI
        /// itself, in order that OPs that might change the return_to's implicit port :80 part
        /// or other minor changes do not invalidate the signature.
        /// </remarks>
        private byte[] GetReturnToSignature(Uri returnTo, CryptoKey cryptoKey = null)
        {
            Requires.NotNull(returnTo, "returnTo");

            // Assemble the dictionary to sign, taking care to remove the signature itself
            // in order to accurately reproduce the original signature (which of course didn't include
            // the signature).
            // Also we need to sort the dictionary's keys so that we sign in the same order as we did
            // the last time.
            var returnToParameters = HttpUtility.ParseQueryString(returnTo.Query);

            returnToParameters.Remove(ReturnToSignatureParameterName);
            var sortedReturnToParameters = new SortedDictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (string key in returnToParameters)
            {
                sortedReturnToParameters.Add(key, returnToParameters[key]);
            }

            Logger.Bindings.DebugFormat("ReturnTo signed data: {0}{1}", Environment.NewLine, sortedReturnToParameters.ToStringDeferred());

            // Sign the parameters.
            byte[] bytesToSign = KeyValueFormEncoding.GetBytes(sortedReturnToParameters);
            byte[] signature;
            try {
                if (cryptoKey == null)
                {
                    cryptoKey = this.cryptoKeyStore.GetKey(SecretUri.AbsoluteUri, returnToParameters[ReturnToSignatureHandleParameterName]);
                    ErrorUtilities.VerifyProtocol(
                        cryptoKey != null,
                        MessagingStrings.MissingDecryptionKeyForHandle,
                        SecretUri.AbsoluteUri,
                        returnToParameters[ReturnToSignatureHandleParameterName]);
                }

                using (var signer = HmacAlgorithms.Create(HmacAlgorithms.HmacSha256, cryptoKey.Key)) {
                    signature = signer.ComputeHash(bytesToSign);
                }
            } catch (ProtocolException ex) {
                throw ErrorUtilities.Wrap(ex, OpenIdStrings.MaximumAuthenticationTimeExpired);
            }

            return(signature);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Queues a message for sending in the response stream where the fields
        /// are sent in the response stream in querystring style.
        /// </summary>
        /// <param name="response">The message to send as a response.</param>
        /// <returns>
        /// The pending user agent redirect based message to be sent as an HttpResponse.
        /// </returns>
        /// <remarks>
        /// This method implements spec V1.0 section 5.3.
        /// </remarks>
        protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response)
        {
            var messageAccessor = this.MessageDescriptions.GetAccessor(response);
            var fields          = messageAccessor.Serialize();

            byte[] keyValueEncoding = KeyValueFormEncoding.GetBytes(fields);

            OutgoingWebResponse preparedResponse = new OutgoingWebResponse();

            preparedResponse.Headers.Add(HttpResponseHeader.ContentType, KeyValueFormContentType);
            preparedResponse.OriginalMessage = response;
            preparedResponse.ResponseStream  = new MemoryStream(keyValueEncoding);

            IHttpDirectResponse httpMessage = response as IHttpDirectResponse;

            if (httpMessage != null)
            {
                preparedResponse.Status = httpMessage.HttpStatusCode;
            }

            return(preparedResponse);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Queues a message for sending in the response stream where the fields
        /// are sent in the response stream in querystring style.
        /// </summary>
        /// <param name="response">The message to send as a response.</param>
        /// <returns>
        /// The pending user agent redirect based message to be sent as an HttpResponse.
        /// </returns>
        /// <remarks>
        /// This method implements spec V1.0 section 5.3.
        /// </remarks>
        protected override UserAgentResponse SendDirectMessageResponse(IProtocolMessage response)
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            var serializer = MessageSerializer.Get(response.GetType());
            var fields     = serializer.Serialize(response);

            byte[] keyValueEncoding = KeyValueFormEncoding.GetBytes(fields);

            UserAgentResponse preparedResponse = new UserAgentResponse();

            preparedResponse.Headers.Add(HttpResponseHeader.ContentType, KeyValueFormContentType);
            preparedResponse.OriginalMessage = response;
            preparedResponse.ResponseStream  = new MemoryStream(keyValueEncoding);

            IHttpDirectResponse httpMessage = response as IHttpDirectResponse;

            if (httpMessage != null)
            {
                preparedResponse.Status = httpMessage.HttpStatusCode;
            }

            return(preparedResponse);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Queues a message for sending in the response stream where the fields
        /// are sent in the response stream in querystring style.
        /// </summary>
        /// <param name="response">The message to send as a response.</param>
        /// <returns>
        /// The pending user agent redirect based message to be sent as an HttpResponse.
        /// </returns>
        /// <remarks>
        /// This method implements spec V1.0 section 5.3.
        /// </remarks>
        protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response)
        {
            var messageAccessor = this.MessageDescriptions.GetAccessor(response);
            var fields          = messageAccessor.Serialize();

            byte[] keyValueEncoding = KeyValueFormEncoding.GetBytes(fields);

            var preparedResponse = new HttpResponseMessageWithOriginal(response);

            ApplyMessageTemplate(response, preparedResponse);
            var content = new StreamContent(new MemoryStream(keyValueEncoding));

            content.Headers.ContentType = new MediaTypeHeaderValue(KeyValueFormContentType);
            preparedResponse.Content    = content;

            IHttpDirectResponse httpMessage = response as IHttpDirectResponse;

            if (httpMessage != null)
            {
                preparedResponse.StatusCode = httpMessage.HttpStatusCode;
            }

            return(preparedResponse);
        }