author | Michael Krelin <hacker@klever.net> | 2007-08-09 11:31:28 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2007-08-09 11:31:28 (UTC) |
commit | ccabea66fe29ae41458d47d7004d28e225caf41a (patch) (side-by-side diff) | |
tree | eb7e6cc2afa3fffe7eafad439113ba2363a74278 | |
parent | 65bab7c9f984d6fe45ce72e7db014c40eba4d240 (diff) | |
download | libopkele-ccabea66fe29ae41458d47d7004d28e225caf41a.zip libopkele-ccabea66fe29ae41458d47d7004d28e225caf41a.tar.gz libopkele-ccabea66fe29ae41458d47d7004d28e225caf41a.tar.bz2 |
fix to previous commit
-rw-r--r-- | include/opkele/types.h | 5 | ||||
-rw-r--r-- | lib/consumer.cc | 2 |
2 files changed, 5 insertions, 2 deletions
diff --git a/include/opkele/types.h b/include/opkele/types.h index 757c0af..8f4bf73 100644 --- a/include/opkele/types.h +++ b/include/opkele/types.h @@ -50,96 +50,101 @@ namespace opkele { /** * plainly encode to base64 representation * @param rv reference to the return value */ void to_base64(string& rv) const; /** * decode cleartext secret from base64 * @param b64 base64-encoded representation of the secret value */ void from_base64(const string& b64); }; /** * Interface to the association. */ class association_t { public: /** * retrieve the server with which association was established. * @return server name */ virtual string server() const = 0; /** * retrieve the association handle. * @return handle */ virtual string handle() const = 0; /** * retrieve the association type. * @return association type */ virtual string assoc_type() const = 0; /** * retrieve the association secret. * @return association secret */ virtual secret_t secret() const = 0; /** * retrieve the number of seconds the association expires in. * @return seconds till expiration */ virtual int expires_in() const = 0; /** * check whether the association is stateless. * @return true if stateless */ virtual bool stateless() const = 0; + /** + * check whether the association is expired. + * @return true if expired + */ + virtual bool is_expired() const = 0; }; /** * the auto_ptr<> for association_t object type */ typedef auto_ptr<association_t> assoc_t; /** * request/response parameters map */ class params_t : public map<string,string> { public: /** * check whether the parameter is present. * @param n the parameter name * @return true if yes */ bool has_param(const string& n) const; /** * retrieve the parameter (const version) * @param n the parameter name * @return the parameter value * @throw failed_lookup if there is no such parameter */ const string& get_param(const string& n) const; /** * retrieve the parameter. * @param n the parameter name * @return the parameter value * @throw failed_lookup if there is no such parameter */ string& get_param(const string& n); /** * parse the OpenID key/value data. * @param kv the OpenID key/value data */ void parse_keyvalues(const string& kv); /** * sign the fields. * @param secret the secret used for signing * @param sig reference to the string, containing base64-encoded * result * @param slist the comma-separated list of fields to sign * @param prefix the string to prepend to parameter names */ void sign(secret_t secret,string& sig,const string& slist,const char *prefix=0) const; diff --git a/lib/consumer.cc b/lib/consumer.cc index af309c1..8f66688 100644 --- a/lib/consumer.cc +++ b/lib/consumer.cc @@ -99,98 +99,96 @@ namespace opkele { secret.from_base64(p.get_param("mac_key")); }else{ util::bignum_t s_pub = util::base64_to_bignum(p.get_param("dh_server_public")); vector<unsigned char> ck(DH_size(dh)+1); unsigned char *ckptr = &(ck.front())+1; int cklen = DH_compute_key(ckptr,s_pub,dh); if(cklen<0) throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); if(cklen && (*ckptr)&0x80) { (*(--ckptr)) = 0; ++cklen; } unsigned char key_sha1[SHA_DIGEST_LENGTH]; SHA1(ckptr,cklen,key_sha1); secret.enxor_from_base64(key_sha1,p.get_param("enc_mac_key")); } int expires_in = 0; if(p.has_param("expires_in")) { expires_in = util::string_to_long(p.get_param("expires_in")); }else if(p.has_param("issued") && p.has_param("expiry")) { expires_in = util::w3c_to_time(p.get_param("expiry"))-util::w3c_to_time(p.get_param("issued")); }else throw bad_input(OPKELE_CP_ "no expiration information"); return store_assoc(server,p.get_param("assoc_handle"),secret,expires_in); } string consumer_t::checkid_immediate(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { return checkid_(mode_checkid_immediate,identity,return_to,trust_root,ext); } string consumer_t::checkid_setup(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { return checkid_(mode_checkid_setup,identity,return_to,trust_root,ext); } string consumer_t::checkid_(mode_t mode,const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { params_t p; if(mode==mode_checkid_immediate) p["mode"]="checkid_immediate"; else if(mode==mode_checkid_setup) p["mode"]="checkid_setup"; else throw bad_input(OPKELE_CP_ "unknown checkid_* mode"); string iurl = canonicalize(identity); string server, delegate; retrieve_links(iurl,server,delegate); p["identity"] = delegate.empty()?iurl:delegate; if(!trust_root.empty()) p["trust_root"] = trust_root; p["return_to"] = return_to; try { string ah = find_assoc(server)->handle(); - if(ah->is_expired()) /* TODO: or should I throw some other exception to force programmer fix his implementation? */ - throw failed_lookup(OPKELE_CP_ "find_assoc() has returned expired handle"); p["assoc_handle"] = ah; }catch(failed_lookup& fl) { string ah = associate(server)->handle(); p["assoc_handle"] = ah; } if(ext) ext->checkid_hook(p,identity); return p.append_query(server); } void consumer_t::id_res(const params_t& pin,const string& identity,extension_t *ext) { if(pin.has_param("openid.user_setup_url")) throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided",pin.get_param("openid.user_setup_url")); string server,delegate; retrieve_links(identity.empty()?pin.get_param("openid.identity"):canonicalize(identity),server,delegate); params_t ps; try { assoc_t assoc = retrieve_assoc(server,pin.get_param("openid.assoc_handle")); if(assoc->is_expired()) /* TODO: or should I throw some other exception to force programmer fix his implementation? */ throw failed_lookup(OPKELE_CP_ "retrieve_assoc() has returned expired handle"); const string& sigenc = pin.get_param("openid.sig"); vector<unsigned char> sig; util::decode_base64(sigenc,sig); const string& slist = pin.get_param("openid.signed"); string kv; string::size_type p = 0; while(true) { string::size_type co = slist.find(',',p); string f = (co==string::npos)?slist.substr(p):slist.substr(p,co-p); kv += f; kv += ':'; f.insert(0,"openid."); kv += pin.get_param(f); kv += '\n'; if(ext) ps[f.substr(sizeof("openid.")-1)] = pin.get_param(f); if(co==string::npos) break; p = co+1; } secret_t secret = assoc->secret(); unsigned int md_len = 0; unsigned char *md = HMAC( EVP_sha1(), &(secret.front()),secret.size(), (const unsigned char *)kv.data(),kv.length(), 0,&md_len); if(sig.size()!=md_len || memcmp(&(sig.front()),md,md_len)) throw id_res_mismatch(OPKELE_CP_ "signature mismatch"); }catch(failed_lookup& e) { /* XXX: more specific? */ |