Skip to content

Instantly share code, notes, and snippets.

@SunDi3yansyah
Forked from pixeltrix/message_encryptor.rb
Created April 17, 2020 05:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SunDi3yansyah/d4944b714c84176b1598e1807b4c7e69 to your computer and use it in GitHub Desktop.
Save SunDi3yansyah/d4944b714c84176b1598e1807b4c7e69 to your computer and use it in GitHub Desktop.
Action Mailer interceptor for encrypting emails using S/MIME
require 'openssl'
class MessageEncryptor
class << self
include OpenSSL
def delivering_email(message)
encrypted_message = sign_and_encrypt(message.encoded, message.to)
overwrite_body(message, encrypted_message)
overwrite_headers(message, encrypted_message)
end
private
def sign_and_encrypt(data, recipients)
encrypt(sign(data), certificates_for(recipients))
end
def sign(data)
PKCS7.write_smime(PKCS7.sign(certificate, private_key, data, [], PKCS7::DETACHED))
end
def encrypt(data, certificates)
Mail.new(PKCS7.write_smime(PKCS7.encrypt(certificates, data, cipher)))
end
def cipher
@cipher ||= Cipher.new('AES-128-CBC')
end
def certificate
@certificate ||= X509::Certificate.new(File.read(certificate_path))
end
def certificate_path
Rails.root.join('config', 'server.pem')
end
def private_key
@private_key ||= PKey::RSA.new(File.read(private_key_path))
end
def private_key_path
Rails.root.join('config', 'server.key')
end
def certificates_for(recipients)
recipients.map do |recipient|
X509::Certificate.new(File.read(certificate_path_for(recipient)))
end
end
def certificate_path_for(recipient)
Rails.root.join('config', 'certificates', "#{recipient}.pem")
end
def overwrite_body(message, encrypted_message)
message.body = nil
message.body = encrypted_message.body.encoded
end
def overwrite_headers(message, encrypted_message)
message.content_disposition = encrypted_message.content_disposition
message.content_transfer_encoding = encrypted_message.content_transfer_encoding
message.content_type = encrypted_message.content_type
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment