summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-04-05 13:36:58 (UTC)
committer Michael Krelin <hacker@klever.net>2008-04-06 09:14:41 (UTC)
commitc56867c814a70505e27501c8f02768a594d8e42d (patch) (unidiff)
tree409a7cae6a4768e09a0217f21c05fbb7d4db26fa
parent0182b9dee269f1a8f3fc0794bfdf4a143fa1b5be (diff)
downloadlibopkele-c56867c814a70505e27501c8f02768a594d8e42d.zip
libopkele-c56867c814a70505e27501c8f02768a594d8e42d.tar.gz
libopkele-c56867c814a70505e27501c8f02768a594d8e42d.tar.bz2
empty trust_root is no trust root.
work around some thoughtful and considerate RPs that take the pain of sending the trust_root parameter, but do not go into as much trouble as setting it to anything but an empty string. Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--lib/basic_op.cc6
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/basic_op.cc b/lib/basic_op.cc
index fa659ac..511b51a 100644
--- a/lib/basic_op.cc
+++ b/lib/basic_op.cc
@@ -1,328 +1,334 @@
1#include <time.h> 1#include <time.h>
2#include <cassert> 2#include <cassert>
3#include <openssl/sha.h> 3#include <openssl/sha.h>
4#include <openssl/hmac.h> 4#include <openssl/hmac.h>
5#include <opkele/data.h> 5#include <opkele/data.h>
6#include <opkele/basic_op.h> 6#include <opkele/basic_op.h>
7#include <opkele/exception.h> 7#include <opkele/exception.h>
8#include <opkele/util.h> 8#include <opkele/util.h>
9#include <opkele/util-internal.h> 9#include <opkele/util-internal.h>
10#include <opkele/uris.h> 10#include <opkele/uris.h>
11 11
12namespace opkele { 12namespace opkele {
13 13
14 void basic_OP::reset_vars() { 14 void basic_OP::reset_vars() {
15 assoc.reset(); 15 assoc.reset();
16 return_to.clear(); realm.clear(); 16 return_to.clear(); realm.clear();
17 claimed_id.clear(); identity.clear(); 17 claimed_id.clear(); identity.clear();
18 invalidate_handle.clear(); 18 invalidate_handle.clear();
19 } 19 }
20 20
21 bool basic_OP::has_return_to() const { 21 bool basic_OP::has_return_to() const {
22 return !return_to.empty(); 22 return !return_to.empty();
23 } 23 }
24 const string& basic_OP::get_return_to() const { 24 const string& basic_OP::get_return_to() const {
25 if(return_to.empty()) 25 if(return_to.empty())
26 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request"); 26 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request");
27 return return_to; 27 return return_to;
28 } 28 }
29 29
30 const string& basic_OP::get_realm() const { 30 const string& basic_OP::get_realm() const {
31 assert(!realm.empty()); 31 assert(!realm.empty());
32 return realm; 32 return realm;
33 } 33 }
34 34
35 bool basic_OP::has_identity() const { 35 bool basic_OP::has_identity() const {
36 return !identity.empty(); 36 return !identity.empty();
37 } 37 }
38 const string& basic_OP::get_claimed_id() const { 38 const string& basic_OP::get_claimed_id() const {
39 if(claimed_id.empty()) 39 if(claimed_id.empty())
40 throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); 40 throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request");
41 assert(!identity.empty()); 41 assert(!identity.empty());
42 return claimed_id; 42 return claimed_id;
43 } 43 }
44 const string& basic_OP::get_identity() const { 44 const string& basic_OP::get_identity() const {
45 if(identity.empty()) 45 if(identity.empty())
46 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); 46 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request");
47 assert(!claimed_id.empty()); 47 assert(!claimed_id.empty());
48 return identity; 48 return identity;
49 } 49 }
50 50
51 bool basic_OP::is_id_select() const { 51 bool basic_OP::is_id_select() const {
52 return identity==IDURI_SELECT20; 52 return identity==IDURI_SELECT20;
53 } 53 }
54 54
55 void basic_OP::select_identity(const string& c,const string& i) { 55 void basic_OP::select_identity(const string& c,const string& i) {
56 claimed_id = c; identity = i; 56 claimed_id = c; identity = i;
57 } 57 }
58 void basic_OP::set_claimed_id(const string& c) { 58 void basic_OP::set_claimed_id(const string& c) {
59 claimed_id = c; 59 claimed_id = c;
60 } 60 }
61 61
62 basic_openid_message& basic_OP::associate( 62 basic_openid_message& basic_OP::associate(
63 basic_openid_message& oum, 63 basic_openid_message& oum,
64 const basic_openid_message& inm) try { 64 const basic_openid_message& inm) try {
65 assert(inm.get_field("mode")=="associate"); 65 assert(inm.get_field("mode")=="associate");
66 util::dh_t dh; 66 util::dh_t dh;
67 util::bignum_t c_pub; 67 util::bignum_t c_pub;
68 unsigned char key_digest[SHA256_DIGEST_LENGTH]; 68 unsigned char key_digest[SHA256_DIGEST_LENGTH];
69 size_t d_len = 0; 69 size_t d_len = 0;
70 string sts = inm.get_field("session_type"); 70 string sts = inm.get_field("session_type");
71 string ats = inm.get_field("assoc_type"); 71 string ats = inm.get_field("assoc_type");
72 if(sts=="DH-SHA1" || sts=="DH-SHA256") { 72 if(sts=="DH-SHA1" || sts=="DH-SHA256") {
73 if(!(dh = DH_new())) 73 if(!(dh = DH_new()))
74 throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); 74 throw exception_openssl(OPKELE_CP_ "failed to DH_new()");
75 c_pub = util::base64_to_bignum(inm.get_field("dh_consumer_public")); 75 c_pub = util::base64_to_bignum(inm.get_field("dh_consumer_public"));
76 try { dh->p = util::base64_to_bignum(inm.get_field("dh_modulus")); 76 try { dh->p = util::base64_to_bignum(inm.get_field("dh_modulus"));
77 }catch(failed_lookup&) { 77 }catch(failed_lookup&) {
78 dh->p = util::dec_to_bignum(data::_default_p); } 78 dh->p = util::dec_to_bignum(data::_default_p); }
79 try { dh->g = util::base64_to_bignum(inm.get_field("dh_gen")); 79 try { dh->g = util::base64_to_bignum(inm.get_field("dh_gen"));
80 }catch(failed_lookup&) { 80 }catch(failed_lookup&) {
81 dh->g = util::dec_to_bignum(data::_default_g); } 81 dh->g = util::dec_to_bignum(data::_default_g); }
82 if(!DH_generate_key(dh)) 82 if(!DH_generate_key(dh))
83 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); 83 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()");
84 vector<unsigned char> ck(DH_size(dh)+1); 84 vector<unsigned char> ck(DH_size(dh)+1);
85 unsigned char *ckptr = &(ck.front())+1; 85 unsigned char *ckptr = &(ck.front())+1;
86 int cklen = DH_compute_key(ckptr,c_pub,dh); 86 int cklen = DH_compute_key(ckptr,c_pub,dh);
87 if(cklen<0) 87 if(cklen<0)
88 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); 88 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()");
89 if(cklen && (*ckptr)&0x80) { 89 if(cklen && (*ckptr)&0x80) {
90 (*(--ckptr)) = 0; ++cklen; } 90 (*(--ckptr)) = 0; ++cklen; }
91 if(sts=="DH-SHA1") { 91 if(sts=="DH-SHA1") {
92 SHA1(ckptr,cklen,key_digest); d_len = SHA_DIGEST_LENGTH; 92 SHA1(ckptr,cklen,key_digest); d_len = SHA_DIGEST_LENGTH;
93 }else if(sts=="DH-SHA256") { 93 }else if(sts=="DH-SHA256") {
94 SHA256(ckptr,cklen,key_digest); d_len = SHA256_DIGEST_LENGTH; 94 SHA256(ckptr,cklen,key_digest); d_len = SHA256_DIGEST_LENGTH;
95 }else 95 }else
96 throw internal_error(OPKELE_CP_ "I thought I knew the session type"); 96 throw internal_error(OPKELE_CP_ "I thought I knew the session type");
97 }else 97 }else
98 throw unsupported(OPKELE_CP_ "Unsupported session_type"); 98 throw unsupported(OPKELE_CP_ "Unsupported session_type");
99 assoc_t a; 99 assoc_t a;
100 if(ats=="HMAC-SHA1") 100 if(ats=="HMAC-SHA1")
101 a = alloc_assoc(ats,SHA_DIGEST_LENGTH,false); 101 a = alloc_assoc(ats,SHA_DIGEST_LENGTH,false);
102 else if(ats=="HMAC-SHA256") 102 else if(ats=="HMAC-SHA256")
103 a = alloc_assoc(ats,SHA256_DIGEST_LENGTH,false); 103 a = alloc_assoc(ats,SHA256_DIGEST_LENGTH,false);
104 else 104 else
105 throw unsupported(OPKELE_CP_ "Unsupported assoc_type"); 105 throw unsupported(OPKELE_CP_ "Unsupported assoc_type");
106 oum.reset_fields(); 106 oum.reset_fields();
107 oum.set_field("ns",OIURI_OPENID20); 107 oum.set_field("ns",OIURI_OPENID20);
108 oum.set_field("assoc_type",a->assoc_type()); 108 oum.set_field("assoc_type",a->assoc_type());
109 oum.set_field("assoc_handle",a->handle()); 109 oum.set_field("assoc_handle",a->handle());
110 oum.set_field("expires_in",util::long_to_string(a->expires_in())); 110 oum.set_field("expires_in",util::long_to_string(a->expires_in()));
111 secret_t secret = a->secret(); 111 secret_t secret = a->secret();
112 if(sts=="DH-SHA1" || sts=="DH-SHA256") { 112 if(sts=="DH-SHA1" || sts=="DH-SHA256") {
113 if(d_len != secret.size()) 113 if(d_len != secret.size())
114 throw bad_input(OPKELE_CP_ "Association secret and session MAC are not of the same size"); 114 throw bad_input(OPKELE_CP_ "Association secret and session MAC are not of the same size");
115 oum.set_field("session_type",sts); 115 oum.set_field("session_type",sts);
116 oum.set_field("dh_server_public",util::bignum_to_base64(dh->pub_key)); 116 oum.set_field("dh_server_public",util::bignum_to_base64(dh->pub_key));
117 string b64; secret.enxor_to_base64(key_digest,b64); 117 string b64; secret.enxor_to_base64(key_digest,b64);
118 oum.set_field("enc_mac_key",b64); 118 oum.set_field("enc_mac_key",b64);
119 }else /* TODO: support cleartext over encrypted connection */ 119 }else /* TODO: support cleartext over encrypted connection */
120 throw unsupported(OPKELE_CP_ "Unsupported session type"); 120 throw unsupported(OPKELE_CP_ "Unsupported session type");
121 return oum; 121 return oum;
122 } catch(unsupported& u) { 122 } catch(unsupported& u) {
123 oum.reset_fields(); 123 oum.reset_fields();
124 oum.set_field("ns",OIURI_OPENID20); 124 oum.set_field("ns",OIURI_OPENID20);
125 oum.set_field("error",u.what()); 125 oum.set_field("error",u.what());
126 oum.set_field("error_code","unsupported-type"); 126 oum.set_field("error_code","unsupported-type");
127 oum.set_field("session_type","DH-SHA256"); 127 oum.set_field("session_type","DH-SHA256");
128 oum.set_field("assoc_type","HMAC-SHA256"); 128 oum.set_field("assoc_type","HMAC-SHA256");
129 return oum; 129 return oum;
130 } 130 }
131 131
132 void basic_OP::checkid_(const basic_openid_message& inm, 132 void basic_OP::checkid_(const basic_openid_message& inm,
133 extension_t *ext) { 133 extension_t *ext) {
134 reset_vars(); 134 reset_vars();
135 string modestr = inm.get_field("mode"); 135 string modestr = inm.get_field("mode");
136 if(modestr=="checkid_setup") 136 if(modestr=="checkid_setup")
137 mode = mode_checkid_setup; 137 mode = mode_checkid_setup;
138 else if(modestr=="checkid_immediate") 138 else if(modestr=="checkid_immediate")
139 mode = mode_checkid_immediate; 139 mode = mode_checkid_immediate;
140 else 140 else
141 throw bad_input(OPKELE_CP_ "Invalid checkid_* mode"); 141 throw bad_input(OPKELE_CP_ "Invalid checkid_* mode");
142 try { 142 try {
143 assoc = retrieve_assoc(invalidate_handle=inm.get_field("assoc_handle")); 143 assoc = retrieve_assoc(invalidate_handle=inm.get_field("assoc_handle"));
144 invalidate_handle.clear(); 144 invalidate_handle.clear();
145 }catch(failed_lookup&) { } 145 }catch(failed_lookup&) { }
146 try { 146 try {
147 openid2 = (inm.get_field("ns")==OIURI_OPENID20); 147 openid2 = (inm.get_field("ns")==OIURI_OPENID20);
148 }catch(failed_lookup&) { openid2 = false; } 148 }catch(failed_lookup&) { openid2 = false; }
149 try { 149 try {
150 return_to = inm.get_field("return_to"); 150 return_to = inm.get_field("return_to");
151 }catch(failed_lookup&) { } 151 }catch(failed_lookup&) { }
152 if(openid2) { 152 if(openid2) {
153 try { 153 try {
154 realm = inm.get_field("realm"); 154 realm = inm.get_field("realm");
155 if(realm.empty())
156 throw failed_lookup(OPKELE_CP_ "Empty realm doesn't count");
155 }catch(failed_lookup&) { 157 }catch(failed_lookup&) {
156 try { 158 try {
157 realm = inm.get_field("trust_root"); 159 realm = inm.get_field("trust_root");
160 if(realm.empty())
161 throw failed_lookup(OPKELE_CP_ "Empty trust_root doesn't count");
158 }catch(failed_lookup&) { 162 }catch(failed_lookup&) {
159 if(return_to.empty()) 163 if(return_to.empty())
160 throw bad_input(OPKELE_CP_ 164 throw bad_input(OPKELE_CP_
161 "Both realm and return_to are unset"); 165 "Both realm and return_to are unset");
162 realm = return_to; 166 realm = return_to;
163 } 167 }
164 } 168 }
165 }else{ 169 }else{
166 try { 170 try {
167 realm = inm.get_field("trust_root"); 171 realm = inm.get_field("trust_root");
172 if(realm.empty())
173 throw failed_lookup(OPKELE_CP_ "Empty trust_root doesn't count");
168 }catch(failed_lookup&) { 174 }catch(failed_lookup&) {
169 if(return_to.empty()) 175 if(return_to.empty())
170 throw bad_input(OPKELE_CP_ 176 throw bad_input(OPKELE_CP_
171 "Both realm and return_to are unset"); 177 "Both realm and return_to are unset");
172 realm = return_to; 178 realm = return_to;
173 } 179 }
174 } 180 }
175 try { 181 try {
176 identity = inm.get_field("identity"); 182 identity = inm.get_field("identity");
177 try { 183 try {
178 claimed_id = inm.get_field("claimed_id"); 184 claimed_id = inm.get_field("claimed_id");
179 }catch(failed_lookup&) { 185 }catch(failed_lookup&) {
180 if(openid2) 186 if(openid2)
181 throw bad_input(OPKELE_CP_ 187 throw bad_input(OPKELE_CP_
182 "claimed_id and identity must be either both present or both absent"); 188 "claimed_id and identity must be either both present or both absent");
183 claimed_id = identity; 189 claimed_id = identity;
184 } 190 }
185 }catch(failed_lookup&) { 191 }catch(failed_lookup&) {
186 if(openid2 && inm.has_field("claimed_id")) 192 if(openid2 && inm.has_field("claimed_id"))
187 throw bad_input(OPKELE_CP_ 193 throw bad_input(OPKELE_CP_
188 "claimed_id and identity must be either both present or both absent"); 194 "claimed_id and identity must be either both present or both absent");
189 } 195 }
190 verify_return_to(); 196 verify_return_to();
191 if(ext) ext->op_checkid_hook(inm); 197 if(ext) ext->op_checkid_hook(inm);
192 } 198 }
193 199
194 basic_openid_message& basic_OP::id_res(basic_openid_message& om, 200 basic_openid_message& basic_OP::id_res(basic_openid_message& om,
195 extension_t *ext) { 201 extension_t *ext) {
196 assert(!return_to.empty()); 202 assert(!return_to.empty());
197 assert(!is_id_select()); 203 assert(!is_id_select());
198 if(!assoc) { 204 if(!assoc) {
199 assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true); 205 assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true);
200 } 206 }
201 time_t now = time(0); 207 time_t now = time(0);
202 struct tm gmt; gmtime_r(&now,&gmt); 208 struct tm gmt; gmtime_r(&now,&gmt);
203 char w3timestr[24]; 209 char w3timestr[24];
204 if(!strftime(w3timestr,sizeof(w3timestr),"%Y-%m-%dT%H:%M:%SZ",&gmt)) 210 if(!strftime(w3timestr,sizeof(w3timestr),"%Y-%m-%dT%H:%M:%SZ",&gmt))
205 throw failed_conversion(OPKELE_CP_ 211 throw failed_conversion(OPKELE_CP_
206 "Failed to build time string for nonce" ); 212 "Failed to build time string for nonce" );
207 om.set_field("ns",OIURI_OPENID20); 213 om.set_field("ns",OIURI_OPENID20);
208 om.set_field("mode","id_res"); 214 om.set_field("mode","id_res");
209 om.set_field("op_endpoint",get_op_endpoint()); 215 om.set_field("op_endpoint",get_op_endpoint());
210 string ats = "ns,mode,op_endpoint,return_to,response_nonce," 216 string ats = "ns,mode,op_endpoint,return_to,response_nonce,"
211 "assoc_handle,signed"; 217 "assoc_handle,signed";
212 if(!identity.empty()) { 218 if(!identity.empty()) {
213 om.set_field("identity",identity); 219 om.set_field("identity",identity);
214 om.set_field("claimed_id",claimed_id); 220 om.set_field("claimed_id",claimed_id);
215 ats += ",identity,claimed_id"; 221 ats += ",identity,claimed_id";
216 } 222 }
217 om.set_field("return_to",return_to); 223 om.set_field("return_to",return_to);
218 string nonce = w3timestr; 224 string nonce = w3timestr;
219 om.set_field("response_nonce",alloc_nonce(nonce)); 225 om.set_field("response_nonce",alloc_nonce(nonce));
220 if(!invalidate_handle.empty()) { 226 if(!invalidate_handle.empty()) {
221 om.set_field("invalidate_handle",invalidate_handle); 227 om.set_field("invalidate_handle",invalidate_handle);
222 ats += ",invalidate_handle"; 228 ats += ",invalidate_handle";
223 } 229 }
224 om.set_field("assoc_handle",assoc->handle()); 230 om.set_field("assoc_handle",assoc->handle());
225 om.add_to_signed(ats); 231 om.add_to_signed(ats);
226 if(ext) ext->op_id_res_hook(om); 232 if(ext) ext->op_id_res_hook(om);
227 om.set_field("sig",util::base64_signature(assoc,om)); 233 om.set_field("sig",util::base64_signature(assoc,om));
228 return om; 234 return om;
229 } 235 }
230 236
231 basic_openid_message& basic_OP::cancel(basic_openid_message& om) { 237 basic_openid_message& basic_OP::cancel(basic_openid_message& om) {
232 assert(!return_to.empty()); 238 assert(!return_to.empty());
233 om.set_field("ns",OIURI_OPENID20); 239 om.set_field("ns",OIURI_OPENID20);
234 om.set_field("mode","cancel"); 240 om.set_field("mode","cancel");
235 return om; 241 return om;
236 } 242 }
237 243
238 basic_openid_message& basic_OP::error(basic_openid_message& om, 244 basic_openid_message& basic_OP::error(basic_openid_message& om,
239 const string& err,const string& contact, 245 const string& err,const string& contact,
240 const string& reference ) { 246 const string& reference ) {
241 assert(!return_to.empty()); 247 assert(!return_to.empty());
242 om.set_field("ns",OIURI_OPENID20); 248 om.set_field("ns",OIURI_OPENID20);
243 om.set_field("mode","error"); 249 om.set_field("mode","error");
244 om.set_field("error",err); 250 om.set_field("error",err);
245 if(!contact.empty()) om.set_field("contact",contact); 251 if(!contact.empty()) om.set_field("contact",contact);
246 if(!reference.empty()) om.set_field("reference",reference); 252 if(!reference.empty()) om.set_field("reference",reference);
247 return om; 253 return om;
248 } 254 }
249 255
250 basic_openid_message& basic_OP::setup_needed( 256 basic_openid_message& basic_OP::setup_needed(
251 basic_openid_message& oum,const basic_openid_message& inm) { 257 basic_openid_message& oum,const basic_openid_message& inm) {
252 assert(mode==mode_checkid_immediate); 258 assert(mode==mode_checkid_immediate);
253 assert(!return_to.empty()); 259 assert(!return_to.empty());
254 if(openid2) { 260 if(openid2) {
255 oum.set_field("ns",OIURI_OPENID20); 261 oum.set_field("ns",OIURI_OPENID20);
256 oum.set_field("mode","setup_needed"); 262 oum.set_field("mode","setup_needed");
257 }else{ 263 }else{
258 oum.set_field("mode","id_res"); 264 oum.set_field("mode","id_res");
259 static const string setupmode = "checkid_setup"; 265 static const string setupmode = "checkid_setup";
260 oum.set_field("user_setup_url", 266 oum.set_field("user_setup_url",
261 util::change_mode_message_proxy(inm,setupmode) 267 util::change_mode_message_proxy(inm,setupmode)
262 .append_query(get_op_endpoint())); 268 .append_query(get_op_endpoint()));
263 } 269 }
264 return oum; 270 return oum;
265 } 271 }
266 272
267 basic_openid_message& basic_OP::check_authentication( 273 basic_openid_message& basic_OP::check_authentication(
268 basic_openid_message& oum, 274 basic_openid_message& oum,
269 const basic_openid_message& inm) try { 275 const basic_openid_message& inm) try {
270 assert(inm.get_field("mode")=="check_authentication"); 276 assert(inm.get_field("mode")=="check_authentication");
271 oum.reset_fields(); 277 oum.reset_fields();
272 oum.set_field("ns",OIURI_OPENID20); 278 oum.set_field("ns",OIURI_OPENID20);
273 bool o2; 279 bool o2;
274 try { 280 try {
275 o2 = (inm.get_field("ns")==OIURI_OPENID20); 281 o2 = (inm.get_field("ns")==OIURI_OPENID20);
276 }catch(failed_lookup&) { o2 = false; } 282 }catch(failed_lookup&) { o2 = false; }
277 string nonce; 283 string nonce;
278 if(o2) { 284 if(o2) {
279 try { 285 try {
280 if(!check_nonce(nonce = inm.get_field("response_nonce"))) 286 if(!check_nonce(nonce = inm.get_field("response_nonce")))
281 throw failed_check_authentication(OPKELE_CP_ "Invalid nonce"); 287 throw failed_check_authentication(OPKELE_CP_ "Invalid nonce");
282 }catch(failed_lookup&) { 288 }catch(failed_lookup&) {
283 throw failed_check_authentication(OPKELE_CP_ "No nonce provided with check_authentication request"); 289 throw failed_check_authentication(OPKELE_CP_ "No nonce provided with check_authentication request");
284 } 290 }
285 } 291 }
286 try { 292 try {
287 assoc = retrieve_assoc(inm.get_field("assoc_handle")); 293 assoc = retrieve_assoc(inm.get_field("assoc_handle"));
288 if(!assoc->stateless()) 294 if(!assoc->stateless())
289 throw failed_check_authentication(OPKELE_CP_ "Will not do check_authentication on a stateful handle"); 295 throw failed_check_authentication(OPKELE_CP_ "Will not do check_authentication on a stateful handle");
290 }catch(failed_lookup&) { 296 }catch(failed_lookup&) {
291 throw failed_check_authentication(OPKELE_CP_ "No assoc_handle or invalid assoc_handle specified with check_authentication request"); 297 throw failed_check_authentication(OPKELE_CP_ "No assoc_handle or invalid assoc_handle specified with check_authentication request");
292 } 298 }
293 static const string idresmode = "id_res"; 299 static const string idresmode = "id_res";
294 try { 300 try {
295 if(util::base64_signature(assoc,util::change_mode_message_proxy(inm,idresmode))!=inm.get_field("sig")) 301 if(util::base64_signature(assoc,util::change_mode_message_proxy(inm,idresmode))!=inm.get_field("sig"))
296 throw failed_check_authentication(OPKELE_CP_ "Signature mismatch"); 302 throw failed_check_authentication(OPKELE_CP_ "Signature mismatch");
297 }catch(failed_lookup&) { 303 }catch(failed_lookup&) {
298 throw failed_check_authentication(OPKELE_CP_ "failed to calculate signature"); 304 throw failed_check_authentication(OPKELE_CP_ "failed to calculate signature");
299 } 305 }
300 oum.set_field("is_valid","true"); 306 oum.set_field("is_valid","true");
301 try { 307 try {
302 string h = inm.get_field("invalidate_handle"); 308 string h = inm.get_field("invalidate_handle");
303 try { 309 try {
304 assoc_t ih = retrieve_assoc(h); 310 assoc_t ih = retrieve_assoc(h);
305 }catch(invalid_handle& ih) { 311 }catch(invalid_handle& ih) {
306 oum.set_field("invalidate_handle",h); 312 oum.set_field("invalidate_handle",h);
307 }catch(failed_lookup& ih) { 313 }catch(failed_lookup& ih) {
308 oum.set_field("invalidate_handle",h); 314 oum.set_field("invalidate_handle",h);
309 } 315 }
310 }catch(failed_lookup&) { } 316 }catch(failed_lookup&) { }
311 if(o2) { 317 if(o2) {
312 assert(!nonce.empty()); 318 assert(!nonce.empty());
313 invalidate_nonce(nonce); 319 invalidate_nonce(nonce);
314 } 320 }
315 return oum; 321 return oum;
316 }catch(failed_check_authentication& ) { 322 }catch(failed_check_authentication& ) {
317 oum.set_field("is_valid","false"); 323 oum.set_field("is_valid","false");
318 return oum; 324 return oum;
319 } 325 }
320 326
321 void basic_OP::verify_return_to() { 327 void basic_OP::verify_return_to() {
322 if(realm.find('#')!=string::npos) 328 if(realm.find('#')!=string::npos)
323 throw opkele::bad_realm(OPKELE_CP_ "authentication realm contains URI fragment"); 329 throw opkele::bad_realm(OPKELE_CP_ "authentication realm contains URI fragment");
324 if(!util::uri_matches_realm(return_to,realm)) 330 if(!util::uri_matches_realm(return_to,realm))
325 throw bad_return_to(OPKELE_CP_ "return_to URL doesn't match realm"); 331 throw bad_return_to(OPKELE_CP_ "return_to URL doesn't match realm");
326 } 332 }
327 333
328} 334}