This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: SSLContext.get_ca_certs() and self-signed certs
Type: behavior Stage: test needed
Components: Extension Modules Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Arfrever, christian.heimes, loewis, pitrou
Priority: normal Keywords:

Created on 2013-12-16 18:53 by christian.heimes, last changed 2022-04-11 14:57 by admin.

Messages (5)
msg206347 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-12-16 18:53
The new method SSLContext.get_ca_certs() returns all certificates in the context's trusted X509_STORE. I recently found out that it is possible to put a self-signed certificate into the store and use it successfully with verify_mode CERT_REQUIRED. get_ca_certs() doesn't return the cert although it is used to successfully validate a remote cert.

I propose to modify and rename the function and to add a "check_ca" to the dict that is returned by getpeercert().
msg206352 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-12-16 19:14
Example:

$ openssl s_server -cert Lib/test/ssl_cert.pem -key Lib/test/ssl_key.pem

$ ./python
>>> import ssl
>>> ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
>>> ctx.verify_mode = ssl.CERT_REQUIRED
>>> ctx.check_hostname = True
>>> ctx.load_verify_locations("Lib/test/ssl_cert.pem")
>>> s = ssl.create_connection(("localhost", 4433))
>>> with ctx.wrap_socket(s, server_hostname="localhost") as ssock:
...     peer = ssock.getpeercert()
... 
>>> peer
{'notAfter': 'Oct  5 23:01:56 2020 GMT', 'version': 3, 'serialNumber': 'D7C7381919AFC24E', 'subjectAltName': (('DNS', 'localhost'),), 'issuer': ((('countryName', 'XY'),), (('localityName', 'Castle Anthrax'),), (('organizationName', 'Python Software Foundation'),), (('commonName', 'localhost'),)), 'subject': ((('countryName', 'XY'),), (('localityName', 'Castle Anthrax'),), (('organizationName', 'Python Software Foundation'),), (('commonName', 'localhost'),)), 'notBefore': 'Oct  8 23:01:56 2010 GMT'}
>>> ctx.get_ca_certs()
[]
msg206417 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-12-17 10:48
> get_ca_certs() doesn't return the cert although it is used to
> successfully validate a remote cert.

Interesting. Is it because of the way you implemented get_ca_certs()?

> I propose to modify and rename the function and to add a "check_ca" to
> the dict that is returned by getpeercert().

Can you explain? What does "check_ca" mean?
msg206423 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-12-17 12:03
> Interesting. Is it because of the way you implemented get_ca_certs()?

Yes, it's the line

  http://hg.python.org/cpython/file/b78de8029606/Modules/_ssl.c#l3103

that skips all certs that are not recognized as CA certs. I wasn't aware
that OpenSSL supports self-signed certs that way.

> Can you explain? What does "check_ca" mean?

The return value of X509_check_ca().

http://git.openssl.org/gitweb/?p=openssl.git;a=blob;f=crypto/x509v3/v3_purp.c;h=6c40c7dfc318e4b46fc20d38581ad3656e344b5e;hb=HEAD#l517
msg207163 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2014-01-02 13:21
BTW, congrats to issue 20,000.
History
Date User Action Args
2022-04-11 14:57:55adminsetstatus: pending -> open
github: 64199
2016-09-08 22:47:29christian.heimessetstatus: open -> pending
versions: + Python 3.7, - Python 3.5
2014-01-02 13:21:33loewissetnosy: + loewis
messages: + msg207163
2013-12-17 12:07:11pitrousetversions: + Python 3.5, - Python 3.4
2013-12-17 12:03:40christian.heimessetmessages: + msg206423
2013-12-17 10:48:18pitrousetnosy: + pitrou
messages: + msg206417
2013-12-16 20:28:29Arfreversetnosy: + Arfrever
2013-12-16 19:14:08christian.heimessetmessages: + msg206352
2013-12-16 18:53:50christian.heimescreate