diff options
-rw-r--r-- | app/models/commit.rb | 17 | ||||
-rw-r--r-- | lib/gitlab/gpg.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/gpg_spec.rb | 17 | ||||
-rw-r--r-- | spec/models/commit_spec.rb | 4 |
4 files changed, 43 insertions, 3 deletions
diff --git a/app/models/commit.rb b/app/models/commit.rb index 9c8edbb097d..a6a11a2d3a5 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -240,7 +240,22 @@ class Commit @signature = nil signature, signed_text = @raw.signature(project.repository) - if signature && signed_text + + return unless signature && signed_text + + Gitlab::Gpg.using_tmp_keychain do + # first we need to get the keyid from the signature... + GPGME::Crypto.new.verify(signature, signed_text: signed_text) do |verified_signature| + @signature = verified_signature + end + + # ... then we query the gpg key belonging to the keyid. + gpg_key = GpgKey.find_by(primary_keyid: @signature.fingerprint) + + return @signature unless gpg_key + + Gitlab::Gpg::CurrentKeyChain.add(gpg_key.key) + GPGME::Crypto.new.verify(signature, signed_text: signed_text) do |verified_signature| @signature = verified_signature end diff --git a/lib/gitlab/gpg.rb b/lib/gitlab/gpg.rb index 486e040adb6..258901bb238 100644 --- a/lib/gitlab/gpg.rb +++ b/lib/gitlab/gpg.rb @@ -2,6 +2,14 @@ module Gitlab module Gpg extend self + module CurrentKeyChain + extend self + + def add(key) + GPGME::Key.import(key) + end + end + def fingerprints_from_key(key) using_tmp_keychain do import = GPGME::Key.import(key) diff --git a/spec/lib/gitlab/gpg_spec.rb b/spec/lib/gitlab/gpg_spec.rb index 55f34e0cf99..edf7405d7f1 100644 --- a/spec/lib/gitlab/gpg_spec.rb +++ b/spec/lib/gitlab/gpg_spec.rb @@ -43,3 +43,20 @@ describe Gitlab::Gpg do end end end + +describe Gitlab::Gpg::CurrentKeyChain, :gpg do + describe '.add', :gpg do + it 'stores the key in the keychain' do + expect(GPGME::Key.find(:public, GpgHelpers::User1.fingerprint)).to eq [] + + described_class.add(GpgHelpers::User1.public_key) + + keys = GPGME::Key.find(:public, GpgHelpers::User1.fingerprint) + expect(keys.count).to eq 1 + expect(keys.first).to have_attributes( + email: GpgHelpers::User1.emails.first, + fingerprint: GpgHelpers::User1.fingerprint + ) + end + end +end diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index 3c6ce49b48d..96af675c3f4 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -422,7 +422,7 @@ eos context 'signed commit', :gpg do it 'returns a valid signature if the public key is known' do - GPGME::Key.import(GpgHelpers::User1.public_key) + create :gpg_key, key: GpgHelpers::User1.public_key raw_commit = double(:raw_commit, signature: [ GpgHelpers::User1.signed_commit_signature, @@ -438,7 +438,7 @@ eos expect(commit.signature.valid?).to be_truthy end - it 'returns an invalid signature if the public commit is unknown', :gpg do + it 'returns an invalid signature if the public key is unknown', :gpg do raw_commit = double(:raw_commit, signature: [ GpgHelpers::User1.signed_commit_signature, GpgHelpers::User1.signed_commit_base_data |