Ignore cipher suites when setting cipher list#7759
Ignore cipher suites when setting cipher list#7759sam-github wants to merge 2 commits intoopenssl:masterfrom sam-github:independent-cipher-list-count
Conversation
tmshort
left a comment
There was a problem hiding this comment.
There's a general requirement to follow the coding/formatting standards.
|
Made all changes suggested. There is one failing test, ./test/recipes/80-test_ssl_old.t, but I haven't been able to figure out how to run it standalone to see where its failing: How do I run the .t tests? |
|
Try |
|
Is this enough code that I need to sign a CLA? If it is, I need to get our lawyer's OK :-(. They will OK it, I just need to get the process moving. If I don't need a CLA, I won't bother them. |
|
Thanks for #7759 (comment), I fixed the tests, PTAL. |
|
I'm not on the OMC, but this was tagged with need-cla, so I think you need to go through the process... |
|
All non-trivial contributions need a CCLA and ICLA on file (in general) so getting that sorted out is a prerequisite for progressing. This contribution is non-trivial. |
|
Kicked CLA process into gear. Looks like it will be rubber stamped. |
|
CLA signed and emailed. |
|
All green! @mattcaswell I made all your requested changes. |
|
Placing this temporarily on hold while we sort out a CLA issue. |
|
Removed the "hold" - the CLA issues are now resolved. @sam-github - please could you update your commits to show your ibm email as the author and then force push? |
|
OK, renamed the counting function, changed to |
|
Another thought I had on this: with TLSv1.3 it may be intentional to set the TLSv1.2 ciphersuites to be empty (e.g. if you never plan to negotiation TLSv1.2). With the implementation as it currently is that's (sort of) fine - you can do that, but you do still get an error return - even though what you were trying to do "worked" (the TLSv1.2 ciphersuites are set to the empty list). It's kind of weird that this function still changes the cipher list to empty even while signalling an error - normally if a function returns an error you expect no change to have been made (but that's the way it has always worked I guess). Perhaps there should be some discussion of this in the docs? This also introduces a problem with the "ciphers" command line application. Say you only want to see the TLSv1.3 ciphersuites. So you might think the following would work (and it did in 1.1.1/1.1.1a) - but it doesn't after this PR. Before the PR: After the PR: |
|
I think there are two seperate issues here:
Some thoughts, no particular order.
I don't understand why clearing cipher_list or ciphersuites should not be an error, but there is no specific api to do either now, unless you count It surprised me that I'd expect that to empty the ciphersuites. " An empty list is permissible." (docs) doesn't really say what an empty list looks like.
Current behaviour. Kindof odd that ":" is not a cipher list error in the first case, but is in the second. This PR makes a cipher list of Stepping back, I'm not sure why set_ciphersuites() was created for TLSv1.3 only. The docs state it as fact, but don't give rationale. Is it because set_cipher_list has a complex legacy string format, and you didn't want to change anything about its behaviour? That would make sense, but I don't understand why set_ciphersuites can't be used with TLSv1.2 and below ciphers -- of course, not with magic characters, but only containing full, exact, cipher suite names, in preference order, as it does for TLSv1.3. Equivalently, I'm not sure why |
|
OK, I found #5359 Summary: it was desired that TLSv1.3 suites not be disabled except very intentionally. I think the splitting was incomplete, since they are all going in the same list, set_cipher_list() is counting TLSv1.3 suites. I suggest openssl 1.2 should make set_cipher_list and set_ciphersuites behave more similarly:
|
I'm wondering if there is any reason why we can't make these three changes now (in master and 1.1.1)? The first one definitely shouldn't break anything. The second I suppose could in theory...but it seems unlikely. I'm also struggling to think of a usage scenario that the third change would break. |
|
I'd be in favour of just fixing this issue as noted - i.e. correctly "empty" string handling inconsistencies. |
I'm not really sure what you mean by that. There are a number of inconsistencies here around empty string handling. This PR fixes one, but introduces more around the output of the "ciphers" command. |
|
I was responding to "I'm wondering if there is any reason why we can't make these three changes now (in master and 1.1.1)?" |
|
Introducing error return with side-effect would be very ugly. I do not think this PR makes much sense without actually doing all the three mentioned changes. |
|
@t8m did someone propose introducing error-return-with-side-effect? I think everything @mattcaswell or I suggested does the opposite. @mattcaswell Backwards compatibility in the face of change is hard to gauge, you know your user base, but for example I was testing yesterday and found #2801 broke https://github.com/mkg20001/ursa/blob/0999dcf62cced5102913f925cb4fcfabdd480dfb/test/native.js#L688. I would call this unnecessary reliance on OpenSSL internals, but someone else might call it an API incompatibility.
Your example!
|
Make OpenSSL 1.1.1 error during cipher list setting if it would have errored with OpenSSL 1.1.0. Can be dropped after our OpenSSL fixes this upstream. See: openssl/openssl#7759
Make OpenSSL 1.1.1 error during cipher list setting if it would have errored with OpenSSL 1.1.0. Can be dropped after our OpenSSL fixes this upstream. See: openssl/openssl#7759
Make OpenSSL 1.1.1 error during cipher list setting if it would have errored with OpenSSL 1.1.0. Can be dropped after our OpenSSL fixes this upstream. See: openssl/openssl#7759 PR-URL: #25381 Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Shigeki Ohtsu <[email protected]>
Make OpenSSL 1.1.1 error during cipher list setting if it would have errored with OpenSSL 1.1.0. Can be dropped after our OpenSSL fixes this upstream. See: openssl/openssl#7759 PR-URL: nodejs#25381 Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Shigeki Ohtsu <[email protected]>
|
See also issue #7196, which was the previous round of folks being affected by this. I agree with @sam-github that this is the more compatible change. In OpenSSL 1.1.0, callers could check the result of These sorts of things do require judgement calls, but, with the benefit of hindsight and now several known affected projects, I think it's clear this PR is the more compatible decision. As another data point, this PR is closer to the strategy BoringSSL took. We preserve the fact that |
|
(Specifically #7196 (comment), which suggested the behavior as this PR, though with a different implementation.) |
test/ssltest_old.c
Outdated
There was a problem hiding this comment.
Really we should do this after each call to SSL_CTX_set_cipher_list above, i.e. each one of them should create an error - but we only check once at the end.
Make OpenSSL 1.1.1 error during cipher list setting if it would have errored with OpenSSL 1.1.0. Can be dropped after our OpenSSL fixes this upstream. See: openssl/openssl#7759 PR-URL: #25381 Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Shigeki Ohtsu <[email protected]> Backport-PR-URL: #25688
|
@sam-github what is the status of this PR? |
|
@mattcaswell I'm not sure, the conversation seemed to suggest that instead of this, much more wide spread changes were wanted. If that's not the case, and its agreed that this is on its way to landing, I'll keep working on the tests. Aside: I worked around the backwards incompatibility in node.js by always calling set_ciphersuites: |
|
IMO this change should proceed. |
|
I'll address your comments tomorrow @mattcaswell |
set_cipher_list() sets TLSv1.2 (and below) ciphers, and its success or failure should not depend on whether set_ciphersuites() has been used to setup TLSv1.3 ciphers.
|
@mattcaswell please take a look |
mattcaswell
left a comment
There was a problem hiding this comment.
Approved. Ping @openssl/committers for second review
| result = 1; | ||
| end: | ||
| SSL_free(s); | ||
| tear_down(fixture); |
There was a problem hiding this comment.
It's unclear that we really need the properties of the fixture setup instead of just an SSL_CTX and an SSL off of it. But it's not really harmful to use it as-is...
set_cipher_list() sets TLSv1.2 (and below) ciphers, and its success or failure should not depend on whether set_ciphersuites() has been used to setup TLSv1.3 ciphers. Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Ben Kaduk <[email protected]> Reviewed-by: Matt Caswell <[email protected]> (Merged from #7759) (cherry picked from commit 3c83c5b)
|
Pushed. Thanks. |
set_cipher_list() sets TLSv1.2 (and below) ciphers, and its success or failure should not depend on whether set_ciphersuites() has been used to setup TLSv1.3 ciphers. Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Ben Kaduk <[email protected]> Reviewed-by: Matt Caswell <[email protected]> (Merged from #7759)
set_cipher_list() sets TLSv1.2 (and below) ciphers, and its success or
failure should not depend on whether set_ciphersuites() has been used to
setup TLSv1.3 ciphers.
Checklist
This is a fix for an issue I posted about on the mailing list.
Currently proposed Node.js workaround and discussion.
So what is happening is happening is that while there are two APIs,
SSL_CTX_set_ciphersuites()(TLSv1.3) and
SSL_CTX_set_cipher_list()(<=TLSv1.2), they both put cipher suites into
SSL_CTX.cipher_list.
This basically makes the cipher_list error check:
bogus, because even when there were, in fact zero TLSv1.2 cipher
suites configured, the check for cipher suite number will find the
number greater than zero if there are TLSv1.3 cipher suites in the
list. Which there will be, by default. The actual behaviour of this
check depends on the order in which set_ciphersuites() and
set_cipher_list() are called, a fact I can exploit to make the API
backwards compatible for Node.js.
I will call SSL_CTX_set_ciphersuites(ctx,"") just before calling
set_cipher_list(). This will clear out the TLSv1.3 suites (we don't
support 1.3 yet). Since the 1.3 suites are gone, the check for a
length of zero causing NO_CIPHER_MATCH will now behave as it would be
expected.
This won't work in the future.
I think what really should be done is that the check for _num(sk) == 0
needs to be rewritten, to iterate the list, and find the number of
TLSv1.2 and below ciphers, and return NO_CIPHER_MATCH if that number
is zero.