Project

General

Profile

Bug #7215

Remaining messages on OpenSSL error queue after Certificate#verify

Added by Lars Kanis about 4 years ago. Updated 7 months ago.

Status:
Closed
Priority:
Normal
Assignee:
openssl
ruby -v:
ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux]
Backport:
[ruby-core:48284]

Description

While investigating a ruby-pg issue [1], we noticed that a SSL connection with PostgreSQL can fail, after a call to OpenSSL::X509::Certificate#verify with result 'false'. Root cause is the thread local error queue of OpenSSL, that is used to transmit textual error messages to the application after a failed crypto operation. A failure in Certificate#verify leaves some messages on the error queue, which can lead to errors in a SSL communication of other parts of the application.

According to the comment on OpenSSL.errors [2], remaining messages on the error queue are probably due to a bug. So the queue should become somehow cleared. I currently see these variants:

  • Return the OpenSSL error list in Certificate#verify instead of true/false - This will change the API in an incompatible way, so it will probably be no real option.
  • Drop the error list at the end of Certificate#verify - So there will be no way to get the particular error text. Maybe add another method in the way as 1.
  • Add a note in the documentation that suggest the user should call OpenSSL.errors after a failed call to Certificate#verify.

A patch for the postgresql side of the issue is already inserted into the patch list for the next commit fest [3].

[1] https://bitbucket.org/ged/ruby-pg/issue/142/async_exec-over-ssl-connection-can-fail-on
[2] https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L349
[3] https://commitfest.postgresql.org/action/patch_view?id=961

Associated revisions

Revision 55051
Added by rhe 7 months ago

openssl: clear OpenSSL error queue before return to Ruby

  • ext/openssl/ossl_x509cert.c (ossl_x509_verify): X509_verify()
    family may put errors on 0 return (0 means verification failure).
    Clear OpenSSL error queue before return to Ruby. Since the queue is
    thread global, remaining errors in the queue can cause an unexpected
    error in the next OpenSSL operation. [Bug #7215]

  • ext/openssl/ossl_x509crl.c (ossl_x509crl_verify): ditto.

  • ext/openssl/ossl_x509req.c (ossl_x509req_verify): ditto.

  • ext/openssl/ossl_x509store.c (ossl_x509stctx_verify): ditto.

  • ext/openssl/ossl_pkey_dh.c (dh_generate): clear the OpenSSL error
    queue before re-raising exception.

  • ext/openssl/ossl_pkey_dsa.c (dsa_generate): ditto.

  • ext/openssl/ossl_pkey_rsa.c (rsa_generate): ditto.

  • ext/openssl/ossl_ssl.c (ossl_start_ssl): ditto.

  • test/openssl: check that OpenSSL.errors is empty every time after
    running a test case.

History

#1 [ruby-core:48285] Updated by Martin Bosslet about 4 years ago

  • Assignee set to Martin Bosslet
  • Status changed from Open to Assigned

#2 [ruby-core:51450] Updated by Maciek Sakrejda almost 4 years ago

Hi,

Any progress on this? Postgres has rejected the patch that was submitted on the grounds that this is an OpenSSL client issue and libpq has no business clearing the error queue.

It seems like clearing the error queue but giving some side channel to access the errors from the last Certifivate#verify call would still make the errors available for interested clients, without forcing a byzantine API requiring a separate step to clear the error queue (something that would likely be missed by many clients).

Thanks!

#3 [ruby-core:63796] Updated by Vladimir Krylov over 2 years ago

Any changes here? Can confirm that problem persists in newer versions of ruby (i.e. 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux] and 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]).

#4 [ruby-core:65816] Updated by Nicolae Rotaru about 2 years ago

the only solution at the moment is running :

OpenSSL.errors.clear

after certificate verifying. This clears OpenSSL errors array and keeps database connection alive.

#5 Updated by Zachary Scott about 1 year ago

  • Assignee changed from Martin Bosslet to openssl

#6 Updated by Anonymous 7 months ago

  • Status changed from Assigned to Closed

Applied in changeset r55051.


openssl: clear OpenSSL error queue before return to Ruby

  • ext/openssl/ossl_x509cert.c (ossl_x509_verify): X509_verify()
    family may put errors on 0 return (0 means verification failure).
    Clear OpenSSL error queue before return to Ruby. Since the queue is
    thread global, remaining errors in the queue can cause an unexpected
    error in the next OpenSSL operation. [Bug #7215]

  • ext/openssl/ossl_x509crl.c (ossl_x509crl_verify): ditto.

  • ext/openssl/ossl_x509req.c (ossl_x509req_verify): ditto.

  • ext/openssl/ossl_x509store.c (ossl_x509stctx_verify): ditto.

  • ext/openssl/ossl_pkey_dh.c (dh_generate): clear the OpenSSL error
    queue before re-raising exception.

  • ext/openssl/ossl_pkey_dsa.c (dsa_generate): ditto.

  • ext/openssl/ossl_pkey_rsa.c (rsa_generate): ditto.

  • ext/openssl/ossl_ssl.c (ossl_start_ssl): ditto.

  • test/openssl: check that OpenSSL.errors is empty every time after
    running a test case.

Also available in: Atom PDF