Commit 36b60c36 authored by David Kim's avatar David Kim

Merge branch 'x509-cert-loading' into 'master'

Forcibly load X509 cert

See merge request gitlab-org/gitlab!54569
parents eedfbf72 56933f2f
---
title: Forcibly load OpenSSL::X509::DEFAULT_CERT_FILE
merge_request: 54569
author:
type: fixed
...@@ -52,6 +52,12 @@ module Gitlab ...@@ -52,6 +52,12 @@ module Gitlab
strong_memoize(:cert_store) do strong_memoize(:cert_store) do
store = OpenSSL::X509::Store.new store = OpenSSL::X509::Store.new
store.set_default_paths store.set_default_paths
if Feature.enabled?(:x509_forced_cert_loading, type: :ops)
# Forcibly load the default cert file because the OpenSSL library seemingly ignores it
store.add_file(OpenSSL::X509::DEFAULT_CERT_FILE) if File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE)
end
# valid_signing_time? checks the time attributes already # valid_signing_time? checks the time attributes already
# this flag is required, otherwise expired certificates would become # this flag is required, otherwise expired certificates would become
# unverified when notAfter within certificate attribute is reached # unverified when notAfter within certificate attribute is reached
......
...@@ -11,6 +11,65 @@ RSpec.describe Gitlab::X509::Signature do ...@@ -11,6 +11,65 @@ RSpec.describe Gitlab::X509::Signature do
} }
end end
shared_examples "a verified signature" do
it 'returns a verified signature if email does match' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_truthy
expect(signature.verification_status).to eq(:verified)
end
it 'returns an unverified signature if email does not match' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
"gitlab@example.com",
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_truthy
expect(signature.verification_status).to eq(:unverified)
end
it 'returns an unverified signature if email does match and time is wrong' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
Time.new(2020, 2, 22)
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_falsey
expect(signature.verification_status).to eq(:unverified)
end
it 'returns an unverified signature if certificate is revoked' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.verification_status).to eq(:verified)
signature.x509_certificate.revoked!
expect(signature.verification_status).to eq(:unverified)
end
end
context 'commit signature' do context 'commit signature' do
let(:certificate_attributes) do let(:certificate_attributes) do
{ {
...@@ -30,62 +89,25 @@ RSpec.describe Gitlab::X509::Signature do ...@@ -30,62 +89,25 @@ RSpec.describe Gitlab::X509::Signature do
allow(OpenSSL::X509::Store).to receive(:new).and_return(store) allow(OpenSSL::X509::Store).to receive(:new).and_return(store)
end end
it 'returns a verified signature if email does match' do it_behaves_like "a verified signature"
signature = described_class.new( end
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_truthy
expect(signature.verification_status).to eq(:verified)
end
it 'returns an unverified signature if email does not match' do context 'with the certificate defined by OpenSSL::X509::DEFAULT_CERT_FILE' do
signature = described_class.new( before do
X509Helpers::User1.signed_commit_signature, store = OpenSSL::X509::Store.new
X509Helpers::User1.signed_commit_base_data, certificate = OpenSSL::X509::Certificate.new(X509Helpers::User1.trust_cert)
"gitlab@example.com", file_path = Rails.root.join("tmp/cert.pem").to_s
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes) File.open(file_path, "wb") do |f|
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes) f.print certificate.to_pem
expect(signature.verified_signature).to be_truthy end
expect(signature.verification_status).to eq(:unverified)
end
it 'returns an unverified signature if email does match and time is wrong' do stub_const("OpenSSL::X509::DEFAULT_CERT_FILE", file_path)
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
Time.new(2020, 2, 22)
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes) allow(OpenSSL::X509::Store).to receive(:new).and_return(store)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_falsey
expect(signature.verification_status).to eq(:unverified)
end end
it 'returns an unverified signature if certificate is revoked' do it_behaves_like "a verified signature"
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.verification_status).to eq(:verified)
signature.x509_certificate.revoked!
expect(signature.verification_status).to eq(:unverified)
end
end end
context 'without trusted certificate within store' do context 'without trusted certificate within store' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment