Ask A Question

Notifications

You’re not receiving notifications from this thread.

[SOLVED] Decrypt S/MIME 'file.xml.p7m' with OpenSSL

Matteo asked in Ruby

I am trying to implement a decoder for a bunch of files (e-bills with extension .xml.p7m) in my rails application within a specific helper.

My goal is to upload the encripted files and read them populating the database meanwhile. I don't need to verify the signature because i want to conserve the original file, with signature, as an attachment. The helper should give me the plain .xml for each file.

I can do this easily in the terminal with the following command:
'openssl smime -verify -noverify -in file.xml.p7m -inform DER -out file.xml'

I am not able to use properly the module 'openssl' inside the helper. Can somebody help me please?

Thanks in advance.

Reply

There's a Ruby package for OpenSSL you can use so you don't have to run shell commands. https://github.com/ruby/openssl

Reply

Thanks Chris,
i'm trying to use this gem according to this sample: https://github.com/ruby/openssl/blob/master/sample/smime_read.rb

My situation is somehow different because i've not any cert/key for my file but the problem comes before...

I've tryied to do something like this:
'OpenSSL::PKCS7::read_smime(File.read(file.xml.p7m))'
but i recive error:
'OpenSSL::PKCS7::PKCS7Error (no content type)'

I can't find a clearer description of this error but i suspect it could be something about encoding or special characters. I don't know what read_smime expect as string.

Reply

I haven't used it, but I would ask for some help on the GitHub issues.

Reply

Ok, thanks Chris. I will try.

If anybody else have suggestions for me are welcome.
If necessary i can send a pm with the file for testing.

Thanks again.

Reply

I have an update for my question.

It seems that OpenSSL::read_smime expects a whole message in S/MIME format.
My file is DER-encoded and to open a DER- or PEM-encoded file, i need to use OpenSSL::PKCS7.new(string) instead (thanks to Kazuki Yamaguchi from GitHub for that).

My promlem remain because i can export and verify certificates but i'm not able to export the content of the message (xml file) which is what i need.

This is what i get:
p7 = OpenSSL::PKCS7.new(string)
=> #

p7.data
=> nil

p7.recipients
=> []

p7.to_s
=> "-----BEGIN PKCS7-----\n ....... -----END PKCS7-----\n"

Somebody knows how can i export the plain file.xml?

Reply

I've resolved everything (thanks again to Kazuki Yamaguchi from GitHub for that).

This is a short recap for everyone who will have the same problem.
Italians e-bill can be a plain file (.xml), signed with PKCS7 (.xml.p7m), or encoded in base64 and signed (.xml.p7m).

First of all verify if it is encoded in base64 and, eventually, decode it.

After that verify if it is signed and eventually follow this steps:
p7 = OpenSSL::PKCS7.new(string) #File.read(fullpath)
certs = nil
store = OpenSSL::X509::Store.new
indata = nil
flags = OpenSSL::PKCS7::NOVERIFY
p7.verify(certs, store, indata, flags)
xml = p7.data

obviously if it is a plain xml file you have nothing to do.

Hope it helps.

Reply

Awesome, thanks for posting your solution. I'm sure at some point when I need to use OpenSSL directly, this will come in handy!

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,329+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.