slosilo 1.1.0 → 2.2.2

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.
@@ -88,5 +88,37 @@ describe Slosilo do
88
88
  expect(subject.token_signer(token)).not_to be
89
89
  end
90
90
  end
91
+
92
+ context "with JWT token" do
93
+ before do
94
+ expect(key).to receive(:validate_jwt) do |jwt|
95
+ expect(jwt.header).to eq 'kid' => key.fingerprint
96
+ expect(jwt.claims).to eq({})
97
+ expect(jwt.signature).to eq 'sig'
98
+ end
99
+ end
100
+
101
+ it "accepts pre-parsed JSON serialization" do
102
+ expect(Slosilo.token_signer(
103
+ 'protected' => 'eyJraWQiOiIxMDdiZGI4NTAxYzQxOWZhZDJmZGIyMGI0NjdkNGQwYTYyYTE2YTk4YzM1ZjJkYTBlYjNiMWZmOTI5Nzk1YWQ5In0=',
104
+ 'payload' => 'e30=',
105
+ 'signature' => 'c2ln'
106
+ )).to eq 'test'
107
+ end
108
+
109
+ it "accepts pre-parsed JWT token" do
110
+ expect(Slosilo.token_signer(Slosilo::JWT(
111
+ 'protected' => 'eyJraWQiOiIxMDdiZGI4NTAxYzQxOWZhZDJmZGIyMGI0NjdkNGQwYTYyYTE2YTk4YzM1ZjJkYTBlYjNiMWZmOTI5Nzk1YWQ5In0=',
112
+ 'payload' => 'e30=',
113
+ 'signature' => 'c2ln'
114
+ ))).to eq 'test'
115
+ end
116
+
117
+ it "accepts compact serialization" do
118
+ expect(Slosilo.token_signer(
119
+ 'eyJraWQiOiIxMDdiZGI4NTAxYzQxOWZhZDJmZGIyMGI0NjdkNGQwYTYyYTE2YTk4YzM1ZjJkYTBlYjNiMWZmOTI5Nzk1YWQ5In0=.e30=.c2ln'
120
+ )).to eq 'test'
121
+ end
122
+ end
91
123
  end
92
124
  end
@@ -1,4 +1,7 @@
1
1
  require "simplecov"
2
+ require "simplecov-cobertura"
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
2
5
  SimpleCov.start
3
6
 
4
7
  require 'slosilo'
@@ -41,7 +44,7 @@ Dg1ikwi8GUF4HPZe9DyhXgDhg19wM/qcpjX8bSypsUWHWP+FanhjdWU=
41
44
  -----END RSA PRIVATE KEY-----
42
45
  """ }
43
46
  let (:key) { Slosilo::Key.new rsa.to_der }
44
- let (:key_fingerprint) { "d28e3a347e368416b3129a40c1b887fe" }
47
+ let (:key_fingerprint) { "107bdb8501c419fad2fdb20b467d4d0a62a16a98c35f2da0eb3b1ff929795ad9" }
45
48
 
46
49
  let (:another_rsa) do
47
50
  OpenSSL::PKey::RSA.new """
@@ -74,7 +77,7 @@ ooQ2FuL0K6ukQfHPjuMswqi41lmVH8gIVqVC+QnImUCrGxH9WXWy
74
77
  -----END RSA PRIVATE KEY-----
75
78
  """
76
79
  end
77
-
80
+
78
81
  def self.mock_own_key
79
82
  before { allow(Slosilo).to receive(:[]).with(:own).and_return key }
80
83
  end
@@ -3,34 +3,56 @@ require 'spec_helper'
3
3
  describe Slosilo::Symmetric do
4
4
  # TODO transform it to class methods only?
5
5
  let(:plaintext) { "quick brown fox jumped over the lazy dog" }
6
+ let(:auth_data) { "some record id" }
6
7
  let(:key) { "^\xBAIv\xDB1\x0Fi\x04\x11\xFD\x14\xA7\xCD\xDFf\x93\xFE\x93}\v\x01\x11\x98\x14\xE0;\xC1\xE2 v\xA5".force_encoding("ASCII-8BIT") }
7
- let(:iv) { "\xA1\xFA#z\x16\x80R\xCC|\x0Fyc\xB7j\x17\xED".force_encoding("ASCII-8BIT") }
8
- let(:ciphertext) { "\xA1\xFA#z\x16\x80R\xCC|\x0Fyc\xB7j\x17\xED\x15\xC9r\xC9\xEE\xB9\xBC5\xB7\ni\x0F\f\xC8X\x80 h\a\xF4\xA6\xE3\x15\x9D\xF1-\xE5\bs\xF6\x02Z\x0F\xCD|S\x1A\xAA\x9At\xEFT\x17\xA5lT\x8C\xF3".force_encoding("ASCII-8BIT") }
8
+ let(:iv) { "\xD9\xABn\x01b\xFA\xBD\xC2\xE5\xEA\x01\xAC".force_encoding("ASCII-8BIT") }
9
+ let(:ciphertext) { "G^W1\x9C\xD4\xCC\x87\xD3\xFF\x86[\x0E3\xC0\xC8^\xD9\xABn\x01b\xFA\xBD\xC2\xE5\xEA\x01\xAC\x9E\xB9:\xF7\xD4ebeq\xDC \xC0sG\xA4\xAE,\xB8A|\x97\xBC\xFD\x85\xE1\xB93\x95>\xBD\n\x05\xFB\x15\x1F\x06#3M9".force_encoding('ASCII-8BIT') }
10
+
9
11
  describe '#encrypt' do
10
- it "encrypts with AES-256-CBC" do
12
+ it "encrypts with AES-256-GCM" do
11
13
  allow(subject).to receive_messages random_iv: iv
12
- expect(subject.encrypt(plaintext, key: key)).to eq(ciphertext)
14
+ expect(subject.encrypt(plaintext, key: key, aad: auth_data)).to eq(ciphertext)
13
15
  end
14
16
  end
15
17
 
16
18
  describe '#decrypt' do
17
- it "decrypts with AES-256-CBC" do
18
- expect(subject.decrypt(ciphertext, key: key)).to eq(plaintext)
19
+ it "decrypts with AES-256-GCM" do
20
+ expect(subject.decrypt(ciphertext, key: key, aad: auth_data)).to eq(plaintext)
21
+ end
22
+
23
+
24
+ context "when the ciphertext has been messed with" do
25
+ let(:ciphertext) { "pwnd!" } # maybe we should do something more realistic like add some padding?
26
+ it "raises an exception" do
27
+ expect{ subject.decrypt(ciphertext, key: key, aad: auth_data)}.to raise_exception /Invalid version/
28
+ end
29
+ context "by adding a trailing 0" do
30
+ let(:new_ciphertext){ ciphertext + '\0' }
31
+ it "raises an exception" do
32
+ expect{ subject.decrypt(new_ciphertext, key: key, aad: auth_data) }.to raise_exception /Invalid version/
33
+ end
34
+ end
19
35
  end
20
-
21
- context "when ciphertext happens to end in a zero" do
22
- let(:ciphertext) { "\x7F\xD6\xEAb\xE56\a\xD3\xC5\xF2J\n\x8C\x8Fg\xB7-\\\x8A\fh\x18\xC8\x91\xB9 \x97\xC9\x12\xE6\xA6\xAE\xB1I\x1E\x80\xAB\xD8\xDC\xBD\xB6\xCD\x9A\xA3MH\xA8\xB0\xC7\xDA\x87\xA7c\xD75,\xD2A\xB8\x9E\xE3o\x04\x00" }
23
- let(:key) { "4pSuk1rAQyuHA5uUYaj0X0BsiPCFb9Nc8J03XA6V5/Y" }
24
- it "works correctly" do
25
- expect(subject.decrypt(ciphertext, key: key)).to eq("R6KNTQ4aUivojbaqhgAqj1I4PaF8h/5/YcENy4uNbfk=")
36
+
37
+ context "when no auth_data is given" do
38
+ let(:auth_data){""}
39
+ let(:ciphertext){ "Gm\xDAT\xE8I\x9F\xB7\xDC\xBB\x84\xD3Q#\x1F\xF4\x8C\aV\x93\x8F_\xC7\xBC87\xC9U\xF1\xAF\x8A\xD62\x1C5H\x86\x17\x19=B~Y*\xBC\x9D\eJeTx\x1F\x02l\t\t\xD3e\xA4\x11\x13y*\x95\x9F\xCD\xC4@\x9C"}
40
+
41
+ it "decrypts the message" do
42
+ expect(subject.decrypt(ciphertext, key: key, aad: auth_data)).to eq(plaintext)
43
+ end
44
+
45
+ context "and the ciphertext has been messed with" do
46
+ it "raises an exception" do
47
+ expect{ subject.decrypt(ciphertext + "\0\0\0", key: key, aad: auth_data)}.to raise_exception OpenSSL::Cipher::CipherError
48
+ end
26
49
  end
27
50
  end
28
51
 
29
- context "when the iv ends in space" do
30
- let(:ciphertext) { "\xC0\xDA#\xE9\xE1\xFD\xEDJ\xADs4P\xA9\xD6\x92 \xF7\xF8_M\xF6\x16\xC2i$\x8BT^\b\xA1\xB2L&\xE9\x80\x02[]6i\x9B\xD3\xC3\xED\xA9\xD1\x94\xE8\x15\xFD\xDA\xFEUj\xC5upH*\xBF\x82\x15le" }
31
- let(:key) { "4pSuk1rAQyuHA5uUYaj0X0BsiPCFb9Nc8J03XA6V5/Y" }
32
- it "works correctly" do
33
- expect(subject.decrypt(ciphertext, key: key)).to eq("zGptmL3vd4obi1vqSiWHt/Ias2k+6qDtuq9vdow8jNA=")
52
+ context "when the auth data doesn't match" do
53
+ let(:auth_data){ "asdf" }
54
+ it "raises an exception" do
55
+ expect{ subject.decrypt(ciphertext, key: key, aad: auth_data)}.to raise_exception OpenSSL::Cipher::CipherError
34
56
  end
35
57
  end
36
58
  end
data/test.sh ADDED
@@ -0,0 +1,27 @@
1
+ #!/bin/bash -xe
2
+
3
+ iid=slosilo-test-$(date +%s)
4
+
5
+ docker build -t $iid -f - . << EOF
6
+ FROM ruby
7
+ WORKDIR /app
8
+ COPY Gemfile slosilo.gemspec ./
9
+ RUN bundle
10
+ COPY . ./
11
+ RUN bundle
12
+ EOF
13
+
14
+ cidfile=$(mktemp -u)
15
+ docker run --cidfile $cidfile -v /app/spec/reports $iid bundle exec rake jenkins || :
16
+
17
+ cid=$(cat $cidfile)
18
+
19
+ docker cp $cid:/app/spec/reports spec/
20
+ docker cp $cid:/app/coverage spec
21
+
22
+ docker rm $cid
23
+
24
+ # untag, will use cache next time if available but no junk will be left
25
+ docker rmi $iid
26
+
27
+ rm $cidfile
metadata CHANGED
@@ -1,111 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slosilo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafał Rzepecki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-20 00:00:00.000000000 Z
11
+ date: 2020-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: ci_reporter_rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: simplecov
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov-cobertura
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: io-grab
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ~>
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
89
  version: 0.0.1
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ~>
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: 0.0.1
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: sequel
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '>='
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
103
  version: '0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '>='
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: sqlite3
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - '>='
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activesupport
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
102
130
  - !ruby/object:Gem::Version
103
131
  version: '0'
104
132
  type: :development
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
- - - '>='
136
+ - - ">="
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0'
111
139
  description: This gem provides an easy way of storing and retrieving encryption keys
@@ -116,12 +144,20 @@ executables: []
116
144
  extensions: []
117
145
  extra_rdoc_files: []
118
146
  files:
119
- - .gitignore
120
- - .kateproject
147
+ - ".dockerignore"
148
+ - ".github/CODEOWNERS"
149
+ - ".github/PULL_REQUEST_TEMPLATE.md"
150
+ - ".gitignore"
151
+ - ".gitleaks.toml"
152
+ - ".kateproject"
153
+ - CHANGELOG.md
154
+ - CONTRIBUTING.md
121
155
  - Gemfile
156
+ - Jenkinsfile
122
157
  - LICENSE
123
158
  - README.md
124
159
  - Rakefile
160
+ - SECURITY.md
125
161
  - lib/slosilo.rb
126
162
  - lib/slosilo/adapters/abstract_adapter.rb
127
163
  - lib/slosilo/adapters/file_adapter.rb
@@ -131,14 +167,18 @@ files:
131
167
  - lib/slosilo/adapters/sequel_adapter/migration.rb
132
168
  - lib/slosilo/attr_encrypted.rb
133
169
  - lib/slosilo/errors.rb
170
+ - lib/slosilo/jwt.rb
134
171
  - lib/slosilo/key.rb
135
172
  - lib/slosilo/keystore.rb
136
173
  - lib/slosilo/random.rb
137
174
  - lib/slosilo/symmetric.rb
138
175
  - lib/slosilo/version.rb
139
176
  - lib/tasks/slosilo.rake
177
+ - publish-rubygem.sh
140
178
  - slosilo.gemspec
179
+ - spec/encrypted_attributes_spec.rb
141
180
  - spec/file_adapter_spec.rb
181
+ - spec/jwt_spec.rb
142
182
  - spec/key_spec.rb
143
183
  - spec/keystore_spec.rb
144
184
  - spec/random_spec.rb
@@ -146,6 +186,7 @@ files:
146
186
  - spec/slosilo_spec.rb
147
187
  - spec/spec_helper.rb
148
188
  - spec/symmetric_spec.rb
189
+ - test.sh
149
190
  homepage: ''
150
191
  licenses:
151
192
  - MIT
@@ -156,22 +197,23 @@ require_paths:
156
197
  - lib
157
198
  required_ruby_version: !ruby/object:Gem::Requirement
158
199
  requirements:
159
- - - '>='
200
+ - - ">="
160
201
  - !ruby/object:Gem::Version
161
202
  version: 1.9.3
162
203
  required_rubygems_version: !ruby/object:Gem::Requirement
163
204
  requirements:
164
- - - '>='
205
+ - - ">="
165
206
  - !ruby/object:Gem::Version
166
207
  version: '0'
167
208
  requirements: []
168
- rubyforge_project:
169
- rubygems_version: 2.2.2
209
+ rubygems_version: 3.1.2
170
210
  signing_key:
171
211
  specification_version: 4
172
212
  summary: Store SSL keys in a database
173
213
  test_files:
214
+ - spec/encrypted_attributes_spec.rb
174
215
  - spec/file_adapter_spec.rb
216
+ - spec/jwt_spec.rb
175
217
  - spec/key_spec.rb
176
218
  - spec/keystore_spec.rb
177
219
  - spec/random_spec.rb
@@ -179,4 +221,3 @@ test_files:
179
221
  - spec/slosilo_spec.rb
180
222
  - spec/spec_helper.rb
181
223
  - spec/symmetric_spec.rb
182
- has_rdoc: