1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
//-----------------------------------------------------------------------
// <copyright file="SignedMessageBase.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace DotNetOAuth.Messages {
using System;
using System.Collections.Generic;
using DotNetOAuth.ChannelElements;
using DotNetOAuth.Messaging;
using DotNetOAuth.Messaging.Bindings;
/// <summary>
/// A base class for all signed OAuth messages.
/// </summary>
internal class SignedMessageBase : MessageBase, ITamperResistantOAuthMessage, IExpiringProtocolMessage, IReplayProtectedProtocolMessage {
/// <summary>
/// The reference date and time for calculating time stamps.
/// </summary>
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// The number of seconds since 1/1/1970, consistent with the OAuth timestamp requirement.
/// </summary>
[MessagePart("oauth_timestamp", IsRequired = true)]
private long timestamp;
/// <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>
internal SignedMessageBase(MessageTransport transport)
: base(MessageProtection.All, transport) {
}
/// <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, ServiceProviderEndpoint recipient)
: base(MessageProtection.All, transport, recipient) {
}
#region ITamperResistantOAuthMessage Members
/// <summary>
/// Gets or sets the signature method used to sign the request.
/// </summary>
[MessagePart("oauth_signature_method", IsRequired = true)]
string ITamperResistantOAuthMessage.SignatureMethod { get; set; }
/// <summary>
/// Gets or sets the Token Secret used to sign the message.
/// Only applicable to Consumer.
/// </summary>
public string TokenSecret { get; set; }
/// <summary>
/// Gets or sets the Consumer key.
/// </summary>
[MessagePart(Name = "oauth_consumer_key", IsRequired = true)]
public string ConsumerKey { get; set; }
/// <summary>
/// Gets or sets the Consumer Secret used to sign the message.
/// Only applicable to Consumer.
/// </summary>
public string ConsumerSecret { get; set; }
/// <summary>
/// Gets or sets the HTTP method that will be used to transmit the message.
/// Only applicable to Consumer.
/// </summary>
string ITamperResistantOAuthMessage.HttpMethod { get; set; }
/// <summary>
/// Gets or sets the extra, non-OAuth parameters that will be included in the request.
/// </summary>
IDictionary<string, string> ITamperResistantOAuthMessage.AdditionalParametersInHttpRequest { get; set; }
#endregion
#region ITamperResistantProtocolMessage Members
/// <summary>
/// Gets or sets the message signature.
/// </summary>
[MessagePart("oauth_signature", IsRequired = true)]
string ITamperResistantProtocolMessage.Signature { get; set; }
#endregion
#region IExpiringProtocolMessage Members
/// <summary>
/// Gets or sets the OAuth timestamp of the message.
/// </summary>
DateTime IExpiringProtocolMessage.UtcCreationDate {
get { return epoch + TimeSpan.FromSeconds(this.timestamp); }
set { this.timestamp = (long)(value - epoch).TotalSeconds; }
}
#endregion
#region IReplayProtectedProtocolMessage Members
/// <summary>
/// Gets or sets the message nonce used for replay detection.
/// </summary>
[MessagePart("oauth_nonce", IsRequired = true)]
string IReplayProtectedProtocolMessage.Nonce { get; set; }
#endregion
/// <summary>
/// Gets or sets the version of the protocol this message was created with.
/// </summary>
[MessagePart(Name = "oauth_version", IsRequired = false)]
private string Version {
get {
return ((IProtocolMessage)this).ProtocolVersion.ToString();
}
set {
if (value != this.Version) {
throw new ArgumentOutOfRangeException("value");
}
}
}
}
}
|