1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
# frozen_string_literal: true
# rubocop:todo all
require 'lite_spec_helper'
require 'webrick'
describe Mongo::Socket::OcspVerifier do
require_ocsp_verifier
shared_examples 'verifies' do
context 'mri' do
fails_on_jruby
it 'verifies the first time and reads from cache the second time' do
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
verifier.verify_with_cache.should be true
end
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).not_to receive(:do_verify)
verifier.verify_with_cache.should be true
end
end
end
context 'jruby' do
require_jruby
# JRuby does not return OCSP endpoints, therefore we never perform
# any validation.
# https://github.com/jruby/jruby-openssl/issues/210
it 'does not verify' do
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
verifier.verify.should be false
end
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
verifier.verify.should be false
end
end
end
end
shared_examples 'fails verification' do
context 'mri' do
fails_on_jruby
it 'verifies the first time, reads from cache the second time, raises an exception in both cases' do
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
lambda do
verifier.verify
# Redirect tests receive responses from port 8101,
# tests without redirects receive responses from port 8100.
end.should raise_error(Mongo::Error::ServerCertificateRevoked, %r,TLS certificate of 'foo' has been revoked according to 'http://localhost:810[01]/status',)
end
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).not_to receive(:do_verify)
lambda do
verifier.verify
# Redirect tests receive responses from port 8101,
# tests without redirects receive responses from port 8100.
end.should raise_error(Mongo::Error::ServerCertificateRevoked, %r,TLS certificate of 'foo' has been revoked according to 'http://localhost:810[01]/status',)
end
end
end
context 'jruby' do
require_jruby
# JRuby does not return OCSP endpoints, therefore we never perform
# any validation.
# https://github.com/jruby/jruby-openssl/issues/210
it 'does not verify' do
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
verifier.verify.should be false
end
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
verifier.verify.should be false
end
end
end
end
shared_examples 'does not verify' do
it 'does not verify and does not raise an exception' do
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
verifier.verify.should be false
end
RSpec::Mocks.with_temporary_scope do
expect_any_instance_of(Mongo::Socket::OcspVerifier).to receive(:do_verify).and_call_original
verifier.verify.should be false
end
end
end
shared_context 'verifier' do |opts|
algorithm = opts[:algorithm]
let(:cert_path) { SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/server.pem") }
let(:ca_cert_path) { SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem") }
let(:cert) { OpenSSL::X509::Certificate.new(File.read(cert_path)) }
let(:ca_cert) { OpenSSL::X509::Certificate.new(File.read(ca_cert_path)) }
let(:cert_store) do
OpenSSL::X509::Store.new.tap do |store|
store.add_cert(ca_cert)
end
end
let(:verifier) do
described_class.new('foo', cert, ca_cert, cert_store, timeout: 3)
end
end
include_context 'verifier', algorithm: 'rsa'
algorithm = 'rsa'
%w(ca delegate).each do |responder_cert|
responder_cert_file_name = {
'ca' => 'ca',
'delegate' => 'ocsp-responder',
}.fetch(responder_cert)
context "when responder uses #{responder_cert} cert" do
context 'good response' do
with_ocsp_mock(
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem"),
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.crt"),
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.key"),
)
include_examples 'verifies'
it 'does not wait for the timeout' do
lambda do
verifier.verify
end.should take_shorter_than 3
end
end
context 'revoked response' do
with_ocsp_mock(
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem"),
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.crt"),
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.key"),
fault: 'revoked'
)
include_examples 'fails verification'
end
context 'unknown response' do
with_ocsp_mock(
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/ca.pem"),
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.crt"),
SpecConfig.instance.ocsp_files_dir.join("#{algorithm}/#{responder_cert_file_name}.key"),
fault: 'unknown',
)
include_examples 'does not verify'
it 'does not wait for the timeout' do
lambda do
verifier.verify
end.should take_shorter_than 3
end
end
end
end
end
|