8000 gh-107361: strengthen default SSL context flags by woodruffw · Pull Request #112389 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content
/ cpython Public

gh-107361: strengthen default SSL context flags #112389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test: add a backstop test for VERIFY_X509_STRICT
  • Loading branch information
woodruffw committed Feb 2, 2024
commit f6c3af3364f0c4d974ae503fb88b87270f657ea5
13 changes: 13 additions & 0 deletions Lib/test/certdata/leaf-missing-aki.ca.pem

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions Lib/test/certdata/leaf-missing-aki.keycert.pem

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 38 additions & 1 deletion Lib/test/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
ssl = import_helper.import_module("ssl")
import _ssl

from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType
from ssl import Purpose, TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType

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

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

# A custom testcase, extracted from `rfc5280::aki::leaf-missing-aki` in x509-limbo:
# The leaf (server) certificate has no AKI, which is forbidden under RFC 5280.
# See: https://x509-limbo.com/testcases/rfc5280/#rfc5280akileaf-missing-aki
LEAF_MISSING_AKI_CERTFILE = data_file("leaf-missing-aki.keycert.pem")
LEAF_MISSING_AKI_CERTFILE_HOSTNAME = "example.com"
LEAF_MISSING_AKI_CA = data_file("leaf-missing-aki.ca.pem")

# Same certificate as pycacert.pem, but without extra text in file
SIGNING_CA = data_file("capath", "ceff1710.0")
# cert with all kinds of subject alt names
Expand Down Expand Up @@ -2949,6 +2956,36 @@ def test_ecc_cert(self):
cipher = s.cipher()[0].split('-')
self.assertTrue(cipher[:2], ('ECDHE', 'ECDSA'))

def test_verify_strict(self):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sethmlarson This test provides a backstop check on VERIFY_X509_STRICT, PTAL!

# verification fails by default, since the server cert is non-conforming
client_context = ssl.create_default_context()
client_context.load_verify_locations(LEAF_MISSING_AKI_CA)
hostname = LEAF_MISSING_AKI_CERTFILE_HOSTNAME

server_context = ssl.create_default_context(purpose=Purpose.CLIENT_AUTH)
server_context.load_cert_chain(LEAF_MISSING_AKI_CERTFILE)
server = ThreadedEchoServer(context=server_context, chatty=True)
with server:
with client_context.wrap_socket(socket.socket(),
server_hostname=hostname) as s:
with self.assertRaises(ssl.SSLCertVerificationError):
s.connect((HOST, server.port))

# explicitly disabling VERIFY_X509_STRICT allows it to succeed
client_context = ssl.create_default_context()
client_context.load_verify_locations(LEAF_MISSING_AKI_CA)
client_context.verify_flags &= ~ssl.VERIFY_X509_STRICT

server_context = ssl.create_default_context(purpose=Purpose.CLIENT_AUTH)
server_context.load_cert_chain(LEAF_MISSING_AKI_CERTFILE)
server = ThreadedEchoServer(context=server_context, chatty=True)
with server:
with client_context.wrap_socket(socket.socket(),
server_hostname=hostname) as s:
s.connect((HOST, server.port))
cert = s.getpeercert()
self.assertTrue(cert, "Can't get peer certificate.")

def test_dual_rsa_ecc(self):
client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
client_context.load_verify_locations(SIGNING_CA)
Expand Down
0