Red Hat Bugzilla – Bug 1497859
Document forwards incompatibility of SSL_OP_NO_TLSv1_1 flag between openssl-1.0.0 and openssl-1.0.1. Document runtime behavior of SSLeay() function.
Last modified: 2018-03-16 06:23:53 EDT
Description of problem: (This is somewhat related to https://bugzilla.redhat.com/show_bug.cgi?id=1301301, but a little different) I work on a project where we use OpenSSL by dynamically linking against it. We recently noticed an issue, where the SSLeay() function does not return the version of the OpenSSL library it's linked against, but rather returns the version that it was compiled against. We used a small test program to verify this as well: `#include <openssl/ssl.h> int main() { unsigned long ssl_version; ssl_version = SSLeay(); printf("Compiled with: %lx (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT); printf("Running with: %lx (%s)\n", ssl_version, SSLeay_version(SSLEAY_VERSION)); return 0; }` We built this on a RHEL6.4 machine which contains "OpenSSL 1.0.0-fips 29 Mar 2010". And we ran it on a RHEL6.7 machine which contains "OpenSSL 1.0.1e-fips 11 Feb 2013". We get: Compiled with: 10000003 (OpenSSL 1.0.0-fips 29 Mar 2010) Running with: 10000003 (OpenSSL 1.0.0-fips 29 Mar 2010) When we compile and run it on the same RHEL6.7 machine, we get: Compiled with: 1000105f (OpenSSL 1.0.1e-fips 11 Feb 2013) Running with: 1000105f (OpenSSL 1.0.1e-fips 11 Feb 2013) When we compile it on RHEL6.7 and run it on RHEL6.4, we get: Compiled with: 1000105f (OpenSSL 1.0.1e-fips 11 Feb 2013) Running with: 10000003 (OpenSSL 1.0.0-fips 29 Mar 2010) So it looks like compiling against a newer version and running against an older version is fine, but not the other way round. Under GDB I noticed that there are 2 definitions of SSLeay() in the same dynamically linked libcrypto.so: (gdb) disas 0x000000384906bfd0 Dump of assembler code for function SSLeay: 0x000000384906bfd0 <+0>: mov $0x1000105f,%eax 0x000000384906bfd5 <+5>: retq (gdb) disas Dump of assembler code for function SSLeay: => 0x000000384906bfc0 <+0>: mov $0x10000003,%eax 0x000000384906bfc5 <+5>: retq Which is confusing to me, why would it have a hardcoded version of a specific older OpenSSL version in the SO? Unless I'm grossly misunderstanding something. So, my question is, is this a bug in OpenSSL? Or are we not supposed to be building against an older OpenSSL and running against a newer version? Version-Release number of selected component (if applicable): OpenSSL 1.0.1e How reproducible: Always Steps to Reproduce: 1. Compile binary against OpenSSL 1.0.0 2. Run same binary on system with OpenSSL 1.0.1 Actual results: Compiled with: 10000003 (OpenSSL 1.0.0-fips 29 Mar 2010) Running with: 10000003 (OpenSSL 1.0.0-fips 29 Mar 2010) Expected results: Compiled with: 10000003 (OpenSSL 1.0.0-fips 29 Mar 2010) Running with: 1000105f (OpenSSL 1.0.1e-fips 11 Feb 2013) Additional info:
This is done on purpose. Some applications perform incorrect (too sensitive) version check and the only way to avoid it is to mask the actual run-time version of OpenSSL built against an old OpenSSL release. You need to build against the oldest OpenSSL version with which you need your software to run. So if your intention is to be able to run the software with RHEL-6.4 then you must also build it on this RHEL release. You should be able to run it with any newer RHEL-6 version as well. But of course you cannot use new features of the newer OpenSSL version except these that do not require any new API call.
Thanks for your response Tomas. I just have a follow up question. Isn't that breaking the expectations of SSLeay() ? And is this behavior documented anywhere? The OpenSSL documentation specifies that this function call would return the version information of the library that it's linked against and our application was built with that expectation.
It is not documented, it should be transparent to applications. In what exact way it is breaking your application?
Some of our build machines are on CentOS 6.4 with OpenSSL 1.0.0, but some of our users run on CentOS6.7 which has OpenSSL 1.0.1e. We also let the users choose their TLS versions. We have some runtime checks with SSLeay() to make sure that the version of TLS they selected is supported on that system. Eg: If they select TLSv1.2, and have only OpenSSL 1.0.0 on their system, we return an error. We have to do this runtime check because of the following OpenSSL API breakage bug: "When disabling, say, TLS1.1 we pass an option bitmask to SSL_CTX_set_options() that includes SSL_OP_NO_TLSv1_1. In OpenSSL 1.0.1 this is defined as 0x10000000L but in 1.0.0 it is not defined. However, in OpenSSL 1.0.0 *another* option for SSL_CTX_set_options() has the *same* value (0x10000000L). This means that passing SSL_OP_NO_TLSv1_1 to OpenSSL 1.0.0 actually does something completely different. This lack of backwards compatibility is the bug." So, now even though we are running on a system which has OpenSSL 1.0.1e, SSLeay() returns the version number as 1.0.0, so it's not really transparent to applications. According to the documentation, it should return OpenSSL 1.0.1e when invoked on a system with OpenSSL 1.0.1e, right? This problem doesn't exist on newer OpenSSL versions, i.e. 1.0.2 and up according to the OpenSSL guys. Thanks for your time.
Hmm, you're right with the backwards (or rather forwards) compatibility issue in regards to the SSL_OP_NO_TLSv1_1 flag. This is an unfortunate thing but I am afraid we cannot fix that at this point. The only thing I can suggest to you is to find out another way how to detect that you're running against OpenSSL 1.0.1 and not 1.0.0 - you could for example use SSL_get_ciphers() to obtain the list of enabled ciphers and try to find a TLS1.2 cipher in that list by parsing SSL_CIPHER_description() output.
Thanks for the suggestion, that seems like it would work. I'll try that moving forward. Also, could we mark this as a known issue?
We can persuade that.
Hi all, Thank you very much for your input. I have added this known issue to RHEL 6.9 Release Notes: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/6.9_release_notes/known_issues_security Also, I will make sure it is repeated in the Release Notes for the next minor version.