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