ssl-test 1.4.0 → 1.5.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.
@@ -1,12 +1,21 @@
1
1
  require "ssl-test"
2
2
  require "benchmark"
3
+ require 'webrick'
4
+ require 'webrick/httpproxy'
3
5
 
4
6
  # Uncomment for debug logging:
5
7
  # require "logger"
6
8
  # SSLTest.logger = Logger.new(STDOUT)
7
9
 
8
10
  describe SSLTest do
9
- describe '.test' do
11
+ before { SSLTest.flush_cache }
12
+
13
+ let(:proxy_thread) { nil }
14
+
15
+
16
+ after(:each) { proxy_thread&.kill }
17
+
18
+ describe '.test_url' do
10
19
  it "returns no error on valid SNI website" do
11
20
  valid, error, cert = SSLTest.test("https://www.mycs.com")
12
21
  expect(error).to be_nil
@@ -15,19 +24,22 @@ describe SSLTest do
15
24
  end
16
25
 
17
26
  it "returns no error on valid SAN" do
18
- valid, error, cert = SSLTest.test("https://1000-sans.badssl.com/")
27
+ # CN is updown.io, www.updown.io is an Alternative Name
28
+ valid, error, cert = SSLTest.test("https://www.updown.io/")
19
29
  expect(error).to be_nil
20
30
  expect(valid).to eq(true)
21
31
  expect(cert).to be_a OpenSSL::X509::Certificate
22
32
  end
23
33
 
24
- it "returns no error when no CN" do
25
- skip "Expired for the moment https://github.com/chromium/badssl.com/issues/447"
26
- valid, error, cert = SSLTest.test("https://no-common-name.badssl.com/")
27
- expect(error).to be_nil
28
- expect(valid).to eq(true)
29
- expect(cert).to be_a OpenSSL::X509::Certificate
30
- end
34
+ # Disabled: unlikely to be repaired anytime soon: https://github.com/chromium/badssl.com/issues/447
35
+ # Couldn't find a good alternative
36
+ # it "returns no error when no CN" do
37
+ # pending "Expired for the moment https://github.com/chromium/badssl.com/issues/447"
38
+ # valid, error, cert = SSLTest.test("https://no-common-name.badssl.com/")
39
+ # expect(error).to be_nil
40
+ # expect(valid).to eq(true)
41
+ # expect(cert).to be_a OpenSSL::X509::Certificate
42
+ # end
31
43
 
32
44
  it "works with websites blocking http requests" do
33
45
  valid, error, cert = SSLTest.test("https://obyava.ua")
@@ -38,7 +50,7 @@ describe SSLTest do
38
50
 
39
51
  it "returns error on self signed certificate" do
40
52
  valid, error, cert = SSLTest.test("https://self-signed.badssl.com/")
41
- expect(error).to eq ("error code 18: self signed certificate")
53
+ expect(error).to eq ("error code 18: self-signed certificate")
42
54
  expect(valid).to eq(false)
43
55
  expect(cert).to be_a OpenSSL::X509::Certificate
44
56
  end
@@ -52,14 +64,14 @@ describe SSLTest do
52
64
 
53
65
  it "returns error on untrusted root" do
54
66
  valid, error, cert = SSLTest.test("https://untrusted-root.badssl.com/")
55
- expect(error).to eq ("error code 19: self signed certificate in certificate chain")
67
+ expect(error).to eq ("error code 19: self-signed certificate in certificate chain")
56
68
  expect(valid).to eq(false)
57
69
  expect(cert).to be_a OpenSSL::X509::Certificate
58
70
  end
59
71
 
60
72
  it "returns error on invalid host" do
61
73
  valid, error, cert = SSLTest.test("https://wrong.host.badssl.com/")
62
- expect(error).to include('hostname "wrong.host.badssl.com" does not match the server certificate')
74
+ expect(error).to include('error code 62: hostname mismatch')
63
75
  expect(valid).to eq(false)
64
76
  expect(cert).to be_a OpenSSL::X509::Certificate
65
77
  end
@@ -73,21 +85,23 @@ describe SSLTest do
73
85
 
74
86
  it "returns undetermined state on unhandled error" do
75
87
  valid, error, cert = SSLTest.test("https://pijoinlrfgind.com")
76
- expect(error).to eq ("SSL certificate test failed: Failed to open TCP connection to pijoinlrfgind.com:443 (getaddrinfo: Name or service not known)")
88
+ expect(error).to include("SSL certificate test failed: Failed to open TCP connection to pijoinlrfgind.com:443")
89
+ expect(error).to include(/name.*not known/i)
77
90
  expect(valid).to be_nil
78
91
  expect(cert).to be_nil
79
92
  end
80
93
 
81
94
  it "stops on timeouts" do
82
95
  valid, error, cert = SSLTest.test("https://updown.io", open_timeout: 0)
83
- expect(error).to eq ("SSL certificate test failed: Net::OpenTimeout")
96
+ expect(error).to include("SSL certificate test failed")
97
+ expect(error).to include(/timeout/i)
84
98
  expect(valid).to be_nil
85
99
  expect(cert).to be_nil
86
100
  end
87
101
 
88
102
  it "reports revocation exceptions" do
89
103
  expect(SSLTest).to receive(:follow_ocsp_redirects).and_raise(ArgumentError.new("test"))
90
- valid, error, cert = SSLTest.test("https://updown.io")
104
+ valid, error, cert = SSLTest.test("https://digicert.com")
91
105
  expect(error).to eq ("SSL certificate test failed: test")
92
106
  expect(valid).to be_nil
93
107
  expect(cert).to be_a OpenSSL::X509::Certificate
@@ -96,8 +110,8 @@ describe SSLTest do
96
110
  it "returns error on revoked cert (OCSP)" do
97
111
  expect(SSLTest).to receive(:follow_ocsp_redirects).once.and_call_original
98
112
  expect(SSLTest).not_to receive(:follow_crl_redirects)
99
- valid, error, cert = SSLTest.test("https://revoked.badssl.com/")
100
- expect(error).to eq ("SSL certificate revoked: The certificate was revoked for an unknown reason (revocation date: 2019-10-07 20:30:39 UTC)")
113
+ valid, error, cert = SSLTest.test("https://revoked-rsa-dv.ssl.com/")
114
+ expect(error).to eq ("SSL certificate revoked: The certificate was revoked for an unknown reason (revocation date: 2025-06-09 15:07:39 UTC)")
101
115
  expect(valid).to eq(false)
102
116
  expect(cert).to be_a OpenSSL::X509::Certificate
103
117
  end
@@ -106,14 +120,15 @@ describe SSLTest do
106
120
  expect(SSLTest).to receive(:test_ocsp_revocation).once.and_return([false, "skip OCSP", nil])
107
121
  expect(SSLTest).to receive(:follow_crl_redirects).once.and_call_original
108
122
  valid, error, cert = SSLTest.test("https://revoked.badssl.com/")
109
- expect(error).to eq ("SSL certificate revoked: Unknown reason (revocation date: 2019-10-07 20:30:39 UTC)")
123
+ expect(error).to eq ("SSL certificate revoked: Key Compromise (revocation date: 2025-11-04 21:01:29 UTC)")
110
124
  expect(valid).to eq(false)
111
125
  expect(cert).to be_a OpenSSL::X509::Certificate
112
126
  end
113
127
 
114
128
  it "stops following redirection after the limit for the revoked certs check" do
115
129
  valid, error, cert = SSLTest.test("https://github.com/", redirection_limit: 0)
116
- expect(error).to eq ("Revocation test couldn't be performed: OCSP: Request failed (URI: http://ocsp.digicert.com): Too many redirections (> 0), CRL: Request failed (URI: http://crl3.digicert.com/sha2-ha-server-g6.crl): Too many redirections (> 0)")
130
+ expect(error).to include("Revocation test couldn't be performed: OCSP: Request failed")
131
+ expect(error).to include("Too many redirections (> 0)")
117
132
  expect(valid).to eq(true)
118
133
  expect(cert).to be_a OpenSSL::X509::Certificate
119
134
  end
@@ -122,7 +137,7 @@ describe SSLTest do
122
137
  # Disable CRL fallback to see error message
123
138
  expect(SSLTest).to receive(:test_crl_revocation).once.and_return([false, "skip CRL", nil])
124
139
  expect(SSLTest).to receive(:follow_ocsp_redirects).once.and_call_original
125
- valid, error, cert = SSLTest.test("https://www.demarches-simplifiees.fr")
140
+ valid, error, cert = SSLTest.test("https://google.com")
126
141
  expect(error).to eq ("Revocation test couldn't be performed: OCSP: Missing OCSP URI in authorityInfoAccess extension, CRL: skip CRL")
127
142
  expect(valid).to eq(true)
128
143
  expect(cert).to be_a OpenSSL::X509::Certificate
@@ -142,30 +157,69 @@ describe SSLTest do
142
157
  # Disable OCSP to see error message
143
158
  expect(SSLTest).to receive(:test_ocsp_revocation).once.and_return([false, "skip OCSP", nil])
144
159
  expect(SSLTest).not_to receive(:follow_crl_redirects)
145
- valid, error, cert = SSLTest.test("https://meta.updown.io")
160
+ valid, error, cert = SSLTest.test("https://github.com")
146
161
  expect(error).to eq ("Revocation test couldn't be performed: OCSP: skip OCSP, CRL: Missing crlDistributionPoints extension")
147
162
  expect(valid).to eq(true)
148
163
  expect(cert).to be_a OpenSSL::X509::Certificate
149
164
  end
150
165
 
151
- it "works with OCSP for first cert and CRL for intermediate (Let's Encrypt R3 intermediate)" do
166
+ it "works with OCSP for first cert and CRL for intermediate (Google)" do
152
167
  expect(SSLTest).to receive(:follow_ocsp_redirects).once.and_call_original
153
168
  expect(SSLTest).to receive(:follow_crl_redirects).once.and_call_original
154
- valid, error, cert = SSLTest.test("https://meta.updown.io/")
169
+ valid, error, cert = SSLTest.test("https://google.com")
155
170
  expect(error).to be_nil
156
171
  expect(valid).to eq(true)
157
172
  expect(cert).to be_a OpenSSL::X509::Certificate
173
+ # make sure both were used
174
+ expect(SSLTest.cache_size).to match({
175
+ crl: hash_including(lists: 1),
176
+ ocsp: hash_including(responses: 1, errors: 0)
177
+ })
158
178
  end
159
179
 
160
- it "works with OCSP for first cert and CRL for intermediate (Certigna Services CA)" do
161
- expect(SSLTest).to receive(:follow_ocsp_redirects).once.and_call_original
162
- expect(SSLTest).to receive(:follow_crl_redirects).once.and_call_original
163
- # Similar chain: https://www.demarches-simplifiees.fr
164
- valid, error, cert = SSLTest.test("https://www.anonymisation.gov.pf")
180
+ it "accepts tcps scheme" do
181
+ valid, error, cert = SSLTest.test("tcps://updown.io:443")
165
182
  expect(error).to be_nil
166
183
  expect(valid).to eq(true)
167
184
  expect(cert).to be_a OpenSSL::X509::Certificate
168
185
  end
186
+
187
+ context 'when specifying a proxy' do
188
+ context 'when the proxy is active' do
189
+ let(:proxy_thread) do
190
+ thread = Thread.new do
191
+ dev_null = WEBrick::Log::new("/dev/null", 7)
192
+ $proxy = WEBrick::HTTPProxyServer.new Port: 8080, :Logger => dev_null, :AccessLog => []
193
+ $proxy.start
194
+ end
195
+
196
+ sleep 0.1 # wait for the proxy to start!
197
+ allow($proxy).to receive(:do_GET).and_call_original
198
+
199
+ thread
200
+ end
201
+
202
+ it 'uses the provided http proxy' do
203
+ proxy_thread
204
+
205
+ valid, error, cert = SSLTest.test("https://updown.io", proxy_host: '127.0.0.1', proxy_port: 8080)
206
+ expect(error).to be_nil
207
+ expect(valid).to eq(true)
208
+ expect(cert).to be_a OpenSSL::X509::Certificate
209
+
210
+ expect($proxy).to have_received(:do_GET).twice
211
+ end
212
+ end
213
+
214
+ context 'when the proxy is not reachable' do
215
+ it 'returns a http error' do
216
+ valid, error, cert = SSLTest.test("https://updown.io", proxy_host: '127.0.0.1', proxy_port: 55000)
217
+ expect(error).to include('(Connection refused - connect(2) for "127.0.0.1" port 55000)')
218
+ expect(valid).to be_nil
219
+ expect(cert).to be_nil
220
+ end
221
+ end
222
+ end
169
223
  end
170
224
 
171
225
  describe '.cache_size' do
@@ -179,17 +233,19 @@ describe SSLTest do
179
233
  end
180
234
 
181
235
  it "returns CRL cache size properly" do
182
- SSLTest.send(:follow_crl_redirects, URI("http://crl.certigna.fr/certigna.crl")) # 1.3k
183
- SSLTest.send(:follow_crl_redirects, URI("http://crl3.digicert.com/ssca-sha2-g6.crl")) # 19M
236
+ SSLTest.send(:follow_crl_redirects, URI("http://crl.certigna.fr/certigna.crl")) # 1.1k
237
+ SSLTest.send(:follow_crl_redirects, URI("http://crl3.digicert.com/DigiCertTLSHybridECCSHA3842020CA1-1.crl")) # 26k
184
238
  expect(SSLTest.cache_size[:crl][:lists]).to eq(2)
185
- expect(SSLTest.cache_size[:crl][:bytes]).to be > 19_000_000
239
+ expect(SSLTest.cache_size[:crl][:bytes]).to be > 6000
186
240
  end
187
241
 
188
242
  it "returns OCSP cache size properly" do
189
- SSLTest.test("https://updown.io")
190
- expect(SSLTest.cache_size[:ocsp][:responses]).to eq(2)
243
+ SSLTest.test("https://google.com")
244
+ expect(SSLTest.cache_size[:ocsp][:responses]).to eq(1)
191
245
  expect(SSLTest.cache_size[:ocsp][:errors]).to eq(0)
192
- expect(SSLTest.cache_size[:ocsp][:bytes]).to be > 200
246
+ expect(SSLTest.cache_size[:ocsp][:bytes]).to be > 150
247
+ expect(SSLTest.cache_size[:crl][:lists]).to eq(1)
248
+ expect(SSLTest.cache_size[:crl][:bytes]).to be > 500
193
249
  end
194
250
  end
195
251
 
@@ -199,7 +255,7 @@ describe SSLTest do
199
255
  it "fetch CRL list and updates cache" do
200
256
  uri = URI("http://crl.certigna.fr/certigna.crl")
201
257
  body, error = SSLTest.send(:follow_crl_redirects, uri)
202
- expect(body.bytesize).to equal 1152
258
+ expect(body.bytesize).to equal 1417
203
259
  expect(error).to be_nil
204
260
 
205
261
  # Check cache status
@@ -223,4 +279,195 @@ describe SSLTest do
223
279
  expect(body2).to be(body) # but we're still using cache because it's a 304
224
280
  end
225
281
  end
226
- end
282
+
283
+ describe '.test_cert' do
284
+ it "returns no error on valid SNI website" do
285
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/www_mycs_com_client.pem')))
286
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/www_mycs_com_ca_bundle.pem')))
287
+
288
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
289
+ expect(error).to be_nil
290
+ expect(valid).to eq(true)
291
+ expect(cert).to eq(cert)
292
+ end
293
+
294
+ it "returns no error on self signed certificates" do
295
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/self_signed_client.pem')))
296
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/self_signed_ca_bundle.pem')))
297
+
298
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
299
+ expect(error).to be_nil
300
+ expect(valid).to eq(true)
301
+ expect(cert).to eq(cert)
302
+ end
303
+
304
+ it "returns error on expired cert" do
305
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/expired_cert_client.pem')))
306
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/expired_cert_ca_bundle.pem')))
307
+
308
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
309
+ expect(error).to eq ("error code 10: certificate has expired")
310
+ expect(valid).to eq(false)
311
+ expect(cert).to eq(cert)
312
+ end
313
+
314
+ it "returns error on incomplete chain" do
315
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/incomplete_chain_client.pem')))
316
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/incomplete_chain_ca_bundle.pem')))
317
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
318
+ expect(error).to eq ("error code 20: unable to get local issuer certificate")
319
+ expect(valid).to eq(false)
320
+ expect(cert).to eq(cert)
321
+ end
322
+
323
+ it "reports revocation exceptions" do
324
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/digicert_com_client.pem')))
325
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/digicert_com_ca_bundle.pem')))
326
+ expect(SSLTest).to receive(:follow_ocsp_redirects).and_raise(ArgumentError.new("test"))
327
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
328
+ expect(error).to eq("SSL certificate test failed: test")
329
+ expect(valid).to be_nil
330
+ expect(cert).to eq(cert)
331
+ end
332
+
333
+ it "returns error on revoked cert (OCSP)" do
334
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/revoked_rsa_dv_client.pem')))
335
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/revoked_rsa_dv_ca_bundle.pem')))
336
+
337
+ expect(SSLTest).to receive(:follow_ocsp_redirects).once.and_call_original
338
+ expect(SSLTest).not_to receive(:follow_crl_redirects)
339
+
340
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
341
+ expect(error).to eq ("SSL certificate revoked: The certificate was revoked for an unknown reason (revocation date: 2025-06-09 15:07:39 UTC)")
342
+ expect(valid).to eq(false)
343
+ expect(cert).to eq(cert)
344
+ end
345
+
346
+ it "returns error on revoked cert (CRL)" do
347
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/revoked_badssl_client.pem')))
348
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/revoked_badssl_ca_bundle.pem')))
349
+
350
+ expect(SSLTest).to receive(:test_ocsp_revocation).once.and_return([false, "skip OCSP", nil])
351
+ expect(SSLTest).to receive(:follow_crl_redirects).once.and_call_original
352
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
353
+ expect(error).to eq ("SSL certificate revoked: Key Compromise (revocation date: 2025-11-04 21:01:29 UTC)")
354
+ expect(valid).to eq(false)
355
+ expect(cert).to eq(cert)
356
+ end
357
+
358
+ it "stops following redirection after the limit for the revoked certs check" do
359
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/www_github_com_client.pem')))
360
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/www_github_com_ca_bundle.pem')))
361
+
362
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle, redirection_limit: 0)
363
+ expect(error).to include("Revocation test couldn't be performed: OCSP: Request failed")
364
+ expect(error).to include("Too many redirections (> 0)")
365
+ expect(valid).to eq(true)
366
+ expect(cert).to eq(cert)
367
+ end
368
+
369
+ it "warns when the OCSP URI is missing" do
370
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/google_com_client.pem')))
371
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/google_com_ca_bundle.pem')))
372
+
373
+ # Disable CRL fallback to see error message
374
+ expect(SSLTest).to receive(:test_crl_revocation).once.and_return([false, "skip CRL", nil])
375
+ expect(SSLTest).to receive(:follow_ocsp_redirects).once.and_call_original
376
+
377
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
378
+ expect(error).to eq ("Revocation test couldn't be performed: OCSP: Missing OCSP URI in authorityInfoAccess extension, CRL: skip CRL")
379
+ expect(valid).to eq(true)
380
+ expect(cert).to eq(cert)
381
+ end
382
+
383
+ it "works with CRL only" do
384
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/www_demarches-simplifiees_fr_client.pem')))
385
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/www_demarches-simplifiees_fr_ca_bundle.pem')))
386
+
387
+ # Disable OCSP
388
+ expect(SSLTest).to receive(:test_ocsp_revocation).twice.and_return([false, "skip OCSP", nil])
389
+ expect(SSLTest).to receive(:follow_crl_redirects).twice.and_call_original
390
+
391
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
392
+ expect(error).to be_nil
393
+ expect(valid).to eq(true)
394
+ expect(cert).to eq(cert)
395
+ end
396
+
397
+ it "warns when the CRL URI is missing" do
398
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/www_github_com_client.pem')))
399
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/www_github_com_ca_bundle.pem')))
400
+
401
+ # Disable OCSP to see error message
402
+ expect(SSLTest).to receive(:test_ocsp_revocation).once.and_return([false, "skip OCSP", nil])
403
+ expect(SSLTest).not_to receive(:follow_crl_redirects)
404
+
405
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
406
+ expect(error).to eq ("Revocation test couldn't be performed: OCSP: skip OCSP, CRL: Missing crlDistributionPoints extension")
407
+ expect(valid).to eq(true)
408
+ expect(cert).to eq(cert)
409
+
410
+ end
411
+
412
+ it "works with OCSP for first cert and CRL for intermediate (Google)" do
413
+ expect(SSLTest).to receive(:follow_ocsp_redirects).once.and_call_original
414
+ expect(SSLTest).to receive(:follow_crl_redirects).once.and_call_original
415
+
416
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/google_com_client.pem')))
417
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/google_com_ca_bundle.pem')))
418
+
419
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
420
+ expect(error).to be_nil
421
+ expect(valid).to eq(true)
422
+ expect(cert).to eq(cert)
423
+ # make sure both were used
424
+ expect(SSLTest.cache_size).to match({
425
+ crl: hash_including(lists: 1),
426
+ ocsp: hash_including(responses: 1, errors: 0)
427
+ })
428
+ end
429
+
430
+ context 'when specifying a proxy' do
431
+ context 'when the proxy is active' do
432
+ let(:proxy_thread) do
433
+ thread = Thread.new do
434
+ dev_null = WEBrick::Log::new("/dev/null", 7)
435
+ $proxy = WEBrick::HTTPProxyServer.new Port: 8080, :Logger => dev_null, :AccessLog => []
436
+ $proxy.start
437
+ end
438
+
439
+ sleep 0.1 # wait for the proxy to start!
440
+ allow($proxy).to receive(:do_GET).and_call_original
441
+
442
+ thread
443
+ end
444
+
445
+ it 'uses the provided http proxy' do
446
+ proxy_thread
447
+
448
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/google_com_client.pem')))
449
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/google_com_ca_bundle.pem')))
450
+
451
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle, proxy_host: '127.0.0.1', proxy_port: 8080)
452
+ expect(error).to be_nil
453
+ expect(valid).to eq(true)
454
+ expect(cert).to eq(cert)
455
+
456
+ expect($proxy).to have_received(:do_GET).once
457
+ end
458
+ end
459
+
460
+ context 'when the proxy is not reachable' do
461
+ it 'returns a http error' do
462
+ cert = OpenSSL::X509::Certificate.new(File.read(File.join(__dir__, 'fixtures/google_com_client.pem')))
463
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read(File.join(__dir__, 'fixtures/google_com_ca_bundle.pem')))
464
+
465
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle, proxy_host: '127.0.0.1', proxy_port: 55000)
466
+ expect(error).to include('(Connection refused - connect(2) for "127.0.0.1" port 55000)')
467
+ expect(valid).to be_nil
468
+ expect(cert).to eq(cert)
469
+ end
470
+ end
471
+ end
472
+ end
473
+ end
data/ssl-test.gemspec CHANGED
@@ -20,4 +20,5 @@ Gem::Specification.new do |spec|
20
20
  spec.add_development_dependency "bundler", ">= 1.7"
21
21
  spec.add_development_dependency "rake"
22
22
  spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "webrick"
23
24
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssl-test
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrien Rey-Jarthon
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-01-16 00:00:00.000000000 Z
10
+ date: 2025-11-28 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -52,15 +51,29 @@ dependencies:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
55
- description:
54
+ - !ruby/object:Gem::Dependency
55
+ name: webrick
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
56
68
  email:
57
69
  - jobs@adrienjarthon.com
58
70
  executables: []
59
71
  extensions: []
60
72
  extra_rdoc_files: []
61
73
  files:
74
+ - ".github/dependabot.yml"
75
+ - ".github/workflows/ruby.yml"
62
76
  - ".gitignore"
63
- - ".travis.yml"
64
77
  - Gemfile
65
78
  - LICENSE.txt
66
79
  - README.md
@@ -69,13 +82,32 @@ files:
69
82
  - lib/ssl-test/crl.rb
70
83
  - lib/ssl-test/object_size.rb
71
84
  - lib/ssl-test/ocsp.rb
85
+ - spec/fixtures/digicert_com_ca_bundle.pem
86
+ - spec/fixtures/digicert_com_client.pem
87
+ - spec/fixtures/expired_cert_ca_bundle.pem
88
+ - spec/fixtures/expired_cert_client.pem
89
+ - spec/fixtures/google_com_ca_bundle.pem
90
+ - spec/fixtures/google_com_client.pem
91
+ - spec/fixtures/incomplete_chain_ca_bundle.pem
92
+ - spec/fixtures/incomplete_chain_client.pem
93
+ - spec/fixtures/revoked_badssl_ca_bundle.pem
94
+ - spec/fixtures/revoked_badssl_client.pem
95
+ - spec/fixtures/revoked_rsa_dv_ca_bundle.pem
96
+ - spec/fixtures/revoked_rsa_dv_client.pem
97
+ - spec/fixtures/self_signed_ca_bundle.pem
98
+ - spec/fixtures/self_signed_client.pem
99
+ - spec/fixtures/www_demarches-simplifiees_fr_ca_bundle.pem
100
+ - spec/fixtures/www_demarches-simplifiees_fr_client.pem
101
+ - spec/fixtures/www_github_com_ca_bundle.pem
102
+ - spec/fixtures/www_github_com_client.pem
103
+ - spec/fixtures/www_mycs_com_ca_bundle.pem
104
+ - spec/fixtures/www_mycs_com_client.pem
72
105
  - spec/ssl-test_spec.rb
73
106
  - ssl-test.gemspec
74
107
  homepage: https://github.com/jarthod/ssl-test
75
108
  licenses:
76
109
  - MIT
77
110
  metadata: {}
78
- post_install_message:
79
111
  rdoc_options: []
80
112
  require_paths:
81
113
  - lib
@@ -90,9 +122,28 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
122
  - !ruby/object:Gem::Version
91
123
  version: '0'
92
124
  requirements: []
93
- rubygems_version: 3.1.2
94
- signing_key:
125
+ rubygems_version: 3.6.2
95
126
  specification_version: 4
96
127
  summary: Test website SSL certificate validity
97
128
  test_files:
129
+ - spec/fixtures/digicert_com_ca_bundle.pem
130
+ - spec/fixtures/digicert_com_client.pem
131
+ - spec/fixtures/expired_cert_ca_bundle.pem
132
+ - spec/fixtures/expired_cert_client.pem
133
+ - spec/fixtures/google_com_ca_bundle.pem
134
+ - spec/fixtures/google_com_client.pem
135
+ - spec/fixtures/incomplete_chain_ca_bundle.pem
136
+ - spec/fixtures/incomplete_chain_client.pem
137
+ - spec/fixtures/revoked_badssl_ca_bundle.pem
138
+ - spec/fixtures/revoked_badssl_client.pem
139
+ - spec/fixtures/revoked_rsa_dv_ca_bundle.pem
140
+ - spec/fixtures/revoked_rsa_dv_client.pem
141
+ - spec/fixtures/self_signed_ca_bundle.pem
142
+ - spec/fixtures/self_signed_client.pem
143
+ - spec/fixtures/www_demarches-simplifiees_fr_ca_bundle.pem
144
+ - spec/fixtures/www_demarches-simplifiees_fr_client.pem
145
+ - spec/fixtures/www_github_com_ca_bundle.pem
146
+ - spec/fixtures/www_github_com_client.pem
147
+ - spec/fixtures/www_mycs_com_ca_bundle.pem
148
+ - spec/fixtures/www_mycs_com_client.pem
98
149
  - spec/ssl-test_spec.rb
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- language: ruby
2
-
3
- rvm:
4
- - 2.4.3
5
- - 2.5.0