rack_encrypted_cookie 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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.