aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2017-06-29 18:44:08 -0500
committerAlex Gaynor <alex.gaynor@gmail.com>2017-06-29 16:44:08 -0700
commit55fb34146c496e7c997d7418e16dd67a191fca7f (patch)
tree45c884398ba1168781abf50a9daefe0ba91bc3ec /tests
parentcded993dbbff8e8c777b95f4de0597cdf3f75c0d (diff)
downloadpyopenssl-55fb34146c496e7c997d7418e16dd67a191fca7f.tar.gz
try loading trusted certs from a list of fallbacks (#633)
* try loading trusted certs from a list of fallbacks pyca/cryptography will shortly begin shipping a wheel. Since SSL_CTX_set_default_verify_paths uses a hardcoded path compiled into the library, this will start failing to load the proper certificates for users on many linux distributions. To avoid this we can use the Go solution of iterating over a list of potential candidates and loading it when found. * capath is lazy loaded so we need to do a lot more checks This now checks to see if env vars are set as well as seeing if the dir exists and has valid certs in it. If either of those are true (or the number of certs is > 0) it won't load the fallback. If it does do the fallback it will also attempt to load certs from a dir as a final fallback * remove an early return * this shouldn't be commented out * oops * very limited testing * sigh, can't use these py3 exceptions of course * expand the tests a bit * coverage! * don't need this now * change the approach to use a pyca/cryptography guard value * test fix * older python sometimes calls itself linux2 * flake8 * add changelog * coverage * slash opt
Diffstat (limited to 'tests')
-rw-r--r--tests/test_ssl.py89
1 files changed, 88 insertions, 1 deletions
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index 96efec8..fafffa3 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -20,6 +20,8 @@ from warnings import simplefilter
import pytest
+from pretend import raiser
+
from six import PY3, text_type
from cryptography import x509
@@ -46,6 +48,7 @@ from OpenSSL.SSL import OP_SINGLE_DH_USE, OP_NO_SSLv2, OP_NO_SSLv3
from OpenSSL.SSL import (
VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE, VERIFY_NONE)
+from OpenSSL import SSL
from OpenSSL.SSL import (
SESS_CACHE_OFF, SESS_CACHE_CLIENT, SESS_CACHE_SERVER, SESS_CACHE_BOTH,
SESS_CACHE_NO_AUTO_CLEAR, SESS_CACHE_NO_INTERNAL_LOOKUP,
@@ -57,7 +60,7 @@ from OpenSSL.SSL import (
Context, ContextType, Session, Connection, ConnectionType, SSLeay_version)
from OpenSSL.SSL import _make_requires
-from OpenSSL._util import lib as _lib
+from OpenSSL._util import ffi as _ffi, lib as _lib
from OpenSSL.SSL import (
OP_NO_QUERY_MTU, OP_COOKIE_EXCHANGE, OP_NO_TICKET, OP_NO_COMPRESSION,
@@ -1109,6 +1112,79 @@ class TestContext(object):
context.load_verify_locations(object(), object())
@pytest.mark.skipif(
+ not platform.startswith("linux"),
+ reason="Loading fallback paths is a linux-specific behavior to "
+ "accommodate pyca/cryptography manylinux1 wheels"
+ )
+ def test_fallback_default_verify_paths(self, monkeypatch):
+ """
+ Test that we load certificates successfully on linux from the fallback
+ path. To do this we set the _CRYPTOGRAPHY_MANYLINUX1_CA_FILE and
+ _CRYPTOGRAPHY_MANYLINUX1_CA_DIR vars to be equal to whatever the
+ current OpenSSL default is and we disable
+ SSL_CTX_SET_default_verify_paths so that it can't find certs unless
+ it loads via fallback.
+ """
+ context = Context(TLSv1_METHOD)
+ monkeypatch.setattr(
+ _lib, "SSL_CTX_set_default_verify_paths", lambda x: 1
+ )
+ monkeypatch.setattr(
+ SSL,
+ "_CRYPTOGRAPHY_MANYLINUX1_CA_FILE",
+ _ffi.string(_lib.X509_get_default_cert_file())
+ )
+ monkeypatch.setattr(
+ SSL,
+ "_CRYPTOGRAPHY_MANYLINUX1_CA_DIR",
+ _ffi.string(_lib.X509_get_default_cert_dir())
+ )
+ context.set_default_verify_paths()
+ store = context.get_cert_store()
+ sk_obj = _lib.X509_STORE_get0_objects(store._store)
+ assert sk_obj != _ffi.NULL
+ num = _lib.sk_X509_OBJECT_num(sk_obj)
+ assert num != 0
+
+ def test_check_env_vars(self, monkeypatch):
+ """
+ Test that we return True/False appropriately if the env vars are set.
+ """
+ context = Context(TLSv1_METHOD)
+ dir_var = "CUSTOM_DIR_VAR"
+ file_var = "CUSTOM_FILE_VAR"
+ assert context._check_env_vars_set(dir_var, file_var) is False
+ monkeypatch.setenv(dir_var, "value")
+ monkeypatch.setenv(file_var, "value")
+ assert context._check_env_vars_set(dir_var, file_var) is True
+ assert context._check_env_vars_set(dir_var, file_var) is True
+
+ def test_verify_no_fallback_if_env_vars_set(self, monkeypatch):
+ """
+ Test that we don't use the fallback path if env vars are set.
+ """
+ context = Context(TLSv1_METHOD)
+ monkeypatch.setattr(
+ _lib, "SSL_CTX_set_default_verify_paths", lambda x: 1
+ )
+ dir_env_var = _ffi.string(
+ _lib.X509_get_default_cert_dir_env()
+ ).decode("ascii")
+ file_env_var = _ffi.string(
+ _lib.X509_get_default_cert_file_env()
+ ).decode("ascii")
+ monkeypatch.setenv(dir_env_var, "value")
+ monkeypatch.setenv(file_env_var, "value")
+ context.set_default_verify_paths()
+
+ monkeypatch.setattr(
+ context,
+ "_fallback_default_verify_paths",
+ raiser(SystemError)
+ )
+ context.set_default_verify_paths()
+
+ @pytest.mark.skipif(
platform == "win32",
reason="set_default_verify_paths appears not to work on Windows. "
"See LP#404343 and LP#404344."
@@ -1141,6 +1217,17 @@ class TestContext(object):
clientSSL.send(b"GET / HTTP/1.0\r\n\r\n")
assert clientSSL.recv(1024)
+ def test_fallback_path_is_not_file_or_dir(self):
+ """
+ Test that when passed empty arrays or paths that do not exist no
+ errors are raised.
+ """
+ context = Context(TLSv1_METHOD)
+ context._fallback_default_verify_paths([], [])
+ context._fallback_default_verify_paths(
+ ["/not/a/file"], ["/not/a/dir"]
+ )
+
def test_add_extra_chain_cert_invalid_cert(self):
"""
`Context.add_extra_chain_cert` raises `TypeError` if called with an