+ def have_crypto?; !@cmd.nil? end
+
+ def sign from, to, payload
+ payload_fn = Tempfile.new "redwood.payload"
+ payload_fn.write format_payload(payload)
+ payload_fn.close
+
+ output = run_gpg "--output - --armor --detach-sign --textmode --local-user '#{from}' #{payload_fn.path}"
+
+ raise Error, (output || "gpg command failed: #{cmd}") unless $?.success?
+
+ envelope = RMail::Message.new
+ envelope.header["Content-Type"] = 'multipart/signed; protocol=application/pgp-signature; micalg=pgp-sha1'
+
+ envelope.add_part payload
+ signature = RMail::Message.make_attachment output, "application/pgp-signature", nil, "signature.asc"
+ envelope.add_part signature
+ envelope
+ end
+
+ def encrypt from, to, payload, sign=false
+ payload_fn = Tempfile.new "redwood.payload"
+ payload_fn.write format_payload(payload)
+ payload_fn.close
+
+ recipient_opts = (to + [ from ] ).map { |r| "--recipient '<#{r}>'" }.join(" ")
+ sign_opts = sign ? "--sign --local-user '#{from}'" : ""
+ gpg_output = run_gpg "--output - --armor --encrypt --textmode #{sign_opts} #{recipient_opts} #{payload_fn.path}"
+ raise Error, (gpg_output || "gpg command failed: #{cmd}") unless $?.success?
+
+ encrypted_payload = RMail::Message.new
+ encrypted_payload.header["Content-Type"] = "application/octet-stream"
+ encrypted_payload.header["Content-Disposition"] = 'inline; filename="msg.asc"'
+ encrypted_payload.body = gpg_output
+
+ control = RMail::Message.new
+ control.header["Content-Type"] = "application/pgp-encrypted"
+ control.header["Content-Disposition"] = "attachment"
+ control.body = "Version: 1\n"
+
+ envelope = RMail::Message.new
+ envelope.header["Content-Type"] = 'multipart/encrypted; protocol="application/pgp-encrypted"'
+
+ envelope.add_part control
+ envelope.add_part encrypted_payload
+ envelope
+ end