def associate(server_url)
dh = OpenID::DiffieHellman.new
cpub = OpenID::Util.to_base64(OpenID::Util.num_to_str(dh.public))
args = {
'openid.mode' => 'associate',
'openid.assoc_type' =>'HMAC-SHA1',
'openid.session_type' =>'DH-SHA1',
'openid.dh_modulus' => OpenID::Util.to_base64(OpenID::Util.num_to_str(dh.p)),
'openid.dh_gen' => OpenID::Util.to_base64(OpenID::Util.num_to_str(dh.g)),
'openid.dh_consumer_public' => cpub
}
body = OpenID::Util.urlencode(args)
ret = @fetcher.post(server_url, body)
return nil if ret.nil?
url, data = ret
results = OpenID::Util.parsekv(data)
assoc_type = results["assoc_type"]
return nil if assoc_type.nil? or assoc_type != "HMAC-SHA1"
assoc_handle = results["assoc_handle"]
return nil if assoc_handle.nil?
expires_in = results.fetch("expires_in", "0").to_i
session_type = results["session_type"]
if session_type.nil?
secret = OpenID::Util.from_base64(results["mac_key"])
else
return nil if session_type != "DH-SHA1"
dh_server_public = results["dh_server_public"]
return nil if dh_server_public.nil?
spub = OpenID::Util.str_to_num(OpenID::Util.from_base64(dh_server_public))
dh_shared = dh.get_shared_secret(spub)
enc_mac_key = results["enc_mac_key"]
secret = OpenID::Util.strxor(OpenID::Util.from_base64(enc_mac_key),
OpenID::Util.sha1(OpenID::Util.num_to_str(dh_shared)))
end
assoc = OpenID::Association.from_expires_in(expires_in, assoc_handle,
secret, 'HMAC-SHA1')
@store.store_association(server_url, assoc)
return assoc
end