2017-07-09 08:06:36 -04:00
|
|
|
# frozen_string_literal: true
|
2017-07-10 09:39:13 -04:00
|
|
|
|
2018-09-29 20:50:43 -04:00
|
|
|
require_relative "abstract_unit"
|
2012-07-03 20:37:31 -04:00
|
|
|
|
|
|
|
begin
|
2016-08-06 12:03:25 -04:00
|
|
|
require "openssl"
|
2012-07-03 20:37:31 -04:00
|
|
|
OpenSSL::PKCS5
|
|
|
|
rescue LoadError, NameError
|
|
|
|
$stderr.puts "Skipping KeyGenerator test: broken OpenSSL install"
|
|
|
|
else
|
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
class KeyGeneratorTest < ActiveSupport::TestCase
|
2020-12-09 05:23:26 -05:00
|
|
|
class InvalidDigest; end
|
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
def setup
|
|
|
|
@secret = SecureRandom.hex(64)
|
|
|
|
@generator = ActiveSupport::KeyGenerator.new(@secret, iterations: 2)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "Generating a key of the default length" do
|
|
|
|
derived_key = @generator.generate_key("some_salt")
|
|
|
|
assert_kind_of String, derived_key
|
|
|
|
assert_equal 64, derived_key.length, "Should have generated a key of the default size"
|
|
|
|
end
|
|
|
|
|
|
|
|
test "Generating a key of an alternative length" do
|
|
|
|
derived_key = @generator.generate_key("some_salt", 32)
|
|
|
|
assert_kind_of String, derived_key
|
|
|
|
assert_equal 32, derived_key.length, "Should have generated a key of the right size"
|
|
|
|
end
|
|
|
|
|
|
|
|
test "Expected results" do
|
|
|
|
# For any given set of inputs, this method must continue to return
|
|
|
|
# the same output: if it changes, any existing values relying on a
|
|
|
|
# key would break.
|
|
|
|
|
|
|
|
expected = "b129376f68f1ecae788d7433310249d65ceec090ecacd4c872a3a9e9ec78e055739be5cc6956345d5ae38e7e1daa66f1de587dc8da2bf9e8b965af4b3918a122"
|
2018-03-02 00:09:24 -05:00
|
|
|
assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64).generate_key("some_salt").unpack1("H*")
|
2016-08-06 13:55:02 -04:00
|
|
|
|
|
|
|
expected = "b129376f68f1ecae788d7433310249d65ceec090ecacd4c872a3a9e9ec78e055"
|
2018-03-02 00:09:24 -05:00
|
|
|
assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64).generate_key("some_salt", 32).unpack1("H*")
|
2016-08-06 13:55:02 -04:00
|
|
|
|
|
|
|
expected = "cbea7f7f47df705967dc508f4e446fd99e7797b1d70011c6899cd39bbe62907b8508337d678505a7dc8184e037f1003ba3d19fc5d829454668e91d2518692eae"
|
2018-03-02 00:09:24 -05:00
|
|
|
assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64, iterations: 2).generate_key("some_salt").unpack1("H*")
|
2016-08-06 13:55:02 -04:00
|
|
|
end
|
2020-12-09 05:23:26 -05:00
|
|
|
|
|
|
|
test "With custom hash digest class" do
|
|
|
|
original_hash_digest_class = ActiveSupport::KeyGenerator.hash_digest_class
|
|
|
|
|
|
|
|
ActiveSupport::KeyGenerator.hash_digest_class = ::OpenSSL::Digest::SHA256
|
|
|
|
|
|
|
|
expected = "c92322ad55ee691520e8e0f279b53e7a5cc9c1f8efca98295ae252b04cc6e2274c3aaf75ef53b260a6dc548f3e5fbb8af0edf10e7663cf7054c35bcc12835fc0"
|
|
|
|
assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64).generate_key("some_salt").unpack1("H*")
|
|
|
|
ensure
|
|
|
|
ActiveSupport::KeyGenerator.hash_digest_class = original_hash_digest_class
|
|
|
|
end
|
|
|
|
|
|
|
|
test "Raises if given a non digest instance" do
|
|
|
|
assert_raises(ArgumentError) { ActiveSupport::KeyGenerator.hash_digest_class = InvalidDigest }
|
|
|
|
assert_raises(ArgumentError) { ActiveSupport::KeyGenerator.hash_digest_class = InvalidDigest.new }
|
|
|
|
end
|
2012-07-03 20:37:31 -04:00
|
|
|
end
|
2016-06-30 11:31:45 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
class CachingKeyGeneratorTest < ActiveSupport::TestCase
|
|
|
|
def setup
|
|
|
|
@secret = SecureRandom.hex(64)
|
|
|
|
@generator = ActiveSupport::KeyGenerator.new(@secret, iterations: 2)
|
|
|
|
@caching_generator = ActiveSupport::CachingKeyGenerator.new(@generator)
|
|
|
|
end
|
2016-06-30 11:31:45 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
test "Generating a cached key for same salt and key size" do
|
|
|
|
derived_key = @caching_generator.generate_key("some_salt", 32)
|
|
|
|
cached_key = @caching_generator.generate_key("some_salt", 32)
|
2016-06-30 11:31:45 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
assert_equal derived_key, cached_key
|
|
|
|
assert_equal derived_key.object_id, cached_key.object_id
|
|
|
|
end
|
2016-06-30 11:31:45 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
test "Does not cache key for different salt" do
|
|
|
|
derived_key = @caching_generator.generate_key("some_salt", 32)
|
|
|
|
different_salt_key = @caching_generator.generate_key("other_salt", 32)
|
2012-07-03 20:37:31 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
assert_not_equal derived_key, different_salt_key
|
|
|
|
end
|
2014-07-19 15:49:52 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
test "Does not cache key for different length" do
|
|
|
|
derived_key = @caching_generator.generate_key("some_salt", 32)
|
|
|
|
different_length_key = @caching_generator.generate_key("some_salt", 64)
|
2014-07-19 15:49:52 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
assert_not_equal derived_key, different_length_key
|
|
|
|
end
|
2020-05-04 13:56:32 -04:00
|
|
|
|
|
|
|
test "Does not cache key for different salts and lengths that are different but are equal when concatenated" do
|
|
|
|
derived_key = @caching_generator.generate_key("13", 37)
|
|
|
|
different_length_key = @caching_generator.generate_key("1", 337)
|
|
|
|
|
|
|
|
assert_not_equal derived_key, different_length_key
|
|
|
|
end
|
2014-07-19 15:49:52 -04:00
|
|
|
end
|
2012-07-03 20:37:31 -04:00
|
|
|
end
|