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 <david...@google.com>
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
     https://www.imperialviolet.org/2014/09/26/pkcs1.html

     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 https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00

     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 <k...@roeckx.be>
     Reviewed-by: Rich Salz <rs...@openssl.org>

     GH: #1474
     (cherry picked from commit 608a026494c1e7a14f6d6cfcc5e4994fe2728836)

Implemented via this pull request:
https://github.com/openssl/openssl/pull/1474

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 server (specifically to timestamp the original CMS signature with a long-valid signed
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 md5RSA, 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 this
format, only that is was present in the wild.



Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S.  https://www.wisemo.com
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

Reply via email to