summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-09-12 06:31:18 -0700
committerAndrew <andrewarnott@gmail.com>2008-09-12 06:31:18 -0700
commit608bdfba197391ddd98acdf1a4a75062e5f431e5 (patch)
tree6baebc9a7e1a5d6b6b32f00380f35a7e4e4080bb /src
parent8fd37aa11f6da68ed6366a3f98a89feac7501f1e (diff)
downloadDotNetOpenAuth-608bdfba197391ddd98acdf1a4a75062e5f431e5.zip
DotNetOpenAuth-608bdfba197391ddd98acdf1a4a75062e5f431e5.tar.gz
DotNetOpenAuth-608bdfba197391ddd98acdf1a4a75062e5f431e5.tar.bz2
Added infrastructure for message signing support to base Channel class.
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOAuth/DotNetOAuth.csproj1
-rw-r--r--src/DotNetOAuth/Messaging/Channel.cs64
-rw-r--r--src/DotNetOAuth/Messaging/ISignedProtocolMessage.cs17
-rw-r--r--src/DotNetOAuth/Messaging/MessagingStrings.Designer.cs18
-rw-r--r--src/DotNetOAuth/Messaging/MessagingStrings.resx6
5 files changed, 101 insertions, 5 deletions
diff --git a/src/DotNetOAuth/DotNetOAuth.csproj b/src/DotNetOAuth/DotNetOAuth.csproj
index 1657b57..fbaa90e 100644
--- a/src/DotNetOAuth/DotNetOAuth.csproj
+++ b/src/DotNetOAuth/DotNetOAuth.csproj
@@ -74,6 +74,7 @@
<Compile Include="Messaging\HttpRequestInfo.cs" />
<Compile Include="Messaging\IDirectedProtocolMessage.cs" />
<Compile Include="Messaging\IMessageTypeProvider.cs" />
+ <Compile Include="Messaging\ISignedProtocolMessage.cs" />
<Compile Include="Messaging\MessagingStrings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
diff --git a/src/DotNetOAuth/Messaging/Channel.cs b/src/DotNetOAuth/Messaging/Channel.cs
index d294816..9ade2de 100644
--- a/src/DotNetOAuth/Messaging/Channel.cs
+++ b/src/DotNetOAuth/Messaging/Channel.cs
@@ -98,6 +98,7 @@ namespace DotNetOAuth.Messaging {
if (message == null) {
throw new ArgumentNullException("message");
}
+ this.SignIfApplicable(message);
switch (message.Transport) {
case MessageTransport.Direct:
@@ -149,10 +150,12 @@ namespace DotNetOAuth.Messaging {
/// <summary>
/// Gets the protocol message that may be embedded in the given HTTP request.
/// </summary>
- /// <param name="request">The request to search for an embedded message.</param>
+ /// <param name="httpRequest">The request to search for an embedded message.</param>
/// <returns>The deserialized message, if one is found. Null otherwise.</returns>
- protected internal IProtocolMessage ReadFromRequest(HttpRequestInfo request) {
- return this.ReadFromRequestInternal(request);
+ protected internal IProtocolMessage ReadFromRequest(HttpRequestInfo httpRequest) {
+ IProtocolMessage requestMessage = this.ReadFromRequestInternal(httpRequest);
+ this.VerifySignatureIfApplicable(requestMessage);
+ return requestMessage;
}
/// <summary>
@@ -161,7 +164,10 @@ namespace DotNetOAuth.Messaging {
/// <param name="request">The message to send.</param>
/// <returns>The remote party's response.</returns>
protected internal IProtocolMessage Request(IDirectedProtocolMessage request) {
- return this.RequestInternal(request);
+ this.SignIfApplicable(request);
+ IProtocolMessage response = this.RequestInternal(request);
+ this.VerifySignatureIfApplicable(response);
+ return response;
}
/// <summary>
@@ -170,7 +176,9 @@ namespace DotNetOAuth.Messaging {
/// <param name="responseStream">The response that is anticipated to contain an OAuth message.</param>
/// <returns>The deserialized message, if one is found. Null otherwise.</returns>
protected internal IProtocolMessage ReadFromResponse(Stream responseStream) {
- return this.ReadFromResponseInternal(responseStream);
+ IProtocolMessage message = this.ReadFromResponseInternal(responseStream);
+ this.VerifySignatureIfApplicable(message);
+ return message;
}
/// <summary>
@@ -313,6 +321,26 @@ namespace DotNetOAuth.Messaging {
}
/// <summary>
+ /// Signs a given message according to the rules of the channel.
+ /// </summary>
+ /// <param name="message">The message to sign.</param>
+ protected virtual void Sign(ISignedProtocolMessage message) {
+ Debug.Assert(message != null, "message == null");
+ throw new NotSupportedException(MessagingStrings.SigningNotSupported);
+ }
+
+ /// <summary>
+ /// Gets whether the signature of a signed message is valid or not
+ /// according to the rules of the channel.
+ /// </summary>
+ /// <param name="message">The message whose signature should be verified.</param>
+ /// <returns>True if the signature is valid. False otherwise.</returns>
+ protected virtual bool IsSignatureValid(ISignedProtocolMessage message) {
+ Debug.Assert(message != null, "message == null");
+ throw new NotSupportedException(MessagingStrings.SigningNotSupported);
+ }
+
+ /// <summary>
/// Gets the protocol message that may be in the given HTTP response stream.
/// </summary>
/// <param name="responseStream">The response that is anticipated to contain an OAuth message.</param>
@@ -369,5 +397,31 @@ namespace DotNetOAuth.Messaging {
}
return size;
}
+
+ /// <summary>
+ /// Signs a given message if the message requires one.
+ /// </summary>
+ /// <param name="message">The message to sign.</param>
+ private void SignIfApplicable(IProtocolMessage message) {
+ ISignedProtocolMessage signedMessage = message as ISignedProtocolMessage;
+ if (signedMessage != null) {
+ this.Sign(signedMessage);
+ }
+ }
+
+ /// <summary>
+ /// Verifies that a given message has a valid signature if the message requires one.
+ /// </summary>
+ /// <param name="message">The message to verify the signature on.</param>
+ /// <exception cref="ProtocolException">Thrown when the signature is invalid.</exception>
+ private void VerifySignatureIfApplicable(IProtocolMessage message) {
+ ISignedProtocolMessage signedMessage = message as ISignedProtocolMessage;
+ if (signedMessage != null) {
+ if (!this.IsSignatureValid(signedMessage)) {
+ // TODO: add inResponseTo and remoteReceiver where applicable
+ throw new ProtocolException(MessagingStrings.SignatureInvalid);
+ }
+ }
+ }
}
}
diff --git a/src/DotNetOAuth/Messaging/ISignedProtocolMessage.cs b/src/DotNetOAuth/Messaging/ISignedProtocolMessage.cs
new file mode 100644
index 0000000..c3aae98
--- /dev/null
+++ b/src/DotNetOAuth/Messaging/ISignedProtocolMessage.cs
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------------
+// <copyright file="ISignedProtocolMessage.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.Messaging {
+ /// <summary>
+ /// The contract a message that is signed must implement.
+ /// </summary>
+ internal interface ISignedProtocolMessage : IProtocolMessage {
+ /// <summary>
+ /// Gets or sets the message signature.
+ /// </summary>
+ string Signature { get; set; }
+ }
+}
diff --git a/src/DotNetOAuth/Messaging/MessagingStrings.Designer.cs b/src/DotNetOAuth/Messaging/MessagingStrings.Designer.cs
index 0de92f6..e4d767d 100644
--- a/src/DotNetOAuth/Messaging/MessagingStrings.Designer.cs
+++ b/src/DotNetOAuth/Messaging/MessagingStrings.Designer.cs
@@ -124,6 +124,24 @@ namespace DotNetOAuth.Messaging {
}
/// <summary>
+ /// Looks up a localized string similar to Message signature was incorrect..
+ /// </summary>
+ internal static string SignatureInvalid {
+ get {
+ return ResourceManager.GetString("SignatureInvalid", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to This channel does not support signing messages. To support signing messages, a derived Channel type must override the Sign and IsSignatureValid methods..
+ /// </summary>
+ internal static string SigningNotSupported {
+ get {
+ return ResourceManager.GetString("SigningNotSupported", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to The type {0} or a derived type was expected, but {1} was given..
/// </summary>
internal static string UnexpectedType {
diff --git a/src/DotNetOAuth/Messaging/MessagingStrings.resx b/src/DotNetOAuth/Messaging/MessagingStrings.resx
index 2ac776a..8548afb 100644
--- a/src/DotNetOAuth/Messaging/MessagingStrings.resx
+++ b/src/DotNetOAuth/Messaging/MessagingStrings.resx
@@ -138,6 +138,12 @@
<data name="QueuedMessageResponseAlreadyExists" xml:space="preserve">
<value>A message response is already queued for sending in the response stream.</value>
</data>
+ <data name="SignatureInvalid" xml:space="preserve">
+ <value>Message signature was incorrect.</value>
+ </data>
+ <data name="SigningNotSupported" xml:space="preserve">
+ <value>This channel does not support signing messages. To support signing messages, a derived Channel type must override the Sign and IsSignatureValid methods.</value>
+ </data>
<data name="UnexpectedType" xml:space="preserve">
<value>The type {0} or a derived type was expected, but {1} was given.</value>
</data>