Class: OpenID::DiffieHelmanAssociator

Inherits:
Object
  • Object
show all
Includes:
OpenID
Defined in:
lib/openid/association.rb

Overview

A class for establishing associations with OpenID servers.

Constant Summary

Constants included from OpenID

DEFAULT_DH_GEN, DEFAULT_DH_MODULUS, SECRET_SIZES

Instance Method Summary collapse

Methods included from OpenID

#append_args, #error_page, #from_btwoc, #normalize_url, #parse_kv, #parse_link_attrs, #quote_minimal, #redirect, #response_page, #sign_reply, #url_encode

Constructor Details

#initialize(http_client) ⇒ DiffieHelmanAssociator

Returns a new instance of DiffieHelmanAssociator.



146
147
148
# File 'lib/openid/association.rb', line 146

def initialize(http_client)
	@http_client = http_client
end

Instance Method Details

#associate(server_url) ⇒ Object

Establishes an association with an OpenID server, indicated by server_url. Returns a ConsumerAssociation.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/openid/association.rb', line 158

def associate(server_url)
	p, g = get_mod_gen()
	private_key = (1 + rand(p-2))
	dh_public = g.mod_exp(private_key, p)
	args = {
		'openid.mode' => 'associate',
		'openid.assoc_type' => 'HMAC-SHA1',
		'openid.session_type' => 'DH-SHA1',
		'openid.dh_modulus' => Base64.encode64(p.to_btwoc).delete("\n"),
		'openid.dh_gen' => Base64.encode64(g.to_btwoc).delete("\n"),
		'openid.dh_consumer_public' => Base64.encode64(dh_public.to_btwoc).delete("\n")
	}
	body = url_encode(args)
	url, data = @http_client.post(server_url, body)
	now = Time.now.utc
	# results are temporarily stored in an instance variable.
	# I'd like to restructure to avoid this.
	@results = parse_kv(data)
	
	assoc_type = get_result('assoc_type')
	if assoc_type != 'HMAC-SHA1'
		raise RuntimeError, "Unknown association type: #{assoc_type}", caller
	end
	
	assoc_handle = get_result('assoc_handle')
	issued = DateTime.strptime(get_result('issued')).to_time
	expiry = DateTime.strptime(get_result('expiry')).to_time
	
	delta = now - issued
	expiry = expiry + delta
	
	replace_after_s = @results['replace_after']
	if replace_after_s
		replace_after = DateTime.strptime(replace_after_s).to_time + delta
	else
		replace_after = nil
	end
	
	session_type = @results['session_type']
	if session_type
		if session_type != 'DH-SHA1'
			raise RuntimeError, "Unknown Session Type: #{session_type}", caller
		end
		dh_server_pub = from_btwoc(Base64.decode64(get_result('dh_server_public')))
		enc_mac_key = get_result('enc_mac_key')
		dh_shared = dh_server_pub.mod_exp(private_key, p)

		secret = Base64.decode64(enc_mac_key) ^ Digest::SHA1.digest(dh_shared.to_btwoc)
	else
		secret = get_result('mac_key')
	end
	@results = nil
	return ConsumerAssociation.new(server_url, assoc_handle, secret, expiry, replace_after)
end

#get_mod_genObject

Returns modulus and generator for Diffie-Helman. Override this for non-default values.



152
153
154
# File 'lib/openid/association.rb', line 152

def get_mod_gen()
	return DEFAULT_DH_MODULUS, DEFAULT_DH_GEN
end