Skip to content

Commit 46e2d8c

Browse files
RUBY-2832 Fix FLE problems on JRuby (#2392)
1 parent 9b83f62 commit 46e2d8c

File tree

5 files changed

+142
-89
lines changed

5 files changed

+142
-89
lines changed

lib/mongo/crypt/binding.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,14 @@ def self.kms_ctx_get_kms_provider(kms_context)
798798
if len_ptr.nil?
799799
nil
800800
else
801-
len = len_ptr.read(:uint32)
801+
len = if BSON::Environment.jruby?
802+
# JRuby FFI implementation does not have `read(type)` method, but it
803+
# has this `get_uint32`.
804+
len_ptr.get_uint32
805+
else
806+
# For MRI we use a documented `read` method - https://www.rubydoc.info/github/ffi/ffi/FFI%2FPointer:read
807+
len_ptr.read(:uint32)
808+
end
802809
provider.read_string(len).to_sym
803810
end
804811
end

spec/integration/client_side_encryption/custom_endpoint_spec.rb

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
2828
)
2929
end
3030

31+
let(:master_key_template) do
32+
{
33+
region: "us-east-1",
34+
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0"
35+
}
36+
end
37+
3138
let(:data_key_id) do
3239
client_encryption.create_data_key('aws', master_key: master_key)
3340
end
@@ -51,85 +58,75 @@
5158

5259
context 'with region and key options' do
5360
let(:master_key) do
54-
{
55-
region: "us-east-1",
56-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0"
57-
}
61+
master_key_template
5862
end
5963

6064
it_behaves_like 'a functioning data key'
6165
end
6266

6367
context 'with region, key, and endpoint options' do
6468
let(:master_key) do
65-
{
66-
region: "us-east-1",
67-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
68-
endpoint: "kms.us-east-1.amazonaws.com"
69-
}
69+
master_key_template.merge({endpoint: "kms.us-east-1.amazonaws.com"})
7070
end
7171

7272
it_behaves_like 'a functioning data key'
7373
end
7474

7575
context 'with region, key, and endpoint with valid port' do
7676
let(:master_key) do
77-
{
78-
region: "us-east-1",
79-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
80-
endpoint: "kms.us-east-1.amazonaws.com:443"
81-
}
77+
master_key_template.merge({endpoint: "kms.us-east-1.amazonaws.com:443"})
8278
end
8379

8480
it_behaves_like 'a functioning data key'
8581
end
8682

83+
shared_examples 'raising a KMS error' do
84+
it 'throws an exception' do
85+
expect do
86+
data_key_id
87+
end.to raise_error(Mongo::Error::KmsError, error_regex)
88+
end
89+
end
90+
8791
context 'with region, key, and endpoint with invalid port' do
8892
let(:master_key) do
89-
{
90-
region: "us-east-1",
91-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
92-
endpoint: "kms.us-east-1.amazonaws.com:12345"
93-
}
93+
master_key_template.merge({endpoint: "kms.us-east-1.amazonaws.com:12345"})
9494
end
9595

96-
it 'throws an exception' do
97-
expect do
98-
data_key_id
99-
end.to raise_error(Mongo::Error::KmsError, /Connection refused/)
96+
let(:error_regex) do
97+
if BSON::Environment.jruby?
98+
/Bad file descriptor/
99+
else
100+
/Connection refused/
101+
end
100102
end
103+
104+
it_behaves_like 'raising a KMS error'
101105
end
102106

107+
103108
context 'with region, key, and endpoint with invalid region' do
104109
let(:master_key) do
105-
{
106-
region: "us-east-1",
107-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
108-
endpoint: "kms.us-east-2.amazonaws.com"
109-
}
110+
master_key_template.merge({endpoint: "kms.us-east-2.amazonaws.com"})
110111
end
111112

112-
it 'throws an exception' do
113-
expect do
114-
data_key_id
115-
end.to raise_error(Mongo::Error::KmsError, /us-east-1/)
113+
let(:error_regex) do
114+
/us-east-1/
116115
end
116+
117+
it_behaves_like 'raising a KMS error'
117118
end
118119

119120
context 'with region, key, and endpoint at incorrect domain' do
120121
let(:master_key) do
121-
{
122-
region: "us-east-1",
123-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
124-
endpoint: "example.com"
125-
}
122+
master_key_template.merge({endpoint: "example.com"})
126123
end
127124

128-
it 'throws an exception' do
129-
expect do
130-
data_key_id
131-
end.to raise_error(Mongo::Error::KmsError, /parse error/)
125+
let(:error_regex) do
126+
/parse error/
132127
end
128+
129+
it_behaves_like 'raising a KMS error'
133130
end
134131
end
135132
end

spec/integration/client_side_encryption/kms_tls_options_spec.rb

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,21 @@
200200

201201
# We do noy use shared examples for AWS because of the way we pass endpoint.
202202
context 'AWS' do
203+
let(:master_key_template) do
204+
{
205+
region: "us-east-1",
206+
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
207+
}
208+
end
209+
203210
context 'with no client certificate' do
204211
it 'TLS handshake failed' do
205212
expect do
206213
client_encryption_no_client_cert.create_data_key(
207214
'aws',
208215
{
209-
master_key: {
210-
region: "us-east-1",
211-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
212-
endpoint: "127.0.0.1:8002",
213-
}
214-
}
216+
master_key: master_key_template.merge({endpoint: "127.0.0.1:8002"})
217+
}
215218
)
216219
end.to raise_error(Mongo::Error::KmsError, /(SocketError|ECONNRESET)/)
217220
end
@@ -223,48 +226,52 @@
223226
client_encryption_with_tls.create_data_key(
224227
'aws',
225228
{
226-
master_key: {
227-
region: "us-east-1",
228-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
229-
endpoint: "127.0.0.1:8002",
230-
}
229+
master_key: master_key_template.merge({endpoint: "127.0.0.1:8002"})
231230
}
232231
)
233232
end.to raise_error(Mongo::Error::KmsError, /libmongocrypt error code/)
234233
end
235234
end
236235

237-
context 'with no expired server certificate' do
236+
context 'with expired server certificate' do
237+
let(:error_regex) do
238+
if BSON::Environment.jruby?
239+
/certificate verify failed/
240+
else
241+
/certificate has expired/
242+
end
243+
end
244+
238245
it 'TLS handshake failed' do
239246
expect do
240247
client_encryption_expired.create_data_key(
241248
'aws',
242249
{
243-
master_key: {
244-
region: "us-east-1",
245-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
246-
endpoint: "127.0.0.1:8000",
247-
}
248-
}
250+
master_key: master_key_template.merge({endpoint: "127.0.0.1:8000"})
251+
}
249252
)
250-
end.to raise_error(Mongo::Error::KmsError, /certificate has expired/)
253+
end.to raise_error(Mongo::Error::KmsError, error_regex)
251254
end
252255
end
253256

254257
context 'with server certificate with invalid hostname' do
258+
let(:error_regex) do
259+
if BSON::Environment.jruby?
260+
/TLS handshake failed due to a hostname mismatch/
261+
else
262+
/certificate verify failed/
263+
end
264+
end
265+
255266
it 'TLS handshake failed' do
256267
expect do
257268
client_encryption_invalid_hostname.create_data_key(
258269
'aws',
259270
{
260-
master_key: {
261-
region: "us-east-1",
262-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
263-
endpoint: "127.0.0.1:8001",
264-
}
265-
}
271+
master_key: master_key_template.merge({endpoint: "127.0.0.1:8001"})
272+
}
266273
)
267-
end.to raise_error(Mongo::Error::KmsError, /certificate verify failed/)
274+
end.to raise_error(Mongo::Error::KmsError, error_regex)
268275
end
269276
end
270277
end
@@ -296,29 +303,45 @@
296303
end
297304
end
298305

299-
context 'with no expired server certificate' do
306+
context 'with expired server certificate' do
307+
let(:error_regex) do
308+
if BSON::Environment.jruby?
309+
/certificate verify failed/
310+
else
311+
/certificate has expired/
312+
end
313+
end
314+
300315
it 'TLS handshake failed' do
301316
expect do
302317
client_encryption_expired.create_data_key(
303318
kms_provider,
304319
{
305320
master_key: master_key
306-
}
321+
}
307322
)
308-
end.to raise_error(Mongo::Error::KmsError, /certificate has expired/)
323+
end.to raise_error(Mongo::Error::KmsError, error_regex)
309324
end
310325
end
311326

312327
context 'with server certificate with invalid hostname' do
328+
let(:error_regex) do
329+
if BSON::Environment.jruby?
330+
/TLS handshake failed due to a hostname mismatch/
331+
else
332+
/certificate verify failed/
333+
end
334+
end
335+
313336
it 'TLS handshake failed' do
314337
expect do
315338
client_encryption_invalid_hostname.create_data_key(
316339
kms_provider,
317340
{
318341
master_key: master_key
319-
}
342+
}
320343
)
321-
end.to raise_error(Mongo::Error::KmsError, /certificate verify failed/)
344+
end.to raise_error(Mongo::Error::KmsError, error_regex)
322345
end
323346
end
324347
end

spec/integration/client_side_encryption/kms_tls_spec.rb

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,47 @@
4444
}
4545
}
4646
)
47-
end.to raise_error(Mongo::Error::KmsError, /certificate verify failed \(certificate has expired\)/)
47+
end.to raise_error(Mongo::Error::KmsError, /certificate verify failed/)
4848
end
4949
end
5050

5151
context 'Invalid Hostname in KMS Certificate' do
52-
it 'raises an error when creating data key' do
53-
expect do
54-
client_encryption.create_data_key(
55-
'aws',
56-
{
57-
master_key: {
58-
region: "us-east-1",
59-
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
60-
endpoint: "127.0.0.1:8001",
61-
}
62-
}
63-
)
64-
end.to raise_error(Mongo::Error::KmsError, /certificate verify failed/)
52+
context 'MRI' do
53+
require_mri
54+
55+
it 'raises an error when creating data key' do
56+
expect do
57+
client_encryption.create_data_key(
58+
'aws',
59+
{
60+
master_key: {
61+
region: "us-east-1",
62+
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
63+
endpoint: "127.0.0.1:8001",
64+
}
65+
}
66+
)
67+
end.to raise_error(Mongo::Error::KmsError, /certificate verify failed/)
68+
end
69+
end
70+
71+
context 'JRuby' do
72+
require_jruby
73+
74+
it 'raises an error when creating data key' do
75+
expect do
76+
client_encryption.create_data_key(
77+
'aws',
78+
{
79+
master_key: {
80+
region: "us-east-1",
81+
key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
82+
endpoint: "127.0.0.1:8001",
83+
}
84+
}
85+
)
86+
end.to raise_error(Mongo::Error::KmsError, /hostname mismatch/)
87+
end
6588
end
6689
end
6790

spec/lite_spec_helper.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,17 @@ class ExampleTimeout < StandardError; end
118118
end
119119

120120
if SpecConfig.instance.ci? && !%w(1 true yes).include?(ENV['INTERACTIVE']&.downcase)
121-
# Allow a max of 30 seconds per test.
122121
# Tests should take under 10 seconds ideally but it seems
123122
# we have some that run for more than 10 seconds in CI.
124123
config.around(:each) do |example|
125124
timeout = if %w(1 true yes).include?(ENV['STRESS']&.downcase)
126125
210
127126
else
128-
45
127+
if BSON::Environment.jruby?
128+
90
129+
else
130+
45
131+
end
129132
end
130133
TimeoutInterrupt.timeout(timeout, ExampleTimeout) do
131134
example.run

0 commit comments

Comments
 (0)