def decrypt payload, armor=false # a RubyMail::Message object
    return unknown_status(@not_working_reason) unless @not_working_reason.nil?

    gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP}
    gpg_opts = HookManager.run("gpg-options",
                               {:operation => "decrypt", :options => gpg_opts}) || gpg_opts
    ctx = GPGME::Ctx.new(gpg_opts)
    cipher_data = GPGME::Data.from_str(format_payload(payload))
    if GPGME::Data.respond_to?('empty')
      plain_data = GPGME::Data.empty
    else
      plain_data = GPGME::Data.empty!
    end
    begin
      ctx.decrypt_verify(cipher_data, plain_data)
    rescue GPGME::Error => exc
      return Chunk::CryptoNotice.new(:invalid, "This message could not be decrypted", gpgme_exc_msg(exc.message))
    end
    begin
      sig = self.verified_ok? ctx.verify_result
    rescue ArgumentError => exc
      sig = unknown_status [gpgme_exc_msg(exc.message)]
    end
    plain_data.seek(0, IO::SEEK_SET)
    output = plain_data.read
    output.transcode(Encoding::ASCII_8BIT, output.encoding)

    ## TODO: test to see if it is still necessary to do a 2nd run if verify
    ## fails.
    #
    ## check for a valid signature in an extra run because gpg aborts if the
    ## signature cannot be verified (but it is still able to decrypt)
    #sigoutput = run_gpg "#{payload_fn.path}"
    #sig = self.old_verified_ok? sigoutput, $?

    if armor
      msg = RMail::Message.new
      # Look for Charset, they are put before the base64 crypted part
      charsets = payload.body.split("\n").grep(/^Charset:/)
      if !charsets.empty? and charsets[0] =~ /^Charset: (.+)$/
        output.transcode($encoding, $1)
      end
      msg.body = output
    else
      # It appears that some clients use Windows new lines - CRLF - but RMail
      # splits the body and header on "\n\n". So to allow the parse below to
      # succeed, we will convert the newlines to what RMail expects
      output = output.gsub(/\r\n/, "\n")
      # This is gross. This decrypted payload could very well be a multipart
      # element itself, as opposed to a simple payload. For example, a
      # multipart/signed element, like those generated by Mutt when encrypting
      # and signing a message (instead of just clearsigning the body).
      # Supposedly, decrypted_payload being a multipart element ought to work
      # out nicely because Message::multipart_encrypted_to_chunks() runs the
      # decrypted message through message_to_chunks() again to get any
      # children. However, it does not work as intended because these inner
      # payloads need not carry a MIME-Version header, yet they are fed to
      # RMail as a top-level message, for which the MIME-Version header is
      # required. This causes for the part not to be detected as multipart,
      # hence being shown as an attachment. If we detect this is happening,
      # we force the decrypted payload to be interpreted as MIME.
      msg = RMail::Parser.read output
      if msg.header.content_type =~ %r{^multipart/} && !msg.multipart?
        output = "MIME-Version: 1.0\n" + output
        output.fix_encoding!
        msg = RMail::Parser.read output
      end
    end
    notice = Chunk::CryptoNotice.new :valid, "This message has been decrypted for display"
    [notice, sig, msg]
  end
def decrypt payload, armor=false # a RubyMail::Message object
    return unknown_status(@not_working_reason) unless @not_working_reason.nil?

    gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP}
    gpg_opts = HookManager.run("gpg-options",
                               {:operation => "decrypt", :options => gpg_opts}) || gpg_opts
    ctx = GPGME::Ctx.new(gpg_opts)
    cipher_data = GPGME::Data.from_str(format_payload(payload))
    if GPGME::Data.respond_to?('empty')
      plain_data = GPGME::Data.empty
    else
      plain_data = GPGME::Data.empty!
    end
    begin
      ctx.decrypt_verify(cipher_data, plain_data)
    rescue GPGME::Error => exc
      return Chunk::CryptoNotice.new(:invalid, "This message could not be decrypted", gpgme_exc_msg(exc.message))
    end
    begin
      sig = self.verified_ok? ctx.verify_result
    rescue ArgumentError => exc
      sig = unknown_status [gpgme_exc_msg(exc.message)]
    end
    plain_data.seek(0, IO::SEEK_SET)
    output = plain_data.read
    output.transcode(Encoding::ASCII_8BIT, output.encoding)

    ## TODO: test to see if it is still necessary to do a 2nd run if verify
    ## fails.
    #
    ## check for a valid signature in an extra run because gpg aborts if the
    ## signature cannot be verified (but it is still able to decrypt)
    #sigoutput = run_gpg "#{payload_fn.path}"
    #sig = self.old_verified_ok? sigoutput, $?

    if armor
      msg = RMail::Message.new
      # Look for Charset, they are put before the base64 crypted part
      charsets = payload.body.split("\n").grep(/^Charset:/)
      if !charsets.empty? and charsets[0] =~ /^Charset: (.+)$/
        output.transcode($encoding, $1)
      end
      msg.body = output
    else
      # It appears that some clients use Windows new lines - CRLF - but RMail
      # splits the body and header on "\n\n". So to allow the parse below to
      # succeed, we will convert the newlines to what RMail expects
      output = output.gsub(/\r\n/, "\n")
      # This is gross. This decrypted payload could very well be a multipart
      # element itself, as opposed to a simple payload. For example, a
      # multipart/signed element, like those generated by Mutt when encrypting
      # and signing a message (instead of just clearsigning the body).
      # Supposedly, decrypted_payload being a multipart element ought to work
      # out nicely because Message::multipart_encrypted_to_chunks() runs the
      # decrypted message through message_to_chunks() again to get any
      # children. However, it does not work as intended because these inner
      # payloads need not carry a MIME-Version header, yet they are fed to
      # RMail as a top-level message, for which the MIME-Version header is
      # required. This causes for the part not to be detected as multipart,
      # hence being shown as an attachment. If we detect this is happening,
      # we force the decrypted payload to be interpreted as MIME.
      msg = RMail::Parser.read output
      if msg.header.content_type =~ %r{^multipart/} && !msg.multipart?
        output = "MIME-Version: 1.0\n" + output
        output.fix_encoding!
        msg = RMail::Parser.read output
      end
    end
    notice = Chunk::CryptoNotice.new :valid, "This message has been decrypted for display"
    [notice, sig, msg]
  end
returns decrypted_message, status, desc, lines