lib/sup/crypto.rb in sup-0.22.1 vs lib/sup/crypto.rb in sup-0.23

- old
+ new

@@ -125,22 +125,31 @@ def not_working_reason; @not_working_reason end def sign from, to, payload return unknown_status(@not_working_reason) unless @not_working_reason.nil? + # We grab this from the GPG::Ctx below after signing, so that we can set + # micalg in Content-Type to match the hash algorithm GPG decided to use. + hash_algo = nil + gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true} gpg_opts.merge!(gen_sign_user_opts(from)) gpg_opts = HookManager.run("gpg-options", {:operation => "sign", :options => gpg_opts}) || gpg_opts begin - if GPGME.respond_to?('detach_sign') - sig = GPGME.detach_sign(format_payload(payload), gpg_opts) - else - crypto = GPGME::Crypto.new - gpg_opts[:mode] = GPGME::SIG_MODE_DETACH - sig = crypto.sign(format_payload(payload), gpg_opts).read + input = GPGME::Data.new(format_payload(payload)) + output = GPGME::Data.new() + GPGME::Ctx.new(gpg_opts) do |ctx| + if gpg_opts[:signer] + signers = GPGME::Key.find(:secret, gpg_opts[:signer], :sign) + ctx.add_signer(*signers) + end + ctx.sign(input, output, GPGME::SIG_MODE_DETACH) + hash_algo = GPGME::hash_algo_name(ctx.sign_result.signatures[0].hash_algo) end + output.seek(0) + sig = output.read rescue GPGME::Error => exc raise Error, gpgme_exc_msg(exc.message) end # if the key (or gpg-agent) is not available GPGME does not complain @@ -148,11 +157,11 @@ if sig.length == 0 raise Error, gpgme_exc_msg("GPG failed to generate signature: check that gpg-agent is running and your key is available.") end envelope = RMail::Message.new - envelope.header["Content-Type"] = 'multipart/signed; protocol=application/pgp-signature' + envelope.header["Content-Type"] = "multipart/signed; protocol=application/pgp-signature; micalg=pgp-#{hash_algo.downcase}" envelope.add_part payload signature = RMail::Message.make_attachment sig, "application/pgp-signature", nil, "signature.asc" envelope.add_part signature envelope @@ -231,10 +240,10 @@ unknown = true end end if valid || !unknown - summary_line = simplify_sig_line(verify_result.signatures[0].to_s, all_trusted) + summary_line = simplify_sig_line(verify_result.signatures[0].to_s.dup, all_trusted) end if all_output_lines.length == 0 Chunk::CryptoNotice.new :valid, "Encrypted message wasn't signed", all_output_lines elsif valid