test_association.rb
266 lines
| 9.1 KiB
| text/x-ruby
|
RubyLexer
|
r2376 | require "test/unit" | ||
require "openid/association" | ||||
module OpenID | ||||
class AssociationTestCase < Test::Unit::TestCase | ||||
def setup | ||||
# Use this funny way of getting a time so that it does not have | ||||
# fractional seconds, and so can be serialized exactly using our | ||||
# standard code. | ||||
issued = Time.at(Time.now.to_i) | ||||
lifetime = 600 | ||||
@assoc = Association.new('handle', 'secret', issued, | ||||
lifetime, 'HMAC-SHA1') | ||||
end | ||||
def test_round_trip | ||||
assoc2 = Association.deserialize(@assoc.serialize()) | ||||
[:handle, :secret, :lifetime, :assoc_type].each do |attr| | ||||
assert_equal(@assoc.send(attr), assoc2.send(attr)) | ||||
end | ||||
end | ||||
def test_deserialize_failure | ||||
field_list = Util.kv_to_seq(@assoc.serialize) | ||||
kv = Util.seq_to_kv(field_list + [['monkeys', 'funny']]) | ||||
assert_raises(ProtocolError) { | ||||
Association.deserialize(kv) | ||||
} | ||||
bad_version_list = field_list.dup | ||||
bad_version_list[0] = ['version', 'moon'] | ||||
bad_version_kv = Util.seq_to_kv(bad_version_list) | ||||
assert_raises(ProtocolError) { | ||||
Association.deserialize(bad_version_kv) | ||||
} | ||||
end | ||||
def test_serialization_identity | ||||
assoc2 = Association.deserialize(@assoc.serialize) | ||||
assert_equal(@assoc, assoc2) | ||||
end | ||||
def test_expires_in | ||||
# Allow one second of slop | ||||
assert(@assoc.expires_in.between?(599,600)) | ||||
assert(@assoc.expires_in(Time.now.to_i).between?(599,600)) | ||||
assert_equal(0,@assoc.expires_in(Time.now.to_i + 10000),"negative expires_in") | ||||
end | ||||
def test_from_expires_in | ||||
start_time = Time.now | ||||
expires_in = @assoc.expires_in | ||||
assoc = Association.from_expires_in(expires_in, | ||||
@assoc.handle, | ||||
@assoc.secret, | ||||
@assoc.assoc_type) | ||||
# Allow one second of slop here for code execution time | ||||
assert_in_delta(1, assoc.expires_in, @assoc.expires_in) | ||||
[:handle, :secret, :assoc_type].each do |attr| | ||||
assert_equal(@assoc.send(attr), assoc.send(attr)) | ||||
end | ||||
# Make sure the issued time is near the start | ||||
assert(assoc.issued >= start_time) | ||||
assert_in_delta(1, assoc.issued.to_f, start_time.to_f) | ||||
end | ||||
def test_sign_sha1 | ||||
pairs = [['key1', 'value1'], | ||||
['key2', 'value2']] | ||||
[['HMAC-SHA256', "\xfd\xaa\xfe;\xac\xfc*\x988\xad\x05d6-"\ | ||||
"\xeaVy\xd5\xa5Z.<\xa9\xed\x18\x82\\$"\ | ||||
"\x95x\x1c&"], | ||||
['HMAC-SHA1', "\xe0\x1bv\x04\xf1G\xc0\xbb\x7f\x9a\x8b"\ | ||||
"\xe9\xbc\xee}\\\xe5\xbb7*"], | ||||
].each do |assoc_type, expected| | ||||
assoc = Association.from_expires_in(3600, "handle", 'very_secret', | ||||
assoc_type) | ||||
sig = assoc.sign(pairs) | ||||
assert_equal(sig, expected) | ||||
m = Message.new(OPENID2_NS) | ||||
pairs.each { |k, v| | ||||
m.set_arg(OPENID_NS, k, v) | ||||
} | ||||
m.set_arg(BARE_NS, "not_an_openid_arg", "bogus") | ||||
signed_m = assoc.sign_message(m) | ||||
assert(signed_m.has_key?(OPENID_NS, 'sig')) | ||||
assert_equal(signed_m.get_arg(OPENID_NS, 'signed'), | ||||
'assoc_handle,key1,key2,ns,signed') | ||||
end | ||||
end | ||||
def test_sign_message_with_sig | ||||
assoc = Association.from_expires_in(3600, "handle", "very_secret", | ||||
"HMAC-SHA1") | ||||
m = Message.new(OPENID2_NS) | ||||
m.set_arg(OPENID_NS, 'sig', 'noise') | ||||
assert_raises(ArgumentError) { | ||||
assoc.sign_message(m) | ||||
} | ||||
end | ||||
def test_sign_message_with_signed | ||||
assoc = Association.from_expires_in(3600, "handle", "very_secret", | ||||
"HMAC-SHA1") | ||||
m = Message.new(OPENID2_NS) | ||||
m.set_arg(OPENID_NS, 'signed', 'fields') | ||||
assert_raises(ArgumentError) { | ||||
assoc.sign_message(m) | ||||
} | ||||
end | ||||
def test_sign_different_assoc_handle | ||||
assoc = Association.from_expires_in(3600, "handle", "very_secret", | ||||
"HMAC-SHA1") | ||||
m = Message.new(OPENID2_NS) | ||||
m.set_arg(OPENID_NS, 'assoc_handle', 'different') | ||||
assert_raises(ArgumentError) { | ||||
assoc.sign_message(m) | ||||
} | ||||
end | ||||
def test_sign_bad_assoc_type | ||||
@assoc.instance_eval { @assoc_type = 'Cookies' } | ||||
assert_raises(ProtocolError) { | ||||
@assoc.sign([]) | ||||
} | ||||
end | ||||
def test_make_pairs | ||||
msg = Message.new(OPENID2_NS) | ||||
msg.update_args(OPENID2_NS, { | ||||
'mode' => 'id_res', | ||||
'identifier' => '=example', | ||||
'signed' => 'identifier,mode', | ||||
'sig' => 'cephalopod', | ||||
}) | ||||
msg.update_args(BARE_NS, {'xey' => 'value'}) | ||||
assoc = Association.from_expires_in(3600, '{sha1}', 'very_secret', | ||||
"HMAC-SHA1") | ||||
pairs = assoc.make_pairs(msg) | ||||
assert_equal([['identifier', '=example'], | ||||
['mode', 'id_res']], pairs) | ||||
end | ||||
def test_check_message_signature_no_signed | ||||
m = Message.new(OPENID2_NS) | ||||
m.update_args(OPENID2_NS, {'mode' => 'id_res', | ||||
'identifier' => '=example', | ||||
'sig' => 'coyote', | ||||
}) | ||||
assoc = Association.from_expires_in(3600, '{sha1}', 'very_secret', | ||||
"HMAC-SHA1") | ||||
assert_raises(ProtocolError) { | ||||
assoc.check_message_signature(m) | ||||
} | ||||
end | ||||
def test_check_message_signature_no_sig | ||||
m = Message.new(OPENID2_NS) | ||||
m.update_args(OPENID2_NS, {'mode' => 'id_res', | ||||
'identifier' => '=example', | ||||
'signed' => 'mode', | ||||
}) | ||||
assoc = Association.from_expires_in(3600, '{sha1}', 'very_secret', | ||||
"HMAC-SHA1") | ||||
assert_raises(ProtocolError) { | ||||
assoc.check_message_signature(m) | ||||
} | ||||
end | ||||
def test_check_message_signature_bad_sig | ||||
m = Message.new(OPENID2_NS) | ||||
m.update_args(OPENID2_NS, {'mode' => 'id_res', | ||||
'identifier' => '=example', | ||||
'signed' => 'mode', | ||||
'sig' => Util.to_base64('coyote'), | ||||
}) | ||||
assoc = Association.from_expires_in(3600, '{sha1}', 'very_secret', | ||||
"HMAC-SHA1") | ||||
assert(!assoc.check_message_signature(m)) | ||||
end | ||||
def test_check_message_signature_good_sig | ||||
m = Message.new(OPENID2_NS) | ||||
m.update_args(OPENID2_NS, {'mode' => 'id_res', | ||||
'identifier' => '=example', | ||||
'signed' => 'mode', | ||||
'sig' => Util.to_base64('coyote'), | ||||
}) | ||||
assoc = Association.from_expires_in(3600, '{sha1}', 'very_secret', | ||||
"HMAC-SHA1") | ||||
class << assoc | ||||
# Override sign, because it's already tested elsewhere | ||||
def sign(pairs) | ||||
"coyote" | ||||
end | ||||
end | ||||
assert(assoc.check_message_signature(m)) | ||||
end | ||||
end | ||||
class AssociationNegotiatorTestCase < Test::Unit::TestCase | ||||
def assert_equal_under(item1, item2) | ||||
val1 = yield(item1) | ||||
val2 = yield(item2) | ||||
assert_equal(val1, val2) | ||||
end | ||||
def test_copy | ||||
neg = AssociationNegotiator.new([['HMAC-SHA1', 'DH-SHA1']]) | ||||
neg2 = neg.copy | ||||
assert_equal_under(neg, neg2) {|n| n.instance_eval{@allowed_types} } | ||||
assert(neg.object_id != neg2.object_id) | ||||
end | ||||
def test_add_allowed | ||||
neg = AssociationNegotiator.new([]) | ||||
assert(!neg.allowed?('HMAC-SHA1', 'DH-SHA1')) | ||||
assert(!neg.allowed?('HMAC-SHA1', 'no-encryption')) | ||||
assert(!neg.allowed?('HMAC-SHA256', 'DH-SHA256')) | ||||
assert(!neg.allowed?('HMAC-SHA256', 'no-encryption')) | ||||
neg.add_allowed_type('HMAC-SHA1') | ||||
assert(neg.allowed?('HMAC-SHA1', 'DH-SHA1')) | ||||
assert(neg.allowed?('HMAC-SHA1', 'no-encryption')) | ||||
assert(!neg.allowed?('HMAC-SHA256', 'DH-SHA256')) | ||||
assert(!neg.allowed?('HMAC-SHA256', 'no-encryption')) | ||||
neg.add_allowed_type('HMAC-SHA256', 'DH-SHA256') | ||||
assert(neg.allowed?('HMAC-SHA1', 'DH-SHA1')) | ||||
assert(neg.allowed?('HMAC-SHA1', 'no-encryption')) | ||||
assert(neg.allowed?('HMAC-SHA256', 'DH-SHA256')) | ||||
assert(!neg.allowed?('HMAC-SHA256', 'no-encryption')) | ||||
assert_equal(neg.get_allowed_type, ['HMAC-SHA1', 'DH-SHA1']) | ||||
end | ||||
def test_bad_assoc_type | ||||
assert_raises(ProtocolError) { | ||||
AssociationNegotiator.new([['OMG', 'Ponies']]) | ||||
} | ||||
end | ||||
def test_bad_session_type | ||||
assert_raises(ProtocolError) { | ||||
AssociationNegotiator.new([['HMAC-SHA1', 'OMG-Ponies']]) | ||||
} | ||||
end | ||||
def test_default_negotiator | ||||
assert_equal(DefaultNegotiator.get_allowed_type, | ||||
['HMAC-SHA1', 'DH-SHA1']) | ||||
assert(DefaultNegotiator.allowed?('HMAC-SHA256', 'no-encryption')) | ||||
end | ||||
def test_encrypted_negotiator | ||||
assert_equal(EncryptedNegotiator.get_allowed_type, | ||||
['HMAC-SHA1', 'DH-SHA1']) | ||||
assert(!EncryptedNegotiator.allowed?('HMAC-SHA256', 'no-encryption')) | ||||
end | ||||
end | ||||
end | ||||