diff --git a/.evergreen/scripts/configure-env.sh b/.evergreen/scripts/configure-env.sh index 8dc328aab3..ae5da8c7e9 100755 --- a/.evergreen/scripts/configure-env.sh +++ b/.evergreen/scripts/configure-env.sh @@ -74,8 +74,8 @@ EOT # Write the .env file for drivers-tools. rm -rf $DRIVERS_TOOLS -BRANCH=master -ORG=mongodb-labs +BRANCH=allow-cert-folder-override +ORG=blink1073 git clone --branch $BRANCH https://github.com/$ORG/drivers-evergreen-tools.git $DRIVERS_TOOLS cat < ${DRIVERS_TOOLS}/.env diff --git a/.evergreen/scripts/run_server.py b/.evergreen/scripts/run_server.py index 9757eb3a4f..b02836ed18 100644 --- a/.evergreen/scripts/run_server.py +++ b/.evergreen/scripts/run_server.py @@ -1,6 +1,7 @@ from __future__ import annotations import os +import sys from typing import Any from utils import DRIVERS_TOOLS, ROOT, get_test_options, run_command @@ -42,6 +43,10 @@ def start_server(): set_env("TLS_CERT_KEY_FILE", certs / "client.pem") set_env("TLS_PEM_KEY_FILE", certs / "server.pem") set_env("TLS_CA_FILE", certs / "ca.pem") + if sys.platform == "darwin": + # macOS MongoDB Enterprise uses Apple SecTrust, which rejects our + # test CA and certs. See test/certificates/README.md for details. + extra_opts.append("--tls-allow-invalid-certificates") if opts.auth: extra_opts.append("--auth") diff --git a/.evergreen/scripts/setup_tests.py b/.evergreen/scripts/setup_tests.py index e188dcaa9d..4f5da987ed 100644 --- a/.evergreen/scripts/setup_tests.py +++ b/.evergreen/scripts/setup_tests.py @@ -341,10 +341,8 @@ def handle_test_env() -> None: run_command(cmd, cwd=DRIVERS_TOOLS) if SSL != "nossl": - if not DRIVERS_TOOLS: - raise RuntimeError("Missing DRIVERS_TOOLS") - write_env("CLIENT_PEM", f"{DRIVERS_TOOLS}/.evergreen/x509gen/client.pem") - write_env("CA_PEM", f"{DRIVERS_TOOLS}/.evergreen/x509gen/ca.pem") + write_env("CLIENT_PEM", ROOT / "test/certificates/client.pem") + write_env("CA_PEM", ROOT / "test/certificates/ca.pem") compressors = os.environ.get("COMPRESSORS") or opts.compressor if compressors == "snappy": @@ -382,6 +380,20 @@ def handle_test_env() -> None: if not DRIVERS_TOOLS: raise RuntimeError("Missing DRIVERS_TOOLS") csfle_dir = Path(f"{DRIVERS_TOOLS}/.evergreen/csfle") + + # Set CSFLE TLS cert paths to our AKI-enabled test/certificates/ before + # setup-secrets.sh runs. setup-secrets.sh uses ${VAR:-default} so + # pre-setting these vars causes them to flow into secrets-export.sh via + # csfle/setup_secrets.py (which reads os.environ for these keys). + # load_config_from_file then persists all vars from that file for the + # test runner, so no separate write_env calls are needed. + certs = ROOT / "test/certificates" + os.environ["CSFLE_TLS_CA_FILE"] = str(certs / "ca.pem") + os.environ["CSFLE_TLS_CERT_FILE"] = str(certs / "server-kms.pem") + os.environ["CSFLE_TLS_CLIENT_CERT_FILE"] = str(certs / "client.pem") + os.environ["CSFLE_TLS_WRONG_HOST_FILE"] = str(certs / "wrong-host.pem") + os.environ["CSFLE_TLS_EXPIRED_FILE"] = str(certs / "expired.pem") + run_command(f"bash {csfle_dir.as_posix()}/setup-secrets.sh", cwd=csfle_dir) load_config_from_file(csfle_dir / "secrets-export.sh") run_command(f"bash {csfle_dir.as_posix()}/start-servers.sh") diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index afb6e2e100..e8506d96f5 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -219,12 +219,18 @@ jobs: - id: setup-mongodb uses: mongodb-labs/drivers-evergreen-tools@master - name: Run tests - run: | + run: | just integration-tests - id: setup-mongodb-ssl uses: mongodb-labs/drivers-evergreen-tools@master with: ssl: true + env: + # drivers-evergreen-tools invokes run-mongodb.sh directly (not via + # run_server.py), so cert paths must be provided explicitly here. + TLS_PEM_KEY_FILE: ${{ github.workspace }}/test/certificates/server.pem + TLS_CA_FILE: ${{ github.workspace }}/test/certificates/ca.pem + TLS_CERT_KEY_FILE: ${{ github.workspace }}/test/certificates/client.pem - name: Run tests run: | just integration-tests diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 00026f8661..e21b4e7eb0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -103,7 +103,7 @@ repos: # - test/test_bson.py:267: isnt ==> isn't # - test/versioned-api/crud-api-version-1-strict.json:514: nin ==> inn, min, bin, nine # - test/test_client.py:188: te ==> the, be, we, to - args: ["-L", "fle,fo,infinit,isnt,nin,te,aks"] + args: ["-L", "fle,fo,infinit,isnt,nin,te,aks", "--skip", "test/certificates/*.pem"] - repo: local hooks: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 773c9ec0d8..61ad4ece29 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -250,6 +250,16 @@ client = MongoClient( If you want to use the actual certificate file then set `tlsCertificateKeyFile` to the local path to `/test/certificates/client.pem` and `tlsCAFile` to the local path to `/test/certificates/ca.pem`. +#### Regenerating test certificates + +If the test certificates in `test/certificates/` need to be regenerated (e.g. after expiry or to add missing extensions), run: + +```bash +cd test/certificates && bash gen-certs.sh +``` + +See `test/certificates/README.md` for full details and constraints on certificate subjects/SANs that must be preserved. + ### Encryption tests - Run `just run-server` to start the server. diff --git a/test/asynchronous/test_encryption.py b/test/asynchronous/test_encryption.py index 455b1940c4..e567833b68 100644 --- a/test/asynchronous/test_encryption.py +++ b/test/asynchronous/test_encryption.py @@ -3045,10 +3045,20 @@ async def asyncSetUp(self): async def http_post(self, path, data=None): # Note, the connection to the mock server needs to be closed after # each request because the server is single threaded. - ctx = ssl.create_default_context(cafile=CA_PEM) + if sys.platform in ("darwin", "win32"): + # macOS/Windows: use PROTOCOL_TLS_CLIENT instead of + # create_default_context so that X509_V_FLAG_X509_STRICT is not + # set. Python 3.14 enables strict mode in create_default_context, + # which requires a Subject Key Identifier (SKI) on the root CA cert. + # The CA cert omits SKI + # to prevent macOS SecTrust from triggering OCSP revocation checks + # during MongoDB server startup; the same cert is used on all + # platforms, so Windows inherits the same constraint. + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + else: + ctx = ssl.create_default_context() + ctx.load_verify_locations(cafile=CA_PEM) ctx.load_cert_chain(CLIENT_PEM) - ctx.check_hostname = False - ctx.verify_mode = ssl.CERT_NONE conn = http.client.HTTPSConnection("127.0.0.1:9003", context=ctx) try: if data is not None: diff --git a/test/certificates/README.md b/test/certificates/README.md new file mode 100644 index 0000000000..3cba9c2a98 --- /dev/null +++ b/test/certificates/README.md @@ -0,0 +1,66 @@ +# Test TLS Certificates + +These certificates are used by the PyMongo test suite for TLS/SSL integration tests. + +## Regenerating certificates + +Run the generation script from this directory: + +```bash +uv run gen-certs.py +``` + +**Prerequisites:** Python 3 and [uv](https://docs.astral.sh/uv/). The script declares its own dependency on `cryptography` via PEP 723 inline metadata, so `uv` installs it automatically. + +## Certificate details + +Two classes of leaf certificate are generated, with different extension profiles to satisfy +conflicting requirements from Python's ssl module and macOS's SecTrust framework: + +**MongoDB certs** — presented to MongoDB Enterprise, verified by Apple SecTrust on macOS. +No Authority Key Identifier (AKI) or Subject Key Identifier (SKI). Adding AKI causes SecTrust to attempt OCSP revocation checks; because our +CA is not in the macOS system keychain, those checks fail with `CSSMERR_TP_CERT_SUSPENDED`. + +**KMS certs** — presented by KMS mock servers, verified by Python's ssl module (OpenSSL). +Carry both AKI and SKI. Python 3.13 requires AKI on non-root certs; Python 3.14 enables +`X509_V_FLAG_X509_STRICT` in `ssl.create_default_context()`, which requires SKI too. + +| File | Subject | Signed by | Extensions | Purpose | +|---|---|---|---|---| +| `ca.pem` | `CN=Drivers Testing CA, ...` | Self (CA) | basicConstraints critical, keyUsage critical | Root CA for all test certs | +| `server.pem` | `CN=localhost, ...` + SAN | Drivers Testing CA | SAN only | MongoDB server cert (key + cert) | +| `client.pem` | `CN=client, O=MDB, ...` | Drivers Testing CA | keyUsage, extKeyUsage | Client auth cert (key + cert) | +| `password_protected.pem` | Same as client | Drivers Testing CA | keyUsage, extKeyUsage | Client cert with AES-256 encrypted key | +| `crl.pem` | — | Drivers Testing CA | — | CRL revoking serial 1 (server.pem) | +| `server-kms.pem` | `CN=localhost, ...` + SAN | Drivers Testing CA | SAN, AKI, SKI | KMS mock server cert (key + cert) | +| `wrong-host.pem` | `CN=wronghost.example.com` | Drivers Testing CA | SAN, AKI, SKI | KMS wrong-host test cert | +| `expired.pem` | `CN=localhost, ...` + SAN | Drivers Testing CA | SAN, AKI, SKI | KMS expired cert (validity 2000–2001) | +| `trusted-ca.pem` | `CN=Trusted Kernel Test CA, ...` | Self (CA) | basicConstraints critical, keyUsage critical | Separate CA for CA-bundle tests | + +**Password** for `password_protected.pem`: `qwerty` + +## Important constraints + +The following values are hardcoded in tests and **must not change**: + +- Client cert subject: `C=US,ST=New York,L=New York City,O=MDB,OU=Drivers,CN=client` + (used as the MongoDB X.509 username in `test/test_ssl.py`) +- Server cert SAN: `DNS:localhost, IP:127.0.0.1, IP:::1` +- The `server` hostname alias for `127.0.0.1` must be present in `/etc/hosts` for SSL tests to pass + (added automatically by `.evergreen/scripts/setup-system.sh`) + +## Background + +Certificates were regenerated for PYTHON-5040 to fix `ssl.SSLCertVerificationError` failures on +macOS and Windows with Python 3.13+. The root causes were: + +1. Python 3.13 / OpenSSL 3.x requires **AKI** on non-root certs. The original 2019 certs had none. +2. Python 3.14 enables `X509_V_FLAG_X509_STRICT` in `ssl.create_default_context()`, which + additionally requires **SKI** on non-root certs and `basicConstraints`/`keyUsage` to be critical + on CA certs. + +The CA cert intentionally omits SKI even though strict mode would normally require it on all +certs: adding SKI to the CA triggers macOS SecTrust OCSP revocation checks on the MongoDB server +startup path (MongoDB Enterprise on macOS uses Apple SecTrust), causing ~67-second connection +timeouts. KMS connections bypass this by using `ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)` instead +of `ssl.create_default_context()`, which does not enable strict mode. diff --git a/test/certificates/ca.pem b/test/certificates/ca.pem index 24beea2d48..6e371ff44f 100644 --- a/test/certificates/ca.pem +++ b/test/certificates/ca.pem @@ -1,21 +1,22 @@ -----BEGIN CERTIFICATE----- -MIIDfzCCAmegAwIBAgIDB1MGMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIwMjMxMVoXDTM5MDUyMjIwMjMxMVoweTEb -MBkGA1UEAxMSRHJpdmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAw -DgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQI -EwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCl7VN+WsQfHlwapcOpTLZVoeMAl1LTbWTFuXSAavIyy0W1Ytky1UP/ -bxCSW0mSWwCgqoJ5aXbAvrNRp6ArWu3LsTQIEcD3pEdrFIVQhYzWUs9fXqPyI9k+ -QNNQ+MRFKeGteTPYwF2eVEtPzUHU5ws3+OKp1m6MCLkwAG3RBFUAfddUnLvGoZiT -pd8/eNabhgHvdrCw+tYFCWvSjz7SluEVievpQehrSEPKe8DxJq/IM3tSl3tdylzT -zeiKNO7c7LuQrgjAfrZl7n2SriHIlNmqiDR/kdd8+TxBuxjFlcf2WyHCO3lIcIgH -KXTlhUCg50KfHaxHu05Qw0x8869yIzqbAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADggEBAEHuhTL8KQZcKCTSJbYA9MgZj7U32arMGBbc1hiq -VBREwvdVz4+9tIyWMzN9R/YCKmUTnCq8z3wTlC8kBtxYn/l4Tj8nJYcgLJjQ0Fwe -gT564CmvkUat8uXPz6olOCdwkMpJ9Sj62i0mpgXJdBfxKQ6TZ9yGz6m3jannjZpN -LchB7xSAEWtqUgvNusq0dApJsf4n7jZ+oBZVaQw2+tzaMfaLqHgMwcu1FzA8UKCD -sxCgIsZUs8DdxaD418Ot6nPfheOTqe24n+TTa+Z6O0W0QtnofJBx7tmAo1aEc57i -77s89pfwIJetpIlhzNSMKurCAocFCJMJLAASJFuu6dyDvPo= +MIIDkjCCAnqgAwIBAgIDB1MGMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMMEkRy +aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMB4XDTI2MDYxMDExMzA1NVoXDTQ2MDYwNjExMzA1NVoweTEb +MBkGA1UEAwwSRHJpdmVycyBUZXN0aW5nIENBMRAwDgYDVQQLDAdEcml2ZXJzMRAw +DgYDVQQKDAdNb25nb0RCMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MREwDwYDVQQI +DAhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC9zwos89VjHIVZU7vsE4hdbXnxlncuePLhRTM50VZpp4TK9zbEJAyg +KXn2NDKGKGjy9wNtH5rPhhQSColJPZX5o2G68XF4wVQvFOMiaQ7Gwcy4b2RJzKHo +uc2pnEokw83oo1C01xkk2fiBHz0G6Ozukcb2980Pye3srdRZUbXvKxJwxdHvQ2s/ +f0ILzs2aQbVKgXryZjJNSZQqex/SbY0PsAsK4u1ztf/AXiykdIaIHNezFSMbC6UW +jqlDGj+30vg9ULB9WKlB75I0kmJOab3FpRA22ZJxLrYLxa7uypS49WLQUDUObVKM +cGDoWvUFeG/871/xgARNu2H1BG4ZaHYdAgMBAAGjIzAhMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQB6qfoZk85/hTmt +Moo3KEDmMxq0pZaPQ96qo9aVvb2l25H6+1CGXSbXQ+aTL0WhOHpAIGIJNB+Vg0ih +6/rrQi59wp2lsNcxbhR77A2fIKdsnj2rBrT62a8u27aK8jLm8DRV79Cq0yJPFTNw +IiiTo1jM/KS7okRe06tuV1xGpYWWnxILBRonlYLr58mmrZc2JJ6DOUPUSOd8BipJ +aYI+p1FcvFcDocxDf3fQuI3PVIEMRQ8wpz/BpcF8yYt/ZCiEy2n28NH35sRTrdSX +EbaA90fUAkFJd7qKXTocplVDrexz0SdUklp4xE2pDffqQlWuigX34HCHmh4EKXf1 +djoKlfPP -----END CERTIFICATE----- diff --git a/test/certificates/client.pem b/test/certificates/client.pem index 5b07001092..4159ddcc2a 100644 --- a/test/certificates/client.pem +++ b/test/certificates/client.pem @@ -1,48 +1,48 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIIDgzCCAmugAwIBAgIDAxOUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy -aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u -Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx -CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIzNTU1NFoXDTM5MDUyMjIzNTU1NFowaTEP -MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx -FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD -VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDUvFBLop+/ -ytvY13yDi6SKIdYxMllasYontjp8e7iSSnKCqJIQN13lJ1TdJOl+TMGFnDedsXJ7 -Oy2LcrdOp0aUxtv3pqFeOMPbik7h7L1G4jsElZv06CkEOBVBWaKqK1x/mZibiKST -X6FvtwpBNbxAwiHnCKugTYOckrD7b0rkiRxo6ZnO/+WVA7xRNmifEGyVN1rNB14h -G+spotOPC5cxC9lSl98Opqqofu3XGRgMu6mJNuRWfZLSrwnkGru5k8lNYbD6yhYi -rTDfENmQCLV9d2rMOfyHkk6ti4CxR5W4+SqauBpi3TQrIcx+V+xMNyGDPBB5rF/H -Zg+pob+76VcCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF -BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAqRcLAGvYMaGYOV4HJTzNotT2qE0I9THNQ -wOV1fBg69x6SrUQTQLjJEptpOA288Wue6Jt3H+p5qAGV5GbXjzN/yjCoItggSKxG -Xg7279nz6/C5faoIKRjpS9R+MsJGlttP9nUzdSxrHvvqm62OuSVFjjETxD39DupE -YPFQoHOxdFTtBQlc/zIKxVdd20rs1xJeeU2/L7jtRBSPuR/Sk8zot7G2/dQHX49y -kHrq8qz12kj1T6XDXf8KZawFywXaz0/Ur+fUYKmkVk1T0JZaNtF4sKqDeNE4zcns -p3xLVDSl1Q5Gwj7bgph9o4Hxs9izPwiqjmNaSjPimGYZ399zcurY +MIIDgTCCAmmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTAxMTMwNTVaFw00NjA2MDYxMTMwNTVaMGkxDzAN +BgNVBAMMBmNsaWVudDEQMA4GA1UECwwHRHJpdmVyczEMMAoGA1UECgwDTURCMRYw +FAYDVQQHDA1OZXcgWW9yayBDaXR5MREwDwYDVQQIDAhOZXcgWW9yazELMAkGA1UE +BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLjKA70eB+V4x6 +gcpMaK58v4CSN3odJR9PLvp+9iZ3y6hjxdc8qd09KXgcL1Tf+e4XmpHqxbAhmvKF +37U8wP01N1m/Bs72+bZy2+7e7JVbIOILmIbTjFvR6jGunPx0fJ7fqtTSqVtuwpJX +3tBw+vFsewJlQc+zfsPhLx9lMukQWCNiX0+GK2DHS9WVDxVAXELMRemuZVlpP8QI +irnydXyAMrL4UNVh2FiYPeg4dS875mq+1sHZM0JLb7Vkfzr2+gzhrAEbjJIRcosx +ZRj/4Jq/XXMtzxWwTwswqx2sw9oR9qsMB+jH7fUzTQJKj5v+Ubv7AtjafJiE7bfV +dAfzNNZDAgMBAAGjJDAiMAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD +AjANBgkqhkiG9w0BAQsFAAOCAQEABR1ZOvDOiwAVTy+z/MtzfCHrVXUmYmnPybaG +j8ADepJhgEzeZjDmiLkR7Cuo10g9N2TzZYTzrhFWjjOP3iWDU47oCYR5j30V3U6x +zX1/Uh/KOKuIu2NkcYNUSPlU2zq3JvyMErYiPvIQ8t8y8M/AhjPxy2uWNQ98hb3j +s9qdiScJ+ejsoI72BzgRMh7eK+wrxhqZRIAKI9VSy1TIGlXwtnTcU3Tk0uN21HaH +LgOksFqnTEOafbvYUZruaU0XM6p3LvUn/9fCTB7NPUiGaDQIfAAixyH5Nuxu/X/Z +j7PvajaG6jMGgYZl9OXGGMw9zRaAiE2NDOOl5XEQ1tbeZr1ANQ== -----END CERTIFICATE----- diff --git a/test/certificates/crl.pem b/test/certificates/crl.pem index 733a0acdc0..845797f3ce 100644 --- a/test/certificates/crl.pem +++ b/test/certificates/crl.pem @@ -1,13 +1,12 @@ -----BEGIN X509 CRL----- -MIIB6jCB0wIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDExJEcml2ZXJzIFRl -c3RpbmcgQ0ExEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01vbmdvREIxFjAU -BgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQG -EwJVUxcNMTkwNTIyMjI0NTUzWhcNMTkwNjIxMjI0NTUzWjAVMBMCAncVFw0xOTA1 -MjIyMjQ1MzJaoA8wDTALBgNVHRQEBAICEAAwDQYJKoZIhvcNAQELBQADggEBACwQ -W9OF6ExJSzzYbpCRroznkfdLG7ghNSxIpBQUGtcnYbkP4em6TdtAj5K3yBjcKn4a -hnUoa5EJGr2Xgg0QascV/1GuWEJC9rsYYB9boVi95l1CrkS0pseaunM086iItZ4a -hRVza8qEMBc3rdsracA7hElYMKdFTRLpIGciJehXzv40yT5XFBHGy/HIT0CD50O7 -BDOHzA+rCFCvxX8UY9myDfb1r1zUW7Gzjn241VT7bcIJmhFE9oV0popzDyqr6GvP -qB2t5VmFpbnSwkuc4ie8Jizip1P8Hg73lut3oVAHACFGPpfaNIAp4GcSH61zJmff -9UBe3CJ1INwqyiuqGeA= +MIIB2DCBwQIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2ZXJzIFRl +c3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdvREIxFjAU +BgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQswCQYDVQQG +EwJVUxcNMjYwNjExMTEzMDU1WhcNNDYwNjA2MTEzMDU1WjAUMBICAQEXDTI2MDYx +MTExMzA1NVowDQYJKoZIhvcNAQELBQADggEBAIWkzWOI2wCWjr7rEwQBgf4mi3iG +edHPWV+4BXQeR9R4SfpfeNAgZidUFEGpX6vLdYNcYysuuqhPZKgnNsQl1IiX8Lp8 +ijUpAZAsj3t29Q/ntK23swW4PJ/rnRjWKoLMRwJybf/8CSEct5knRi1kfxN69kv8 +SgeTo97xrEfBH6czdzk8A1Wwlz44Qz28Q4VdsMkl7lqsJERjSH2XFTuhbq2Dvj3S +PvnUnj0i+RFH4T2CVaZnp2zbFh1gaDAbQstHtdd8ZFCmsTmkFjcZ4NRxUmJAEgd8 +chaq11h3Zto8Ja26TK8Yi3vS8sXq6pHjmCbEwgvvo6+F0FogM0hlxiCw3AY= -----END X509 CRL----- diff --git a/test/certificates/expired.pem b/test/certificates/expired.pem new file mode 100644 index 0000000000..31a54f3dc7 --- /dev/null +++ b/test/certificates/expired.pem @@ -0,0 +1,52 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAygbU020ifgr+Pe4ee9JtQQS6lsnuQs7FWBno5P196F12gb94 +7uRhFT6e63ZTJ82Ds0peSqTgmek8kM8EMXU4rsQL3LQKToaAKRVWPBmssPTMolBS +1XmG55cgXy5QUkfvo826pwrSATqEFpkByEoP55wn9jX3C2UBPo4hoVdBjDFCplY1 +IvvFe4fvbxfZSbM3TPdkyxnfAuoRvmuu2h5kcKsKrqSyHqFV3e4K5PgmRtnONHH2 +dhwVXQRHNLxAFpwRSYLZBUJcoOdV9hUBK+5oayMAFjeQao0dmH75Vtu8uDrlBKCm +8ruI5xqsUaWFyoLDhdv+4rptL+M+Zjj3iaAEYwIDAQABAoIBADvnpKoAvW6UgekJ +N57NubnC1jUqMW079MZ4AFgOVoxVUnOMvCZSL/tlsyfs0SGHThsW3TjTBQp+X4gs +6nhj4ufnmADcngXE2jHUctqlXlCmdhtXKAjG3VrEtEOk7wpG7Gcs9MDdc4ILwOkW +e7HRTEAITM00GUoWrDTJXm2B+xy/YuRa8xM83JLtN63pm1g6Bp4I22wngig+ZBgg +7UXZiGTJ4RBj0xdXT2A0xBNzJ791snenN+m73fhqbsqdFFt867jrKNVB7LVm50vD +sBiJFo37q1PwFIq/7Nr5vdjo4TfIyuIMmgkkSFRhxpqZteVq/A0ehInQYxaMvHA4 +d54Y3VECgYEA/nN14Xes3PYScAga/XOeDzNpcFp+2MVaVmMt3DoJtIcwOHfpgh9i +gQ+kHxK5DkpQgc2i+22YdHoHKLBf++hW75Eqt4ZU0msDMjtuETTrdwWfi0BQvx89 +aVAGsCpyWbaCSGd09TNgf6u0VHuBmAXIsihNPjX5s1Y1r/BfFpbVokkCgYEAy0Gs +Ez+aUNGGe8PDwvQqfI3bV8tEKufO4YoZZ++0LNTwUTc0+EjGQhzJnv2jBmerlwZR +J0HZFrF6QFHNZoQ5J34AIqZLHIl+v1NHtUztKoCpO9ow2JuSNYd/Pmb1SYv9XlT1 +5Iw5pfYRAW0/wf3IXjfVoWIqZ6KxuC5poTUtsUsCgYEAgmhCXg+rtIMY5/n/ey4q +L7g1rbNzlz1uEyA5fMjx+GfgutAaCOp03ZhakOJTnZNQt3XgteNxYyC3Uo8yYjSt +eZJ4xh4+kqjttmzm+EKa+yESp5eKyqkEHFk7VEYs3PXAx8LeGlz+c/BYN4Qk4vjz +5vrou52GH/drBIS49ybOzqECgYA3e+vfLUOQwEF3047Czygx6/9uTdyD4deFlc8t +oi+K9W3Mncdl52fHcFhRgGdaPj6G8YCBuOXr3fLDUBFD5OA9OZYL310toxLoY3F1 +ulQbgBeycPNYjc8xsZU4kZ5vvzkg4QxmoSizdyJZQ1teN0rU/WThswxkUfM1leXb +zcp1VQKBgQCvCkuRVBliJethGU0fj8rhTycFC1uACqwCcw5PAwm6SjW2rfsB/+y8 +U0XvKbed8AB8yNIbzxVmIyPQa1TTiuTSLmSZVLDlepmfMRcTnsZJJzfM8mrZHdFP +Exg0mcIBDqI5V6z0PKAOjrYqFQBC8Yvk/dc31dfyLlOJiwHerOpP2g== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIBBDANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0wMDAxMDEwMDAwMDBaFw0wMTAxMDEwMDAwMDBaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAygbU +020ifgr+Pe4ee9JtQQS6lsnuQs7FWBno5P196F12gb947uRhFT6e63ZTJ82Ds0pe +SqTgmek8kM8EMXU4rsQL3LQKToaAKRVWPBmssPTMolBS1XmG55cgXy5QUkfvo826 +pwrSATqEFpkByEoP55wn9jX3C2UBPo4hoVdBjDFCplY1IvvFe4fvbxfZSbM3TPdk +yxnfAuoRvmuu2h5kcKsKrqSyHqFV3e4K5PgmRtnONHH2dhwVXQRHNLxAFpwRSYLZ +BUJcoOdV9hUBK+5oayMAFjeQao0dmH75Vtu8uDrlBKCm8ruI5xqsUaWFyoLDhdv+ +4rptL+M+Zjj3iaAEYwIDAQABo4HiMIHfMCwGA1UdEQQlMCOCCWxvY2FsaG9zdIcE +fwAAAYcQAAAAAAAAAAAAAAAAAAAAATCBjwYDVR0jBIGHMIGEoX2kezB5MRswGQYD +VQQDDBJEcml2ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNV +BAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5l +dyBZb3JrMQswCQYDVQQGEwJVU4IDB1MGMB0GA1UdDgQWBBQ3oyQ4KHs5v8o4YN73 +YoZSOuL3szANBgkqhkiG9w0BAQsFAAOCAQEAROHXMBYMDlcpcpsyVp40Wiapl9wJ +nB7ZIjAiFxW3B88O4Grc3coHibBleoiRRXrJLYX6dnSp2e7h8lv5o0MEhBxkTs/W +iCJCqeC6U3G8pLVgbmW+nOjcvGgfUCMx3cBUvet1tfwiaqj0Vu+nYuHTy3LkZGbE +INm/G1kL3vZQC/OLpnL3yXG9Nw/z3JM3k85Dj0ewZHLEjKgIg2l6N8lC0v+R/z1y +X+n9ZfK187r0aEumgR8GQq+NbtnGIKlUx60mN5FGdDFsEDkGQbuL1XygRjs6VdS0 +Rq3gELV0aYZnxETX15YeTB/6IZ1vkkMmCrgFXwvaq7w3fg29h+Yww3eySQ== +-----END CERTIFICATE----- diff --git a/test/certificates/gen-certs.py b/test/certificates/gen-certs.py new file mode 100644 index 0000000000..a2d99926a1 --- /dev/null +++ b/test/certificates/gen-certs.py @@ -0,0 +1,474 @@ +# /// script +# requires-python = ">=3.8" +# dependencies = ["cryptography>=44.0.0"] +# /// +"""Generate TLS test certificates for the PyMongo test suite. + +Two classes of leaf cert are generated: + + MongoDB certs (server.pem, client.pem, password_protected.pem): + No Authority Key Identifier (AKI) extension. MongoDB Enterprise on macOS uses Apple SecTrust with + kSecRevocationRequirePositiveResponse. When AKI is present, SecTrust uses + it to identify the issuer, then attempts OCSP. Because our CA is not in + the macOS system keychain on Evergreen driver CI hosts, OCSP fails and + SecTrust returns CSSMERR_TP_CERT_SUSPENDED. Without AKI, SecTrust cannot + identify the issuer and skips the OCSP attempt. + + KMS certs (server-kms.pem, wrong-host.pem, expired.pem): + Carry AKI in the issuer form (DirName + serial, no keyid). These certs + are verified by Python's ssl module (OpenSSL), not by MongoDB Enterprise. + Python 3.13 / OpenSSL 3.x requires AKI on non-root certs. The issuer + form satisfies that requirement. Using the issuer form (not keyid) avoids + providing a keyid, which would separately enable macOS SecTrust's + keyid-based OCSP lookup on any path that does use SecTrust. + +The CA (ca.pem) intentionally has only basicConstraints: CA:TRUE and no other +extensions. The original test CA shipped in this directory (from 2019) used +exactly this minimal profile and worked fine on macOS. Adding keyUsage, +subjectAltName, or Subject Key Identifier (SKI)/AKI to the CA cert causes macOS SecTrust to treat it +like a leaf cert requiring its own OCSP check, which then fails +(CSSMERR_TP_CERT_SUSPENDED) because the CA is not in the system keychain. + +Usage: + uv run gen-certs.py # run from test/certificates/ + +Password for password_protected.pem: qwerty +""" +from __future__ import annotations + +import datetime +import ipaddress +import sys +from pathlib import Path + +from cryptography import x509 +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.serialization import ( + BestAvailableEncryption, + Encoding, + NoEncryption, + PrivateFormat, +) +from cryptography.x509.oid import ExtendedKeyUsageOID, NameOID + +SCRIPT_DIR = Path(__file__).parent.resolve() +DAYS = 7300 # ~20 years +NOW = datetime.datetime.now(datetime.timezone.utc) +NOT_BEFORE = NOW - datetime.timedelta(days=1) +NOT_AFTER = NOW + datetime.timedelta(days=DAYS) + + +def make_key() -> rsa.RSAPrivateKey: + return rsa.generate_private_key(public_exponent=65537, key_size=2048) + + +def key_pem(key, password=None) -> bytes: + enc = BestAvailableEncryption(password) if password else NoEncryption() + return key.private_bytes(Encoding.PEM, PrivateFormat.TraditionalOpenSSL, enc) + + +def cert_pem(cert) -> bytes: + return cert.public_bytes(Encoding.PEM) + + +def aki_from_ca(ca_cert: x509.Certificate) -> x509.AuthorityKeyIdentifier: + # Issuer form (DirName + serial, no keyid). OpenSSL 3.3+ (bundled with + # Windows Python 3.13+) requires the issuer cert to have SKI when the leaf + # uses keyid-form AKI. Our CA intentionally omits SKI, so we use issuer + # form to avoid that requirement. Issuer form still satisfies Python 3.13+ + # which requires AKI to be present on non-root certs. + return x509.AuthorityKeyIdentifier( + key_identifier=None, + authority_cert_issuer=[x509.DirectoryName(ca_cert.issuer)], + authority_cert_serial_number=ca_cert.serial_number, + ) + + +def server_san() -> x509.SubjectAlternativeName: + return x509.SubjectAlternativeName( + [ + x509.DNSName("localhost"), + x509.IPAddress(ipaddress.IPv4Address("127.0.0.1")), + x509.IPAddress(ipaddress.IPv6Address("::1")), + ] + ) + + +CA_NAME = x509.Name( + [ + x509.NameAttribute(NameOID.COMMON_NAME, "Drivers Testing CA"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Drivers"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "MongoDB"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "New York City"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "New York"), + x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), + ] +) + +SERVER_NAME = x509.Name( + [ + x509.NameAttribute(NameOID.COMMON_NAME, "localhost"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Drivers"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "MongoDB"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "New York City"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "New York"), + x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), + ] +) + +# Attribute order must be CN→OU→O→L→ST→C so that MongoDB's reversed-order +# x509 username string is "C=US,ST=New York,L=New York City,O=MDB,OU=Drivers,CN=client" +CLIENT_NAME = x509.Name( + [ + x509.NameAttribute(NameOID.COMMON_NAME, "client"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Drivers"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "MDB"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "New York City"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "New York"), + x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), + ] +) + +TRUSTED_CA_NAME = x509.Name( + [ + x509.NameAttribute(NameOID.COMMON_NAME, "Trusted Kernel Test CA"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Kernel"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "MongoDB"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "New York City"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "New York"), + x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), + ] +) + + +# --------------------------------------------------------------------------- +# 0. Drivers Testing CA. +# Has basicConstraints (critical) and keyUsage (critical, keyCertSign + +# crlSign) as required by RFC 5280 and enforced by Python 3.14 / OpenSSL +# 3.x strict mode (ssl.create_default_context). +# No SKI, no AKI, no SAN. Adding SKI to the CA triggers a macOS +# SecTrust OCSP sweep on the server startup path even when +# --tlsAllowInvalidCertificates is set, causing connection timeouts +# on MongoDB 4.2 sharded-cluster tests. Python 3.14 only requires SKI +# on non-root (leaf) certs, so the CA can safely omit it. +# --------------------------------------------------------------------------- +print("==> Generating Drivers Testing CA...") +ca_key = make_key() +ca_cert = ( + x509.CertificateBuilder() + .subject_name(CA_NAME) + .issuer_name(CA_NAME) + .public_key(ca_key.public_key()) + .serial_number(480006) + .not_valid_before(NOT_BEFORE) + .not_valid_after(NOT_AFTER) + .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) + .add_extension( + x509.KeyUsage( + digital_signature=False, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=False, + key_cert_sign=True, + crl_sign=True, + encipher_only=False, + decipher_only=False, + ), + critical=True, + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "ca.pem").write_bytes(cert_pem(ca_cert)) +print(" ca.pem written (subject:", ca_cert.subject.rfc4514_string(), ")") + + +# --------------------------------------------------------------------------- +# 1. Server certificate — serial 1, revoked in crl.pem for test_tlsCRLFile_support +# No AKI: presented to MongoDB Enterprise (Apple SecTrust on macOS). +# --------------------------------------------------------------------------- +print("==> Generating server certificate (no AKI)...") +server_key = make_key() +server_cert = ( + x509.CertificateBuilder() + .subject_name(SERVER_NAME) + .issuer_name(CA_NAME) + .public_key(server_key.public_key()) + .serial_number(1) + .not_valid_before(NOT_BEFORE) + .not_valid_after(NOT_AFTER) + .add_extension(server_san(), critical=False) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "server.pem").write_bytes(key_pem(server_key) + cert_pem(server_cert)) +print(" server.pem written") + + +# --------------------------------------------------------------------------- +# 1b. KMS server certificate — serial 5, with AKI. +# Used by kms_failpoint_server.py (port 9003). Verified by Python's ssl +# module (OpenSSL), NOT by MongoDB Enterprise — so AKI is safe here and +# is required for Python 3.13 / OpenSSL 3.x chain building. +# --------------------------------------------------------------------------- +print("==> Generating KMS server certificate (with AKI)...") +server_kms_key = make_key() +server_kms_cert = ( + x509.CertificateBuilder() + .subject_name(SERVER_NAME) + .issuer_name(CA_NAME) + .public_key(server_kms_key.public_key()) + .serial_number(5) + .not_valid_before(NOT_BEFORE) + .not_valid_after(NOT_AFTER) + .add_extension(server_san(), critical=False) + .add_extension(aki_from_ca(ca_cert), critical=False) + .add_extension( + x509.SubjectKeyIdentifier.from_public_key(server_kms_key.public_key()), critical=False + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "server-kms.pem").write_bytes(key_pem(server_kms_key) + cert_pem(server_kms_cert)) +print(" server-kms.pem written") + + +# --------------------------------------------------------------------------- +# 2. Client certificate — serial 2 +# No AKI: presented to MongoDB Enterprise during x509 auth. +# --------------------------------------------------------------------------- +print("==> Generating client certificate (no AKI)...") +client_key = make_key() +client_cert = ( + x509.CertificateBuilder() + .subject_name(CLIENT_NAME) + .issuer_name(CA_NAME) + .public_key(client_key.public_key()) + .serial_number(2) + .not_valid_before(NOT_BEFORE) + .not_valid_after(NOT_AFTER) + .add_extension( + x509.KeyUsage( + digital_signature=True, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=False, + key_cert_sign=False, + crl_sign=False, + encipher_only=False, + decipher_only=False, + ), + critical=False, + ) + .add_extension( + x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CLIENT_AUTH]), + critical=False, + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "client.pem").write_bytes(key_pem(client_key) + cert_pem(client_cert)) +print(" client.pem written") + + +# --------------------------------------------------------------------------- +# 3. Password-protected client certificate (same cert, encrypted key) +# --------------------------------------------------------------------------- +print("==> Generating password-protected client certificate...") +(SCRIPT_DIR / "password_protected.pem").write_bytes( + key_pem(client_key, password=b"qwerty") + cert_pem(client_cert) +) +print(" password_protected.pem written (password: qwerty)") + + +# --------------------------------------------------------------------------- +# 4. CRL — revokes the server cert (serial 1) for test_tlsCRLFile_support +# --------------------------------------------------------------------------- +print("==> Generating CRL...") +crl = ( + x509.CertificateRevocationListBuilder() + .issuer_name(CA_NAME) + .last_update(NOW) + .next_update(NOW + datetime.timedelta(days=DAYS)) + .add_revoked_certificate( + x509.RevokedCertificateBuilder().serial_number(1).revocation_date(NOW).build() + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "crl.pem").write_bytes(crl.public_bytes(Encoding.PEM)) +print(" crl.pem written") + + +# --------------------------------------------------------------------------- +# 5. Wrong-host certificate (serial 3) — used in KMS TLS tests (with AKI) +# --------------------------------------------------------------------------- +print("==> Generating wrong-host certificate (with AKI)...") +wrong_host_key = make_key() +wrong_host_cert = ( + x509.CertificateBuilder() + .subject_name( + x509.Name( + [ + x509.NameAttribute(NameOID.COMMON_NAME, "wronghost.example.com"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Drivers"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "MongoDB"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "New York City"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "New York"), + x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), + ] + ) + ) + .issuer_name(CA_NAME) + .public_key(wrong_host_key.public_key()) + .serial_number(3) + .not_valid_before(NOT_BEFORE) + .not_valid_after(NOT_AFTER) + .add_extension( + x509.SubjectAlternativeName([x509.DNSName("wronghost.example.com")]), + critical=False, + ) + .add_extension(aki_from_ca(ca_cert), critical=False) + .add_extension( + x509.SubjectKeyIdentifier.from_public_key(wrong_host_key.public_key()), critical=False + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "wrong-host.pem").write_bytes(key_pem(wrong_host_key) + cert_pem(wrong_host_cert)) +print(" wrong-host.pem written (SAN: wronghost.example.com)") + + +# --------------------------------------------------------------------------- +# 6. Expired certificate (serial 4) — used in KMS TLS tests (with AKI) +# --------------------------------------------------------------------------- +print("==> Generating expired certificate (with AKI)...") +expired_key = make_key() +expired_cert = ( + x509.CertificateBuilder() + .subject_name(SERVER_NAME) + .issuer_name(CA_NAME) + .public_key(expired_key.public_key()) + .serial_number(4) + .not_valid_before(datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc)) + .not_valid_after(datetime.datetime(2001, 1, 1, tzinfo=datetime.timezone.utc)) + .add_extension(server_san(), critical=False) + .add_extension(aki_from_ca(ca_cert), critical=False) + .add_extension( + x509.SubjectKeyIdentifier.from_public_key(expired_key.public_key()), critical=False + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "expired.pem").write_bytes(key_pem(expired_key) + cert_pem(expired_cert)) +print(" expired.pem written (expired 2001-01-01)") + + +# --------------------------------------------------------------------------- +# 7. Trusted Kernel Test CA — separate CA used in CA-bundle tests only. +# This is an independent CA unrelated to the main Drivers Testing CA. +# --------------------------------------------------------------------------- +print("==> Generating Trusted Kernel Test CA...") +trusted_ca_key = make_key() +trusted_ca_cert = ( + x509.CertificateBuilder() + .subject_name(TRUSTED_CA_NAME) + .issuer_name(TRUSTED_CA_NAME) + .public_key(trusted_ca_key.public_key()) + .serial_number(200) + .not_valid_before(NOT_BEFORE) + .not_valid_after(NOT_AFTER) + .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) + .add_extension( + x509.KeyUsage( + digital_signature=False, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=False, + key_cert_sign=True, + crl_sign=True, + encipher_only=False, + decipher_only=False, + ), + critical=True, + ) + .sign(trusted_ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "trusted-ca.pem").write_bytes(cert_pem(trusted_ca_cert)) +print(" trusted-ca.pem written") + + +# --------------------------------------------------------------------------- +# Verification +# --------------------------------------------------------------------------- +print() +print("==> Verifying cert properties...") + +import subprocess + + +def cert_text(path: Path) -> str: + return subprocess.check_output( + ["openssl", "x509", "-noout", "-text", "-in", str(path)], + stderr=subprocess.DEVNULL, + ).decode() + + +errors = 0 + +# CA cert must have critical basicConstraints + keyUsage; must NOT have AKI/SKI/SAN. +# SKI is intentionally omitted from the CA: adding it causes macOS SecTrust to +# attempt OCSP on the MongoDB server startup path, producing 67-second timeouts. +# Python 3.14 only requires SKI on non-root leaf certs, not on the root CA. +ca_text = cert_text(SCRIPT_DIR / "ca.pem") +ca_errors = 0 +if "Basic Constraints: critical" not in ca_text: + print( + " ca.pem: ERROR — basicConstraints not critical (required by RFC 5280 / Python 3.14)", + file=sys.stderr, + ) + ca_errors += 1 +if "Key Usage: critical" not in ca_text: + print( + " ca.pem: ERROR — keyUsage missing or not critical (required by Python 3.14)", + file=sys.stderr, + ) + ca_errors += 1 +for ext in ("Authority Key Identifier", "Subject Key Identifier", "Subject Alternative Name"): + if ext in ca_text: + print(f" ca.pem: ERROR — has {ext} (would cause macOS OCSP issues)", file=sys.stderr) + ca_errors += 1 +if ca_errors: + errors += ca_errors +else: + print(" ca.pem: OK") + +# MongoDB certs must NOT have AKI. +for name in ("server.pem", "client.pem"): + text = cert_text(SCRIPT_DIR / name) + if "Authority Key Identifier" in text: + print( + f" {name}: ERROR — has AKI (would cause CSSMERR_TP_CERT_SUSPENDED on macOS)", + file=sys.stderr, + ) + errors += 1 + else: + print(f" {name}: OK (no AKI)") + +# KMS certs MUST have AKI and SKI. +for name in ("server-kms.pem", "wrong-host.pem", "expired.pem"): + text = cert_text(SCRIPT_DIR / name) + cert_errors = 0 + if "Authority Key Identifier" not in text: + print(f" {name}: ERROR — missing AKI (required for Python 3.13)", file=sys.stderr) + cert_errors += 1 + if "Subject Key Identifier" not in text: + print(f" {name}: ERROR — missing SKI (required for Python 3.14)", file=sys.stderr) + cert_errors += 1 + if cert_errors: + errors += cert_errors + else: + print(f" {name}: OK (has AKI + SKI)") + +if errors: + sys.exit(1) + +print() +print("Done. All certificates regenerated.") diff --git a/test/certificates/gen-certs.sh b/test/certificates/gen-certs.sh new file mode 100755 index 0000000000..84db9ec1e2 --- /dev/null +++ b/test/certificates/gen-certs.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# Thin wrapper — delegates certificate generation to gen-certs.py. +# See gen-certs.py for full documentation on the cert design. +# +# Usage: bash gen-certs.sh (run from test/certificates/) +# Requires: uv + +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")" +uv run gen-certs.py diff --git a/test/certificates/password_protected.pem b/test/certificates/password_protected.pem index cc9e124703..7b1fb0be78 100644 --- a/test/certificates/password_protected.pem +++ b/test/certificates/password_protected.pem @@ -1,51 +1,51 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIC8as6PDVhwECAggA -MB0GCWCGSAFlAwQBAgQQTYOgCJcRqUI7dsgqNojv/ASCBNCG9fiu642V4AuFK34c -Q42lvy/cR0CIXLq/rDXN1L685kdeKex7AfDuRtnjY2+7CLJiJimgQNJXDJPHab/k -MBHbwbBs38fg6eSYX8V08/IyyTege5EJMhYxmieHDC3DXKt0gyHk6hA/r5+Mr49h -HeVGwqBLJEQ3gVIeHaOleZYspsXXWqOPHnFiqnk/biaJS0+LkDDEiQgTLEYSnOjP -lexxUc4BV/TN0Z920tZCMfwx7IXD/C+0AkV/Iqq4LALmT702EccB3indaIJ8biGR -radqDLR32Q+vT9uZHgT8EFiUsISMqhob2mnyTfFV/s9ghWwogjSz0HrRcq6fxdg7 -oeyT9K0ET53AGTGmV0206byPu6qCj1eNvtn+t1Ob+d5hecaTugRMVheWPlc5frsz -AcewDNa0pv4pZItjAGMqOPJHfzEDnzTJXpLqGYhg044H1+OCY8+1YK7U0u8dO+/3 -f5AoDMq18ipDVTFTooJURej4/Wjbrfad3ZFjp86nxfHPeWM1YjC9+IlLtK1wr0/U -V8TjGqCkw8yHayz01A86iA8X53YQBg+tyMGjxmivo6LgFGKa9mXGvDkN+B+0+OcA -PqldAuH/TJhnkqzja767e4n9kcr+TmV19Hn1hcJPTDrRU8+sSqQFsWN4pvHazAYB -UdWie+EXI0eU2Av9JFgrVcpRipXjB48BaPwuBw8hm+VStCH7ynF4lJy6/3esjYwk -Mx+NUf8+pp1DRzpzuJa2vAutzqia5r58+zloQMxkgTZtJkQU6OCRoUhHGVk7WNb1 -nxsibOSzyVSP9ZNbHIHAn43vICFGrPubRs200Kc4CdXsOSEWoP0XYebhiNJgGtQs -KoISsV4dFRLwhaJhIlayTBQz6w6Ph87WbtuiAqoLiuqdXhUGz/79j/6JZqCH8t/H -eZs4Dhu+HdD/wZKJDYAS+JBsiwYWnI3y/EowZYgLdOMI4u6xYDejhxwEw20LW445 -qjJ7pV/iX2uavazHgC91Bfd4zodfXIQ1IDyTmb51UFwx0ARzG6enntduO6xtcYU9 -MXwfrEpuZ/MkWTLkR0PHPbIPcR1MiVwPKdvrLk42Bzj/urtXYrAFUckMFMzEh+uv -0lix2hbq/Xwj4dXcY4w9hnC6QQDCJTf9S6MU6OisrZHKk0qZ2Vb4aU/eBcBsHBwo -X/QGcDHneHxlrrs2eLX26Vh8Odc5h8haeIxnfaa1t+Yv56OKHuAztPMnJOUL7KtQ -A556LxT0b5IGx0RcfUcbG8XbxEHseACptoDOoguh9923IBI0uXmpi8q0P815LPUu -0AsE47ATDMGPnXbopejRDicfgMGjykJn8vKO8r/Ia3Fpnomx4iJNCXGqomL+GMpZ -IhQbKNrRG6XZMlx5kVCT0Qr1nOWMiOTSDCQ5vrG3c1Viu+0bctvidEvs+LCm98tb -7ty8F0uOno0rYGNQz18OEE1Tj+E19Vauz1U35Z5SsgJJ/GfzhSJ79Srmdg2PsAzk -AUNTKXux1GLf1cMjTiiU5g+tCEtUL9Me7lsv3L6aFdrCyRbhXUQfJh4NAG8+3Pvh -EaprThBzKsVvbOfU81mOaH9YMmUgmxG86vxDiNtaWd4v6c1k+HGspJr/q49pcXZP -ltBMuS9AihstZ1sHJsyQCmNXkA== ------END ENCRYPTED PRIVATE KEY----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,9B26104D72E90A4AE4E8355541FD1B81 + +QDsm9JSkQpHo9VB3dll1d9B8IDwWVyJ0afv5OibY68tMkUizJfwDIg4NdKHeJ93F +gfSRTt5WYLJX//WTJS9QaERD3Om5/k/4Jgp4RXysh9qApCojwWWEziKqcGmO4rYq +nD9caU9XDheDmM8bFzoOQMP08DAEpDv6pjVh4S8zdjx/x2rP6+9pSCMcW0AA4L9F +U2RF67rWoZL10hetrpuPCq955axY8O0p6spXicbMOWnXvK2muTmpzpm896Q8pEu9 +NHmKsb0NnY2WiC0iZMz1FUPyHgCiMrOb5OXrX9UkPM8Kk5eHiiMmSV77ry2awPD0 +o5czmvjY6m8dKaDbsKEUjNV7NNm2HfbF0B3Cl9Yi6OQj81WavwreQ7y3AcHxiqmz +RVwItH0txM7HWOUqc6oCbLkiRGz3ahRLzUGG+Uvba6KON+zIp+6E2dC9z8CTbTxo +3vSh3MKK9rH/4L/CTeef5dPdnZIN0jlWPJlK9hyY2clu8AdpqYzg+p9fo2R8q5Yf +YNlsBv8UdnD0WA2aS8vQfSXYtcOckgtnS4xY8H1ODzm7js472H3svSi4rvXLqHsU +npsttzgrKPJlLtGcI7c6OGDyWGMyDAz+ERYEp2qNHVYI4LM+GY99UhvnxJJvchGJ +Cw05gJMHUXbYaap/NQRTJTLgmYmJpbKZGMEvg97JrM10wHM4Tte0OqTdYjEPREHo +20Z3wx4ocunA23V749HyknhgzrsMwQ8p6wVUu5RglgyutWr97y+HatyPswLPHI1d +gzUqx8ujBt3wrUYVfFy8ZxNgqumwZau98rMF87YwH1w/dikVjzceFbfAU7wvESG0 +t2ZkIhmJ6N73nc2/AUx0uwbHBcpax4eP7dNSEhWJ/DSRfbdC8Gw1n+uxzGaNqfXF +z5Ex9imurgQGTRqwX+JgUK6S7DMaw+5sqEJxqpfwmP8l6RCy36Ty2u3wfu/cXBN3 +PWt8GQRDWaqgZmfu7qrkA4qk6Wx1/ZuKzpSMgLzhm3l+xT92+bXf+PnlQ3KaJNlF +mq71/0lLnWxkPDQ+E3BE5xDyJxsE11Tj0Gu1+Q+diENVkb0ASdNlCDap/IbTRs/2 +ngYN1jAAtJnqoBe0DE30NExtTbEBX1RZTTRBAwAw2PKCZHI8ncCZr7ITWm9O8yAC +HlNn0/nLsbnySbzVs8/CSO16K5bDz64ltAwJE7nj3VG7g2F+ouCaMIAcTd1iLpSF +qHsjYjPg767lU08MLhsbcMfhP6mciGfbjlRyvSyHqTir+I1r2X6gvrqJkTHdmER9 +t/QPA16FaA8HeqF1xmqccr9TCZyeco/TW4e6M9R4NVn1ey5BS7SM9iq/O3LyLtqm +x0Qriy3KQlO8eIWsmzKxEqvP2RQhvUxN1zeOgCv7VrfTRp0nmv0Iz+zwRZhlulYB +gSsV6Frta3jl7v29bKtbkqMuB+Ix4VeycuALfz6JkKyIfYtSJOPZfvQrBaFXX/8I +Bo6fJ26nhCf2/dFRynC5uTtefU/7X5mP1uBcEku8QKv6f0VhnUnUaKkt+4RLNPgT +iDek+Mc8gxZr5BAbYnahE790m9ho8F3ce60ITr2K4pypE6zHHjSHr4Cz75CXeoz0 +-----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/test/certificates/server-kms.pem b/test/certificates/server-kms.pem new file mode 100644 index 0000000000..1a4cf62255 --- /dev/null +++ b/test/certificates/server-kms.pem @@ -0,0 +1,52 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAnr7w+Qvx3cfgYSj3Ha+kbO/1dJoZ3PZA+NbG5gBuePZVrFS2 ++g4heiVMy1vv9oCbNpTcszqaC0yqkQKz3r63ar5u8uqYjOaf3RHEMDQEP3GFYaOF +XDFKUx+CZXrmgZoeMWNYmUP5VwTF2M3dq/APE3zAB0mnMcBv8omJ8jgb2DbvI3X1 +KmK9SWqaRvG8OQu/9gaAyBzR/dS+NpcVxakdeK2uBe3UzldYnqu7VRrFJfQ4zjdp +9LJ098vYVhKwLhaByj3IdqIBiaQpGtDkbJUVHgZoHYKjmnK8bc4rRdkvxTbH1jJg +B9pBnyDpCfWezSP+G9a7nsXFkaAp+zx40bgKQwIDAQABAoIBAAhmmgGdl5u6zSDQ +wysUaKlfLxuP+b7PK8Cl1ROTTqu8e+vJW+ZY9kqTGMCv4wxyrkQYL3AvF+6kv84G +v5Z4SOQvcCQPNPcX6VPdcdPY0A5V2pvAXiyMnmtOgPipciaS2lz9h4Qs31AZYsL5 +05/nh1S3rSd1k8SDpsKS2fSYi/JIK8x1PdtSy3K2+1LMIxEya2oP05nLfA2g5yW8 +ejpM2IlAqgHalfJlrHa5BH8L95QUnKmYKL8dTjdlATeC4WsEJB60MBwnpS2pscKH +u7sXGm32mK9b58bxDiKbQSxxyF51tyRWGk8Ls7yA04rN5+pzdghzMxhOcksia3Gk +k1EzdEkCgYEA0FgiLA33B+X6/ds/2vBoWu623KjQNff6e2ynWktBmQWQR+ixEuJs +s098QyXKrHPvFvtl9WzQjqyixARhvcRr5Ex+q43vjbrPqtFis5rhqIankZoBC5z0 +Z0/hQ0hA/ugXW6bZR0OYXVcAFxhm8oRGupVfUnG/U/jkDT3ibkP0RH8CgYEAww6C +ZdHV9TMSOCdps02Er/kIVSetnJNTqAdNnGtILGmT/31ufjTQM4TIZReGhlHXfXSD +MA5SjxFzlfxxtW+HwBs96KNy1H7ieM7dFWcveyg8JFxXa+Azr8UkrmEVZHEGJhK0 +gQoVi7/bQUCIwlBSOPJsdgL4dqWZewY/nnLASD0CgYEAp8lCg+4fMrow3z4x97VC +pXC3zY8aV0xE6h8/y4Tt6DlFz9OCv22gEuwBa+ZEiYu4Ue7WVsdyUmSPlILe4EAO +j8ZXAPwGn0KCOdP0xCYIc3s1+hlnnB2j6ou3I0NOLLtnDEWbmDvEue71wKPDTK3g +dCUVpkS6y/qWVl+vOhP55SsCgYATSUv7ZVQSeopCoyMAZ5nHDIiWYuX3pVmQM6io +3rK0MXxAttZGBFLRxT9LP5g9j7oO3YZbKg9ftgoHun5DwlNZ21ezuPWRrToXV9zk +UN+Q/dl0fuzl7bUum/+UfmTvGX3SJedTGvwmZUH4objj/a0jlFTFFmYa1STn1SZV +NGNuwQKBgQDBc1VxI4ynqIny+yOUIS+I6Z+QpnFFJqS2QC9+NQMwf4XIpIz1vieQ +Icg0pszZele0P9szv/MP8uEJI65SCTwYwMYSakFXq7r9M6CplDRZsib1ZzjzO4uB +bH/XeYMR2xdhyHsw8D35gDdkewBCJlwIWKVNidhQZxLILoQPlwXXcg== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIBBTANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTAxMTMwNTVaFw00NjA2MDYxMTMwNTVaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnr7w ++Qvx3cfgYSj3Ha+kbO/1dJoZ3PZA+NbG5gBuePZVrFS2+g4heiVMy1vv9oCbNpTc +szqaC0yqkQKz3r63ar5u8uqYjOaf3RHEMDQEP3GFYaOFXDFKUx+CZXrmgZoeMWNY +mUP5VwTF2M3dq/APE3zAB0mnMcBv8omJ8jgb2DbvI3X1KmK9SWqaRvG8OQu/9gaA +yBzR/dS+NpcVxakdeK2uBe3UzldYnqu7VRrFJfQ4zjdp9LJ098vYVhKwLhaByj3I +dqIBiaQpGtDkbJUVHgZoHYKjmnK8bc4rRdkvxTbH1jJgB9pBnyDpCfWezSP+G9a7 +nsXFkaAp+zx40bgKQwIDAQABo4HiMIHfMCwGA1UdEQQlMCOCCWxvY2FsaG9zdIcE +fwAAAYcQAAAAAAAAAAAAAAAAAAAAATCBjwYDVR0jBIGHMIGEoX2kezB5MRswGQYD +VQQDDBJEcml2ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNV +BAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5l +dyBZb3JrMQswCQYDVQQGEwJVU4IDB1MGMB0GA1UdDgQWBBSb8uTbKT1h1ac1q2q3 +EFUpyKS+JzANBgkqhkiG9w0BAQsFAAOCAQEAlzfi7bSvgQTU3pivzOiQUMBzNA+i +UULX/GdcK2526LvTbrdMKWxolsZyMiLawOXHCmPdM2fuqKXzsaYGIF4u6AVZAOce +ouBAUsMZRwM/tIiFQWEO8fZRBAYtxTTS/EofNZXnoQyqEzabSn4KPabBtN+U8nk1 +pJ0s8ZIyoww39I3x7ePrIVU0fJh7HyI8FkCe2RO0C1F5SlHViSIDZIYDEgx7lFvc +xhytgDRLaI28cSiQrOVD/cDSNzIMZkaQMZEfOoyS1VHNW2HVkl3wiHZf4/p/9GoY +FbL4Ivp7EI7wV7Y9u2h9oPni7s/GbmJ72peYwbkbftswL/kFP/YuKeZvTw== +-----END CERTIFICATE----- diff --git a/test/certificates/server.pem b/test/certificates/server.pem index e745e037fc..dc249d39eb 100644 --- a/test/certificates/server.pem +++ b/test/certificates/server.pem @@ -1,49 +1,49 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAhNrB0E6GY/kFSd8/vNpu/t952tbnOsD5drV0XPvmuy7SgKDY -a/S+xb/jPnlZKKehdBnH7qP/gYbv34ZykzcDFZscjPLiGc2cRGP+NQCSFK0d2/7d -y15zSD3zhj14G8+MkpAejTU+0/qFNZMc5neDvGanTe0+8aWa0DXssM0MuTxIv7j6 -CtsMWeqLLofN7a1Kw2UvmieCHfHMuA/08pJwRnV/+5T9WONBPJja2ZQRrG1BjpI4 -81zSPUZesIqi8yDlExdvgNaRZIEHi/njREqwVgJOZomUY57zmKypiMzbz48dDTsV -gUStxrEqbaP+BEjQYPX5+QQk4GdMjkLf52LR6QIDAQABAoIBAHSs+hHLJNOf2zkp -S3y8CUblVMsQeTpsR6otaehPgi9Zy50TpX4KD5D0GMrBH8BIl86y5Zd7h+VlcDzK -gs0vPxI2izhuBovKuzaE6rf5rFFkSBjxGDCG3o/PeJOoYFdsS3RcBbjVzju0hFCs -xnDQ/Wz0anJRrTnjyraY5SnQqx/xuhLXkj/lwWoWjP2bUqDprnuLOj16soNu60Um -JziWbmWx9ty0wohkI/8DPBl9FjSniEEUi9pnZXPElFN6kwPkgdfT5rY/TkMH4lsu -ozOUc5xgwlkT6kVjXHcs3fleuT/mOfVXLPgNms85JKLucfd6KiV7jYZkT/bXIjQ+ -7CZEn0ECgYEA5QiKZgsfJjWvZpt21V/i7dPje2xdwHtZ8F9NjX7ZUFA7mUPxUlwe -GiXxmy6RGzNdnLOto4SF0/7ebuF3koO77oLup5a2etL+y/AnNAufbu4S5D72sbiz -wdLzr3d5JQ12xeaEH6kQNk2SD5/ShctdS6GmTgQPiJIgH0MIdi9F3v0CgYEAlH84 -hMWcC+5b4hHUEexeNkT8kCXwHVcUjGRaYFdSHgovvWllApZDHSWZ+vRcMBdlhNPu -09Btxo99cjOZwGYJyt20QQLGc/ZyiOF4ximQzabTeFgLkTH3Ox6Mh2Rx9yIruYoX -nE3UfMDkYELanEJUv0zenKpZHw7tTt5yXXSlEF0CgYBSsEOvVcKYO/eoluZPYQAA -F2jgzZ4HeUFebDoGpM52lZD+463Dq2hezmYtPaG77U6V3bUJ/TWH9VN/Or290vvN -v83ECcC2FWlSXdD5lFyqYx/E8gqE3YdgqfW62uqM+xBvoKsA9zvYLydVpsEN9v8m -6CSvs/2btA4O21e5u5WBTQKBgGtAb6vFpe0gHRDs24SOeYUs0lWycPhf+qFjobrP -lqnHpa9iPeheat7UV6BfeW3qmBIVl/s4IPE2ld4z0qqZiB0Tf6ssu/TpXNPsNXS6 -dLFz+myC+ufFdNEoQUtQitd5wKbjTCZCOGRaVRgJcSdG6Tq55Fa22mOKPm+mTmed -ZdKpAoGAFsTYBAHPxs8nzkCJCl7KLa4/zgbgywO6EcQgA7tfelB8bc8vcAMG5o+8 -YqAfwxrzhVSVbJx0fibTARXROmbh2pn010l2wj3+qUajM8NiskCPFbSjGy7HSUze -P8Kt1uMDJdj55gATzn44au31QBioZY2zXleorxF21cr+BZCJgfA= ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDlTCCAn2gAwIBAgICdxUwDQYJKoZIhvcNAQELBQAweTEbMBkGA1UEAxMSRHJp -dmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdNb25n -b0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazEL -MAkGA1UEBhMCVVMwHhcNMTkwNTIyMjIzMjU2WhcNMzkwNTIyMjIzMjU2WjBwMRIw -EAYDVQQDEwlsb2NhbGhvc3QxEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01v -bmdvREIxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3Jr -MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAITa -wdBOhmP5BUnfP7zabv7fedrW5zrA+Xa1dFz75rsu0oCg2Gv0vsW/4z55WSinoXQZ -x+6j/4GG79+GcpM3AxWbHIzy4hnNnERj/jUAkhStHdv+3ctec0g984Y9eBvPjJKQ -Ho01PtP6hTWTHOZ3g7xmp03tPvGlmtA17LDNDLk8SL+4+grbDFnqiy6Hze2tSsNl -L5ongh3xzLgP9PKScEZ1f/uU/VjjQTyY2tmUEaxtQY6SOPNc0j1GXrCKovMg5RMX -b4DWkWSBB4v540RKsFYCTmaJlGOe85isqYjM28+PHQ07FYFErcaxKm2j/gRI0GD1 -+fkEJOBnTI5C3+di0ekCAwEAAaMwMC4wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/ -AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IBAQBol8+YH7MA -HwnIh7KcJ8h87GkCWsjOJCDJWiYBJArQ0MmgDO0qdx+QEtvLMn3XNtP05ZfK0WyX -or4cWllAkMFYaFbyB2hYazlD1UAAG+22Rku0UP6pJMLbWe6pnqzx+RL68FYdbZhN -fCW2xiiKsdPoo2VEY7eeZKrNr/0RFE5EKXgzmobpTBQT1Dl3Ve4aWLoTy9INlQ/g -z40qS7oq1PjjPLgxINhf4ncJqfmRXugYTOnyFiVXLZTys5Pb9SMKdToGl3NTYWLL -2AZdjr6bKtT+WtXyHqO0cQ8CkAW0M6VOlMluACllcJxfrtdlQS2S4lUIj76QKBdZ -khBHXq/b8MFX ------END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEoQIBAAKCAQEAtu0LbjJp24OJQEc67YfvP42Gtvu12gjvJSsaqd1lkIvxs+qs +CvaN48ZKeMMgcPZHKZdKntI1vkJZTDmmn/XkBju/uoN+5QE6vEZJ6vEYR3JKVLRR +SAbGTv3FaIF3DsJbWjjzZzaZ571OC55vEwX6oClPO3HbY3N3cNshnvm/1lo0hBVO +WAyqMIoCfpV1fDts8kTL1j/AWWu15Vd5IaibdzKEzzZZmH4+r2pq6IXSXsrLRK3N +iI59uXkuHNXw6vYlDzhluWxH2J1I1ABILM2/aljQ8Ij2X/rKrpoShoKun2RJdVBR +pKRCcij2WqWOtozO7S0FjYzYNZeOPMVfgKSYPQIDAQABAoIBAADDbXxIvpNZca2w +fmj2W8O+ofTKiSA/UEwt6V8TGvTm+JvBG3WyQLZWIgJuAgkmpfZg+ME/7FR+b2P3 +i5/4RTrXbf3nxZRMFIQroOxXlDvcGL5QwFQWHya+PWApxibsHbh7K1zfZ/YFHrnC +sAD60ehwM7HyUDGSjkmMyI+iyC+rT+Fd0pSlkwi+Nsdlglj/mOfwPGD9DuQQFou5 +Itx1iBOPs1lfO3alK7pAyt+i1SkfNosR3n/PC0y+4XVhoNOj+lD2AgIlCKQH7kVU +Hez+BEGakhQY+dsQ/A+cRGuHO0GKfwXwQYeYTHmYaj485B7GpUQe32lHBxe3AeZi +9PB6Z9sCgYEA9va3i1dZpTUKQn2kXr8SKqzpaiEK2EG6Ev+I7bK7n8HDlEUQfjRt +Mzn308U/I5p3W6lYnX+blUkY/WdGFjuw3QM9FIicQy2R5JmUurggZx+zeo9noYAM +FzEF7mw1FbzQ4tKMiHL7/CshH/mjRNZmEMd5H0CZflyZrFkhR1bCBa8CgYEAvZ5+ +Gox9B35PDoaFr8UrOGjK8D10qyNp7fSc21+U9vEUOuKGa6bdrt1TlVUo66Z93rpN +ooe8/ErEJxqR/9+oihfYtpsCw432DHfVjVqFzLZzFwp/cdn/biLyLpceh8ghnXQr +tpz92rwiqj5AMslwLjhLCUK2KeJCGp4KwD0359MCgYEAn5Gv7GeHM7i+pVGbJ+Db +MxnAQ2OQJ0TonqffaH5IvqOq5B1v16u2NxgoafuTnUSMBHy6FiHCfEXb0Leu0GTH +FTane6H9HWbPUl5te+vGe/s+s1z/P5mFtmJli7T848u5SCV0yiFJcZjIcWmSNcM1 +9Xd9alUKGFxqqrJ4Tyjeel8CgYBTcu74bB+SLqpIMDehdVpiBuxY8hLoRjuWN3LY +sKX0T4ChsZOKyPMCw/DG5aWOn8UBQmhsQOSQ+657rxvVye54Z6o+ItYCjfVc41ge +T1pXD2xzFXGk/1WEeOiwTF1pUFBK5Rdf1JN7shRna+IA99ng3XFYb/2PTT3eTPNa +SxbRdQJ/HXiUZE941VKKPbAXODRL0YG/hZvFmHAJbaPbo4SCi6m4uk/bSRGYRTZ8 +OWZplp1PjIKkxK76+Wd6AINLRluwQKbGThq3ESup/rbcnTxF0haGds6iyuvsKLJc +lD406o2rIhIPFSDco2fiLNmAlA2X6j811ysszB4FjTGYHeSNTA== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTAxMTMwNTVaFw00NjA2MDYxMTMwNTVaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtu0L +bjJp24OJQEc67YfvP42Gtvu12gjvJSsaqd1lkIvxs+qsCvaN48ZKeMMgcPZHKZdK +ntI1vkJZTDmmn/XkBju/uoN+5QE6vEZJ6vEYR3JKVLRRSAbGTv3FaIF3DsJbWjjz +ZzaZ571OC55vEwX6oClPO3HbY3N3cNshnvm/1lo0hBVOWAyqMIoCfpV1fDts8kTL +1j/AWWu15Vd5IaibdzKEzzZZmH4+r2pq6IXSXsrLRK3NiI59uXkuHNXw6vYlDzhl +uWxH2J1I1ABILM2/aljQ8Ij2X/rKrpoShoKun2RJdVBRpKRCcij2WqWOtozO7S0F +jYzYNZeOPMVfgKSYPQIDAQABozAwLjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggEBAIiuZmP4NFfn +/nNrZCMgR5cVPeFgBmFhyOS4HgqdXjSeebUYyz2Jbhu7y5djbo2r92lTjvKZKGUE +u1+Xj4qhJ8WrcCP6Bfz7/zBCqZRw++uT6lfEdLr76c+8GbqoJPfoYyDxlYWYtSCn +AGb7VbXkeUYPDLUgcIAUFdyfOjGTxdZDiaM2MQa7tw1GRJTAncX7efCfCjLpcN16 +Iywhn4E/r7QhNXwe5Vfwee1dn08MFYn2lud38he6oW0N2A0/aIyVz25xB+H5DP5j +RDpoXUquyhjOyEFrcDelDFX+EBxCPr+VvVXJK773JK8jTi7C3mu3Eip2KqJ/7gRZ +A23MpqOzisM= +-----END CERTIFICATE----- diff --git a/test/certificates/trusted-ca.pem b/test/certificates/trusted-ca.pem index a6f6f312d0..b968a1c62e 100644 --- a/test/certificates/trusted-ca.pem +++ b/test/certificates/trusted-ca.pem @@ -1,82 +1,22 @@ -# CA bundle file used to test tlsCAFile loading for OCSP. -# Copied from the server: -# https://github.com/mongodb/mongo/blob/r4.3.4/jstests/libs/trusted-ca.pem - -# Autogenerated file, do not edit. -# Generate using jstests/ssl/x509/mkcert.py --config jstests/ssl/x509/certs.yml trusted-ca.pem -# -# CA for alternate client/server certificate chain. -----BEGIN CERTIFICATE----- -MIIDojCCAooCBG585gswDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxETAP -BgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAwDgYDVQQK -DAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxHzAdBgNVBAMMFlRydXN0ZWQgS2Vy -bmVsIFRlc3QgQ0EwHhcNMTkwOTI1MjMyNzQxWhcNMzkwOTI3MjMyNzQxWjB8MQsw -CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr -IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEfMB0GA1UE -AwwWVHJ1c3RlZCBLZXJuZWwgVGVzdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANlRxtpMeCGhkotkjHQqgqvO6O6hoRoAGGJlDaTVtqrjmC8nwySz -1nAFndqUHttxS3A5j4enOabvffdOcV7+Z6vDQmREF6QZmQAk81pmazSc3wOnRiRs -AhXjld7i+rhB50CW01oYzQB50rlBFu+ONKYj32nBjD+1YN4AZ2tuRlbxfx2uf8Bo -Zowfr4n9nHVcWXBLFmaQLn+88WFO/wuwYUOn6Di1Bvtkvqum0or5QeAF0qkJxfhg -3a4vBnomPdwEXCgAGLvHlB41CWG09EuAjrnE3HPPi5vII8pjY2dKKMomOEYmA+KJ -AC1NlTWdN0TtsoaKnyhMMhLWs3eTyXL7kbkCAwEAAaMxMC8wDAYDVR0TBAUwAwEB -/zAfBgNVHREEGDAWgglsb2NhbGhvc3SCCTEyNy4wLjAuMTANBgkqhkiG9w0BAQsF -AAOCAQEAQk56MO9xAhtO077COCqIYe6pYv3uzOplqjXpJ7Cph7GXwQqdFWfKls7B -cLfF/fhIUZIu5itStEkY+AIwht4mBr1F5+hZUp9KZOed30/ewoBXAUgobLipJV66 -FKg8NRtmJbiZrrC00BSO+pKfQThU8k0zZjBmNmpjxnbKZZSFWUKtbhHV1vujver6 -SXZC7R6692vLwRBMoZxhgy/FkYRdiN0U9wpluKd63eo/O02Nt6OEMyeiyl+Z3JWi -8g5iHNrBYGBbGSnDOnqV6tjEY3eq600JDWiodpA1OQheLi78pkc/VQZwof9dyBCm -6BoCskTjip/UB+vIhdPFT9sgUdgDTg== ------END CERTIFICATE----- ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDZUcbaTHghoZKL -ZIx0KoKrzujuoaEaABhiZQ2k1baq45gvJ8Mks9ZwBZ3alB7bcUtwOY+Hpzmm7333 -TnFe/merw0JkRBekGZkAJPNaZms0nN8Dp0YkbAIV45Xe4vq4QedAltNaGM0AedK5 -QRbvjjSmI99pwYw/tWDeAGdrbkZW8X8drn/AaGaMH6+J/Zx1XFlwSxZmkC5/vPFh -Tv8LsGFDp+g4tQb7ZL6rptKK+UHgBdKpCcX4YN2uLwZ6Jj3cBFwoABi7x5QeNQlh -tPRLgI65xNxzz4ubyCPKY2NnSijKJjhGJgPiiQAtTZU1nTdE7bKGip8oTDIS1rN3 -k8ly+5G5AgMBAAECggEAS7GjLKgT88reSzUTgubHquYf1fZwMak01RjTnsVdoboy -aMJVwzPsjgo2yEptUQvuNcGmz54cg5vJaVlmPaspGveg6WGaRmswEo/MP4GK98Fo -IFKkKM2CEHO74O14XLN/w8yFA02+IdtM3X/haEFE71VxXNmwawRXIBxN6Wp4j5Fb -mPLKIspnWQ/Y/Fn799sCFAzX5mKkbCt1IEgKssgQQEm1UkvmCkcZE+mdO/ErYP8A -COO0LpM+TK6WQY2LKiteeCCiosTZFb1GO7MkXrRP5uOBZKaW5kq1R0b6PcopJPCM -OcYF0Zli6KB7oiQLdXgU2jCaxYOnuRb6RYh2l7NvAQKBgQD6CZ9TKOn/EUQtukyw -pvYTyt1hoLXqYGcbRtLc1gcC+Z2BD28hd3eD/mEUv+g/8bq/OP4wYV9X+VRvR8xN -MmfAG/sJeOCOClz1A1TyNeA+G0GZ25qWHyHQ2W4WlSG1CXQgxGzU6wo/t6wiVW5R -O4jplFVEOXznf4vmVfBJK50R2QKBgQDegGxm23jF2N5sIYDZ14oxms8bbjPz8zH6 -tiIRYNGbSzI7J4KFGY2HiBwtf1yxS22HBL69Y1WrEzGm1vm4aZG/GUwBzI79QZAO -+YFIGaIrdlv12Zm6lpJMmAWlOs9XFirC17oQEwOQFweOdQSt7F/+HMZOigdikRBV -pK+8Kfay4QKBgQDarDevHwUmkg8yftA7Xomv3aenjkoK5KzH6jTX9kbDj1L0YG8s -sbLQuVRmNUAFTH+qZUnJPh+IbQIvIHfIu+CI3u+55QFeuCl8DqHoAr5PEr9Ys/qK -eEe2w7HIBj0oe1AYqDEWNUkNWLEuhdCpMowW3CeGN1DJlX7gvyAang4MYQKBgHwM -aWNnFQxo/oiWnTnWm2tQfgszA7AMdF7s0E2UBwhnghfMzU3bkzZuwhbznQATp3rR -QG5iRU7dop7717ni0akTN3cBTu8PcHuIy3UhJXLJyDdnG/gVHnepgew+v340E58R -muB/WUsqK8JWp0c4M8R+0mjTN47ShaLZ8EgdtTbBAoGBAKOcpuDfFEMI+YJgn8zX -h0nFT60LX6Lx+zcSDY9+6J6a4n5NhC+weYCDFOGlsLka1SwHcg1xanfrLVjpH7Ok -HDJGLrSh1FP2Rq/oFxZ/OKCjonHLa8IulqD/AA+sqYRbysKNsT3Pi0554F2xFEqQ -z/C84nlT1R2uTCWIxvrnpU2h ------END PRIVATE KEY----- -# Pre Oct 2019 trusted-ca.pem -# Transitional pending BUILD update. ------BEGIN CERTIFICATE----- -MIIDpjCCAo6gAwIBAgIDAghHMA0GCSqGSIb3DQEBBQUAMHwxHzAdBgNVBAMTFlRy -dXN0ZWQgS2VybmVsIFRlc3QgQ0ExDzANBgNVBAsTBktlcm5lbDEQMA4GA1UEChMH -TW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlv -cmsxCzAJBgNVBAYTAlVTMB4XDTE2MDMzMTE0NTY1NVoXDTM2MDMzMTE0NTY1NVow -fDEfMB0GA1UEAxMWVHJ1c3RlZCBLZXJuZWwgVGVzdCBDQTEPMA0GA1UECxMGS2Vy -bmVsMRAwDgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREw -DwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUA -A4IBDwAwggEKAoIBAQCePFHZTydC96SlSHSyu73vw//ddaE33kPllBB9DP2L7yRF -6D/blFmno9fSM+Dfg64VfGV+0pCXPIZbpH29nzJu0DkvHzKiWK7P1zUj8rAHaX++ -d6k0yeTLFM9v+7YE9rHoANVn22aOyDvTgAyMmA0CLn+SmUy6WObwMIf9cZn97Znd -lww7IeFNyK8sWtfsVN4yRBnjr7kKN2Qo0QmWeFa7jxVQptMJQrY8k1PcyVUOgOjQ -ocJLbWLlm9k0/OMEQSwQHJ+d9weUbKjlZ9ExOrm4QuuA2tJhb38baTdAYw3Jui4f -yD6iBAGD0Jkpc+3YaWv6CBmK8NEFkYJD/gn+lJ75AgMBAAGjMTAvMAwGA1UdEwQF -MAMBAf8wHwYDVR0RBBgwFoIJbG9jYWxob3N0ggkxMjcuMC4wLjEwDQYJKoZIhvcN -AQEFBQADggEBADYikjB6iwAUs6sglwkE4rOkeMkJdRCNwK/5LpFJTWrDjBvBQCdA -Y5hlAVq8PfIYeh+wEuSvsEHXmx7W29X2+p4VuJ95/xBA6NLapwtzuiijRj2RBAOG -1EGuyFQUPTL27DR3+tfayNykDclsVDNN8+l7nt56j8HojP74P5OMHtn+6HX5+mtF -FfZMTy0mWguCsMOkZvjAskm6s4U5gEC8pYEoC0ZRbfUdyYsxZe/nrXIFguVlVPCB -XnfB/0iG9t+VH5cUVj1LP9skXTW4kXfhQmljUuo+EVBNR6n2nfTnpoC65WeAgHV4 -V+s9mJsUv2x72KtKYypqEVT0gaJ1WIN9N1s= +MIIDlzCCAn+gAwIBAgICAMgwDQYJKoZIhvcNAQELBQAwfDEfMB0GA1UEAwwWVHJ1 +c3RlZCBLZXJuZWwgVGVzdCBDQTEPMA0GA1UECwwGS2VybmVsMRAwDgYDVQQKDAdN +b25nb0RCMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MREwDwYDVQQIDAhOZXcgWW9y +azELMAkGA1UEBhMCVVMwHhcNMjYwNjEwMTEzMDU1WhcNNDYwNjA2MTEzMDU1WjB8 +MR8wHQYDVQQDDBZUcnVzdGVkIEtlcm5lbCBUZXN0IENBMQ8wDQYDVQQLDAZLZXJu +ZWwxEDAOBgNVBAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAP +BgNVBAgMCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKnupoVXRCZ/jsWlG243YaCG3i9EzIcW/X8CKbhkpPdwr6eH +bi3z+67U/6epks32zQBZTwWOomSlm1BD7OUrUW+k1ahujGFHnwOmLeXxN9otgBr6 +aGPUu1P8P4kU1dDFKMBPdfFRrHs3f8LKMkdLFwnJ1w32P+6X6Drq4Sq0kB0kZqu5 +fFCVvW2a1Uit6JWdfgMybN98pGsMDqI+T25eMMN6MwDj5C5XhVk4OZGOJ6ltJN34 +UnRqURZvOXAxGP94Uw6IAbyWcYWw/Z4LpleMyWk9djHntFzenwKiRDfpHrs6i2Xh +/kdAdYYIWfyqSTUfywxZX+OFCAG991lZUKRwcf0CAwEAAaMjMCEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAJSkpDcH +Ar9hyACHDm1c6Gotl+ZW2J+IU9W9RHsmfMvD2rKg/zMylVXcUzwWeuxf9CsZ2Kxc +yK/bKcLyKOQ8oAlQVmgaaYaH655t8jXSoLJqd79N7huEP3uuzJSpiei9c4G/UOdi +XWqJlJkevdLpoqmVyvFrXutcxbAIWTBx3WM2xxTu1hEmDEI+fOr6xdvcxQ6X+9h1 +/Cp+ZFvasCQfcSfozeneQPkd3B7WGfhPLZdJDvO/ppQD7P0xAcOsxBCAaHVDpQM0 ++aMt+lavkJv449NJy2pdrF00M3V1KLrF2JBeRUbRae9EZPGvL60eGeqB1ngd+pb8 +0+P1vwrci1lNtwU= -----END CERTIFICATE----- diff --git a/test/certificates/wrong-host.pem b/test/certificates/wrong-host.pem new file mode 100644 index 0000000000..3b7c92d91f --- /dev/null +++ b/test/certificates/wrong-host.pem @@ -0,0 +1,52 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvz86Ioh1BWdD+J4jUGRlmgx16sLlaC/u3Gq/KCfIwIw9/MJ5 +p24cEqT6tnPEVV5cg2mhL8lAzZvsZEZcXpFGqMHoub+AA7Cxkddh1kOuWHzBanfs +Q6Q0jEV5FRu7g7u/ucS+PekQ5j8LkF/4YJNGjBNWFgWgbnzA941/h6aCr0oZQqpW +g8SFiXfYtmV7DSvA+Fw9kEmkVh3j6yM9+rGTv0LqCZ1BjRuVb8e/MsDl8wKTXjCU +D7OwA0efC87WtB/Z4d7lUIfRV4iHb5EtcfKAB0YsFp7F7tsfchxTZ//3SyWffheI +pduc9zxDRDM44Tev5UvNEoJtSICnLu1DuLVEEwIDAQABAoIBABNVz0kDgR/r5KWD +nhq4Hm+N1/QarTqJ3L01y6AXLvGMnDhsPwQW7/P7RbUMN5V78KAr80BouUpa+8eC +4j7WCDidQNawDj9mmKVKixkwXDWVCLGncIsW1GXkIOLp8VzXBAIXlTZJfyG6zllT +4pbSUlJszV9079c2egSX2S9mkxV+nGi2dK/0yNVdhav1C9FyKjyXfHGepTiTGR4w +PXzLwf0Sk/TuVVNDmqTt3+1XAxIpdxnkorR9KyOx/8NIxNb4/0LzrWsF9nZJyXew +sNPwnRLyXaqF2aSyOcqTx51+O1uDJWfb0SBapyBwwaDkqCxpUDoZTm/sCKjrwAMs +jBOtGBECgYEA5F6xsHCd43meX1A/X0CUWmxT6JJlnDqcj9ioPPJyFdBiOu00e7aU +tOkiM2vg+djLRYcmtP9DwB2yOs3uy59wXpciGoxIjbRnoqJyNuWlg0KcGQU2NDhb +RzyoJbI3aSCeDZzrWkLy1uZtLlevEb/OPIs4bbVlTGTAPXcto/I8J5ECgYEA1mK5 +WlZmKpDbPl6Unjr6Go06ZbRXqhiRwSHjnMZwuS0UgezRKLzUbKJQ8z5zd1k+b2u0 +B6C8tahGVGi3LiQC3qkzMvfjvbGOXF6jyETorf4A4v0ueqAtzNTcBR5Boq+F8Z76 +uhO2cZoy7DBLDuVxIKP/ye17EgDfzsz1LyQNB2MCgYEAtCdPnZT5uR2UJjS0CXx0 +i/CxMONsbRZ/s6qC7bGE9lhxZXMC2CVsolrXtCECVZcEpFC95EMLO18x3tnd65xX +lQc8zBymj8MljlMALvZy312IruRBomhi+YuMSlCRDcnBZZPIxmfSEl2s+8YIQcRB ++dkKJuHWi7FfRh3iT1ckxUECgYEA0X0W8heLLfzuwDtbrmKjEl7+uXNIVoY7pyWe +bQvcCpbqeysWF2Ctkpnp0EcuPWmPgQEVon6G6FvOnZzVoti9lSZxSVTBzhM6sTgp +gwES/TI/W49bY6gyGP3HIZk3OemaUUiwaDPrC4dKS1HFhoDd0q9uu7q7kBQantHY +pH/t21ECgYBOLQrxiI9pqQuHd6S9P7bm72j61D/iTf91gJ4S1FouBURTvU8KioX8 +vwzVxbdyr0wP5Wzo7vqaUrmD9OKUpuCR1W8twvOKZeBku5YacSJSIgDH9L0T9Z6K +WVTIWEnOf/JaFYrhrOu/15UtrnY/KYfiQS/C6q3el9tIKY8e110IBw== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTAxMTMwNTVaFw00NjA2MDYxMTMwNTVaMHwxHjAc +BgNVBAMMFXdyb25naG9zdC5leGFtcGxlLmNvbTEQMA4GA1UECwwHRHJpdmVyczEQ +MA4GA1UECgwHTW9uZ29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UE +CAwITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAvz86Ioh1BWdD+J4jUGRlmgx16sLlaC/u3Gq/KCfIwIw9/MJ5p24c +EqT6tnPEVV5cg2mhL8lAzZvsZEZcXpFGqMHoub+AA7Cxkddh1kOuWHzBanfsQ6Q0 +jEV5FRu7g7u/ucS+PekQ5j8LkF/4YJNGjBNWFgWgbnzA941/h6aCr0oZQqpWg8SF +iXfYtmV7DSvA+Fw9kEmkVh3j6yM9+rGTv0LqCZ1BjRuVb8e/MsDl8wKTXjCUD7Ow +A0efC87WtB/Z4d7lUIfRV4iHb5EtcfKAB0YsFp7F7tsfchxTZ//3SyWffheIpduc +9zxDRDM44Tev5UvNEoJtSICnLu1DuLVEEwIDAQABo4HWMIHTMCAGA1UdEQQZMBeC +FXdyb25naG9zdC5leGFtcGxlLmNvbTCBjwYDVR0jBIGHMIGEoX2kezB5MRswGQYD +VQQDDBJEcml2ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNV +BAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5l +dyBZb3JrMQswCQYDVQQGEwJVU4IDB1MGMB0GA1UdDgQWBBSQFJeOAoIcQj1SsDX/ +wEZu7Z1JkTANBgkqhkiG9w0BAQsFAAOCAQEAKhRUllW9XSWZjpsWosKQg0iDaBk5 +tTpkg0eeNAT8PexmeTzeoPyT3dPmlJ/ouVgp8CGHHYP+Lrdo6xUxUpRQXYTjN9lL +h0GS4qKaELJauKVimA0+CqK6OzSn/TnS0/Gv82YC1i4KWYBwhnH73USjnRleiZ9W +/oDH6PTSWmbCG312W30fYaDCOnBafbIsbDHrzbe/HF8XWWgFX/Q5WKb/91goahmN +Fiz0GbjWRv0MyaL4wy/hUw+XIHimW7cccl2RaMI3BRyw6Rirsu4p1eqAXVOkeN4v +X+VnZQUtuG7fle/t9dZqArN7FUId9lzOX7ERr3ZAh6Ss/Ps9Ll6m8/KJWg== +-----END CERTIFICATE----- diff --git a/test/test_encryption.py b/test/test_encryption.py index 7df9e7ac38..1a6f9b93e1 100644 --- a/test/test_encryption.py +++ b/test/test_encryption.py @@ -3027,10 +3027,20 @@ def setUp(self): def http_post(self, path, data=None): # Note, the connection to the mock server needs to be closed after # each request because the server is single threaded. - ctx = ssl.create_default_context(cafile=CA_PEM) + if sys.platform in ("darwin", "win32"): + # macOS/Windows: use PROTOCOL_TLS_CLIENT instead of + # create_default_context so that X509_V_FLAG_X509_STRICT is not + # set. Python 3.14 enables strict mode in create_default_context, + # which requires a Subject Key Identifier (SKI) on the root CA cert. + # The CA cert omits SKI + # to prevent macOS SecTrust from triggering OCSP revocation checks + # during MongoDB server startup; the same cert is used on all + # platforms, so Windows inherits the same constraint. + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + else: + ctx = ssl.create_default_context() + ctx.load_verify_locations(cafile=CA_PEM) ctx.load_cert_chain(CLIENT_PEM) - ctx.check_hostname = False - ctx.verify_mode = ssl.CERT_NONE conn = http.client.HTTPSConnection("127.0.0.1:9003", context=ctx) try: if data is not None: diff --git a/tools/synchro.py b/tools/synchro.py index 5570a22bdb..c96b569db3 100644 --- a/tools/synchro.py +++ b/tools/synchro.py @@ -25,7 +25,7 @@ from os import listdir from pathlib import Path -from unasync import Rule, unasync_files # type: ignore[import-not-found] +from unasync import Rule, unasync_files # type: ignore replacements = { "AsyncCollection": "Collection",