[issue32813] SSL shared_ciphers implementation wrong - returns configured but not shared ciphers
New submission from Steffen Ullrich : The current implementation of shared_ciphers uses the SSL_get_ciphers method. This method returns the list of configured ciphers (i.e. from the context) and not the list of ciphers shared between client and server. To get this list one can use the documented SSL_get_client_ciphers for OpenSSL >= 1.1.0, access ssl->sessions->ciphers directly or parse the result from the undocumented SSL_get_shared_ciphers for older versions of OpenSSL. See also https://stackoverflow.com/questions/48717497/python-ssl-shared-ciphers-not-as-documented/48718081#48718081 -- messages: 311940 nosy: noxxi priority: normal severity: normal status: open title: SSL shared_ciphers implementation wrong - returns configured but not shared ciphers type: behavior versions: Python 3.5, Python 3.6, Python 3.7, Python 3.8 ___ Python tracker <https://bugs.python.org/issue32813> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue32813] SSL shared_ciphers implementation wrong - returns configured but not shared ciphers
Steffen Ullrich added the comment: Actually, it looks like that neither SSL_get_shared ciphers nor SSL_get_client_ciphers nor accessing ssl->session->ciphers nor SSL_get_ciphers return the **shared** ciphers. The first three seem to return the ciphers offered by the client and the last one returns the ciphers set for the server. It looks like even the OpenSSL developers do not really know what they are doing. The same contents of ssl->session->ciphers is made available through the functions SSL_get_shared_ciphers and SSL_get_client_ciphers which based on the names should return different information. And, the ciphers member of the ssl_session_st structure is documented in for the newest and even the oldest versions (i.e. like 0.9.8) as: STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ In other words: the developers are not sure themselves if this contains the shared ciphers or not (and it does not, at least in OpenSSL 1.0.2 and OpenSSL 1.1.0). In other words: I doubt that there is a documented way to get the actually shared ciphers. One need probably to reimplement parts of the internal ssl3_choose_cipher function since this is the place where cipher_list and session->ciphers gets combined with various other restrictions (i.e. like type of certificate) to get the shared and thus the final cipher. -- ___ Python tracker <https://bugs.python.org/issue32813> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue32813] SSL shared_ciphers implementation wrong - returns configured but not shared ciphers
Steffen Ullrich added the comment: It looks like the function shared_ciphers actually returned the list of client ciphers when initially implemented although I think that the name is misleading and suggests that it would return the ciphers shared between client and server (i.e. same meaning of shared as in the infamous "no shared cipher" SSL handshake problem). Anyway, it looks like the original functionality was broken while adding support for OpenSSL 1.1.0 "Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0.". The relevant part of this change: https://github.com/python/cpython/commit/598894ff48e9c1171cb2ec1c798235826a75c7e0#diff-e1cc5bf74055e388cda128367a814c8fR1534 -- ___ Python tracker <https://bugs.python.org/issue32813> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21430] Document ssl.pending()
Steffen Ullrich added the comment: Data transport in SSL is not done with plain TCP, but with encoded frames inside TCP. To get decoded data one has to first receive the full frame, even if one is only interested in the first bytes. Example: - server does an SSL_write with 200 bytes. This will result in a frame which contain all the 200 bytes. - if the client does a SSL_read (e.g. recv) to get 100 bytes the underlying SSL stack will read the full frame, but return only 100 bytes of the 200 bytes. - if the client then would call select to check if more data are available this would fail, because select checks the data on the socket only. But pending would return that there are still 100 bytes available for read in the SSL stack. So to make use of select with SSL the application would have to check first with pending, if there are already buffered data, and only if there are no buffered data it should call select to check if there are data on the socket. But, one could skip the call of pending if all SSL_read (recv) are at least 16k, because this is the maximum size of an SSL frame and SSL_read will not read more than one SSL frame at a time (actually I'm not sure if python calls only SSL_read once within recv, but I assume so). You might have a look at the examples and documentation for non-blocking I/O for Perls IO::Socket::SSL package (disclaimer: I'm the maintainer): http://search.cpan.org/~sullr/IO-Socket-SSL-1.987/lib/IO/Socket/SSL.pm -- nosy: +noxxi ___ Python tracker <http://bugs.python.org/issue21430> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21430] Document ssl.pending()
Steffen Ullrich added the comment: > What's the point of checking? Just call SSL_read() and catch the > SSL_ERROR_WANT_{READ,WRITE} to determine that no data is available; as a > bonus it also tells you whether you have to select() for read or for write. A common scenario with non-blocking sockets is to have lots of sockets at the same time and a central select loop. And whenever a socket gets ready it usually reads only as much as is needed for its current task and then returns to the select-loop. I was trying to point out that for SSL enabled sockets this approach will no longer work and might cause odd stalling of connections, because select will not show the socket as readable although data are there for read. I don't think it is enough to just document pending, but it should be documented that the behavior with SSL sockets with select differs from the behavior one is used from normal TCP sockets. -- ___ Python tracker <http://bugs.python.org/issue21430> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28938] match_hostname treats SAN IP address as DNS name and fails to check CN then
New submission from Steffen Ullrich: from Lib/ssl.py 303elif key == 'IP Address': 304if host_ip is not None and _ipaddress_match(value, host_ip): 305return 306dnsnames.append(value) 307if not dnsnames: 308# The subject is only checked when there is no dNSName entry 309# in subjectAltName RFC 2818 and RFC 6125 say that CN should not be used if subjectAltNames contains DNS names. This means CN should still be checked if SAN contains only IP addresses. By appending IP address to dnsnames in line 306 it will not check the CN if there are no DNS names in SAN but only IP address. See also http://stackoverflow.com/questions/41089539/authentication-issue-with-ssl-certificate-using-python-requests-lib/41090559#41090559 -- messages: 282940 nosy: noxxi priority: normal severity: normal status: open title: match_hostname treats SAN IP address as DNS name and fails to check CN then versions: Python 3.3, Python 3.4, Python 3.5, Python 3.6, Python 3.7 ___ Python tracker <http://bugs.python.org/issue28938> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28938] match_hostname treats SAN IP address as DNS name and fails to check CN then
Steffen Ullrich added the comment: On Sun, Dec 11, 2016 at 08:26:32PM +, Christian Heimes wrote: > > Christian Heimes added the comment: > > Python's implementation of host name verification conforms to RFC 6125, > section 6.4.4. The CN check is optional (MAY). Python treats the presence of > an IP Address as indicator that CN check should not be performed. RFC 6125 does not obsolete RFC 2818. In fact it says in section 1.4: This document also does not supersede the rules for verifying service identity provided in specifications for existing application protocols published prior to this document, such as those excerpted under Appendix B... Where Appendix B.2 explicitly cites the relevant parts from RFC 2818 like this in section 3.1: If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Thus while RFC 6125 might say MAY for checking the CN the more specific RFC 2818 says clearly MUST. Also, the intention of RFC 6125 in 6.4.4 is in my opinion to distinguish between applications never checking the CN and applications which check the CN, while addressing the last ones that CN should not be checked for specific SAN record types. iPAddress is not a type which is considered for this special treatment. Regards, Steffen -- ___ Python tracker <http://bugs.python.org/issue28938> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com