[issue36011] ssl - tls verify on Windows 10 fails

2019-02-16 Thread Christian Korneck


New submission from Christian Korneck :

Hello,

I have the impression that there's a general issue with how the Python stdlib 
module `ssl` uses the Windows certificate store to read the "bundle" of trusted 
Root CA certificates. At a first look, I couldn't find this issue documented 
elsewhere, so I'm trying to describe it below (apologies if its a duplicate). 

This issue leads to that on a standard Windows 10 installation with a standard 
Python 2.x or 3.x installation TLS verification for many webservers fails out 
of the box, including for common domains/webservers with a highly correct TLS 
setup like https://google.de or https://www.verisign.com/ .

In short: On a vanilla Win 10 with a vanilla Python 2/3 installation, HTTPS 
connections to "commonly trusted" domain names fail out of the box. Example 
with Python 2.7.15:

>>> import urllib2
>>> response = urllib2.urlopen("https://google.de";)
[...]
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 
(_ssl.c:726)

Expected Behavior: TLS verify succeeds
Actual Behavior: TLS verify fails

Affected Python version/environment: I believe every Python version that uses 
the Windows certificate store is affected (since 3.4 / 2.7.9). However, I've 
only tested 2.7.11, 2.7.15, 3.7.2 (all 64 bit). I did test on Windows 10 1803, 
1809, Windows Server 2019 1809 (all Pro x64 with latest patchlevel, i.e. the 
Jan 2019 cumulative update). All tested Python versions on all tested Windows 
10 versions show the same behavior.



Details:

1.) Background

- Factor1: Python's "ssl" std lib
Since Python 3.4 / 2.7.9 the ssl lib uses the Windows certificate store to get 
a "bundle" of the trusted root CA certificates. (Some Python libraries like 
requests bring their own ca bundle though, usually through certifi. These libs 
are not affected). However, the ssl lib is not using the Windows SCHANNEL 
library but instead bundles its own copy of openssl.

- Factor2: Windows 10 behavior
Windows provides a certificate store, a vendor managed and updated "bundle" of 
Trusted Root CA certificates and a library for TLS operations called SCHANNEL 
(the native Windows openssl equivalent).

On Windows 10, the list of pre-installed Trusted Root CA certificates is very 
minimal. On Windows 10 1809 only 12 Root CAs are known by the certificate 
store. In comparison certifi (Mozilla cabundle) currently lists 134 trusted 
RootCAs. Many widely trusted RootCAs are missing out of the box in the Windows 
certstore. Instead there's an online download mechanism used by the SCHANNEL 
library to download additional trusted root CA certificates from a Microsoft 
server when they are needed for the first time.

Example: The certificate currently used for https://google.de was signed by an 
IntermediateCA which was signed by the RootCA "GlobalSign Root CA - R2". The 
cert for this RootCA is not out of the box present in the Windows certstore and 
therefore not trusted. When I make a HTTPS connection to this domain with a 
client that uses the SCHANNEL library (i.e. Microsoft Edge or Internet Explorer 
browser), the connection succeeds and is shown as "trusted". Afterwards the 
previously missing RootCA certificate appears in the windows certstore. (The 
Windows certstores can get inspected with the GUIs certml.msc (Machine store) 
and certmgr.msc (User store)).


2.) Behavior

- install a vanilla Windows 10 1809 with default settings
- install a vanilla Python 2.7.15 and/or 3.7.2

In Python:

c:\python27\python.exe
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit 
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket, ssl
>>> context = ssl.SSLContext(ssl.PROTOCOL_TLS)
>>> context.verify_mode = ssl.CERT_REQUIRED
>>> context.check_hostname = True
# by default there are no cacerts in the context
>>> len(context.get_ca_certs())
0
>>> context.load_default_certs()
>>> len(context.get_ca_certs())
# after loading the cacerts from the Windows cert store "ROOT", we are seeing 
some - but it's only 12 root cacerts in a vanilla Windows 10 (compared to 134 
in the certifi / mozilla cabundle!)
12
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> ssl_sock = context.wrap_socket(s, server_hostname='www.google.de')
>>> ssl_sock.connect(('www.google.de', 443))
Traceback (most recent call last):
  File "", line 1, in 
  File "c:\python27\lib\ssl.py", line 882, in connect
self._real_connect(addr, False)
  File "c:\python27\lib\ssl.py", line 873, in _real_connect
self.do_handshake()
  File "c:\python27\lib\ssl.py", line 846, in do_handshake
self._sslobj.

[issue36010] Please provide a .zip Windows release of Python that is not crippled/for embedding only

2019-02-17 Thread Christian Korneck


Christian Korneck  added the comment:

for Python 2.7 you can extract the MSI installer (much like a zip file):
mkdir "c:\targetdir"
msiexec /a "c:\python-2.7.8.amd64.msi" /quiet /norestart TARGETDIR=c:\targetdir

msiexec is part of all Windows editions (except for nanoserver). Side note: 
extracting the MSI does not enable pip. If you need pip, run this on your 
targetdir:
c:\targetdir\python.exe -m ensurepip

alternatively, you could perform an unattended installation:
msiexec /i "c:\python-2.7.8.amd64.msi" /quiet /norestart 

Unattended installation also works for Python 3.7:
"c:\python-3.7.2-amd64.exe" /quiet InstallAllUsers=1 PrependPath=1

These options worked fine for me in windows containers for CI stuff with 
servercore. The unattended installation of Python 3.7 also worked fine for me 
in nanoserver.

--
nosy: +chris-k

___
Python tracker 
<https://bugs.python.org/issue36010>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36011] ssl - tls verify on Windows fails

2019-02-18 Thread Christian Korneck


Christian Korneck  added the comment:

quick addition: It looks like all recent Windows versions (Win8/Server 2012, 
Win8.1/Server 2012R2, Win10 (older versions)/Server 2016, Win10-1809/Server 
2019 behave the same (= only very few RootCAs are pre-installed out of the box, 
additional ones are added on the fly when HTTPS requests are being made via the 
SCHANNEL api).


Possible workaround for Windows admins:

Import the RootCA certs from "certifi" into the Windows local machine Trusted 
RootCA store.

To do so, first download and convert the certifi cabundle (https://certifi.io) 
to a pfx container, i.e. with something like:

wget -O certs.pem https://mkcert.org/generate/
openssl pkcs12 -export -nokeys -out certs.pfx -in certs.pem

Then import the pfx via the certlm.msc GUI or the certutil.exe cmdline tool. 
This imports all certs at once. This can also be centralized for a larger 
number of machines via an Active Directory Group Policy (Local Machine -> 
Windows Settings -> Security Settings -> PKI).

This isn't ideal as it puts the admin into the responsibility to update the 
certstore/GPO whenever there's a change in the certifi cabundle, but works well 
for me besides that.

--
title: ssl - tls verify on Windows 10 fails -> ssl - tls verify on Windows fails

___
Python tracker 
<https://bugs.python.org/issue36011>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com