-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
gh-96931: Fix incorrect results in ssl.SSLSocket.shared_ciphers #96932
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…pythonGH-96932) (cherry picked from commit af9c34f) Co-authored-by: Benjamin Fogle <benfogle@gmail.com>
GH-102918 is a backport of this pull request to the 3.11 branch. |
…pythonGH-96932) (cherry picked from commit af9c34f) Co-authored-by: Benjamin Fogle <benfogle@gmail.com>
GH-102919 is a backport of this pull request to the 3.10 branch. |
FWIW, I would suggest you all just deprecate this method. I've never seen anything use this method across Google (other than First, the meaning of this method seems also to have been lost over time. And this PR in particular seems to run into an ambiguous meaning of the word "shared". :-) Client cipher list Looking back, this seems to date to 4cb1781, which aimed to fix #67375. Interestingly, #67375 (comment) talks about seeing the complete client list, not the list intersected with the server list. I.e. It was implemented by reading Configured cipher list Then 598894f ported to OpenSSL 1.1.0. However, in doing so, it switched to Intersected cipher list Then we have this PR, which switches it to yet another interpretation, the intersection between client and server ciphers. I think the root mixup is "list of ciphers shared by the client" here did not mean "the ciphers which you and the client share". It meant "the list of ciphers that the client shared with you"! What to do So, which meaning do you take? Now, I think of the three behaviors this function has had over the years, the intersected is the most useless. I've done TLS things my whole career, and I cannot imagine a scenario where you'd want this, apart from cipher negotiation. But cipher negotiation is done in OpenSSL anyway. By the time Python gets a pop at it, only the final cipher matters. You could switch to More importantly, having this method cements a memory cost to the whole open source ecosystem. The problem with returning either the client cipher list (as a server) or the intersected cipher list is that merely offering this API implies you retain that cipher list for the duration of a connection. Per-connection memory on a server with many, many connections is precious, and there's really no reason to retain this list after the handshake. (Of course, whether you all use that function, OpenSSL retains the list in memory anyway, so it won't actually help you. But I don't think OpenSSL should retain the memory either, and removing the method at least removes Python from the list of reasons why OpenSSL needs to do this. 😄 And if you ever change your TLS strategy, this method will constrain you here.) Context: I came across this because @Yhg1s pointed me at an incompatibility between this patch and BoringSSL. In BoringSSL, to reduce per-connection memory, we never added |
shared_ciphers
implementation.SSL_get_client_ciphers
, though from the rest of the description and the test, this is not what was intended.