Skip to content

Commit b93b406

Browse files
committed
Fix x509 tests by using trustme
This way the certificate won't be able to expire anymore and we won't have to store a blob in git. trustme only supports PEM, not DER, which is why test_x509_der has to re-export the certificate and key to DER. Additionally, since trustme does not support password-protected keys, the re-export was the perfect place to add a password, so test_x509_der also tests the password case, while it was test_x509_pem until now. The tests are still not end-to-end, we're just running the x509.py code without actually establishing a TLS connection. This could be fixed at a later point, but is considered out of scope here as that would be a new feature.
1 parent 8b17435 commit b93b406

4 files changed

Lines changed: 25 additions & 23 deletions

File tree

dev-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ pytest
22
mock;python_version<"3.3"
33
pyopenssl
44
git+git://github.com/sigmavirus24/betamax
5+
trustme

tests/certs/test_cert.p12

-1.9 KB
Binary file not shown.

tests/test_x509_adapter.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@
44
import pytest
55

66
try:
7-
from OpenSSL.crypto import load_pkcs12
7+
import OpenSSL
88
except ImportError:
99
PYOPENSSL_AVAILABLE = False
1010
else:
1111
PYOPENSSL_AVAILABLE = True
1212
from requests_toolbelt.adapters.x509 import X509Adapter
13+
from cryptography import x509
1314
from cryptography.hazmat.primitives.serialization import (
1415
Encoding,
1516
PrivateFormat,
16-
NoEncryption,
17-
BestAvailableEncryption
17+
BestAvailableEncryption,
18+
load_pem_private_key,
1819
)
1920

2021
from requests_toolbelt import exceptions as exc
2122
from . import get_betamax
23+
import trustme
2224

2325
REQUESTS_SUPPORTS_SSL_CONTEXT = requests.__build__ >= 0x021200
2426

@@ -27,27 +29,20 @@ class TestX509Adapter(unittest.TestCase):
2729
"""Tests a simple requests.get() call using a .p12 cert.
2830
"""
2931
def setUp(self):
30-
with open('./tests/certs/test_cert.p12', 'rb') as pkcs12_file:
31-
self.pkcs12_data = pkcs12_file.read()
32-
3332
self.pkcs12_password_bytes = "test".encode('utf8')
3433
self.session = requests.Session()
3534

36-
@pytest.mark.xfail
3735
@pytest.mark.skipif(not REQUESTS_SUPPORTS_SSL_CONTEXT,
38-
reason="Requires Requests v2.12.0 or later")
36+
reason="Requires Requests v2.12.0 or later")
3937
@pytest.mark.skipif(not PYOPENSSL_AVAILABLE,
40-
reason="Requires OpenSSL")
38+
reason="Requires OpenSSL")
4139
def test_x509_pem(self):
42-
p12 = load_pkcs12(self.pkcs12_data, self.pkcs12_password_bytes)
43-
cert_bytes = p12.get_certificate().to_cryptography().public_bytes(Encoding.PEM)
44-
pk_bytes = p12.get_privatekey().\
45-
to_cryptography_key().\
46-
private_bytes(Encoding.PEM, PrivateFormat.PKCS8,
47-
BestAvailableEncryption(self.pkcs12_password_bytes))
40+
ca = trustme.CA()
41+
cert = ca.issue_cert('pkiprojecttest01.dev.labs.internal')
42+
cert_bytes = cert.cert_chain_pems[0].bytes()
43+
pk_bytes = cert.private_key_pem.bytes()
4844

49-
adapter = X509Adapter(max_retries=3, cert_bytes=cert_bytes,
50-
pk_bytes=pk_bytes, password=self.pkcs12_password_bytes)
45+
adapter = X509Adapter(max_retries=3, cert_bytes=cert_bytes, pk_bytes=pk_bytes)
5146
self.session.mount('https://', adapter)
5247
recorder = get_betamax(self.session)
5348
with recorder.use_cassette('test_x509_adapter_pem'):
@@ -56,16 +51,21 @@ def test_x509_pem(self):
5651
assert r.status_code == 200
5752
assert r.text
5853

59-
@pytest.mark.xfail
6054
@pytest.mark.skipif(not REQUESTS_SUPPORTS_SSL_CONTEXT,
6155
reason="Requires Requests v2.12.0 or later")
6256
@pytest.mark.skipif(not PYOPENSSL_AVAILABLE,
6357
reason="Requires OpenSSL")
64-
def test_x509_der(self):
65-
p12 = load_pkcs12(self.pkcs12_data, self.pkcs12_password_bytes)
66-
cert_bytes = p12.get_certificate().to_cryptography().public_bytes(Encoding.DER)
67-
pk_bytes = p12.get_privatekey().to_cryptography_key().private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption())
68-
adapter = X509Adapter(max_retries=3, cert_bytes=cert_bytes, pk_bytes=pk_bytes, encoding=Encoding.DER)
58+
def test_x509_der_and_password(self):
59+
ca = trustme.CA()
60+
cert = ca.issue_cert('pkiprojecttest01.dev.labs.internal')
61+
cert_bytes = x509.load_pem_x509_certificate(
62+
cert.cert_chain_pems[0].bytes()).public_bytes(Encoding.DER)
63+
pem_pk = load_pem_private_key(cert.private_key_pem.bytes(), password=None)
64+
pk_bytes = pem_pk.private_bytes(Encoding.DER, PrivateFormat.PKCS8,
65+
BestAvailableEncryption(self.pkcs12_password_bytes))
66+
67+
adapter = X509Adapter(max_retries=3, cert_bytes=cert_bytes, pk_bytes=pk_bytes,
68+
password=self.pkcs12_password_bytes, encoding=Encoding.DER)
6969
self.session.mount('https://', adapter)
7070
recorder = get_betamax(self.session)
7171
with recorder.use_cassette('test_x509_adapter_der'):

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ deps =
1818
pyopenssl
1919
ndg-httpsclient
2020
betamax>0.5.0
21+
trustme
2122
commands =
2223
py.test {posargs}
2324

0 commit comments

Comments
 (0)