[openssl-users] How to "unwrap" S/MIME messages using openssl?

Viktor Dukhovni openssl-users at dukhovni.org
Thu Apr 6 20:51:02 UTC 2017

> On Apr 6, 2017, at 3:54 PM, Blumenthal, Uri - 0553 - MITLL <uri at ll.mit.edu> wrote:
> Content-Type: multipart/signed;
> ...

> Hoping that it includes the signing certificate of the signer, I tried to verify its signature by:
> $ openssl cms -verify -inform SMIME -in ~/Documents/test-smime-decr.txt
> Verification failure
> 140735229702224:error:2E099064:CMS routines:CMS_SIGNERINFO_VERIFY_CERT:certificate verify error:cms_smime.c:287:Verify error:self signed certificate in certificate chain

You really should peruse the cms(1) manpage, daunting as that might be. :-)


   author=$(mktemp author.pem.XXXXXX)
   data=$(mktemp data.eml.XXXXXX)
   openssl cms -verify_retcode -verify -signer $author -CAfile /some/ca/certs.pem -out $data || {
	rm -f "$author" "$data"
        echo "verification failed"

The original data (sans signature encapsulation) will be in the file named "$data".

> How do I find out what certificate chain the signer used? How do I verify
> the signature? If I have a directory that holds files of all the CAs I use,
> is it enough to just give it in “-CApath ${HOME}/my_cert_dir”,

You can use some appropriate combination of -CAfile and -CApath.  Perhaps both,
just in case, to avoid use of default CAfile or CApath, I don't recall whether
cms(1) uses the default file/path.

> or does that directory have to have a special structure (and the certs have to
> be in a certain format)?

No, just standard, unless the keyUsage or extendedKeyUsage bits prohibit use
for emailProtection.

> And if I (failing to validate the certificate chain) want to just check
> whether the decrypted message was tampered with – is there a way to do
> that (without validating the certificate chain)?

If a single self-signed certificate is the expected signer, then you
can dispense with all the PKI nonsense and just test for the expected
signer.  With OpenSSL 1.1.0:

   openssl cms -CAfile signer.pem -no-CApath ...

with older versions:

   empty=$(mktemp -d empty.XXXXXX)
   openssl cms -CAfile signer.pem -CApath "$empty" ...
   rmdir "$empty"


More information about the openssl-users mailing list