Skip to content

Commit f6c3af3

Browse files
committed
test: add a backstop test for VERIFY_X509_STRICT
1 parent c8a7bb5 commit f6c3af3

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

Lib/test/certdata/leaf-missing-aki.ca.pem

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/certdata/leaf-missing-aki.keycert.pem

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_ssl.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
ssl = import_helper.import_module("ssl")
3939
import _ssl
4040

41-
from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType
41+
from ssl import Purpose, TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType
4242

4343
Py_DEBUG_WIN32 = support.Py_DEBUG and sys.platform == 'win32'
4444

@@ -128,6 +128,13 @@ def data_file(*name):
128128
SIGNED_CERTFILE_ECC = data_file("keycertecc.pem")
129129
SIGNED_CERTFILE_ECC_HOSTNAME = 'localhost-ecc'
130130

131+
# A custom testcase, extracted from `rfc5280::aki::leaf-missing-aki` in x509-limbo:
132+
# The leaf (server) certificate has no AKI, which is forbidden under RFC 5280.
133+
# See: https://x509-limbo.com/testcases/rfc5280/#rfc5280akileaf-missing-aki
134+
LEAF_MISSING_AKI_CERTFILE = data_file("leaf-missing-aki.keycert.pem")
135+
LEAF_MISSING_AKI_CERTFILE_HOSTNAME = "example.com"
136+
LEAF_MISSING_AKI_CA = data_file("leaf-missing-aki.ca.pem")
137+
131138
# Same certificate as pycacert.pem, but without extra text in file
132139
SIGNING_CA = data_file("capath", "ceff1710.0")
133140
# cert with all kinds of subject alt names
@@ -2949,6 +2956,36 @@ def test_ecc_cert(self):
29492956
cipher = s.cipher()[0].split('-')
29502957
self.assertTrue(cipher[:2], ('ECDHE', 'ECDSA'))
29512958

2959+
def test_verify_strict(self):
2960+
# verification fails by default, since the server cert is non-conforming
2961+
client_context = ssl.create_default_context()
2962+
client_context.load_verify_locations(LEAF_MISSING_AKI_CA)
2963+
hostname = LEAF_MISSING_AKI_CERTFILE_HOSTNAME
2964+
2965+
server_context = ssl.create_default_context(purpose=Purpose.CLIENT_AUTH)
2966+
server_context.load_cert_chain(LEAF_MISSING_AKI_CERTFILE)
2967+
server = ThreadedEchoServer(context=server_context, chatty=True)
2968+
with server:
2969+
with client_context.wrap_socket(socket.socket(),
2970+
server_hostname=hostname) as s:
2971+
with self.assertRaises(ssl.SSLCertVerificationError):
2972+
s.connect((HOST, server.port))
2973+
2974+
# explicitly disabling VERIFY_X509_STRICT allows it to succeed
2975+
client_context = ssl.create_default_context()
2976+
client_context.load_verify_locations(LEAF_MISSING_AKI_CA)
2977+
client_context.verify_flags &= ~ssl.VERIFY_X509_STRICT
2978+
2979+
server_context = ssl.create_default_context(purpose=Purpose.CLIENT_AUTH)
2980+
server_context.load_cert_chain(LEAF_MISSING_AKI_CERTFILE)
2981+
server = ThreadedEchoServer(context=server_context, chatty=True)
2982+
with server:
2983+
with client_context.wrap_socket(socket.socket(),
2984+
server_hostname=hostname) as s:
2985+
s.connect((HOST, server.port))
2986+
cert = s.getpeercert()
2987+
self.assertTrue(cert, "Can't get peer certificate.")
2988+
29522989
def test_dual_rsa_ecc(self):
29532990
client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
29542991
client_context.load_verify_locations(SIGNING_CA)

0 commit comments

Comments
 (0)