slosilo 1.1.0 → 2.2.2

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