rack_encrypted_cookie 0.1.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37f851fd1c4669c9aaa27891cd6e1999b02288b9
4
- data.tar.gz: 315f45d56f3d7d95f8e01932c618bc63f0740206
3
+ metadata.gz: 3a56244311887c06f5a713734e8cf1680db23649
4
+ data.tar.gz: c0bcaea9daa22d73887e2d1e859cc516eb8250e0
5
5
  SHA512:
6
- metadata.gz: 336e1835ccfd59a16cc4a9098586ed8ceb8858d65f52636a8295a6684c17bb4e2aa1ff3045b49b9226ac8c203a2759022f1fc5bc846ee2f09ae9f0832e61debc
7
- data.tar.gz: 12c70b46342d8090e71e1446ef11a7b0cc4ee5d7db65553073aee4c7c2008cca8c1d6a94d15afacc0a3fed125aa67a2ec01ae3212041a84c30f7a6695d7f89c5
6
+ metadata.gz: 88a3bbcec54ea098875da7d613cff4320071fb0589ed210eb7365115d61a5e483d3d0f5e9c201cbfa8902b1f5781f7b6c0bc65c48d8b5aa640852ce19b09b46e
7
+ data.tar.gz: 9f7da1a3c229c1fa8df184fcd84b92701dffd1b2674be33c2f0af5f05ec31e8908c4220eae0a6733ca0e05116ce66bbeb001515a3971700d2335f6ad2277df81
@@ -2,78 +2,33 @@
2
2
  require 'rack/session/cookie'
3
3
  require 'openssl'
4
4
  require 'base64'
5
+ require 'coder_decorator'
5
6
 
6
7
  module Rack
7
8
  module Session
8
9
  class EncryptedCookie < Cookie #:nodoc:
10
+ Coders = CoderDecorator::Coders
9
11
  def initialize(app, options = {})
10
- super
11
- @salt = options.fetch(:salt, 'encrypted cookie')
12
- @signed_salt = options.fetch(:signed_salt, 'signed encrypted cookie')
12
+ @secret_key_bases = options.values_at(:secret, :old_secret).compact
13
+ return super if @secret_key_bases.empty?
13
14
  @iterations = options.fetch(:iterations, 1024)
14
15
  @key_size = options.fetch(:key_size, 64)
15
- @cipher = OpenSSL::Cipher::Cipher.new(options.fetch(:cipher, 'AES-256-CBC'))
16
- @cipher_secrets = @secrets.map { |secret| generate_key(secret, @salt) }
17
- @secrets.map! { |secret| generate_key(secret, @signed_salt) }
16
+ cipher = options.fetch(:cipher, 'AES-256-CBC')
17
+ digest = options.fetch(:digest, 'SHA1')
18
+ salt = options.fetch(:salt, 'encrypted cookie')
19
+ signed_salt = options.fetch(:signed_salt, 'signed encrypted cookie')
20
+ cipher_secrets = @secret_key_bases.map { |secret_key_base| generate_key(secret_key_base, salt) }
21
+ sign_secrets = @secret_key_bases.map { |secret_key_base| generate_key(secret_key_base, signed_salt) }
22
+ encrypted_coder = Coders::Cipher.new(Coders::Marshal.new, secret: cipher_secrets.first, old_secret: cipher_secrets.last, cipher: cipher)
23
+ signed_coder = Coders::HMAC.new(encrypted_coder, secret: sign_secrets.first, old_secret: sign_secrets.last, digest: digest)
24
+ options[:coder] = Coders::Rescue.new(signed_coder)
25
+ options[:let_coder_handle_secure_encoding] = true
26
+ super
27
+ @secrets = [] # hack, lie to Rack::Session that there is no @secrets
18
28
  end
19
29
 
20
30
  private
21
31
 
22
- def unpacked_cookie_data(request)
23
- request.fetch_header(RACK_SESSION_UNPACKED_COOKIE_DATA) do |k|
24
- session_data = request.cookies[@key]
25
-
26
- if !@secrets.empty? && session_data
27
- digest, session_data = session_data.reverse.split('--', 2)
28
- digest&.reverse!
29
- session_data&.reverse!
30
- session_data = nil unless digest_match?(session_data, digest)
31
- end
32
-
33
- if !@cipher_secrets.empty? && session_data
34
- encrypted_data, iv = ::Base64.strict_decode64(session_data).split('--').map! { |v| ::Base64.strict_decode64(v) }
35
-
36
- @cipher_secrets.each do |cipher_secret|
37
- @cipher.decrypt
38
- @cipher.key = cipher_secret
39
- @cipher.iv = iv
40
- begin
41
- session_data = @cipher.update(encrypted_data) << @cipher.final
42
- break
43
- rescue OpenSSL::Cipher::CipherError
44
- next
45
- end
46
- end
47
- end
48
- request.set_header(k, coder.decode(session_data) || {})
49
- end
50
- end
51
-
52
- def write_session(req, session_id, session, _options)
53
- session = session.merge('session_id' => session_id)
54
- session_data = coder.encode(session)
55
-
56
- if @cipher_secrets.first
57
- @cipher.encrypt
58
- @cipher.key = @cipher_secrets.first
59
- iv = @cipher.random_iv
60
- encrypted_data = @cipher.update(session_data) << @cipher.final
61
- blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
62
- session_data = ::Base64.strict_encode64(blob)
63
- end
64
-
65
- if @secrets.first
66
- session_data << "--#{generate_hmac(session_data, @secrets.first)}"
67
- end
68
-
69
- if session_data.size > (4096 - @key.size)
70
- req.get_header(RACK_ERRORS).puts('Warning! Rack::Session::Cookie data size exceeds 4K.')
71
- nil
72
- else
73
- session_data
74
- end
75
- end
76
-
77
32
  def generate_key(secret, salt)
78
33
  OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret, salt, @iterations, @key_size)
79
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack_encrypted_cookie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jian Weihang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-05 00:00:00.000000000 Z
11
+ date: 2016-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coder_decorator
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.2
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: minitest
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
108
  version: '0'
95
109
  requirements: []
96
110
  rubyforge_project:
97
- rubygems_version: 2.6.4
111
+ rubygems_version: 2.6.8
98
112
  signing_key:
99
113
  specification_version: 4
100
114
  summary: Rack middleware for signed encrypted session cookie.