Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

X509_verify() failing to verify valid certificate in old OpenSSL versions

157 views
Skip to first unread message

Dimitrios Apostolou

unread,
Nov 14, 2013, 4:38:56 AM11/14/13
to
Hello,

some time now I'm having problems with X509_verify() from
openssl-1.0.0-27.el6_4.2.i686 shipped with latest RHEL 6. The problem is
that a self-signed certificate that I generate and verify on the server
side, fails to verify on the client side after the TLS handshake.

Since this works fine with latest OpenSSL I assumed it's a bug in OpenSSL
and did a git-bisect. The commit that fixes it seems to be:


commit 39239280f3576f3418dadbf751bc7a2bb3252d4e
Author: Dr. Stephen Henson <st...@openssl.org>
Date: Sun Oct 3 18:58:09 2010 +0000

Add call to ENGINE_register_all_complete() to
ENGINE_load_builtin_engines(), this means that some implementations will
be used automatically, e.g. aesni, we do this for cryptodev anyway.

Setup cpuid in ENGINE_load_builtin_engines() too as some ENGINEs use
it.


This commit contains the following description in CHANGES:

+ *) Don't reencode certificate when calculating signature: cache and use
+ the original encoding instead. This makes signature verification of
+ some broken encodings work correctly.


Can you please explain me what a "broken" encoding is, and how I might
be using it? How can I self-sign a certificate that can be verified in old
versions as well?


Thank you in advance,
Dimitris
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Dr. Stephen Henson

unread,
Nov 14, 2013, 7:31:08 AM11/14/13
to
On Thu, Nov 14, 2013, Dimitrios Apostolou wrote:

> some time now I'm having problems with X509_verify() from
> openssl-1.0.0-27.el6_4.2.i686 shipped with latest RHEL 6. The
> problem is that a self-signed certificate that I generate and verify
> on the server side, fails to verify on the client side after the TLS
> handshake.
>
> Since this works fine with latest OpenSSL I assumed it's a bug in
> OpenSSL and did a git-bisect. The commit that fixes it seems to be:
>
>
> commit 39239280f3576f3418dadbf751bc7a2bb3252d4e
> Author: Dr. Stephen Henson <st...@openssl.org>
> Date: Sun Oct 3 18:58:09 2010 +0000
>
> This commit contains the following description in CHANGES:
>
> + *) Don't reencode certificate when calculating signature: cache and use
> + the original encoding instead. This makes signature verification of
> + some broken encodings work correctly.
>
>
> Can you please explain me what a "broken" encoding is, and how I
> might be using it? How can I self-sign a certificate that can be
> verified in old versions as well?
>

When a certificate is parsed various fields are decoded. Before this change
when a signature was verified it was re-encoded. Any discrepancy between the
original encoding and the re-encoded version would result in a signature
failure. This can happen for all sorts of reasons, usually violation of DER.

This change stores the original encoding and verifies signatures against that
instead of re-encoding.

It's not clear how you could create a certificate that violates DER using
OpenSSL, though you're not using a standard version so some bug fixes might be
missing.

Can you send a sample certificate that fails signature verification in the way
you describe?

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org

Dimitrios Apostolou

unread,
Nov 14, 2013, 7:59:24 AM11/14/13
to
On Thu, 14 Nov 2013, Dr. Stephen Henson wrote:
> On Thu, Nov 14, 2013, Dimitrios Apostolou wrote:
>>
>> + *) Don't reencode certificate when calculating signature: cache and use
>> + the original encoding instead. This makes signature verification of
>> + some broken encodings work correctly.
>>
>>
>> Can you please explain me what a "broken" encoding is, and how I
>> might be using it? How can I self-sign a certificate that can be
>> verified in old versions as well?
>>
>
> When a certificate is parsed various fields are decoded. Before this change
> when a signature was verified it was re-encoded. Any discrepancy between the
> original encoding and the re-encoded version would result in a signature
> failure. This can happen for all sorts of reasons, usually violation of DER.
>
> This change stores the original encoding and verifies signatures against that
> instead of re-encoding.
>
> It's not clear how you could create a certificate that violates DER using
> OpenSSL, though you're not using a standard version so some bug fixes might be
> missing.
>
> Can you send a sample certificate that fails signature verification in the way
> you describe?

Thanks for explaining! It's quite possible I'm missusing OpenSSL API since
I'm trying to work my way into veryfying self-signed certificates
generated from RSA keys, which is not that common. I privately sent you a
test program that replicates the problem, feel free to reply here.

Thanks,
Dimitris

Dimitrios Apostolou

unread,
Nov 16, 2013, 9:06:29 AM11/16/13
to
On Fri, 15 Nov 2013, Dr. Stephen Henson wrote:

> On Fri, Nov 15, 2013, Dimitrios Apostolou wrote:
>
>> On Fri, 15 Nov 2013, Dr. Stephen Henson wrote:
>>>
>>> If the certificate contains no useful information then why check it at all
>>> other than to make sure it carries the correct public key?
>>
>> I was not sure if the TLS handshake assures that the certificate is
>> not tampered so I decided to go the safe way.
>>
>> Specifically I assumed that a man in the middle can craft a
>> certificate that contains the same public key (it's public after
>> all), but he can not sign it since he is missing the private key.
>> And since I'm overriding all of the default OpenSSL verification
>> (see my call to SSL_CTX_set_cert_verify_callback) I'm the one that
>> has to manually checked a valid signature, no?
>>
>
> Depending on the ciphersuite either an RSA decryption operation or an RSA
> signature operation is performed by the server. So if the handshake completes
> successfully you can be sure that the same key is used as the one present in
> the certificate.

Thank you Steve, this is very reassuring, I'll remove the X509_verify()
call that checks the self-signed certificate. Cc'ing the list since I've
been looking for such information all over the web.

FWIW I've only enabled ciphers with RSA key exchange, no DH. The reason is
that since the certificate is always generated by an existing RSA key pair
I assumed this way I'm saving computational overhead related to DH and
maybe EC operations. Do you think this is logical?
0 new messages