WIP: Mitigate regression errors when linking older apps with libssl 1.1.1#5945
WIP: Mitigate regression errors when linking older apps with libssl 1.1.1#5945levitte wants to merge 4 commits intoopenssl:masterfrom
Conversation
I'm wondering whether we could use symbol versioning to do this same thing? It wouldn't work on platforms without symbol versioning though. |
|
This requires a special-built 1.1.1 library which seems to defeat the purpose. Can this library be used for both 1.3 and earlier protocol versions? I think that simply not enabling 1.3 by default is much easier to understand. |
Uhmmm, no, no special building should be required. If you're thinking about |
mattcaswell
left a comment
There was a problem hiding this comment.
It would need some documentation and probably a FAQ entry
ssl/ssl_lib.c
Outdated
There was a problem hiding this comment.
I can't say I'm massively fond of this name. What happens when we have 1.1.2 or 1.1.3...or...
Maybe SSL_CTX_new_ex()?
There was a problem hiding this comment.
why not SSL_CTX_new_ex?
it is not yet specified which paramters it will have.
There was a problem hiding this comment.
Exactly because of that, and because I see this as an interim solution that should disappear with 1.2.0 at the latest.
We could, but as you said, this isn't universally available, so we'll get the pleasure of maintaining two ways of doing this instead of just one. I'm not at all keen to do this. |
No. The same library would be able to support pre-1.1.1 apps and 1.1.1 apps. If an app was compiled against 1.1.0 headers but run against the 1.1.1 library then it will get a maximum of TLSv1.2. Apps compiled against the 1.1.1 headers would get TLSv1.3 by default unless you build the app with |
include/openssl/ssl.h
Outdated
There was a problem hiding this comment.
Is that a lower case v? Seems not quite right when everything else is in caps.
There was a problem hiding this comment.
You originally suggested DISABLE_TLSv13, with lower case v. However, considering all other macros, this should really be OPENSSL_DISABLE_TLS1_3, should it not?
There was a problem hiding this comment.
Oh right...well that was just an example :-)
Yes, dropping the "v" seems best.
|
I like this idea because it removes a significant barrier to upgrading without removing TLSv1.3 being on-by-default. |
|
So how about the internal API being called like this: That seems more general purpose and future-proof. min or max can be "0" to mean lowest or highest supported by the library. And for 1.1.1 the highest should be explicitly set to 1.3 And, of course, that function needs to be documented. |
I was thinking about that myself, but actually I think it would be wrong to encourage people to hard code a maximum protocol version into their apps. |
But maybe some of the other params you suggest would be ok. |
|
It would not be wrong. There are special-cases where someone wants fine-grain control over which protocol version. The implementation is trivial In other words, we provide functions to allow is. This just makes it more convenient. |
|
+1 to Rich's proposal. |
|
I was thinking that this would be an interim solution. With OpenSSL 1.2.0, How often would you expect that people would call |
Agreed. I still think we should avoid version specific names These things have a tendency to stick around even when we don't plan them to. We should probably have a comment in the header saying something like "don't use this directly - always call SSL_CTX". Unless that is we go with Rich's proposal. |
|
I think the new I also know that in my $DAYJOB we have many customers who want us to limit what versions we support. |
|
I would like that this not get approved until we have more discussion. For example, I feel strongly that the full "ex" API is the way to go. |
Sure. Either way, I would say that the regression situation is a release show stopper. (I'll note, btw, that this simple move greatly improves the tests that failed in #5661. Not entirely, but quite a lot) |
PR #3761 is the fix for #2397, and it defines SSL_CTX_new_ex() That being said, there are ways to tag inputs to allow the number of inputs to expand without redefining the function each time (kinda like named arguments, but in C): Edit: include a type in the argument type, so that unknown arguments can be ignored |
Applications that were built for libssl 1.1.0 will most probably get into trouble when re-linked against libssl 1.1.1. This is especially serious when re-linking happens due to a shared library upgrade. We try to mitigate against this with a sneaky trick, where re-linked application will simply not have access to TLSv1.3, while programs that are re-compiled will, through a macro that redirects a call to SSL_CTX_new() to SSL_CTX_new_111(). For applications where access to TLSv1.3 is undesirable (because it requires some source code changes), it can still be disabled by defining the macro OPENSSL_DISABLE_TLSv13 when building it. Fixes openssl#5944
9a9d1aa to
db692e8
Compare
|
Too late for now, but knowing in a library initialization function, what version the application was compiled with, might be useful. |
|
That would require cooperation from the application, or exactly the kind of hackery this PR does... |
tmshort
left a comment
There was a problem hiding this comment.
Maybe something like:
__owur SSL_CTX *SSL_CTX_new_ver(const SSL_METHOD *meth, int ver);
# define SSL_CTX_new(meth) SSL_CTX_new_ver(meth, OPENSSL_VERSION_NUMBER)
Then it's something that could be kept for future use?
|
Ah, you meant like that... That could be made part of this PR. I assume, btw, that the version passed to /* Users should never call this function directly */
__owur SSL_CTX *SSL_CTX_new_ver(const SSL_METHOD *meth, int ver);
/* OPENSSL_DISABLE_TLSV1_3 is optional, defined by the user when building their programs */
#ifdef OPENSSL_DISABLE_TLS1_3
/*
* TLSv1.3 is new in version 1.1.1, and behaves differently than earlier TLS versions.
* When the user disables it to be able to compile older programs without having to
* change them, we simply pretend that they build for a pre-1.1.1 version, i.e. 1.1.0
*/
# define SSL_CTX_new(meth) SSL_CTX_new_ver((meth), 0x10100000UL)
#else
# define SSL_CTX_new(meth) SSL_CTX_new_ver((meth), OPENSSL_VERSION_NUMBER)
#endif |
| /* | ||
| * With TLSv1.3 enabled, we make sure that apps linked against the shared | ||
| * libraries of earlier OpenSSL versions don't get it by mistake, as TLSv1.3 | ||
| * is different enough to be able to cause faults for the unknowing. |
There was a problem hiding this comment.
Is this actually true? Is common 1.1.0 application bound to fail if library negotiates TLS 1.3? At least 1.1.0 s_client and s_server don't. And if they don't, then why would we want to deny them the option to use the protocol? I'd say opposite is more natural. Indeed, they concentrate on application logic and we concentrate on transport mechanism. If anything, we should facilitate use on new protocol with old applications.
There was a problem hiding this comment.
I've been trying to ask @mattcaswell if there's a subset of functionality that still works, and I keep getting the answer back that TLSv1.3 works differently. I take that as there not being any guarantee, and that it's pure luck that s_client and s_server work when no extra options are added (have you tried with different options? How long before it fails surprisingly?)
One of the test programs that I've been worried about is test/sslapitest. After all, it tests the behaviour of the SSL API! I'm thinking that if that one fails (i.e. that one from 1.1.0 linked with 1.1.1 libraries), we do have a regression problem.
There was a problem hiding this comment.
This is, btw, a discussion that could happen in #5944
There was a problem hiding this comment.
Ahm, do you mean when a program is just re-compiled then it will fail in a surprising way?
There was a problem hiding this comment.
I keep getting the answer back that TLSv1.3 works differently.
It does work differently. That doesn't mean that all applications will start failing. Quite the opposite. I expect most applications to work without noticing TLSv1.3. However, there are certain scenarios where unexpected things might start happening. Some examples:
- if you expect your session to have been created during the handshake then you're going to be disappointed (it happens post-handshake). This means some callbacks could happen when an application isn't expecting them.
- If you're expecting a particular ciphersuite to be negotiated (because you disabled others) then that might not happen because TLSv1.3 ciphersuite configuration happens differently. This could actually cause an application to fail in some circumstances.
- If your application is using custom extensions you might suddenly find them not being used when they always were before because they are not compatible with TLSv1.3
- etc
There's probably a whole load of other things. Most of these problems are edge cases. What we don't know is what kind of proportion of applications will fall foul of them.
There was a problem hiding this comment.
I'd like to repeat the suggestion that libssl could look at certain facts (sigalgs derived from server certs, ciphersuites, whatever else that's possible to check) and adapt the range of TLS versions to be negotiated. For example, is s_server is started with a DSA server certificate, TLSv1.2 would be the newest version negotiated, rather than selecting TLSv1.3 and then generating an error because the sigalg doesn't fit...
|
Why do you keep using |
|
|
I'd like to suggest that we put this PR on hold until we determine whether any of this is necessary. |
|
The discussion on openssl-project concluded that the solution in this PR isn't the right move, so I'm closing this. Further technical discussions should happen in #5944. |
Applications that were built for libssl 1.1.0 will most probably get
into trouble when re-linked against libssl 1.1.1. This is especially
serious when re-linking happens due to a shared library upgrade.
We try to mitigate against this with a sneaky trick, where re-linked
application will simply not have access to TLSv1.3, while programs
that are re-compiled will, through a macro that redirects a call to
SSL_CTX_new() to SSL_CTX_new_111(). For applications where access to
TLSv1.3 is undesirable (because it requires some source code changes),
it can still be disabled by defining the macro OPENSSL_DISABLE_TLSv13
when building it.
Fixes #5944, #5661