diff options
author | Vipul A M <vipulnsward@gmail.com> | 2016-07-09 15:51:56 -0700 |
---|---|---|
committer | Vipul A M <vipulnsward@gmail.com> | 2016-09-01 03:00:10 +0530 |
commit | 79c847892f5a08515769ad2598d4e6726dcd65e3 (patch) | |
tree | d330726952e6e5a8175a0144cf7de4d272703aea | |
parent | ae32b69ab9647f4072d6852c4d4d1f2a939360c1 (diff) | |
download | rails-79c847892f5a08515769ad2598d4e6726dcd65e3.tar.gz rails-79c847892f5a08515769ad2598d4e6726dcd65e3.tar.bz2 rails-79c847892f5a08515769ad2598d4e6726dcd65e3.zip |
Start passing cipher from EncryptedCookieJar since we use it to determine key length
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/cookies.rb | 12 | ||||
-rw-r--r-- | actionpack/test/dispatch/cookies_test.rb | 25 | ||||
-rw-r--r-- | activesupport/lib/active_support/message_encryptor.rb | 7 | ||||
-rw-r--r-- | activesupport/test/message_encryptor_test.rb | 4 |
4 files changed, 26 insertions, 22 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 8d7884b3b5..6f4fab396a 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -372,7 +372,7 @@ module ActionDispatch handle_options(options) - if @cookies[name.to_s] != value or options[:expires] + if @cookies[name.to_s] != value || options[:expires] @cookies[name.to_s] = value @set_cookies[name.to_s] = options @delete_cookies.delete(name.to_s) @@ -567,19 +567,17 @@ module ActionDispatch class EncryptedCookieJar < AbstractCookieJar # :nodoc: include SerializedCookieJars - DEFAULT_CIPHER = 'aes-256-cbc' - def initialize(parent_jar, cipher: DEFAULT_CIPHER) - super(parent_jar) + def initialize(parent_jar) + super if ActiveSupport::LegacyKeyGenerator === key_generator raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " + "Read the upgrade documentation to learn more about this new config option." end - key_len = OpenSSL::Cipher.new(cipher).key_len - secret = key_generator.generate_key(request.encrypted_cookie_salt || '')[0, key_len] - sign_secret = key_generator.generate_key(request.encrypted_signed_cookie_salt || '') + secret = key_generator.generate_key(request.encrypted_cookie_salt || "")[0, ActiveSupport::MessageEncryptor.key_len] + sign_secret = key_generator.generate_key(request.encrypted_signed_cookie_salt || "") @encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, digest: digest, serializer: ActiveSupport::MessageEncryptor::NullSerializer) end diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index 2bee6c75bb..38cf0a2346 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -603,7 +603,7 @@ class CookiesTest < ActionController::TestCase secret = key_generator.generate_key(encrypted_cookie_salt) sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt) - marshal_value = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: Marshal).encrypt_and_sign("bar") + marshal_value = ActiveSupport::MessageEncryptor.new(secret[0, ActiveSupport::MessageEncryptor.key_len], sign_secret, serializer: Marshal).encrypt_and_sign("bar") @request.headers["Cookie"] = "foo=#{marshal_value}" get :get_encrypted_cookie @@ -612,7 +612,7 @@ class CookiesTest < ActionController::TestCase assert_not_equal "bar", cookies[:foo] assert_equal "bar", cookies.encrypted[:foo] - encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON) + encryptor = ActiveSupport::MessageEncryptor.new(secret[0, ActiveSupport::MessageEncryptor.key_len], sign_secret, serializer: JSON) assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"]) end @@ -624,7 +624,7 @@ class CookiesTest < ActionController::TestCase encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"] secret = key_generator.generate_key(encrypted_cookie_salt) sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt) - json_value = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON).encrypt_and_sign("bar") + json_value = ActiveSupport::MessageEncryptor.new(secret[0, ActiveSupport::MessageEncryptor.key_len], sign_secret, serializer: JSON).encrypt_and_sign("bar") @request.headers["Cookie"] = "foo=#{json_value}" get :get_encrypted_cookie @@ -636,10 +636,9 @@ class CookiesTest < ActionController::TestCase assert_nil @response.cookies["foo"] end - def test_compat_encrypted_cookie_using_64_byte_key # Cookie generated with 64 bytes secret - message = ["566d4e75536d686e633246564e6b493062557079626c566d51574d30515430394c53315665564a694e4563786555744f57537454576b396a5a31566a626e52525054303d2d2d34663234333330623130623261306163363562316266323335396164666364613564643134623131"].pack('H*') + message = ["566d4e75536d686e633246564e6b493062557079626c566d51574d30515430394c53315665564a694e4563786555744f57537454576b396a5a31566a626e52525054303d2d2d34663234333330623130623261306163363562316266323335396164666364613564643134623131"].pack("H*") @request.headers["Cookie"] = "foo=#{message}" get :get_encrypted_cookie @@ -813,8 +812,8 @@ class CookiesTest < ActionController::TestCase key_generator = @request.env["action_dispatch.key_generator"] secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"]) sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"]) - encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret) - assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"]) + encryptor = ActiveSupport::MessageEncryptor.new(secret[0, ActiveSupport::MessageEncryptor.key_len], sign_secret) + assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"]) end def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_cookie_jar_if_both_secret_token_and_secret_key_base_are_set @@ -852,8 +851,8 @@ class CookiesTest < ActionController::TestCase key_generator = @request.env["action_dispatch.key_generator"] secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"]) sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"]) - encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON) - assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"]) + encryptor = ActiveSupport::MessageEncryptor.new(secret[0, ActiveSupport::MessageEncryptor.key_len], sign_secret, serializer: JSON) + assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"]) end def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set @@ -891,8 +890,8 @@ class CookiesTest < ActionController::TestCase key_generator = @request.env["action_dispatch.key_generator"] secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"]) sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"]) - encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON) - assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"]) + encryptor = ActiveSupport::MessageEncryptor.new(secret[0, ActiveSupport::MessageEncryptor.key_len], sign_secret, serializer: JSON) + assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"]) end def test_legacy_marshal_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set @@ -930,8 +929,8 @@ class CookiesTest < ActionController::TestCase key_generator = @request.env["action_dispatch.key_generator"] secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"]) sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"]) - encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON) - assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"]) + encryptor = ActiveSupport::MessageEncryptor.new(secret[0, ActiveSupport::MessageEncryptor.key_len], sign_secret, serializer: JSON) + assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"]) end def test_legacy_signed_cookie_is_treated_as_nil_by_signed_cookie_jar_if_tampered diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index ab8b2f8ded..7b33dc3481 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -19,6 +19,8 @@ module ActiveSupport # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..." # crypt.decrypt_and_verify(encrypted_data) # => "my secret data" class MessageEncryptor + DEFAULT_CIPHER = "aes-256-cbc" + module NullSerializer #:nodoc: def self.load(value) value @@ -77,6 +79,11 @@ module ActiveSupport _decrypt(verifier.verify(value)) end + # Given a cipher, returns the key length of the cipher to help generate the key of desired size + def self.key_len(cipher = DEFAULT_CIPHER) + OpenSSL::Cipher.new(cipher).key_len + end + private def _encrypt(value) diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index fc17fdf3ee..f8282c89ca 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -50,12 +50,12 @@ class MessageEncryptorTest < ActiveSupport::TestCase def test_backwards_compat_for_64_bytes_key # 64 bit key - secret = ["3942b1bf81e622559ed509e3ff274a780784fe9e75b065866bd270438c74da822219de3156473cc27df1fd590e4baf68c95eeb537b6e4d4c5a10f41635b5597e"].pack('H*') + secret = ["3942b1bf81e622559ed509e3ff274a780784fe9e75b065866bd270438c74da822219de3156473cc27df1fd590e4baf68c95eeb537b6e4d4c5a10f41635b5597e"].pack("H*") # Encryptor with 32 bit key, 64 bit secret for verifier encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], secret) # Message generated with 64 bit key message = "eHdGeExnZEwvMSt3U3dKaFl1WFo0TjVvYzA0eGpjbm5WSkt5MXlsNzhpZ0ZnbWhBWFlQZTRwaXE1bVJCS2oxMDZhYVp2dVN3V0lNZUlWQ3c2eVhQbnhnVjFmeVVubmhRKzF3WnZyWHVNMDg9LS1HSisyakJVSFlPb05ISzRMaXRzcFdBPT0=--831a1d54a3cda8a0658dc668a03dedcbce13b5ca" - assert_equal 'data', encryptor.decrypt_and_verify(message)[:some] + assert_equal "data", encryptor.decrypt_and_verify(message)[:some] end def test_alternative_serialization_method |