Project

General

Profile

« Previous | Next » 

Revision c0979b3e

Added by Marc Dequènes about 15 years ago

  • ID c0979b3eb0412e410e1215171c043eeb29253823

[evol] moved signed/encrypted mail creation from original mail to TMail class, and removed mail object duplication in the process (references to inners objects caused original mail to be altered, copying original headers instead)

View differences:

lib/tmail_extra.rb
:passphrase_callback_value => passphrase_callback, :textmode => true})
end
def pgp_crypt(fingerprint)
GPGME.encrypt([gpg_key(fingerprint)], self.to_s, {:armor => true, :always_trust => true})
def pgp_crypt(crypters_id)
crypters_id = [crypters_id] unless crypters_id.is_a? Array
crypters = crypters_id.collect{|key_id| gpg_key(key_id, false) }
GPGME.encrypt(crypters, self.to_s, {:armor => true, :always_trust => true})
end
def pgp_sign(signers_id, &passphrase_callback)
signers_id = [signers_id] unless signers_id.is_a? Array
signers = signers_id.collect{|key_id| gpg_key(key_id, true) }
# we don't use GPGME.sign(), because we need to get operation information to get the hash_algo and compute the micalg parameter
gpg = GPGME::Ctx.new({:signers => signers, :passphrase_callback => method(:gpg_passphrase_callback_wrapper),
......
raw.chomp.gsub(/\r?\n/, "\r\n")
end
def create_encrypted(crypters_id)
clear_data = build_intermediate_mail()
encrypted_data = clear_data.pgp_crypt(crypters_id)
# build properly encrypted mail
# (preserving headers from original mail)
mail = TMail::Mail.new
mail.copy_headers_from(self)
mail.set_content_type("multipart", "encrypted", {'boundary' => TMail.new_boundary, "protocol" => "application/pgp-encrypted"})
mail.transfer_encoding = "7bit"
mail['content-disposition'] = nil
mail.body = "This mail is a RFC3156 encrypted message.\n"
mail.parts.clear
# cryptographic info
p_pgp = TMail::Mail.new
p_pgp.set_content_type("application", "pgp-encrypted")
p_pgp.transfer_encoding = "7bit"
p_pgp.content_disposition = "inline"
p_pgp.body = "Version: 1\n"
mail.parts << p_pgp
# encrypted message
p_encrypted = TMail::Mail.new
p_encrypted.set_content_type("application", "octet-stream")
p_encrypted.transfer_encoding = "7bit"
p_encrypted.content_disposition = "inline"
p_encrypted.body = encrypted_data
mail.parts << p_encrypted
# store the calculated content, to be able to use parsing methods
mail.write_back
mail
end
def create_signed(signers_id)
data = build_intermediate_mail()
sign_data = data.pgp_sign(signers_id) do |uid_hint, passphrase_info, prev_was_bad|
yield(uid_hint, passphrase_info, prev_was_bad)
end
# build properly signed mail
# (preserving headers from original mail)
mail = TMail::Mail.new
mail.copy_headers_from(self)
mail.set_content_type("multipart", "signed", {'boundary' => TMail.new_boundary, 'protocol' => "application/pgp-signature", 'micalg' => sign_data[:micalg]})
mail.transfer_encoding = "7bit"
mail['content-disposition'] = nil
mail.body = "This mail is a RFC3156 signed message.\n"
mail.parts.clear
# signed message
p_signed = data
mail.parts << p_signed
# signature
p_signature = TMail::Mail.new
p_signature.set_content_type("application", "pgp-signature")
p_signature.transfer_encoding = "7bit"
p_signature.content_disposition = "inline"
p_signature.body = sign_data[:signature]
mail.parts << p_signature
# store the calculated content, to be able to use parsing methods
mail.write_back
mail
end
def create_signed_and_encrypted(signers_id, crypters_id)
create_signed(signers_id) do |uid_hint, passphrase_info, prev_was_bad|
yield(uid_hint, passphrase_info, prev_was_bad)
end.create_encrypted(crypters_id)
end
def copy_headers_from(mail)
mail.header.keys.each do |h|
self[h] = mail[h].to_s
end
end
protected
def build_intermediate_mail
# build a fake mail to get the generated content to be crypted/signed
fake_mail = TMail::Mail.new
fake_mail['content-type'] = self['content-type'].to_s
fake_mail.transfer_encoding = self.transfer_encoding if self.transfer_encoding
fake_mail.content_disposition = self.content_disposition if self.content_disposition
if self.multipart?
self.each_part {|p| fake_mail.parts << p }
else
fake_mail.body = self.body
end
# store the calculated content, to be able to use parsing methods
fake_mail.write_back
fake_mail
end
def gpg_key(fingerprint, secret = false)
gpg = GPGME::Ctx.new
gpg.get_key(fingerprint, secret)

Also available in: Unified diff