Class: Redwood::CryptoManager
- Inherits:
-
Object
- Object
- Redwood::CryptoManager
- Includes:
- Singleton
- Defined in:
- lib/sup/crypto.rb
Defined Under Namespace
Classes: Error
Constant Summary
- OUTGOING_MESSAGE_OPERATIONS =
OrderedHash.new( [:sign, "Sign"], [:sign_and_encrypt, "Sign and encrypt"], [:encrypt, "Encrypt only"] )
Instance Method Summary (collapse)
-
- (Object) decrypt(payload)
returns decrypted_message, status, desc, lines.
- - (Object) encrypt(from, to, payload, sign = false)
- - (Boolean) have_crypto?
-
- (CryptoManager) initialize
constructor
A new instance of CryptoManager.
- - (Object) sign(from, to, payload)
- - (Object) sign_and_encrypt(from, to, payload)
-
- (Object) verify(payload, signature)
both RubyMail::Message objects.
Constructor Details
- (CryptoManager) initialize
A new instance of CryptoManager
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/sup/crypto.rb', line 14 def initialize @mutex = Mutex.new self.class.i_am_the_instance self bin = `which gpg`.chomp @cmd = case bin when /\S/ Redwood::log "crypto: detected gpg binary in #{bin}" "#{bin} --quiet --batch --no-verbose --logger-fd 1 --use-agent" else Redwood::log "crypto: no gpg binary detected" nil end end |
Instance Method Details
- (Object) decrypt(payload)
returns decrypted_message, status, desc, lines
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/sup/crypto.rb', line 109 def decrypt payload # a RubyMail::Message object return unknown_status(cant_find_binary) unless @cmd payload_fn = Tempfile.new "redwood.payload" payload_fn.write payload.to_s payload_fn.close output = run_gpg "--decrypt #{payload_fn.path}" if $?.success? decrypted_payload, sig_lines = if output =~ /\A(.*?)((^gpg: .*$)+)\Z/m [$1, $2] else [output, nil] end sig = if sig_lines # encrypted & signed if sig_lines =~ /^gpg: (Good signature from .*$)/ Chunk::CryptoNotice.new :valid, $1, sig_lines.split("\n") else Chunk::CryptoNotice.new :invalid, $1, sig_lines.split("\n") end end notice = Chunk::CryptoNotice.new :valid, "This message has been decrypted for display" [RMail::Parser.read(decrypted_payload), sig, notice] else notice = Chunk::CryptoNotice.new :invalid, "This message could not be decrypted", output.split("\n") [nil, nil, notice] end end |
- (Object) encrypt(from, to, payload, sign = false)
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/sup/crypto.rb', line 51 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 |
- (Boolean) have_crypto?
31 |
# File 'lib/sup/crypto.rb', line 31 def have_crypto?; !@cmd.nil? end |
- (Object) sign(from, to, payload)
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/sup/crypto.rb', line 33 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. output, "application/pgp-signature", nil, "signature.asc" envelope.add_part signature envelope end |
- (Object) sign_and_encrypt(from, to, payload)
79 80 81 |
# File 'lib/sup/crypto.rb', line 79 def sign_and_encrypt from, to, payload encrypt from, to, payload, true end |
- (Object) verify(payload, signature)
both RubyMail::Message objects
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/sup/crypto.rb', line 83 def verify payload, signature # both RubyMail::Message objects return unknown_status(cant_find_binary) unless @cmd payload_fn = Tempfile.new "redwood.payload" payload_fn.write format_payload(payload) payload_fn.close signature_fn = Tempfile.new "redwood.signature" signature_fn.write signature.decode signature_fn.close output = run_gpg "--verify #{signature_fn.path} #{payload_fn.path}" output_lines = output.split(/\n/) if output =~ /^gpg: (.* signature from .*$)/ if $? == 0 Chunk::CryptoNotice.new :valid, $1, output_lines else Chunk::CryptoNotice.new :invalid, $1, output_lines end else unknown_status output_lines end end |