[issue32813] SSL shared_ciphers implementation wrong - returns configured but not shared ciphers

2018-02-09 Thread Steffen Ullrich

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

2018-02-10 Thread Steffen Ullrich

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

2018-02-10 Thread Steffen Ullrich

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()

2014-05-17 Thread Steffen Ullrich

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()

2014-05-17 Thread Steffen Ullrich

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

2016-12-11 Thread Steffen Ullrich

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

2016-12-11 Thread Steffen Ullrich

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