/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.2. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { string key = GetConsumerAndTokenSecretString(message); HashAlgorithm hasher = new HMACSHA1(Encoding.ASCII.GetBytes(key)); string baseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] digest = hasher.ComputeHash(Encoding.ASCII.GetBytes(baseString)); return Convert.ToBase64String(digest); }
/// <summary> /// Constructs the OAuth Signature Base String and returns the result. /// </summary> /// <param name="message">The message to derive the signature base string from.</param> /// <returns>The signature base string.</returns> /// <remarks> /// This method implements OAuth 1.0 section 9.1. /// </remarks> protected static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message) { if (String.IsNullOrEmpty(message.HttpMethod)) { throw new ArgumentException( string.Format( CultureInfo.CurrentCulture, MessagingStrings.ArgumentPropertyMissing, typeof(ITamperResistantOAuthMessage).Name, "HttpMethod"), "message"); } List <string> signatureBaseStringElements = new List <string>(3); signatureBaseStringElements.Add(message.HttpMethod.ToUpperInvariant()); UriBuilder endpoint = new UriBuilder(message.Recipient); endpoint.Query = null; endpoint.Fragment = null; signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri); var encodedDictionary = OAuthChannel.GetUriEscapedParameters(message); encodedDictionary.Remove("oauth_signature"); var sortedKeyValueList = new List <KeyValuePair <string, string> >(encodedDictionary); sortedKeyValueList.Sort(SignatureBaseStringParameterComparer); StringBuilder paramBuilder = new StringBuilder(); foreach (var pair in sortedKeyValueList) { if (paramBuilder.Length > 0) { paramBuilder.Append("&"); } paramBuilder.Append(pair.Key); paramBuilder.Append('='); paramBuilder.Append(pair.Value); } signatureBaseStringElements.Add(paramBuilder.ToString()); StringBuilder signatureBaseString = new StringBuilder(); foreach (string element in signatureBaseStringElements) { if (signatureBaseString.Length > 0) { signatureBaseString.Append("&"); } signatureBaseString.Append(Uri.EscapeDataString(element)); } Logger.DebugFormat("Constructed signature base string: {0}", signatureBaseString); return(signatureBaseString.ToString()); }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) { if (this.ConsumerCertificateProvider == null) { throw new InvalidOperationException(OAuthStrings.ConsumerCertificateProviderNotAvailable); } string signatureBaseString = ConstructSignatureBaseString(message); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); byte[] carriedSignature = Convert.FromBase64String(message.Signature); X509Certificate2 cert = this.ConsumerCertificateProvider.GetCertificate(message); if (cert == null) { Logger.WarnFormat("Incoming message from consumer '{0}' could not be matched with an appropriate X.509 certificate for signature verification.", message.ConsumerKey); return(false); } var provider = (RSACryptoServiceProvider)cert.PublicKey.Key; bool valid = provider.VerifyData(data, "SHA1", carriedSignature); return(valid); }
/// <summary> /// Initializes a new instance of the <see cref="SignedMessageBase"/> class. /// </summary> /// <param name="transport">A value indicating whether this message requires a direct or indirect transport.</param> /// <param name="recipient">The URI that a directed message will be delivered to.</param> internal SignedMessageBase(MessageTransport transport, MessageReceivingEndpoint recipient) : base(MessageProtections.All, transport, recipient) { ITamperResistantOAuthMessage self = (ITamperResistantOAuthMessage)this; HttpDeliveryMethods methods = ((IDirectedProtocolMessage)this).HttpMethods; self.HttpMethod = (methods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET"; }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected virtual bool IsSignatureValid(ITamperResistantOAuthMessage message) { Contract.Requires <ArgumentNullException>(message != null); string signature = this.GetSignature(message); return(MessagingUtilities.EqualsConstantTime(message.Signature, signature)); }
/// <summary> /// Initializes a new instance of the <see cref="SignedMessageBase"/> class. /// </summary> /// <param name="transport">A value indicating whether this message requires a direct or indirect transport.</param> /// <param name="recipient">The URI that a directed message will be delivered to.</param> /// <param name="version">The OAuth version.</param> internal SignedMessageBase(MessageTransport transport, MessageReceivingEndpoint recipient, Version version) : base(MessageProtections.All, transport, recipient, version) { ITamperResistantOAuthMessage self = (ITamperResistantOAuthMessage)this; HttpDeliveryMethods methods = ((IDirectedProtocolMessage)this).HttpMethods; self.HttpMethod = MessagingUtilities.GetHttpVerb(methods); }
/// <summary> /// Checks whether this binding element applies to this message. /// </summary> /// <param name="message">The message that needs to be signed.</param> /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns> protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) { if (string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { return true; } else { Logger.Bindings.DebugFormat("The {0} element will not sign this message because the URI scheme is not https.", this.GetType().Name); return false; } }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected virtual bool IsSignatureValid(ITamperResistantOAuthMessage message) { Requires.NotNull(message, "message"); string signature = this.GetSignature(message); return(MessagingUtilities.EqualsConstantTime(message.Signature, signature)); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.2. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { string key = GetConsumerAndTokenSecretString(message); HashAlgorithm hasher = new HMACSHA1(Encoding.ASCII.GetBytes(key)); string baseString = ConstructSignatureBaseString(message); byte[] digest = hasher.ComputeHash(Encoding.ASCII.GetBytes(baseString)); return(Convert.ToBase64String(digest)); }
protected override string GetSignature(ITamperResistantOAuthMessage message) { string key = GetConsumerAndTokenSecretString(message); using (var hasher = HmacAlgorithms.Create(HmacAlgorithms.HmacSha1, Encoding.ASCII.GetBytes(key))) { string baseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] digest = hasher.ComputeHash(Encoding.ASCII.GetBytes(baseString)); return(Convert.ToBase64String(digest)); } }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.3. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { ErrorUtilities.VerifyOperation(this.SigningCertificate != null, OAuthStrings.X509CertificateNotProvidedForSigning); string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); var provider = (RSACryptoServiceProvider)this.SigningCertificate.PrivateKey; byte[] binarySignature = provider.SignData(data, "SHA1"); string base64Signature = Convert.ToBase64String(binarySignature); return base64Signature; }
/// <summary> /// Checks whether this binding element applies to this message. /// </summary> /// <param name="message">The message that needs to be signed.</param> /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns> protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) { if (string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { return(true); } else { Logger.Bindings.DebugFormat("The {0} element will not sign this message because the URI scheme is not https.", this.GetType().Name); return(false); } }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.3. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { ErrorUtilities.VerifyOperation(this.SigningCertificate != null, OAuthStrings.X509CertificateNotProvidedForSigning); string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); var provider = (RSACryptoServiceProvider)this.SigningCertificate.PrivateKey; byte[] binarySignature = provider.SignData(data, "SHA1"); string base64Signature = Convert.ToBase64String(binarySignature); return(base64Signature); }
/// <summary> /// Gets the "ConsumerSecret&TokenSecret" string, allowing either property to be empty or null. /// </summary> /// <param name="message">The message to extract the secrets from.</param> /// <returns>The concatenated string.</returns> protected static string GetConsumerAndTokenSecretString(ITamperResistantOAuthMessage message) { StringBuilder builder = new StringBuilder(); if (!string.IsNullOrEmpty(message.ConsumerSecret)) { builder.Append(MessagingUtilities.EscapeUriDataStringRfc3986(message.ConsumerSecret)); } builder.Append("&"); if (!string.IsNullOrEmpty(message.TokenSecret)) { builder.Append(MessagingUtilities.EscapeUriDataStringRfc3986(message.TokenSecret)); } return(builder.ToString()); }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) { ErrorUtilities.VerifyInternal(this.tokenManager != null, "No token manager available for fetching Consumer public certificates."); string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); byte[] carriedSignature = Convert.FromBase64String(message.Signature); X509Certificate2 cert = this.tokenManager.GetConsumer(message.ConsumerKey).Certificate; if (cert == null) { Logger.Signatures.WarnFormat("Incoming message from consumer '{0}' could not be matched with an appropriate X.509 certificate for signature verification.", message.ConsumerKey); return false; } var provider = (RSACryptoServiceProvider)cert.PublicKey.Key; bool valid = provider.VerifyData(data, "SHA1", carriedSignature); return valid; }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.3. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { if (message == null) { throw new ArgumentNullException("message"); } if (this.SigningCertificate == null) { throw new InvalidOperationException(OAuthStrings.X509CertificateNotProvidedForSigning); } string signatureBaseString = ConstructSignatureBaseString(message); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); var provider = (RSACryptoServiceProvider)this.SigningCertificate.PublicKey.Key; byte[] binarySignature = provider.SignData(data, "SHA1"); string base64Signature = Convert.ToBase64String(binarySignature); return(base64Signature); }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) { ErrorUtilities.VerifyInternal(this.tokenManager != null, "No token manager available for fetching Consumer public certificates."); string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); byte[] carriedSignature = Convert.FromBase64String(message.Signature); X509Certificate2 cert = this.tokenManager.GetConsumer(message.ConsumerKey).Certificate; if (cert == null) { Logger.Signatures.WarnFormat("Incoming message from consumer '{0}' could not be matched with an appropriate X.509 certificate for signature verification.", message.ConsumerKey); return(false); } var provider = (RSACryptoServiceProvider)cert.PublicKey.Key; bool valid = provider.VerifyData(data, "SHA1", carriedSignature); return(valid); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns> /// The signature for the message. /// </returns> protected override string GetSignature(ITamperResistantOAuthMessage message) { throw new NotImplementedException(); }
internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) { Requires.NotNull(message, "message"); Requires.NotNull(message.HttpMethod, "message.HttpMethod"); Requires.NotNull(messageDictionary, "messageDictionary"); ErrorUtilities.VerifyInternal(messageDictionary.Message == message, "Message references are not equal."); List <string> signatureBaseStringElements = new List <string>(3); signatureBaseStringElements.Add(message.HttpMethod.ToString().ToUpperInvariant()); // For multipart POST messages, only include the message parts that are NOT // in the POST entity (those parts that may appear in an OAuth authorization header). var encodedDictionary = new Dictionary <string, string>(); IEnumerable <KeyValuePair <string, string> > partsToInclude = Enumerable.Empty <KeyValuePair <string, string> >(); var binaryMessage = message as IMessageWithBinaryData; if (binaryMessage != null && binaryMessage.SendAsMultipart) { HttpDeliveryMethods authHeaderInUseFlags = HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest; ErrorUtilities.VerifyProtocol((binaryMessage.HttpMethods & authHeaderInUseFlags) == authHeaderInUseFlags, OAuthStrings.MultipartPostMustBeUsedWithAuthHeader); // Include the declared keys in the signature as those will be signable. // Cache in local variable to avoid recalculating DeclaredKeys in the delegate. ICollection <string> declaredKeys = messageDictionary.DeclaredKeys; partsToInclude = messageDictionary.Where(pair => declaredKeys.Contains(pair.Key)); } else { partsToInclude = messageDictionary; } // If this message was deserialized, include only those explicitly included message parts (excludes defaulted values) // in the signature. var originalPayloadMessage = (IMessageOriginalPayload)message; if (originalPayloadMessage.OriginalPayload != null) { partsToInclude = partsToInclude.Where(pair => originalPayloadMessage.OriginalPayload.ContainsKey(pair.Key)); } foreach (var pair in OAuthChannel.GetUriEscapedParameters(partsToInclude)) { encodedDictionary[pair.Key] = pair.Value; } // An incoming message will already have included the query and form parameters // in the message dictionary, but an outgoing message COULD have SOME parameters // in the query that are not in the message dictionary because they were included // in the receiving endpoint (the original URL). // In an outgoing message, the POST entity can only contain parameters if they were // in the message dictionary, so no need to pull out any parameters from there. if (message.Recipient.Query != null) { NameValueCollection nvc = HttpUtility.ParseQueryString(message.Recipient.Query); foreach (string key in nvc) { string escapedKey = MessagingUtilities.EscapeUriDataStringRfc3986(key); string escapedValue = MessagingUtilities.EscapeUriDataStringRfc3986(nvc[key]); string existingValue; if (!encodedDictionary.TryGetValue(escapedKey, out existingValue)) { encodedDictionary.Add(escapedKey, escapedValue); } else { ErrorUtilities.VerifyInternal(escapedValue == existingValue, "Somehow we have conflicting values for the '{0}' parameter.", escapedKey); } } } encodedDictionary.Remove("oauth_signature"); UriBuilder endpoint = new UriBuilder(message.Recipient); endpoint.Query = null; endpoint.Fragment = null; signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri); var sortedKeyValueList = new List <KeyValuePair <string, string> >(encodedDictionary); sortedKeyValueList.Sort(SignatureBaseStringParameterComparer); StringBuilder paramBuilder = new StringBuilder(); foreach (var pair in sortedKeyValueList) { if (paramBuilder.Length > 0) { paramBuilder.Append("&"); } paramBuilder.Append(pair.Key); paramBuilder.Append('='); paramBuilder.Append(pair.Value); } signatureBaseStringElements.Add(paramBuilder.ToString()); StringBuilder signatureBaseString = new StringBuilder(); foreach (string element in signatureBaseStringElements) { if (signatureBaseString.Length > 0) { signatureBaseString.Append("&"); } signatureBaseString.Append(MessagingUtilities.EscapeUriDataStringRfc3986(element)); } Logger.Bindings.DebugFormat("Constructed signature base string: {0}", signatureBaseString); return(signatureBaseString.ToString()); }
protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) { message.Recipient = new Uri(new Uri(CustomUrlProvider.CreateApplicationUri(null)), message.Recipient.PathAndQuery); return(base.IsSignatureValid(message)); }
/// <summary> /// Checks whether this binding element applies to this message. /// </summary> /// <param name="message">The message that needs to be signed.</param> /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns> protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) { return string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase); }
/// <summary> /// Checks whether this binding element applies to this message. /// </summary> /// <param name="message">The message that needs to be signed.</param> /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns> protected virtual bool IsMessageApplicable(ITamperResistantOAuthMessage message) { return string.IsNullOrEmpty(message.SignatureMethod) || message.SignatureMethod == this.signatureMethod; }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected virtual bool IsSignatureValid(ITamperResistantOAuthMessage message) { Requires.NotNull(message, "message"); string signature = this.GetSignature(message); return MessagingUtilities.EqualsConstantTime(message.Signature, signature); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> protected override string GetSignature(ITamperResistantOAuthMessage message) { Contract.Requires(this.Channel != null); throw new NotImplementedException(); }
/// <summary> /// Checks whether this binding element applies to this message. /// </summary> /// <param name="message">The message that needs to be signed.</param> /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns> protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) { return(string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase)); }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) { throw new NotImplementedException(); }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected virtual bool IsSignatureValid(ITamperResistantOAuthMessage message) { Contract.Requires<ArgumentNullException>(message != null); string signature = this.GetSignature(message); return MessagingUtilities.EqualsConstantTime(message.Signature, signature); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.3. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { if (message == null) { throw new ArgumentNullException("message"); } if (this.SigningCertificate == null) { throw new InvalidOperationException(OAuthStrings.X509CertificateNotProvidedForSigning); } string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); var provider = (RSACryptoServiceProvider)this.SigningCertificate.PublicKey.Key; byte[] binarySignature = provider.SignData(data, "SHA1"); string base64Signature = Convert.ToBase64String(binarySignature); return base64Signature; }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) { if (this.ConsumerCertificateProvider == null) { throw new InvalidOperationException(OAuthStrings.ConsumerCertificateProviderNotAvailable); } string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); byte[] carriedSignature = Convert.FromBase64String(message.Signature); X509Certificate2 cert = this.ConsumerCertificateProvider.GetCertificate(message); if (cert == null) { Logger.Signatures.WarnFormat("Incoming message from consumer '{0}' could not be matched with an appropriate X.509 certificate for signature verification.", message.ConsumerKey); return false; } var provider = (RSACryptoServiceProvider)cert.PublicKey.Key; bool valid = provider.VerifyData(data, "SHA1", carriedSignature); return valid; }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.2. /// </remarks> internal string GetSignatureTestHook(ITamperResistantOAuthMessage message) { return this.GetSignature(message); }
/// <summary> /// Gets the "ConsumerSecret&TokenSecret" string, allowing either property to be empty or null. /// </summary> /// <param name="message">The message to extract the secrets from.</param> /// <returns>The concatenated string.</returns> protected static string GetConsumerAndTokenSecretString(ITamperResistantOAuthMessage message) { StringBuilder builder = new StringBuilder(); if (!string.IsNullOrEmpty(message.ConsumerSecret)) { builder.Append(MessagingUtilities.EscapeUriDataStringRfc3986(message.ConsumerSecret)); } builder.Append("&"); if (!string.IsNullOrEmpty(message.TokenSecret)) { builder.Append(MessagingUtilities.EscapeUriDataStringRfc3986(message.TokenSecret)); } return builder.ToString(); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> protected abstract string GetSignature(ITamperResistantOAuthMessage message);
/// <summary> /// Constructs the OAuth Signature Base String and returns the result. /// </summary> /// <param name="message">The message.</param> /// <param name="messageDictionary">The message to derive the signature base string from.</param> /// <returns>The signature base string.</returns> /// <remarks> /// This method implements OAuth 1.0 section 9.1. /// </remarks> internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) { Contract.Requires(message != null); Contract.Requires(messageDictionary != null); Contract.Requires(messageDictionary.Message == message); if (String.IsNullOrEmpty(message.HttpMethod)) { throw new ArgumentException( string.Format( CultureInfo.CurrentCulture, MessagingStrings.ArgumentPropertyMissing, typeof(ITamperResistantOAuthMessage).Name, "HttpMethod"), "message"); } List<string> signatureBaseStringElements = new List<string>(3); signatureBaseStringElements.Add(message.HttpMethod.ToUpperInvariant()); UriBuilder endpoint = new UriBuilder(message.Recipient); endpoint.Query = null; endpoint.Fragment = null; signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri); var encodedDictionary = OAuthChannel.GetUriEscapedParameters(messageDictionary); encodedDictionary.Remove("oauth_signature"); var sortedKeyValueList = new List<KeyValuePair<string, string>>(encodedDictionary); sortedKeyValueList.Sort(SignatureBaseStringParameterComparer); StringBuilder paramBuilder = new StringBuilder(); foreach (var pair in sortedKeyValueList) { if (paramBuilder.Length > 0) { paramBuilder.Append("&"); } paramBuilder.Append(pair.Key); paramBuilder.Append('='); paramBuilder.Append(pair.Value); } signatureBaseStringElements.Add(paramBuilder.ToString()); StringBuilder signatureBaseString = new StringBuilder(); foreach (string element in signatureBaseStringElements) { if (signatureBaseString.Length > 0) { signatureBaseString.Append("&"); } signatureBaseString.Append(Uri.EscapeDataString(element)); } Logger.Bindings.DebugFormat("Constructed signature base string: {0}", signatureBaseString); return signatureBaseString.ToString(); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message according to OAuth 1.0 section 9.4.1. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { return GetConsumerAndTokenSecretString(message); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> protected override string GetSignature(ITamperResistantOAuthMessage message) { Requires.NotNull(message, "message"); Requires.ValidState(this.Channel != null); throw new NotImplementedException(); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> protected override string GetSignature(ITamperResistantOAuthMessage message) { Contract.Requires<ArgumentNullException>(message != null); Contract.Requires<InvalidOperationException>(this.Channel != null); throw new NotImplementedException(); }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected virtual bool IsSignatureValid(ITamperResistantOAuthMessage message) { string signature = this.GetSignature(message); return message.Signature == signature; }
/// <summary> /// Determines whether the signature on some message is valid. /// </summary> /// <param name="message">The message to check the signature on.</param> /// <returns> /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>. /// </returns> protected virtual bool IsSignatureValid(ITamperResistantOAuthMessage message) { string signature = this.GetSignature(message); return(message.Signature == signature); }
/// <summary> /// Constructs the OAuth Signature Base String and returns the result. /// </summary> /// <param name="message">The message.</param> /// <param name="messageDictionary">The message to derive the signature base string from.</param> /// <returns>The signature base string.</returns> /// <remarks> /// This method implements OAuth 1.0 section 9.1. /// </remarks> internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) { Contract.Requires(message != null); Contract.Requires(messageDictionary != null); Contract.Requires(messageDictionary.Message == message); if (String.IsNullOrEmpty(message.HttpMethod)) { throw new ArgumentException( string.Format( CultureInfo.CurrentCulture, MessagingStrings.ArgumentPropertyMissing, typeof(ITamperResistantOAuthMessage).Name, "HttpMethod"), "message"); } List<string> signatureBaseStringElements = new List<string>(3); signatureBaseStringElements.Add(message.HttpMethod.ToUpperInvariant()); var encodedDictionary = OAuthChannel.GetUriEscapedParameters(messageDictionary); // An incoming message will already have included the query and form parameters // in the message dictionary, but an outgoing message COULD have SOME parameters // in the query that are not in the message dictionary because they were included // in the receiving endpoint (the original URL). // In an outgoing message, the POST entity can only contain parameters if they were // in the message dictionary, so no need to pull out any parameters from there. if (message.Recipient.Query != null) { NameValueCollection nvc = HttpUtility.ParseQueryString(message.Recipient.Query); foreach (string key in nvc) { string escapedKey = MessagingUtilities.EscapeUriDataStringRfc3986(key); string escapedValue = MessagingUtilities.EscapeUriDataStringRfc3986(nvc[key]); string existingValue; if (!encodedDictionary.TryGetValue(escapedKey, out existingValue)) { encodedDictionary.Add(escapedKey, escapedValue); } else { ErrorUtilities.VerifyInternal(escapedValue == existingValue, "Somehow we have conflicting values for the '{0}' parameter.", escapedKey); } } } encodedDictionary.Remove("oauth_signature"); UriBuilder endpoint = new UriBuilder(message.Recipient); endpoint.Query = null; endpoint.Fragment = null; signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri); var sortedKeyValueList = new List<KeyValuePair<string, string>>(encodedDictionary); sortedKeyValueList.Sort(SignatureBaseStringParameterComparer); StringBuilder paramBuilder = new StringBuilder(); foreach (var pair in sortedKeyValueList) { if (paramBuilder.Length > 0) { paramBuilder.Append("&"); } paramBuilder.Append(pair.Key); paramBuilder.Append('='); paramBuilder.Append(pair.Value); } signatureBaseStringElements.Add(paramBuilder.ToString()); StringBuilder signatureBaseString = new StringBuilder(); foreach (string element in signatureBaseStringElements) { if (signatureBaseString.Length > 0) { signatureBaseString.Append("&"); } signatureBaseString.Append(MessagingUtilities.EscapeUriDataStringRfc3986(element)); } Logger.Bindings.DebugFormat("Constructed signature base string: {0}", signatureBaseString); return signatureBaseString.ToString(); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> protected override string GetSignature(ITamperResistantOAuthMessage message) { Contract.Requires <ArgumentNullException>(message != null); Contract.Requires <InvalidOperationException>(this.Channel != null); throw new NotImplementedException(); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message per OAuth 1.0 section 9.2. /// </remarks> internal string GetSignatureTestHook(ITamperResistantOAuthMessage message) { return(this.GetSignature(message)); }
/// <summary> /// Calculates a signature for a given message. /// </summary> /// <param name="message">The message to sign.</param> /// <returns>The signature for the message.</returns> /// <remarks> /// This method signs the message according to OAuth 1.0 section 9.4.1. /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { return(GetConsumerAndTokenSecretString(message)); }
internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) { Requires.NotNull(message, "message"); Requires.NotNullOrEmpty(message.HttpMethod, "message.HttpMethod"); Requires.NotNull(messageDictionary, "messageDictionary"); ErrorUtilities.VerifyInternal(messageDictionary.Message == message, "Message references are not equal."); List<string> signatureBaseStringElements = new List<string>(3); signatureBaseStringElements.Add(message.HttpMethod.ToUpperInvariant()); // For multipart POST messages, only include the message parts that are NOT // in the POST entity (those parts that may appear in an OAuth authorization header). var encodedDictionary = new Dictionary<string, string>(); IEnumerable<KeyValuePair<string, string>> partsToInclude = Enumerable.Empty<KeyValuePair<string, string>>(); var binaryMessage = message as IMessageWithBinaryData; if (binaryMessage != null && binaryMessage.SendAsMultipart) { HttpDeliveryMethods authHeaderInUseFlags = HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest; ErrorUtilities.VerifyProtocol((binaryMessage.HttpMethods & authHeaderInUseFlags) == authHeaderInUseFlags, OAuthStrings.MultipartPostMustBeUsedWithAuthHeader); // Include the declared keys in the signature as those will be signable. // Cache in local variable to avoid recalculating DeclaredKeys in the delegate. ICollection<string> declaredKeys = messageDictionary.DeclaredKeys; partsToInclude = messageDictionary.Where(pair => declaredKeys.Contains(pair.Key)); } else { partsToInclude = messageDictionary; } // If this message was deserialized, include only those explicitly included message parts (excludes defaulted values) // in the signature. var originalPayloadMessage = (IMessageOriginalPayload)message; if (originalPayloadMessage.OriginalPayload != null) { partsToInclude = partsToInclude.Where(pair => originalPayloadMessage.OriginalPayload.ContainsKey(pair.Key)); } foreach (var pair in OAuthChannel.GetUriEscapedParameters(partsToInclude)) { encodedDictionary[pair.Key] = pair.Value; } // An incoming message will already have included the query and form parameters // in the message dictionary, but an outgoing message COULD have SOME parameters // in the query that are not in the message dictionary because they were included // in the receiving endpoint (the original URL). // In an outgoing message, the POST entity can only contain parameters if they were // in the message dictionary, so no need to pull out any parameters from there. if (message.Recipient.Query != null) { NameValueCollection nvc = HttpUtility.ParseQueryString(message.Recipient.Query); foreach (string key in nvc) { string escapedKey = MessagingUtilities.EscapeUriDataStringRfc3986(key); string escapedValue = MessagingUtilities.EscapeUriDataStringRfc3986(nvc[key]); string existingValue; if (!encodedDictionary.TryGetValue(escapedKey, out existingValue)) { encodedDictionary.Add(escapedKey, escapedValue); } else { ErrorUtilities.VerifyInternal(escapedValue == existingValue, "Somehow we have conflicting values for the '{0}' parameter.", escapedKey); } } } encodedDictionary.Remove("oauth_signature"); UriBuilder endpoint = new UriBuilder(message.Recipient); endpoint.Query = null; endpoint.Fragment = null; signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri); var sortedKeyValueList = new List<KeyValuePair<string, string>>(encodedDictionary); sortedKeyValueList.Sort(SignatureBaseStringParameterComparer); StringBuilder paramBuilder = new StringBuilder(); foreach (var pair in sortedKeyValueList) { if (paramBuilder.Length > 0) { paramBuilder.Append("&"); } paramBuilder.Append(pair.Key); paramBuilder.Append('='); paramBuilder.Append(pair.Value); } signatureBaseStringElements.Add(paramBuilder.ToString()); StringBuilder signatureBaseString = new StringBuilder(); foreach (string element in signatureBaseStringElements) { if (signatureBaseString.Length > 0) { signatureBaseString.Append("&"); } signatureBaseString.Append(MessagingUtilities.EscapeUriDataStringRfc3986(element)); } Logger.Bindings.DebugFormat("Constructed signature base string: {0}", signatureBaseString); return signatureBaseString.ToString(); }
/// <summary> /// Checks whether this binding element applies to this message. /// </summary> /// <param name="message">The message that needs to be signed.</param> /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns> protected virtual bool IsMessageApplicable(ITamperResistantOAuthMessage message) { return(string.IsNullOrEmpty(message.SignatureMethod) || message.SignatureMethod == this.signatureMethod); }