⬆️ ⬇️

ActionMailer_X509: Sign and Encrypt Emails Directly in Ruby On Rails

In one of the last projects, it was necessary to sign and encrypt using X.509 certificates letters sent by the application to Ruby on Rails 3. A quick search resulted in the actionmailer_x509 plugin, but then the problems started.



It turned out that it has not been updated since 2008, most likely it does not work with Rails 3 (in particular, it embarrassed the author’s comment: “It has been tested with Rails 2.0.1”) and is only able to sign, but not encrypt letters. Search for alternative solutions gave nothing, and had to get acquainted with the plugin closer.





')

The acquaintance was complicated very quickly: the test suite that came with the plugin fell during the run. As it turned out, although it was not easy to notice right away, the fact was that the certificates that the author included in the test set had expired. Recreated certificates. Next, I removed the libraries from Rails 2 from the test helper and added the corresponding ones from Rails 3, made a number of changes



It immediately turned out that Mail , the new mail processing gem, which is now used in Ruby on Rails 3, is significantly different from Tmail . I had to cut into the internal Mail and Tmail device, rewrite all the parts affecting Tmail. Ok, done. Of course, I tinker, and the letter headers were not transferred, but this was solvable.



New problem: in the comments to the code, the author writes “NOTE: we can’t reparse the whole mail, TMail adds a \ r \ n which breaks the signature ...”. Indeed, the signature verification does not work and in the resulting body of the Mail object \ r \ n stand every 60 characters, while in the original, every 64 characters. It took a very long time to fight this problem. I tried gsub to get everything in place, I studied the code of gem Mail, left bug reports in Mail, wrote to the list of mailings, but everything was in vain. In the end, I was saved by a stackoverflow question . It turned out that Mail adds a content-id that changes the headers of the letter, and, therefore, the signature becomes incorrect, and this has nothing to do with \ r \ n, which the author wrote about the original actionmailer_x509.



After the correction and the forced installation of content_id, everything went smoothly: I cleaned the code, wrapped everything in a separate gem, corrected the rake tasks and added the code responsible for encrypting the letter.



You can enjoy the result of my labors in my forma actionmailer_x509 on github or with the help of the line gem 'actionmailer_x509' in your Gemfile.



It allows the following simple code to include signature and / or encrypt outgoing mail.



class FooMailer < ActionMailer::Base def sending_method(email, from , subject = "Empty subject for signed") #    x509_sign true x509_sign_cert "certs/yourwebsite.crt" x509_sign_key "certs/yourwebsite.key" #     x509_sign_passphrase "my passphrase for the certificate" #    x509_crypt true x509_crypt_cert "certs/crypt.crt" #    ,     DES x509_crypt_cipher "AES-128-CBC" mail(:subject => subject, :to => email, :from => from) end end 




In addition, the plugin allows you to set all these key settings for the entire application as a whole and provides several rake tasks for testing settings and speed. Read more about this in the README .



Instead of conclusion


I spent more than a month adapting actionmailer_x509 to Ruby on Rails 3 features. I learned smime openssl, gem Mail, gem Tmail, and ActionMailer. I learned how to wrap code in a gem and how the gem structure should look like; how correctly, with the help of the railtie, load the rake tasks so that they become visible in the final Rails application. There were moments when I was ready to give up, and looked for workarounds for solving my problem, but, fortunately, I managed to finish the game with a gem.



I do not regret the time spent, and I look at the newly created gem with a sense of satisfaction. Now I feel the whole Ruby on Rails mailbox much better, and I’ve become a lot more knowledgeable about OpenSSL related issues. If you suddenly have to choose to finish / create an existing solution or try to work around the problem somehow - try to do something new for the community, you should like it!

Source: https://habr.com/ru/post/127222/



All Articles