[bpo-28414] Make all hostnames in SSL module IDN A-labels#5128
Conversation
134072e to
eacb9e9
Compare
January 7, 2018 15:42
eacb9e9 to
9bd40df
Compare
January 7, 2018 16:06
|
I did a quick skim and the code seems fine to me, but... I do think that for
|
Sorry, something went wrong.
9bd40df to
31b862e
Compare
January 13, 2018 19:19
|
Meh! :( Let's make it PEP 543 compatible and add |
Sorry, something went wrong.
31b862e to
0b512f1
Compare
January 14, 2018 00:18
0b512f1 to
428265e
Compare
January 20, 2018 14:23
428265e to
5ec02e4
Compare
January 28, 2018 19:50
Historically, our handling of international domain names (IDNs) in the
ssl module has been very broken. The flow went like:
1. User passes server_hostname= to the SSLSocket/SSLObject
constructor. This gets normalized to an A-label by using the
PyArg_Parse "et" mode: bytes objects get passed through
unchanged (assumed to already be A-labels); str objects get run
through .encode("idna") to convert them into A-labels.
2. newPySSLSocket takes this A-label, and for some reason decodes
it *back* to a U-label, and stores that as the object's
server_hostname attribute.
3. Later, this U-label server_hostname attribute gets passed to
match_hostname, to compare against the hostname seen in the
certificate. But certificates contain A-labels, and match_hostname
expects to be passed an A-label, so this doesn't work at all.
This PR fixes the problem by removing the pointless decoding at step
2, so that internally we always use A-labels, which matches how
internet protocols are designed in general: A-labels are used
everywhere internally and on-the-wire, and U-labels are basically just
for user interfaces.
This also matches the general advice to handle encoding/decoding once
at the edges, though for backwards-compatibility we continue to use
'str' objects to store A-labels, even though they're now always
ASCII. Technically there is a minor compatibility break here: if a
user examines the .server_hostname attribute of an ssl-wrapped socket,
then previously they would have seen a U-label like "pythön.org", and
now they'll see an A-label like "xn--pythn-mua.org". But this only
affects non-ASCII domain names, which have never worked in the first
place, so it seems unlikely that anyone is relying on the old
behavior.
This PR also adds an end-to-end test for IDN hostname
validation. Previously there were no tests for this functionality.
Fixes bpo-28414.
All test certs must be generated by CPython's own test helper. Signed-off-by: Christian Heimes <christian@python.org>
Signed-off-by: Christian Heimes <christian@python.org>
5ec02e4 to
1ec0678
Compare
February 22, 2018 18:19
njsmith
left a comment
There was a problem hiding this comment.
I pushed some prose changes, and here are some comments on the code. Overall looks good, but there are a few small cleanups to consider, and a few points where I have questions.
Sorry, something went wrong.
Drop extra code for PEP 543 future compatibility in sni callback Use callable() and encode_hostname in shim for old SNI callback. Signed-off-by: Christian Heimes <christian@python.org>
|
The context special handling is pining for the fjords. |
Sorry, something went wrong.
) Previously, the ssl module stored international domain names (IDNs) as U-labels. This is problematic for a number of reasons -- for example, it made it impossible for users to use a different version of IDNA than the one built into Python. After this change, we always convert to A-labels as soon as possible, and use them for all internal processing. In particular, server_hostname attribute is now an A-label, and on the server side there's a new sni_callback that receives the SNI servername as an A-label rather than a U-label. (cherry picked from commit 11a1493) Co-authored-by: Christian Heimes <christian@python.org>
…H-5843) Previously, the ssl module stored international domain names (IDNs) as U-labels. This is problematic for a number of reasons -- for example, it made it impossible for users to use a different version of IDNA than the one built into Python. After this change, we always convert to A-labels as soon as possible, and use them for all internal processing. In particular, server_hostname attribute is now an A-label, and on the server side there's a new sni_callback that receives the SNI servername as an A-label rather than a U-label. (cherry picked from commit 11a1493) Co-authored-by: Christian Heimes <christian@python.org>
|
Why are there no tests for the new function name, the tests in the stdlib all refer to |
Sorry, something went wrong.
Alternative approach to PR #3010
https://bugs.python.org/issue28414