PKCS#7/CMS verify reports bad signature

Jakob Bohm jb-openssl at
Tue Apr 2 10:42:18 UTC 2019

On 02/04/2019 10:44, Matt Caswell wrote:
> On 01/04/2019 22:23, Steffen wrote:
>> Hello,
>> I believe that I have narrowed the problem down to one specific version of
>> OpenSSL. Version 1.1.0b works as expected while OpenSSL 1.1.0c does not.
> Using the cert/data files you provided me off-list (thanks), I was able to
> confirm the above and narrow it down further to the following commit:
> commit b71079a375116a8a52ed493afcd8f69cb08c195a
> Author: David Benjamin <davidben at>
> Date:   Sat Aug 20 13:35:17 2016 -0400
>      Implement RSASSA-PKCS1-v1_5 as specified.
>      RFC 3447, section 8.2.2, steps 3 and 4 states that verifiers must encode
>      the DigestInfo struct and then compare the result against the public key
>      operation result. This implies that one and only one encoding is legal.
>      OpenSSL instead parses with crypto/asn1, then checks that the encoding
>      round-trips, and allows some variations for the parameter. Sufficient
>      laxness in this area can allow signature forgeries, as described in
>      Although there aren't known attacks against OpenSSL's current scheme,
>      this change makes OpenSSL implement the algorithm as specified. This
>      avoids the uncertainty and, more importantly, helps grow a healthy
>      ecosystem. Laxness beyond the spec, particularly in implementations
>      which enjoy wide use, risks harm to the ecosystem for all. A signature
>      producer which only tests against OpenSSL may not notice bugs and
>      accidentally become widely deployed. Thus implementations have a
>      responsibility to honor the specification as tightly as is practical.
>      In some cases, the damage is permanent and the spec deviation and
>      security risk becomes a tax all implementors must forever pay, but not
>      here. Both BoringSSL and Go successfully implemented and deployed
>      RSASSA-PKCS1-v1_5 as specified since their respective beginnings, so
>      this change should be compatible enough to pin down in future OpenSSL
>      releases.
>      See also
>      As a bonus, by not having to deal with sign/verify differences, this
>      version is also somewhat clearer. It also more consistently enforces
>      digest lengths in the verify_recover codepath. The NID_md5_sha1 codepath
>      wasn't quite doing this right.
>      Reviewed-by: Kurt Roeckx <kurt at>
>      Reviewed-by: Rich Salz <rsalz at>
>      GH: #1474
>      (cherry picked from commit 608a026494c1e7a14f6d6cfcc5e4994fe2728836)
> Implemented via this pull request:
> So, based on the above description, it appears that older versions of OpenSSL
> were unduly lenient in tolerating incorrectly formatted signatures. As a
> security hardening measure that tolerance was removed. If you want to know more
> then David Benjamin may be able to expand.
Please note that CMS countersignatures made using a specific Symantec 
(specifically to timestamp the original CMS signature with a long-valid 
timestamp) happened to use a different PKCS#1.x signature format until very
recently.  This signature had a different but similar input to the raw RSA
algorithm, and was only ever done with Sha1RSA.

According to my notes, this format was only ever used with sha1RSA and 
In this format, the DER encoding and hash OID is skipped, and instead 
the raw
20 or 16 byte hash is placed where the DER encoded tuple should be.  The
surrounding padding was apparently the same is in PKCS#1.5 signatures, 
as was
the OIDs identifying this algorithm.

I don't know if an older PKCS#1 document (before 1.5) actually specified 
format, only that is was present in the wild.


Jakob Bohm, CIO, Partner, WiseMo A/S.
Transformervej 29, 2860 Søborg, Denmark.  Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded

More information about the openssl-users mailing list