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
|
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
namespace DotNetOpenId.Provider {
/// <summary>
/// A request to verify the validity of a previous response.
/// </summary>
internal class CheckAuthRequest : AssociatedRequest {
string signature;
IDictionary<string, string> signedFields;
IList<string> signedKeyOrder;
public CheckAuthRequest(OpenIdProvider provider)
: base(provider) {
AssociationHandle = Util.GetRequiredArg(Query, Protocol.openid.assoc_handle);
signature = Util.GetRequiredArg(Query, Protocol.openid.sig);
signedKeyOrder = Util.GetRequiredArg(Query, Protocol.openid.signed).Split(',');
signedFields = new Dictionary<string, string>();
Debug.Assert(!signedKeyOrder.Contains(Protocol.openidnp.mode), "openid.mode must not be included in signature because it necessarily changes in checkauth requests.");
foreach (string key in signedKeyOrder) {
signedFields.Add(key, Util.GetRequiredArgAllowEmptyValue(Query, Protocol.openid.Prefix + key));
}
}
public override bool IsResponseReady {
// This type of request can always be responded to immediately.
get { return true; }
}
/// <summary>
/// Gets the string "check_authentication".
/// </summary>
internal override string Mode {
get { return Protocol.Args.Mode.check_authentication; }
}
/// <summary>
/// Respond to this request.
/// </summary>
internal EncodableResponse Answer() {
EncodableResponse response = EncodableResponse.PrepareDirectMessage(Protocol);
bool validSignature = Provider.Signatory.Verify(AssociationHandle, signature, signedFields, signedKeyOrder);
response.Fields[Protocol.openidnp.is_valid] = validSignature ?
Protocol.Args.IsValid.True : Protocol.Args.IsValid.False;
// By invalidating our dumb association, we make it impossible to
// verify the same authentication again, making a response_nonce check
// to protect against replay attacks unnecessary.
Provider.Signatory.Invalidate(AssociationHandle, AssociationRelyingPartyType.Dumb);
// The RP may be asking for confirmation that an association should
// be invalidated. If so, double-check and send a reply in our response.
string invalidate_handle = Util.GetOptionalArg(Query, Protocol.openid.invalidate_handle);
if (invalidate_handle != null) {
Association assoc = Provider.Signatory.GetAssociation(invalidate_handle, AssociationRelyingPartyType.Smart);
if (assoc == null) {
Logger.Warn("No matching association found. Returning invalidate_handle. ");
response.Fields[Protocol.openidnp.invalidate_handle] = invalidate_handle;
}
}
return response;
}
protected override IEncodable CreateResponse() {
return Answer();
}
public override string ToString() {
string returnString = @"
CheckAuthRequest._sig = '{0}'
CheckAuthRequest.AssocHandle = '{1}'";
return base.ToString() + string.Format(CultureInfo.CurrentCulture,
returnString, signature, AssociationHandle);
}
}
}
|