classification
Title: ssl.get_default_verify_paths()
Type: enhancement Stage: resolved
Components: Versions: Python 3.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, christian.heimes, pitrou, python-dev
Priority: normal Keywords: patch

Created on 2013-06-05 15:44 by christian.heimes, last changed 2013-06-24 13:42 by christian.heimes. This issue is now closed.

Files
File name Uploaded Description Edit
sslverifypath2.patch christian.heimes, 2013-06-05 17:31 review
Messages (11)
msg190669 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-06-05 15:44
The patch implements a get_default_verify_paths() function for the ssl module. It returns the env vars and paths that are used by openssl's set_default_verify_paths() to load CA certs from default locations. I think it makes a useful addition for debugging purposes.

On my system:

>>> import ssl
>>> ssl.get_default_verify_paths()
(None, '/usr/lib/ssl/certs')
>>> ssl.get_default_verify_paths(raw=True)
('SSL_CERT_FILE', '/usr/lib/ssl/cert.pem', 'SSL_CERT_DIR', '/usr/lib/ssl/certs')

SSL_CTX_set_default_verify_paths() first tries the env var. If the env var is set the second element is ignored.
msg190672 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2013-06-05 15:59
I have no clue what is being returned by this function. Any chance of using types.SimpleNamespace to give meaningful names to the returned values instead of a tuple?
msg190674 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-06-05 16:15
Sure! I can add SimpleNamespace.

The C function returns four elements:

 * environment var that is used to look up the path to a CA cert file
 * path to a CA cert file
 * environment var that is used to look up the path to a CA cert directory
 * path to a CA cert directory

SSLContext.set_default_verify_paths() is unable to return information if it was able to load any CA certs. With get_default_verify_paths() a developer is able to debug which file or directory is used by OpenSSL. The code is based on OpenSSL's X509_STORE_set_default_paths(). If you want to read up on it:

http://cvs.openssl.org/fileview?f=openssl/crypto/x509/x509_d2.c&v=1.7
http://cvs.openssl.org/fileview?f=openssl/crypto/x509/x509_def.c&v=1.5
http://cvs.openssl.org/fileview?f=openssl/crypto/x509/by_file.c&v=1.12.4.4
msg190675 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-06-05 16:25
I forgot that a SimpleNamespace is an unorder collection. However the order is significant. OpenSSL uses the cafile first and ignores capath if a cert in cafile matches. The path to cafile or capath is ignored when the environment key exists -- even when it doesn't point to any existing file or directory.

I think a named tuple is better here.
msg190678 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-06-05 16:44
How about that output, Brett? cafile is None because /usr/lib/ssl/cert.pem doesn't exist on my system.

>>> import ssl
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile=None, capath='/usr/lib/ssl/certs')
>>> ssl.get_default_verify_paths(raw=True)
RawDefaultVerifyPaths(cafile_env_key='SSL_CERT_FILE', cafile='/usr/lib/ssl/cert.pem', capath_env_key='SSL_CERT_DIR', capath='/usr/lib/ssl/certs')
msg190680 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2013-06-05 16:47
That's better. As long as you use result[1::2] then the tuple is reasonable to use for the order need and still make sense as an iterable.
msg190682 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-06-05 17:31
New patch with tests and documentation.
msg190801 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-06-08 15:21
Your "raw" parameter is one too many IMO. You should find a way to present all relevant information in a single API call.
msg190808 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-06-08 16:43
How about a single return value:

DefaultVerifyPaths = collections.namedtuple("DefaultVerifyPaths",
    "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env openssl_capath")
msg190814 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-06-08 18:02
> How about a single return value:
>
> DefaultVerifyPaths = collections.namedtuple("DefaultVerifyPaths",
>      "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env openssl_capath")

Sounds good.
msg190859 - (view) Author: Roundup Robot (python-dev) Date: 2013-06-09 16:03
New changeset a4d31e56075d by Christian Heimes in branch 'default':
Issue #18143: Implement ssl.get_default_verify_paths() in order to debug
http://hg.python.org/cpython/rev/a4d31e56075d
History
Date User Action Args
2013-06-24 13:42:35christian.heimessetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2013-06-09 16:03:10python-devsetnosy: + python-dev
messages: + msg190859
2013-06-08 18:02:56pitrousetmessages: + msg190814
2013-06-08 16:43:53christian.heimessetmessages: + msg190808
2013-06-08 15:21:37pitrousetmessages: + msg190801
2013-06-05 17:31:30christian.heimessetfiles: + sslverifypath2.patch

messages: + msg190682
2013-06-05 17:31:05christian.heimessetfiles: - sslverifypath.patch
2013-06-05 16:47:28brett.cannonsetmessages: + msg190680
2013-06-05 16:44:29christian.heimessetmessages: + msg190678
2013-06-05 16:25:59christian.heimessetmessages: + msg190675
2013-06-05 16:15:46christian.heimessetmessages: + msg190674
2013-06-05 15:59:55brett.cannonsetnosy: + brett.cannon
messages: + msg190672
2013-06-05 15:44:20christian.heimescreate