commit 104e89e51733eca481a02bab731b7d030d74e400
parent 07ae55696a4121295386b4cd6ae498b2c00254a0
Author: Dan Callaghan <djc@djc.id.au>
Date: Sat, 12 Apr 2025 15:28:19 +1000
fix signing key selection for sign_and_encrypt
The GPGME::Crypto#encrypt() method looks for :signers in its options
hash, but Sup was passing :signer which has no effect. As a result, the
mail would always be signed with the user's default signing key.
Keep the :signer misspelling on the Sup side, to avoid breaking anyone's
existing 'gpg-options' hooks, but pass :signers to GPGME.
Fixes #522.
Diffstat:
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
@@ -177,6 +177,8 @@ EOS
end
gpg_opts = HookManager.run("gpg-options",
{:operation => "encrypt", :options => gpg_opts}) || gpg_opts
+ ## On the sup side we use :signer for backwards compatibility, but GPGME wants :signers.
+ gpg_opts[:signers] = gpg_opts[:signer]
recipients = to + [from]
recipients = HookManager.run("gpg-expand-keys", { :recipients => recipients }) || recipients
begin
diff --git a/test/test_crypto.rb b/test/test_crypto.rb
@@ -113,6 +113,39 @@ class TestCryptoManager < Minitest::Test
assert_equal "ABCDEFG" , decrypted[2].body
end
+ def test_decrypt_and_verify
+ skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
+
+ encrypted = CryptoManager.sign_and_encrypt @from_email, [@to_email], "ABCDEFG"
+ assert_instance_of RMail::Message, encrypted
+ assert_instance_of String, (encrypted.body[1].body)
+ decrypted = CryptoManager.decrypt encrypted.body[1], true
+ assert_instance_of Array, decrypted
+ assert_instance_of Chunk::CryptoNotice, decrypted[0]
+ assert_instance_of Chunk::CryptoNotice, decrypted[1]
+ assert_instance_of RMail::Message, decrypted[2]
+ assert_match(/^Signature made .* using RSA key ID 072B50BE/,
+ decrypted[1].lines[0])
+ assert_equal "Good signature from \"#{@from_email}\"", decrypted[1].lines[1]
+ assert_equal "ABCDEFG" , decrypted[2].body
+ end
+
+ def test_decrypt_and_verify_nondefault_key
+ skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
+
+ encrypted = CryptoManager.sign_and_encrypt @from_email_ecc, [@to_email], "ABCDEFG"
+ assert_instance_of RMail::Message, encrypted
+ assert_instance_of String, (encrypted.body[1].body)
+ decrypted = CryptoManager.decrypt encrypted.body[1], true
+ assert_instance_of Array, decrypted
+ assert_instance_of Chunk::CryptoNotice, decrypted[0]
+ assert_instance_of Chunk::CryptoNotice, decrypted[1]
+ assert_instance_of RMail::Message, decrypted[2]
+ assert_match(/^Signature made .* key ID AC34B83C/, decrypted[1].lines[0])
+ assert_equal "Good signature from \"#{@from_email_ecc}\"", decrypted[1].lines[1]
+ assert_equal "ABCDEFG" , decrypted[2].body
+ end
+
def test_verify
skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?