logstash-filter-cipher 2.0.7 → 3.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: eb8a36f3ee9e8c96a94133c1dec5528514c2c448
4
- data.tar.gz: 85bf16fd717f4eece52336c2cc206539d77d6a85
3
+ metadata.gz: 98f7eee7d009598d46ceb96dd6c731a328206b1e
4
+ data.tar.gz: 434b055742014838598d35287605c9975b893c56
5
5
  SHA512:
6
- metadata.gz: 4d4181334e38e3eafce57eee431da438be940eb17307fd0a79458cbb2d069961add8d6413fed31af43ca0892252f17060bb07f7a8e712a21a855a9a38cab3197
7
- data.tar.gz: fe1a7a34af4d2b2a672b3ba4fe2593bda637cf29ff1a9a101a613febe9b236971cbdbf4f352aebf4b29b79230efbf62e005201514da57c13a985ed821eca478b
6
+ metadata.gz: a10c0455125608f96177b00d607020d805be56db9749316e7a554ed43000d88cc685637f0b65a78350811c7cd8b73294274cf7ede1ecacf3a4d31f87bbf65c4a
7
+ data.tar.gz: 61cf16ce5286967379ccddb678e437d6b9d1468ed735a6f9dc76b764de9663d81a257e66e39384347860a2cca5b68ca91f665ad63325836f76843c29bf7d26fd
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ # 3.0.0
2
+ - Mark deprecated iv field obsolete
3
+
1
4
  ## 2.0.7
2
5
  - Fix some documentation issues
3
6
 
data/docs/index.asciidoc CHANGED
@@ -97,29 +97,6 @@ it, Set this parameter to 0
97
97
  [source,ruby]
98
98
  filter { cipher { cipher_padding => 0 }}
99
99
 
100
- [id="plugins-{type}s-{plugin}-iv"]
101
- ===== `iv` (DEPRECATED)
102
-
103
- * DEPRECATED WARNING: This configuration item is deprecated and may not be available in future versions.
104
- * Value type is <<string,string>>
105
- * There is no default value for this setting.
106
-
107
- The initialization vector to use (statically hard-coded). For
108
- a random IV see the iv_random_length property
109
-
110
- NOTE: If iv_random_length is set, it takes precedence over any value set for "iv"
111
-
112
- The cipher modes CBC, CFB, OFB and CTR all need an "initialization
113
- vector", or short, IV. ECB mode is the only mode that does not require
114
- an IV, but there is almost no legitimate use case for this mode
115
- because of the fact that it does not sufficiently hide plaintext patterns.
116
-
117
- For AES algorithms set this to a 16 byte string.
118
- [source,ruby]
119
- filter { cipher { iv => "1234567890123456" }}
120
-
121
- Deprecated: Please use `iv_random_length` instead
122
-
123
100
  [id="plugins-{type}s-{plugin}-iv_random_length"]
124
101
  ===== `iv_random_length`
125
102
 
@@ -1,9 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require "logstash/filters/base"
3
- require "logstash/namespace"
4
3
  require "openssl"
5
4
 
6
-
7
5
  # This filter parses a source and apply a cipher or decipher before
8
6
  # storing it in the target.
9
7
  #
@@ -85,30 +83,13 @@ class LogStash::Filters::Cipher < LogStash::Filters::Base
85
83
  # filter { cipher { cipher_padding => 0 }}
86
84
  config :cipher_padding, :validate => :string
87
85
 
88
- # The initialization vector to use (statically hard-coded). For
89
- # a random IV see the iv_random_length property
90
- #
91
- # NOTE: If iv_random_length is set, it takes precedence over any value set for "iv"
92
- #
93
- # The cipher modes CBC, CFB, OFB and CTR all need an "initialization
94
- # vector", or short, IV. ECB mode is the only mode that does not require
95
- # an IV, but there is almost no legitimate use case for this mode
96
- # because of the fact that it does not sufficiently hide plaintext patterns.
97
- #
98
- # For AES algorithms set this to a 16 byte string.
99
- # [source,ruby]
100
- # filter { cipher { iv => "1234567890123456" }}
101
- #
102
- # Deprecated: Please use `iv_random_length` instead
103
- config :iv, :validate => :string, :deprecated => "Please use 'iv_random_length'"
86
+ config :iv, :validate => :string, :obsolete => "Please use 'iv_random_length'"
104
87
 
105
88
  # Force an random IV to be used per encryption invocation and specify
106
89
  # the length of the random IV that will be generated via:
107
90
  #
108
91
  # OpenSSL::Random.random_bytes(int_length)
109
92
  #
110
- # If iv_random_length is set, it takes precedence over any value set for "iv"
111
- #
112
93
  # Enabling this will force the plugin to generate a unique
113
94
  # random IV for each encryption call. This random IV will be prepended to the
114
95
  # encrypted result bytes and then base64 encoded. On decryption "iv_random_length" must
@@ -118,7 +99,7 @@ class LogStash::Filters::Cipher < LogStash::Filters::Base
118
99
  # For AES algorithms you can set this to a 16
119
100
  # [source,ruby]
120
101
  # filter { cipher { iv_random_length => 16 }}
121
- config :iv_random_length, :validate => :number
102
+ config :iv_random_length, :validate => :number, :required => true
122
103
 
123
104
  # If this is set the internal Cipher instance will be
124
105
  # re-used up to @max_cipher_reuse times before being
@@ -147,32 +128,24 @@ class LogStash::Filters::Cipher < LogStash::Filters::Base
147
128
  #If decrypt or encrypt fails, we keep it it intact.
148
129
  begin
149
130
 
150
- if (event[@source].nil? || event[@source].empty?)
131
+ if (event.get(@source).nil? || event.get(@source).empty?)
151
132
  @logger.debug("Event to filter, event 'source' field: " + @source + " was null(nil) or blank, doing nothing")
152
133
  return
153
134
  end
154
135
 
155
136
  #@logger.debug("Event to filter", :event => event)
156
- data = event[@source]
137
+ data = event.get(@source)
157
138
  if @mode == "decrypt"
158
139
  data = Base64.strict_decode64(data) if @base64 == true
159
-
160
- if !@iv_random_length.nil?
161
- @random_iv = data.byteslice(0,@iv_random_length)
162
- data = data.byteslice(@iv_random_length..data.length)
163
- end
164
-
140
+ @random_iv = data.byteslice(0,@iv_random_length)
141
+ data = data.byteslice(@iv_random_length..data.length)
165
142
  end
166
143
 
167
- if !@iv_random_length.nil? and @mode == "encrypt"
144
+ if @mode == "encrypt"
168
145
  @random_iv = OpenSSL::Random.random_bytes(@iv_random_length)
169
146
  end
170
147
 
171
- # if iv_random_length is specified, generate a new one
172
- # and force the cipher's IV = to the random value
173
- if !@iv_random_length.nil?
174
- @cipher.iv = @random_iv
175
- end
148
+ @cipher.iv = @random_iv
176
149
 
177
150
  result = @cipher.update(data) + @cipher.final
178
151
 
@@ -197,7 +170,7 @@ class LogStash::Filters::Cipher < LogStash::Filters::Base
197
170
 
198
171
  result = result.force_encoding("utf-8") if @mode == "decrypt"
199
172
 
200
- event[@target]= result
173
+ event.set(@target, result)
201
174
 
202
175
  #Is it necessary to add 'if !result.nil?' ? exception have been already catched.
203
176
  #In doubt, I keep it.
@@ -238,18 +211,9 @@ class LogStash::Filters::Cipher < LogStash::Filters::Base
238
211
 
239
212
  @cipher.key = @key
240
213
 
241
- if !@iv.nil? and !@iv.empty? and @iv_random_length.nil?
242
- @cipher.iv = @iv if @iv
243
-
244
- elsif !@iv_random_length.nil?
245
- @logger.debug("iv_random_length is configured, ignoring any statically defined value for 'iv'", :iv_random_length => @iv_random_length)
246
- else
247
- raise "cipher plugin: either 'iv' or 'iv_random_length' must be configured, but not both; aborting"
248
- end
249
-
250
214
  @cipher.padding = @cipher_padding if @cipher_padding
251
215
 
252
- @logger.debug("Cipher initialisation done", :mode => @mode, :key => @key, :iv => @iv, :iv_random => @iv_random, :cipher_padding => @cipher_padding)
216
+ @logger.debug("Cipher initialisation done", :mode => @mode, :key => @key, :iv_random_length => @iv_random_length, :iv_random => @iv_random, :cipher_padding => @cipher_padding)
253
217
  end # def init_cipher
254
218
 
255
219
 
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-cipher'
4
- s.version = '2.0.7'
4
+ s.version = '3.0.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "This filter parses a source and apply a cipher or decipher before storing it in the target"
7
7
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -19,8 +19,9 @@ Gem::Specification.new do |s|
19
19
  # Special flag to let us know this is actually a logstash plugin
20
20
  s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
21
21
 
22
+
22
23
  # Gem dependencies
23
- s.add_runtime_dependency "logstash-core-plugin-api", "~> 1.0"
24
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
25
 
25
26
  s.add_development_dependency 'logstash-devutils'
26
27
  end
@@ -1,215 +1,143 @@
1
- # encoding: utf-8
1
+ # encoding: utf-8
2
+ require 'logstash-core'
3
+ require "logstash/codecs/base"
4
+ require 'logstash/filters/cipher'
2
5
 
3
- require "logstash/devutils/rspec/spec_helper"
4
- require 'logstash/filters/cipher'
6
+ describe LogStash::Filters::Cipher do
5
7
 
6
- describe LogStash::Filters::Cipher do
8
+ let(:cleartext) do
9
+ 'شسيبشن٤٤ت٥ت داھدساققبمر фывапролдзщшгнекутцйячсмить asdfghjklqpoiuztreyxcvbnm,.-öäü+ä123ß´yö.,;LÖÜ*O 來少精清皆人址法田手扌打表氵開日大木裝 1234567890#$%^&*()!@#;:\'?.>,<testAESEn+=_-~`}]'
10
+ end
7
11
 
8
- let(:cleartext) do
9
- 'شسيبشن٤٤ت٥ت داھدساققبمر фывапролдзщшгнекутцйячсмить asdfghjklqpoiuztreyxcvbnm,.-öäü+ä123ß´yö.,;LÖÜ*O 來少精清皆人址法田手扌打表氵開日大木裝 1234567890#$%^&*()!@#;:\'?.>,<testAESEn+=_-~`}]'
10
- end
12
+ describe 'single event, encrypt/decrypt aes-128-cbc, 16b RANDOM IV, 16b key, b64 encode' do
13
+ let(:event) do
14
+ LogStash::Event.new(LogStash::Json.load("{\"message\":\"#{cleartext}\"}"))
15
+ end
11
16
 
12
- let(:event) do
13
- "{\"message\":\"#{cleartext}\"}"
14
- end
17
+ let(:encrypter) do
18
+ described_class.new(
19
+ "algorithm" => "aes-128-cbc",
20
+ "cipher_padding" => 1,
21
+ "iv_random_length" => 16,
22
+ "key" => "1234567890123456",
23
+ "key_size" => 16,
24
+ "mode" => "encrypt",
25
+ "source" => "message",
26
+ "target" => "message_crypted",
27
+ "base64" => true,
28
+ "max_cipher_reuse" => 1)
29
+ end
15
30
 
16
- let(:pipeline) { LogStash::Pipeline.new(config) }
31
+ let(:decrypter) do
32
+ described_class.new(
33
+ "algorithm" => "aes-128-cbc",
34
+ "cipher_padding" => 1,
35
+ "iv_random_length" => 16,
36
+ "key" => "1234567890123456",
37
+ "key_size" => 16,
38
+ "mode" => "decrypt",
39
+ "source" => "message_crypted",
40
+ "target" => "message_decrypted",
41
+ "base64" => true,
42
+ "max_cipher_reuse" => 1)
43
+ end
17
44
 
18
- let(:events) do
19
- arr = event.is_a?(Array) ? event : [event]
20
- arr.map do |evt|
21
- LogStash::Event.new(evt.is_a?(String) ? LogStash::Json.load(evt) : evt)
22
- end
23
- end
45
+ before(:each) do
46
+ encrypter.register
47
+ decrypter.register
48
+ end
24
49
 
25
- let(:results) do
26
- pipeline.instance_eval { @filters.each(&:register) }
27
- results = []
28
- events.each do |evt|
29
- # filter call the block on all filtered events, included new events added by the filter
30
- pipeline.filter(evt) do |filtered_event|
31
- results.push(filtered_event)
32
- end
33
- end
34
- pipeline.flush_filters(:final => true) { |flushed_event| results << flushed_event }
35
-
36
- results.select { |e| !e.cancelled? }
37
- end
50
+ let(:result) do
51
+ encrypter.filter(event)
52
+ decrypter.filter(event)
53
+ event
54
+ end
38
55
 
39
- describe 'single event, encrypt/decrypt aes-128-cbc, 16b RANDOM IV, 16b key, b64 encode' do
40
-
41
- let(:config) do
42
- <<-CONFIG
43
- filter {
44
-
45
- cipher {
46
- algorithm => "aes-128-cbc"
47
- cipher_padding => 1
48
- iv_random_length => 16
49
- key => "1234567890123456"
50
- key_size => 16
51
- mode => "encrypt"
52
- source => "message"
53
- target => "message_crypted"
54
- base64 => true
55
- max_cipher_reuse => 1
56
- }
57
-
58
- cipher {
59
- algorithm => "aes-128-cbc"
60
- cipher_padding => 1
61
- iv_random_length => 16
62
- key => "1234567890123456"
63
- key_size => 16
64
- mode => "decrypt"
65
- source => "message_crypted"
66
- target => "message_decrypted"
67
- base64 => true
68
- max_cipher_reuse => 1
69
- }
70
- }
71
- CONFIG
72
- end
73
-
74
- it 'validate initial cleartext message' do
75
- result = results.first
76
- expect(result["message"]).to eq(cleartext)
77
- end
78
-
79
- it 'validate decrypted message' do
80
- result = results.first
81
- expect(result["message_decrypted"]).to eq(result["message"])
82
- end
83
-
84
- it 'validate encrypted message is not equal to message' do
85
- result = results.first
86
- expect(result["message"]).not_to eq(result["message_crypted"])
87
- end
56
+ it 'validate initial cleartext message' do
57
+ expect(result.get("message")).to eq(cleartext)
58
+ end
88
59
 
89
- end
60
+ it 'validate decrypted message' do
61
+ expect(result.get("message_decrypted")).to eq(result.get("message"))
62
+ end
63
+
64
+ it 'validate encrypted message is not equal to message' do
65
+ expect(result.get("message")).not_to eq(result.get("message_crypted"))
66
+ end
67
+
68
+ end
90
69
 
70
+ describe '1000 events, 11 re-use, encrypt/decrypt aes-128-cbc, 16b RANDOM IV, 16b key, b64 encode' do
91
71
 
92
- describe 'single event, encrypt/decrypt aes-128-cbc, 16b STATIC IV, 16b key, b64 encode' do
93
-
94
- let(:config) do
95
- <<-CONFIG
96
- filter {
97
-
98
- cipher {
99
- algorithm => "aes-128-cbc"
100
- cipher_padding => 1
101
- iv => "1234567890123456"
102
- key => "1234567890123456"
103
- key_size => 16
104
- mode => "encrypt"
105
- source => "message"
106
- target => "message_crypted"
107
- base64 => true
108
- max_cipher_reuse => 1
109
- }
110
-
111
- cipher {
112
- algorithm => "aes-128-cbc"
113
- cipher_padding => 1
114
- iv => "1234567890123456"
115
- key => "1234567890123456"
116
- key_size => 16
117
- mode => "decrypt"
118
- source => "message_crypted"
119
- target => "message_decrypted"
120
- base64 => true
121
- max_cipher_reuse => 1
122
- }
123
- }
124
- CONFIG
125
- end
126
-
127
- it 'validate initial cleartext message' do
128
- result = results.first
129
- expect(result["message"]).to eq(cleartext)
130
- end
131
-
132
- it 'validate decrypted message' do
133
- result = results.first
134
- expect(result["message_decrypted"]).to eq(result["message"])
135
- end
136
-
137
- it 'validate encrypted message is not equal to message' do
138
- result = results.first
139
- expect(result["message"]).not_to eq(result["message_crypted"])
140
- end
72
+ total_events = 1000
141
73
 
74
+ let(:events) do
75
+ (1..total_events).map do |i|
76
+ LogStash::Event.new(LogStash::Json.load("{\"message\":\"#{cleartext}\"}"))
142
77
  end
78
+ end
79
+
80
+ let(:encrypter) do
81
+ described_class.new(
82
+ "algorithm" => "aes-128-cbc",
83
+ "cipher_padding" => 1,
84
+ "iv_random_length" => 16,
85
+ "key" => "1234567890123456",
86
+ "key_size" => 16,
87
+ "mode" => "encrypt",
88
+ "source" => "message",
89
+ "target" => "message_crypted",
90
+ "base64" => true,
91
+ "max_cipher_reuse" => 11)
92
+ end
93
+
94
+ let(:decrypter) do
95
+ described_class.new(
96
+ "algorithm" => "aes-128-cbc",
97
+ "cipher_padding" => 1,
98
+ "iv_random_length" => 16,
99
+ "key" => "1234567890123456",
100
+ "key_size" => 16,
101
+ "mode" => "decrypt",
102
+ "source" => "message_crypted",
103
+ "target" => "message_decrypted",
104
+ "base64" => true,
105
+ "max_cipher_reuse" => 11)
106
+ end
107
+
108
+ before(:each) do
109
+ encrypter.register
110
+ decrypter.register
111
+ end
143
112
 
113
+ let(:results) do
114
+ events.each do |e|
115
+ encrypter.filter(e)
116
+ decrypter.filter(e)
117
+ end
118
+ events
119
+ end
144
120
 
145
- describe '1000 events, 11 re-use, encrypt/decrypt aes-128-cbc, 16b RANDOM IV, 16b key, b64 encode' do
146
-
147
- total_events = 1000
148
-
149
- let(:event) do
150
- events = []
151
- (1..total_events).each do |i|
152
- events.push("{\"message\":\"#{cleartext}\"}")
153
- end
154
- return events
155
- end
156
-
157
- let(:config) do
158
- <<-CONFIG
159
- filter {
160
-
161
- cipher {
162
- algorithm => "aes-128-cbc"
163
- cipher_padding => 1
164
- iv_random_length => 16
165
- key => "1234567890123456"
166
- key_size => 16
167
- mode => "encrypt"
168
- source => "message"
169
- target => "message_crypted"
170
- base64 => true
171
- max_cipher_reuse => 11
172
- }
173
-
174
- cipher {
175
- algorithm => "aes-128-cbc"
176
- cipher_padding => 1
177
- iv_random_length => 16
178
- key => "1234567890123456"
179
- key_size => 16
180
- mode => "decrypt"
181
- source => "message_crypted"
182
- target => "message_decrypted"
183
- base64 => true
184
- max_cipher_reuse => 11
185
- }
186
- }
187
- CONFIG
188
- end
189
-
190
- it 'validate total events' do
191
- expect(results.length).to eq(total_events)
192
- end
193
-
194
- it 'validate initial cleartext message' do
195
- results.each do |result|
196
- expect(result["message"]).to eq(cleartext)
197
- end
198
- end
199
-
200
- it 'validate decrypted message' do
201
- results.each do |result|
202
- expect(result["message_decrypted"]).to eq(result["message"])
203
- end
204
- end
205
-
206
- it 'validate encrypted message is not equal to message' do
207
- results.each do |result|
208
- expect(result["message"]).not_to eq(result["message_crypted"])
209
- end
210
- end
121
+ it 'validate total events' do
122
+ expect(results.length).to eq(total_events)
123
+ end
211
124
 
125
+ it 'validate initial cleartext message' do
126
+ results.each do |result|
127
+ expect(result.get("message")).to eq(cleartext)
212
128
  end
129
+ end
213
130
 
131
+ it 'validate decrypted message' do
132
+ results.each do |result|
133
+ expect(result.get("message_decrypted")).to eq(result.get("message"))
134
+ end
214
135
  end
215
136
 
137
+ it 'validate encrypted message is not equal to message' do
138
+ results.each do |result|
139
+ expect(result.get("message")).not_to eq(result.get("message_crypted"))
140
+ end
141
+ end
142
+ end
143
+ end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-cipher
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-15 00:00:00.000000000 Z
11
+ date: 2017-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.60'
19
+ - - "<="
17
20
  - !ruby/object:Gem::Version
18
- version: '1.0'
21
+ version: '2.99'
19
22
  name: logstash-core-plugin-api
20
23
  prerelease: false
21
24
  type: :runtime
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.60'
30
+ - - "<="
25
31
  - !ruby/object:Gem::Version
26
- version: '1.0'
32
+ version: '2.99'
27
33
  - !ruby/object:Gem::Dependency
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements: