diff --git a/.evergreen/scripts/run_server.py b/.evergreen/scripts/run_server.py index 9757eb3a4f..ba7afbaa08 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,14 @@ 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": + # MongoDB Enterprise on macOS uses Apple SecTrust with + # kSecRevocationRequirePositiveResponse, which requires a + # positive OCSP response for every cert in the chain. Our + # test CA is not in the macOS system keychain so OCSP always + # fails with CSSMERR_TP_CERT_SUSPENDED. Bypass cert + # verification to allow the server to start. + 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..a425b04547 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 / "kms-server.pem") + os.environ["CSFLE_TLS_CLIENT_CERT_FILE"] = str(certs / "client.pem") + os.environ["CSFLE_TLS_WRONG_HOST_FILE"] = str(certs / "kms-wrong-host.pem") + os.environ["CSFLE_TLS_EXPIRED_FILE"] = str(certs / "kms-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 1d5d572cd3..f98494638f 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 c48f7efb1b..8d983acaa3 100644 --- a/test/asynchronous/test_encryption.py +++ b/test/asynchronous/test_encryption.py @@ -3039,10 +3039,9 @@ 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) + 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..c5e81a5ff4 --- /dev/null +++ b/test/certificates/README.md @@ -0,0 +1,88 @@ +# 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, SKI | 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) | +| `kms-server.pem` | `CN=localhost, ...` + SAN | Drivers Testing CA | SAN, AKI, SKI | KMS mock server cert (key + cert) | +| `kms-wrong-host.pem` | `CN=wronghost.example.com` | Drivers Testing CA | SAN, AKI, SKI | KMS wrong-host test cert | +| `kms-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 enables `X509_V_FLAG_X509_STRICT` in `ssl.create_default_context()`, which + requires **AKI** on non-root certs. The KMS mock-server connection (`http_post`) used + `create_default_context()`, so the original 2019 KMS certs (no AKI) started failing. +2. Python 3.14 sets OpenSSL's `X509_V_FLAG_X509_STRICT` (via `ssl.VERIFY_X509_STRICT`) in + `ssl.create_default_context()`, which additionally requires **SKI** on non-root certs and + **keyUsage** on CA certs. + +The MongoDB certs intentionally carry no AKI: Apple SecTrust triggers OCSP revocation checks when +any cert in the chain has AKI, and those checks fail with `CSSMERR_TP_CERT_SUSPENDED` because our +test CA is not in the macOS system keychain. The CA carries SKI (but not AKI); macOS SecTrust +OCSP is triggered by AKI on leaf certs, so the CA's SKI does not re-enable OCSP. + +MongoDB Enterprise on macOS uses Apple SecTrust with `kSecRevocationRequirePositiveResponse`, which +requires a positive OCSP response for every cert in the chain regardless of whether AKI is present. +Because our test CA has no OCSP responder, the server startup always fails with +`CSSMERR_TP_CERT_SUSPENDED` without `--tls-allow-invalid-certificates`. This flag is set for +macOS in `.evergreen/scripts/run_server.py`. + +As long as the driver verifies MongoDB server certs without `X509_V_FLAG_X509_STRICT` (which is +the case — `pymongo.ssl_support.get_ssl_context` uses `PROTOCOL_SSLv23`), no AKI is required on +the MongoDB leaf certs. + +KMS connections use `ssl.create_default_context()`, which sets OpenSSL's `X509_V_FLAG_X509_STRICT` +via `ssl.VERIFY_X509_STRICT`. The CA cert carries SKI, enabling keyid-form AKI on the KMS leaf +certs. OpenSSL 3.3+ strict mode requires the `keyIdentifier` field within AKI (issuer/serial form +is not sufficient). macOS SecTrust OCSP is triggered by AKI on leaf certs that identify an issuer +— since the MongoDB leaf certs carry no AKI, adding SKI to the CA does not re-enable OCSP checks. + +> **If the driver is changed to use `ssl.create_default_context()` for MongoDB connections**, the +> MongoDB certs will need AKI and SKI. Adding AKI will re-trigger macOS SecTrust OCSP failures; +> to resolve that, either add `--tls-allow-invalid-certificates` to the server startup in +> `run_server.py`, or install the test CA into the macOS system keychain in the CI setup. diff --git a/test/certificates/ca.pem b/test/certificates/ca.pem index 24beea2d48..f15d63a265 100644 --- a/test/certificates/ca.pem +++ b/test/certificates/ca.pem @@ -1,21 +1,22 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/test/certificates/client.pem b/test/certificates/client.pem index 5b07001092..069779f089 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 +CQYDVQQGEwJVUzAeFw0yNjA2MTQxNTExNTlaFw00NjA2MTAxNTExNTlaMGkxDzAN +BgNVBAMMBmNsaWVudDEQMA4GA1UECwwHRHJpdmVyczEMMAoGA1UECgwDTURCMRYw +FAYDVQQHDA1OZXcgWW9yayBDaXR5MREwDwYDVQQIDAhOZXcgWW9yazELMAkGA1UE +BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/bs4sKJnvEjlx +SzUqaP5BBZwrLCllfR0u1W8aPc4u13tRtPd8hamcuyZJc6T781EEV08uAZSerxAF +S4msHf5MPyVvXmg/IS5R923IdBuwGQR01vMdLZ2PLfcFiAKiW3wQ3+sa04Mwy0Gf +pWVv3Mu4mLgXmJfNLgByR0HPGL+0Ws4/3s28rFUUZ5sm8yHDpBFavxJH1oTHxxzh +NAIIqXLYy/ZZRUt5fouwH25y9mEys3UFn18uIEFMJNfM1BgZbaxyl5wN9rQLPd4m +cCWJmtaENMRkIPYzMOGjNH4mWnJ8ltxoF16RI0xnLQIalRUPdoYCEdisqskxtlZf +HPm3r5AZAgMBAAGjJDAiMAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD +AjANBgkqhkiG9w0BAQsFAAOCAQEALhvRiiV/C5uAt7xmyMalHuQqBhR67gA55jBb +faIKSnhEBcWaOAx+2PiHMRhI4BraOxDT2IIjar1vL/Lp4QB81RIfBTjefVgldGOD +FjvyU2PrBLoeVLOsrtYdjyjwciXrErYRKyOx9B+cBm5hUKA2kTnJz8ad+01Qquw5 +s+e8rzVRL4Brrc3L2F0MURrx6H3VPwXSbVk8hFc4qSBf1WHSULkjVD/QP0uitwH4 +qKCRhq/h9m43IPRE+rLseldJhAWvlqMNxyJLoSOLgOfUd0iXV8pGqN+OOx4OJGPS +g4ry+fZLqf+k6Du7pfrdlv3VOwC4tylSsl0EyzlLqDtXO20G9A== -----END CERTIFICATE----- diff --git a/test/certificates/crl.pem b/test/certificates/crl.pem index 733a0acdc0..4c8480e5ec 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 +EwJVUxcNMjYwNjE1MTUxMTU5WhcNNDYwNjEwMTUxMTU5WjAUMBICAQEXDTI2MDYx +NTE1MTE1OVowDQYJKoZIhvcNAQELBQADggEBAEXSAduUtfJ3OREvCGA2q+grEroK +twR4d4o51dGKvQ/1+xgRzn5BdTSxH1AL5ma4wHRZRrOSYrTgkUcKb3EwwILKBxxP +mwakrgp9EcOG9ORoYqqi0kVsxkuLdns6J6EH7uzmaDp4XKM5ddpV1uEClXWSCOF5 +mKQkeqnTdSAI8ruvWecHb7Who/mRxmYZZBxhjm3KMcnhpCTDFJTVi8+/+hsfT5XR +7Daq8Rlb4DyJx+O2yeygvbUc2rCaV6NR1kPDGFiL60yT6ZSIJEAOzcjF53VGD/fu +rggjGltH0FdhKiOC2ZkTTV+2+LFIPMUyXWhECDYxe6LWCUA6mp8clIZJY6Y= -----END X509 CRL----- diff --git a/test/certificates/gen-certs.py b/test/certificates/gen-certs.py new file mode 100644 index 0000000000..a3c946db0b --- /dev/null +++ b/test/certificates/gen-certs.py @@ -0,0 +1,447 @@ +# /// script +# requires-python = ">=3.8" +# dependencies = ["cryptography>=44.0.0"] +# /// +"""Generate TLS test certificates for the PyMongo test suite. + +See README.md in this directory for background on the certificate design. + +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_key_pub) -> x509.AuthorityKeyIdentifier: + # Keyid form: the keyIdentifier is the SHA-1 hash of the CA's public key + # (same value as the CA's SKI). OpenSSL 3.3+ strict mode requires this + # form; issuer/serial form is not recognised as satisfying the AKI check. + return x509.AuthorityKeyIdentifier.from_issuer_public_key(ca_key_pub) + + +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 — basicConstraints (critical), keyUsage (critical), SKI. +# --------------------------------------------------------------------------- +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, + ) + .add_extension(x509.SubjectKeyIdentifier.from_public_key(ca_key.public_key()), critical=False) + .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 (see README.md). +# --------------------------------------------------------------------------- +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 + SKI (see README.md). +# Used by kms_failpoint_server.py (port 9003). +# --------------------------------------------------------------------------- +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_key.public_key()), critical=False) + .add_extension( + x509.SubjectKeyIdentifier.from_public_key(server_kms_key.public_key()), critical=False + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "kms-server.pem").write_bytes(key_pem(server_kms_key) + cert_pem(server_kms_cert)) +print(" kms-server.pem written") + + +# --------------------------------------------------------------------------- +# 2. Client certificate — serial 2, no AKI (see README.md). +# --------------------------------------------------------------------------- +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_key.public_key()), critical=False) + .add_extension( + x509.SubjectKeyIdentifier.from_public_key(wrong_host_key.public_key()), critical=False + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "kms-wrong-host.pem").write_bytes(key_pem(wrong_host_key) + cert_pem(wrong_host_cert)) +print(" kms-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_key.public_key()), critical=False) + .add_extension( + x509.SubjectKeyIdentifier.from_public_key(expired_key.public_key()), critical=False + ) + .sign(ca_key, hashes.SHA256()) +) +(SCRIPT_DIR / "kms-expired.pem").write_bytes(key_pem(expired_key) + cert_pem(expired_cert)) +print(" kms-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, critical keyUsage, and SKI; must NOT have AKI or SAN. +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 Python 3.14 strict mode)", + file=sys.stderr, + ) + ca_errors += 1 +if "Key Usage: critical" not in ca_text: + print( + " ca.pem: ERROR — missing critical keyUsage (required by Python 3.14 strict mode)", + file=sys.stderr, + ) + ca_errors += 1 +if "Subject Key Identifier" not in ca_text: + print( + " ca.pem: ERROR — missing SKI (required for keyid-form AKI on KMS leaf certs)", + file=sys.stderr, + ) + ca_errors += 1 +for ext in ("Authority Key Identifier", "Subject Alternative Name"): + if ext in ca_text: + print( + f" ca.pem: ERROR — has {ext} (would cause issues on Windows or macOS)", + file=sys.stderr, + ) + ca_errors += 1 +if ca_errors: + errors += ca_errors +else: + print(" ca.pem: OK (has basicConstraints critical, keyUsage critical, SKI; no AKI/SAN)") + +# 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 keyid-form AKI and SKI. +for name in ("kms-server.pem", "kms-wrong-host.pem", "kms-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 + elif "keyid:" not in text.lower() and "Key Identifier" not in text: + print( + f" {name}: ERROR — AKI missing keyIdentifier (OpenSSL 3.3+ strict mode requires keyid form)", + 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 keyid-form 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/kms-expired.pem b/test/certificates/kms-expired.pem new file mode 100644 index 0000000000..51b883b86e --- /dev/null +++ b/test/certificates/kms-expired.pem @@ -0,0 +1,50 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAmsQW841XAoeUi+kTUrlrN6UZ9byDExsETfPIYryZJ1CoyMRg +HEb1oC80DHWlFXfNs4iOhQgPIx+qA3G/vhAuNeezv/+UyuvtlrQXLi7TuGJv2Rlt +ntGklc2+U/F77ag0YM95T6HKD2xs61YOHxBQKYZ+Xy0QeUEVo4LQOyaIDpK/A3Cq +71NfAAwJFSo3kikd4hB0+CZ6N5zJye+HJ8MunxTXUP9OPY8K6ULDtwjFG6AHBeb8 +Pri673gkVshsTE/lqaITUhR4tw8zIeEel14E5OAYv3izschTofyorOlkI4lLVU/+ +uquJbc1FQCIrzT2XswFiVs4stc4TFyIvTawrMQIDAQABAoIBAANFhaQuntIeflcC +TW6kXYY6utyhWGZ7HdlNf9UJflXQzE6ZKxxx6g+Rq+CfDIcyhgJHbtbUU6iXCuOh +gA+DHUz1qcyzWQh8mgRDaJGI+yAE0a81zMXMkfV6OM2it09P7NKGlD6JEaHHlZpY +cno44K7uCUYXCGf9xpizI1Z6wynGqy7zRS0F/XGO1LF1c/TEeq31o6Jg+U/k+DWy +PeKKfN0kUM+tfCQdi9OImCAdQ8X3fTLfiDmV5QoSifkUrC8auABaRQdur/tft2wR +ADxbubbGWMVUsi1zmtjSH6U7tTSnHlgs+qCVIDzzEmtjqEZ7RU+5tum3JAelrA5g +2PYhC1kCgYEA0NQz9VRjmroaFHlf+inSezHDD5t+walCIEBherHjqv/TesgyKEXe +AGpi/0SIkJRZDzSthb2aB+ivF3fVbntmmc9yL/xWN0rQWB46whojAkBd/4tzC77O +m9mV0SDc5InAttvbeDNMKHe5qpXmOjp4bVGs3DAKbgcnXz7wFq0prbkCgYEAvbmg +4xngyCsCAjq0Dti5agoelMeaopFODepkesXFYmHxJjVE1OtwGVVJ2irepwH5TbkF +Va7PQ4lSwTl32djIYnPVgKrSKL4L8CSr9u2ielydWJ8uj9SGlhiPChznNKwKaTna +AqAWWf6ij78fwZhlzqgw/wPyAwvuel3Exx3u5TkCgYEAxtBgrz6qnZJ0Ze2wXIEY +rMURinhl04aLOB1TMPbPY+uvsYOLjSAHXanrmk/rHIq/x2RFl8CNNt5mZBdokYjW +g7UmZ1z70CRf+qS9GDK+BdS2KSbgXtxH48Thh3qcEtC7MtxaNDPSW+ywTSHtUJ5+ +LMXHptHt/Ba/e0R2W4B837ECgYEAuXpuZVb5P/d7wT4upY0OxzIZb44sCN5RFp2d +mcEbFPF3Vckh/54kOz/8MUNT5KWzWl6Vboy1p+rqcmiCWQDr9gQUJ/PX/Wi+NwlC +7Oaov0MnuGn2lTpKURa1UEetaPsAOpsKHSLwdw7PUgShQRyB+yTGsajjwkK54/sj +0x3aXVECgYEArVFz/lLGT3crBBbeX9yy8C0BQMHEKL59uJSjZLvk+sNhmD66GuqG +a8koIOMBA+Oq+actkDpZZmaN1LOxRIelGcVsDVSkHwQcKIUmtgExzBQKAjOl2to+ +K9KVcZbBr5oUi108LtENSrctB8BkFhIzV9zu9vSk9NofyMbj7QUIP38= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID1DCCArygAwIBAgIBBDANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0wMDAxMDEwMDAwMDBaFw0wMTAxMDEwMDAwMDBaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmsQW +841XAoeUi+kTUrlrN6UZ9byDExsETfPIYryZJ1CoyMRgHEb1oC80DHWlFXfNs4iO +hQgPIx+qA3G/vhAuNeezv/+UyuvtlrQXLi7TuGJv2RltntGklc2+U/F77ag0YM95 +T6HKD2xs61YOHxBQKYZ+Xy0QeUEVo4LQOyaIDpK/A3Cq71NfAAwJFSo3kikd4hB0 ++CZ6N5zJye+HJ8MunxTXUP9OPY8K6ULDtwjFG6AHBeb8Pri673gkVshsTE/lqaIT +UhR4tw8zIeEel14E5OAYv3izschTofyorOlkI4lLVU/+uquJbc1FQCIrzT2XswFi +Vs4stc4TFyIvTawrMQIDAQABo3AwbjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwHwYDVR0jBBgwFoAUVSUq23EHFVcS+0Ojkk71 +tM/EuNQwHQYDVR0OBBYEFFESWqHkAjTYHxZyEl3JZdziJR/gMA0GCSqGSIb3DQEB +CwUAA4IBAQBFTAF/Ds5BykV9kW9Or3lsqopnJnu6q4Z+xvw0vFksLcSBE0fICN5r +oquAud/KFp48QYnxggkLxKKCseR3VV/fL081AFsgJFFjpvkJ7b2Z1md7g4AH6hFz ++fs5KyUlcpxJEi1bf34KAqnHLsFYEhNSu8r8IxqgUvYcjypr/ynzsFe1QlH/56hS +YCf0dt0dNB+Bqnj2D8Mc54UbIt1nktGXqPIk9dQQptCXXqalETn5mukpn1fBsyCR +lo27Ss1v9XP1kTIHgXiPK3mGefzkVO+sY47KsQL2/g19xgtC4Xih/niVGqqLtZGv +tcMPGCpxRvTkZaJLvTRi3/x1i+synX60 +-----END CERTIFICATE----- diff --git a/test/certificates/kms-server.pem b/test/certificates/kms-server.pem new file mode 100644 index 0000000000..7ebf157057 --- /dev/null +++ b/test/certificates/kms-server.pem @@ -0,0 +1,50 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAveSnmFZ7VQ6eZsDWIm/ceuemvGwxSs/8n8JBqfv3M9GCF/mb +VoCpDn4J7wrNX4Fo6YZusjwzIQITzZhrO8H2nDvYzqbcQRu8CZhM75QCWAomOZcm +wZY6yXJpyJZgOyw4p45QMwRUpe8caTwKxyUtBxVk35R7wvfyzW9qtVshSKJYM3d1 +ylULDTwEAMlPS2d0DecutKiffKyR134+TMOYVO1gEM4lwh1MviaryFzch1RZJvis +L+6Aiug1xa5VIAIVckJL4Z2K+yw0FV0yQwhooVFs8Kv5GikYwhM2a49q5E0psrI8 +HPYLSJPfvMKYh81iSaIGiJ81zEuUW0CM2yjznQIDAQABAoH/SLN0uExMG1NcvPpG +3azSTqb2tQ8iOz3LGBG7a2fldV98ZkZE4keDp5SrjE11sr6sRT7iUkL7f+A82GsC +Z5QfjCJLsq7cOXZb6bup9HqnQWb0sprPtcsS7E603fZJdlI/UqWdzVuQra9YBJ7X +dZyrREmEZCD0+a07mJsShA8VUtPMuuXJ4cQfb1YXpklZaVBjimT9naKL57P/B7Iq +i4uzcBdqp70brGri+x780lF1piut+lHxsSXNJPVw0whvnZ0cH9AF2Mkgs8r1Mfwg +clHwcVSR629b7YyCWSAl0DlUSV74a4g8hBZ4r3grDeE3fyILu1ZtEua8UBLOZcid +LlkhAoGBAN8bHo3+k/CE+4m9jotUSIYa4LjWrg8ks8VXGm684HIwuT8xodeDA26d +G87X/qsxfNnsCJvquhzDuAesHJEJywjJxdPpPyUkcI914qiTvUQSQcG6mElAZ3N4 +b6RGPs9dkcpjXCsf+UgEaXllSZBGIFwiJkb4HgORVrgQbAGfhgBRAoGBANnj9SXI +XJe2061LBGdkk+zmzgo0TM+QNJWecQap8GqcaK+7Yn+1Lbms4eIZojBTzQqFMkt2 +gCc+mNxE20h7Z2tALlVyYnkn8NxTJ0TcMyTf7zq7HuUOBd9DHyHe2sI44i8Miv1k ++4UkTwum496LqHLXi/q/Hra6WL6iZiTpu5eNAoGBAMBfROhQs8U3FSD+dnOC2Any +EQSv72OVVQD6iwsjBzDO/FwV8qO+Du6Iv1qJ+cgpIqtRD1dJfPKifAL5j6Qr2oqY +WGDRhKYFFp1Mm4SZ5x9T0qk1uGupAcqZ9UGjZDMvTi9Bn058AljrnPqUsGqbXPm0 +ZGbbOB4BatHJLyfzIfsRAoGBAJ26D47PMH++oBKU+FYkD5TxKvtmCqhCOl6IeEcb +o2Z5XKrBWbcan0QGaulyJt8W+pl/+/12haRjAuKIkbgxZJbVufSuvav4hrnnE8kc +IYWy+QkpxV6IPSX1/8ZT/UWVSd5HFSIDBLPHqdTEdbV2oXSopbLYwNIDqRQumQRl +kh9NAoGAJEhwY/w/C8SC+wsmyAhgd3pLx6+7Ab9hv1Y9vMvp5dBvPZjNPp6OH/6h +lnPD4Sp+VIvKgb+NbrJZWOZ3GZjeT9xdaKVffvsm/5xKk8LnEng642ZddkiOOxzt +2ejU35RDpRsJFHBqYmZ7RR7zUk7EDt0vbm0SYLgdnvt/hRp4uaQ= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID1DCCArygAwIBAgIBBTANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTQxNTExNTlaFw00NjA2MTAxNTExNTlaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAveSn +mFZ7VQ6eZsDWIm/ceuemvGwxSs/8n8JBqfv3M9GCF/mbVoCpDn4J7wrNX4Fo6YZu +sjwzIQITzZhrO8H2nDvYzqbcQRu8CZhM75QCWAomOZcmwZY6yXJpyJZgOyw4p45Q +MwRUpe8caTwKxyUtBxVk35R7wvfyzW9qtVshSKJYM3d1ylULDTwEAMlPS2d0Decu +tKiffKyR134+TMOYVO1gEM4lwh1MviaryFzch1RZJvisL+6Aiug1xa5VIAIVckJL +4Z2K+yw0FV0yQwhooVFs8Kv5GikYwhM2a49q5E0psrI8HPYLSJPfvMKYh81iSaIG +iJ81zEuUW0CM2yjznQIDAQABo3AwbjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwHwYDVR0jBBgwFoAUVSUq23EHFVcS+0Ojkk71 +tM/EuNQwHQYDVR0OBBYEFDBqDOXtzfPRT+0LYaItzyrOMAW4MA0GCSqGSIb3DQEB +CwUAA4IBAQAFKRNRuzFzQFiVAYHEgq/wxuxayODJqbJahixZXLocTfq7lupQWTbq +BaqAyKvkY0C4sF8ladnbu0FpdcfCUU4yEO1PBjOHSWllMb5gSFpFXZR/1jdRWOQO +6NsWHz7swym51mIhkK7QltJ7YwFSfq8YjxftwbkMcygnBRcTjV5DMWXmXKV0LFTg +XCHbqLNMxfN+ZAfn6JR4Hc7q+0u++js4ptmrhBgOUJvnx3E80sKcrx49XV/WOr1c +UItNxFbHkf5Y5F2f2kQxhuiPrgo6+5F4SwwUjB9+dX7K03CUfneR0U4Fp7GqpRZR +Q3+C+C9PN7MfSiSjV8kcDOUT1K+tIoNB +-----END CERTIFICATE----- diff --git a/test/certificates/kms-wrong-host.pem b/test/certificates/kms-wrong-host.pem new file mode 100644 index 0000000000..fc7b158623 --- /dev/null +++ b/test/certificates/kms-wrong-host.pem @@ -0,0 +1,50 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAkPjQHrFqAGdYD46a+GSAocs0bGYJ+rGs8leoT1GvUsPeD8cP +dXTI9o64zZSCS3m6Tm2enwoGaJdOvslfSqwARSwnzM3H77kr5tjQqmCTVRji4rxd +7xo9VIvvIcsDcI/i6+O6dSioOpDcXejvmvPYrq2rPCtKR3czmHy5p5zPs4dN4z5X +oHQqDoWNBj6du92nVvyyVM4lkmrXCLgkSaCe6hMuo4THfbRUOxTXyLha+0MkE4D0 +tC1t1A42rePm2/RPcsGYTZh3NNGBwvG0oOaYd75w+frtzJTgNYvdjx6neYPz0PFr +78yZV9nDs1i3saLSz1RQy5iH0is7Tqz5X9I92QIDAQABAoIBAASTsACIEWF3v6e3 +rnXmdEG4eXCPeCX8bxs86LOv2D9NfAWMkGG2RE/Xo0cPnTtVUQoQ1xymSfnGBr0V +Hv/8yWAQXRSDARIBxt6mXoNTl5/9wWneEJGrqRJtuaBXw/AJBZA5O0bXGgeBc003 ++OeFVXNKFa/A4mWYRqB3890Yskxn2yFd1K6lK82/6QKGMNu6EVW/niP4kcjrPcfH +xX6+lqxXVS99BDzR4vyPyK+uC1iGuua2t2k68q5ydBUqdHsFfHybdZPwVmV5CJbk +LinGtm6TS5EQGzDfQTCrCdzuNSrrNGlBVF1o1Tlij+nHIPXEM7tVU7GBpkLd+TSX +RYJVC5ECgYEAw575hmNrSeMrIWKGx/NbTZb+xSUJK4IlLnwRnZyaBlalfsMsFE+g +qJ0BTxazk7/QV0okHuT/9wBwQg5Y/AJnjqBSAlKKATcdI/B2fqyKpkO6Wd8f/m4a ++SFDf8dXpgF83ZWgooLsbUZv3XQAbn/CgCQjLHUWrMN+KJ3bCqg5ewMCgYEAvbfL +LdwIvNWattQWTqI8s3NDGHWlLzKXP5WyYMjUTYPe/06BN6eHVo2Zd4n0w8edItIz +7HuTdZkkr8/cmsnuaP8/ksF53TxuOuyEauYQO3SRw+IDnj90zCH62OroPCheAoKp +//0CjlBCtPp5GygQtGNl67MevNZCqJhHj109fvMCgYA1YDlBe/sYTA3GrDWOdU5i +W2Lks/hOkNJIXr4HvWUheZ7qeaKbYCa8GyryQ4V4OQxF5Qr6Cw30fYAj5fpNuPI8 +rm3yCEdzkXA4EDKk2btzJmPAhesa5zwg4fyi7udxelJxu5P7A7IzFtcLG83KWL3f +bPzT8pbfSPAxcPEFdWVJtQKBgQCn3in84RYmKIdmQNGgMHOvgUycJvTLh2NHUujs +NKeOEyJNG6TAnw7kqhRiLoKSfVzwA7kIBexbgO9yVWVo3UaER150N5fiB2et4bvl +br5sLWARSDpVWua4/VQdffWRzVIpvH450SDi1efAhWSFf/UP+Geln++RvbBrx5qC +I0mXuwKBgGXtjFzjNJwouCEdqMtnJ63DNAFSN4xBAACVPI3yFqeZPpo7JhpDxtR9 +5EJjAzPWMf70rhHTR/VHTesDK6L8ybvehCVFMbO7HLKYRSejOm9Hh1WA+U+rbRlK +NWBpVpM28ufn3BVSwpFYqNBVp3VQnpCABy1SG0ofhlSptd+ZaktB +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID1DCCArygAwIBAgIBAzANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTQxNTExNTlaFw00NjA2MTAxNTExNTlaMHwxHjAc +BgNVBAMMFXdyb25naG9zdC5leGFtcGxlLmNvbTEQMA4GA1UECwwHRHJpdmVyczEQ +MA4GA1UECgwHTW9uZ29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UE +CAwITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAkPjQHrFqAGdYD46a+GSAocs0bGYJ+rGs8leoT1GvUsPeD8cPdXTI +9o64zZSCS3m6Tm2enwoGaJdOvslfSqwARSwnzM3H77kr5tjQqmCTVRji4rxd7xo9 +VIvvIcsDcI/i6+O6dSioOpDcXejvmvPYrq2rPCtKR3czmHy5p5zPs4dN4z5XoHQq +DoWNBj6du92nVvyyVM4lkmrXCLgkSaCe6hMuo4THfbRUOxTXyLha+0MkE4D0tC1t +1A42rePm2/RPcsGYTZh3NNGBwvG0oOaYd75w+frtzJTgNYvdjx6neYPz0PFr78yZ +V9nDs1i3saLSz1RQy5iH0is7Tqz5X9I92QIDAQABo2QwYjAgBgNVHREEGTAXghV3 +cm9uZ2hvc3QuZXhhbXBsZS5jb20wHwYDVR0jBBgwFoAUVSUq23EHFVcS+0Ojkk71 +tM/EuNQwHQYDVR0OBBYEFDoo5mlJ/kTj55SFCBeuYrK/0XEuMA0GCSqGSIb3DQEB +CwUAA4IBAQCU2A8qhaoLc2ghpcKGyqiyTCRRv2UvASaEOxgeOYYLVpCZA5n5A+Zp +F0Qi68xxFohSnTGEJ+mzU5GLJuGDeK9Hnmxip8oKyP8aB819uy/fZD8BvGVeeTel +gMSvIdsI/njzz9x1QnMXhMD1Bpxc/EkeXoTQpqL/sgjMzbOiT9j3CoCjP1vxhpgs +tMj76gUpHI625qnGb9g0Ke/ZZNfolaz2k25bEVeFH7a1zYRsk52r1lLn2v3O6SgO +LMRUsIATDcO/4r/AFXIq1z4jNAQQPNmqVaGJ+qr2HXvbASDX7k4XGGBPtsFgYvh4 +SQsDzRgfAzBW4bS2+QYzassW8l6dqPi9 +-----END CERTIFICATE----- diff --git a/test/certificates/password_protected.pem b/test/certificates/password_protected.pem index cc9e124703..51bac10f8f 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,BC29FBC7351F801467EFC29733BFF255 + +M5CwZkLrLVHGKiZSNNjEDHM/caWdiVFcaWGHiGA811ItpsQ07QiYCK6cOT+D1QhJ +OX9z0h9uVbkXevChoSNebSHPQl38/JO0bUNrAye02RJua5y8n78t19lZDvtTtA3v ++w1vlrvqB3HkqC21LGbXOw6REIuu2+7IXlD8K3MWcBa1pPIYIZmIQVzxw12o/90x +OVy+V/r3Owh9lpokJNiDZ+1WR+G6obsx8O1Q+cPAtxI21U7zrIuovJmDLGDm7BdG +yarqByOfb0O/W+26QK6yTcQXlIPIm5SKxJ5YcuRiZ1RVB1uc0VDkz8BET/Q8ETHs +4IBb5+PtKXnYW+b/FzykU8WKUsOPBAERgpHdOgTUFtOVXefV4n+VMyXLVBJvt7yh +FccVrVVw9QlTih2KmdfD3zsbUq+OfEugvJXNPGiFu6ekqZk+719PQvBIlVuxvkgc +nnQsPUOZJtiyi3Rx2Q1Y9VgOvJi0o/uToMrNUw+ubq8MG89gkyt8EirHE9eDTI2S +LF0yQYeUfzdzCF2eICVa3fQthMor2h30QQLUDWCUn05te/qU8eH0nnC44V8R1dZS +5qTUFFmgNKTw8T+3Lp1swmcKDW8ZOFgvB7lYHacvneWDB6P2Gw/uMilrdhxDv2EU +0Hl0c4hB0uxA1JVR4Y1ndCeJv/XQJloogeQJG0qbEu3S6Oy3DW0OyykohnLIxmau +kjf0a/O5k75gTMH+YcrHcsJq0A4wJ1B3KzxMQolBou18Key/VmUkqc6sj2TlXyUn +wsqqF7aJCUuHhRIPa1GopdDFINxIDz02gpRgk0GjGGa2krxyvZ+ZgA4q85pb7Zj5 +lkJNsP9I2S+nPD5fnK4KAzeQxfTVG09Gwrlrm2+wTsF85Sp3nV+A0LybT2GNvTTZ +6K4LtNFl1PGxBATpJGVkOpZUHuzqJFPdM7OqDuzW3Z1llyz5mEvwqaEPWDrnpbuK +IrIAKmplLah6t7frJ1i25Do0s5LAS4RhXMNvzRCihoXsVVy+OUDFfh/UtHkuJKzp +Hpenf+fpUxe8Bcugtg4ouCCHTF84aQgLaxTFHoCD2Pk18LuKjGyLfxhVsYQYvxgk +cQLaI3dKcLCCCbpeN8MPZmry3W4ZozbI0FiWqxQXcpecAW5ombP6xnMrj81bFE0J +WoEGF5AdPYUX8aiu3PYmGdkVPZbrHHB6GXtb4AlA+f+ZbJN+dczwIKkpzWT01DKX +hkUDN6I8yewkv3FRVFZt2yNvczrlS5bPzLVpBrR8e8yHjEPvrPwoYvdsx54Mh5EK +CSiKpAWFFiItyce80GHy1XAoyMg3MrPEa5ovfc6yBWYRiF8XDg+wkBpejEjJSH6s +9howc8eogwQnOzUcr1Wj0TtR/DmcmEVj+qwG/RBff8eDedBJgSZLvEp4lQxKVZkz +tCOUsJM4FW6myCghjjM877dxnfz55jZVf3Ey8BJBOm3E32/3WSnXGYeuCGbIn7a1 +6Wh4oV6qTD9e7wvxwBRQ9k5asKv/klaMRmE3sPI1Z75WwsH5stG8/4ebaJUZyRoO +CY5Hi7toj3JSR1xXSz1g1WwycrYnTKDeqCR9TtvwOCC9aQPhiaMKQpToByl6BBW/ +-----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/test/certificates/server.pem b/test/certificates/server.pem index e745e037fc..02ae0af19b 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----- +MIIEpAIBAAKCAQEAxuGeRu6DuO88SeAnsn3Cj7R0VQ/hTBmZTTjse0NAYBuGYUse +0qvtiAA/wXMoAkbzfQh8vqQtFb7mPAoL86f9nbNfmQ8n7oYRgkqjWnFqryK2icS0 +EpENKqi0iIYrx1456cTOlF38eLkm4/Uq59rg41Lfcuqe4vHmGRa1BWggUI5zMUUw +lqtTxxbqiqvx2r4XaiY3OAdrXahynEN4ZCJwEOT59Cw+oBCLeObq8qcXJIJReYxC +WU/vyOJ0lnfFwN8NIR2uHc+dZoKeaJLtiNvTbKaaF7GOg7ja6Bm2sfRbURpsD17H +yPfnOBwQ48D6wwWaFvhe3FbJJ9Z1YqGnGqqjMwIDAQABAoIBABnVWbVgqwHdKtQf +xphJUfn6WI1qCXup7D9bJbX3LN1ZsJwNDB0VEb7I5X8v1vfAwUUG/V6CveElZwul +HxtQbBb4I0f4RNlsrHPjqmdc9HIjt1lFkJcZef/bYnlEuwVjyHBZ957PEd9D5vjV +B585T7Kc463Y1bhTRUO8rtkxHC11BdGeOPGwb9+NDtBeLKL0PDx8oPs/NTeik5Tk +P+4bMtLLUS2KLkkNpmKd9M5IGskwoJR1h7nFtFy8cZFLSMTS3nJpDMIO5UuAhgfG +G1APNDRWhCQd8hVy4qwAKcjlCcm2hkFEZiPdi2LuHtHYj8bGDJBSIK+BOuDpb/jm +YqsyAXUCgYEA/DJxK6HR5/L35J40FClfUBw/RmzsU+TbhjFSxuYM1CpIfb78h2BH +qx+6PcyvDDKLyB1TKswuOncPrpP0RBOm1OJUK2YzXgdLVtUIXKKPhjO4Bxl09uIa +8wClAGd8GHUCygM2FVV9eP5562miccVzDU6K7TYpi9urAQEHA2ya99cCgYEAyeFc +ddSLllxzZRbs8nbCHdDCsckmg+RddZArcd++wzDACpvxRqvzk2aFdkOq/uHhyyu2 +kqm48pQdCGMcNiWepczRhlpL60IIAUsnPBsdS7pAQEPvwG64cOWKj53CmrK+XVBJ +u/YELIXmwjwQUoJzsNA5usF61uCSYBZfYo0RFAUCgYEAgIdUleAKkiOJosHd2Mid +Ar7ioImyh68DEgjhHuzvbNF/0FYdbQDshZHN4OEH9Tdtdbc8Q3t7s+Ap5dcRjgBV +7fjK3LNhSnJ9OuunL07JxqNlDnky2v+wrFePv/z9iZlYqouobIb9Q0St7gQP/dub +HxUASJRp6BUzuXdEk8It2FECgYEAomk/bTwVIF44J7eN4HJSMJJmT4k4BxuNZKsb +iH0shvONS/uw294yEv+Dl2VRB8TJVh5QvyTzuZQW10yEwbr6KwDf/2pdcWKp9gB0 +DBL0OpwYXJtLIlDw6UKBepC8op/yLjgNWb3OFdOTleekafyw/ipGh0xoer4ohEz7 +Z9l9R9ECgYA8NKDuKMmJYcbie2+cZNGGEAL6Q2eOgbm5qY74xyj6JzmgqH5TofY7 +blUToH+5fOzs3FH/S2WLb+Zmw2Oihi3msp7YoYJYxb57y5/tpx2haZEaVFiSAxG6 +PML98PAOVfVJMrKn9KI0b2m9zal0JnkxTa3VJ1d5RylGLVP490x5XQ== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTQxNTExNTlaFw00NjA2MTAxNTExNTlaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxuGe +Ru6DuO88SeAnsn3Cj7R0VQ/hTBmZTTjse0NAYBuGYUse0qvtiAA/wXMoAkbzfQh8 +vqQtFb7mPAoL86f9nbNfmQ8n7oYRgkqjWnFqryK2icS0EpENKqi0iIYrx1456cTO +lF38eLkm4/Uq59rg41Lfcuqe4vHmGRa1BWggUI5zMUUwlqtTxxbqiqvx2r4XaiY3 +OAdrXahynEN4ZCJwEOT59Cw+oBCLeObq8qcXJIJReYxCWU/vyOJ0lnfFwN8NIR2u +Hc+dZoKeaJLtiNvTbKaaF7GOg7ja6Bm2sfRbURpsD17HyPfnOBwQ48D6wwWaFvhe +3FbJJ9Z1YqGnGqqjMwIDAQABozAwLjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggEBAEtHva5l4hnw +rNfC9a+lVL13APFPRcS+b8cfANEme6D+VdsZMqUkbaetTLxxJSNpvmTidDSDgwWy +oEpoKLpQSH1wZNs52uu0UkYVPJTRmRlEGRu1HpV6A9MD9+Bq6dYtw16kBRod30Wb +a+Ot7BfSd63hHOwQZUj3Ob28Wv1+LzjqWG1emCKJQakpEkaXpjUVTtoRqf6yU4oz +PQ15N2gunQMMkVz4ULO5GhBqIZOSj1OieFnSlSuVUXyDplUTGdBdZG4bEMoC5TYU +dmGxyppzAMnxPUpXvIYye6JSf+rpEpXN0flDVerCOFECdhtRpLoMLn8yjcL/cniV +RsI0HLZr2Xk= +-----END CERTIFICATE----- diff --git a/test/certificates/trusted-ca.pem b/test/certificates/trusted-ca.pem index a6f6f312d0..2779383682 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 +azELMAkGA1UEBhMCVVMwHhcNMjYwNjE0MTUxMTU5WhcNNDYwNjEwMTUxMTU5WjB8 +MR8wHQYDVQQDDBZUcnVzdGVkIEtlcm5lbCBUZXN0IENBMQ8wDQYDVQQLDAZLZXJu +ZWwxEDAOBgNVBAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAP +BgNVBAgMCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAK6ITeEFh4PdTFbO+ao5wJs7MrM6/mRvt7e978QrLMxIna6A +EA8Pnh/ZfhYQBPiqAFijDYEgINEi5CyWOJN4AKDRRahORHb+Uk2voxrBeLE99vBo +RtoEF+4adD8SjjQ+7zZvImi6PLXiR61YGX3Rs06NXf2p8+2d9hgHULTyfwBJhRPD +Q1c3141pU2+gzicRgf208lEMfV4/tv87VYrQU6EYxJvXKPYf/HF1Ycx86a/Z8NHb +Iqvo7SSTC+B51EobCffts3hIPXOE5mdyE0ByMzpzUVRETOp3D/oHdGfKnLxe7JU5 +KxKToaQm8W6mV6Vfp8llulG5SMswclaleacCsq0CAwEAAaMjMCEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAGADW9XM +oMu/65Y3YgNEGqvVD2LbeHKfglULLqK9zUPA+rt1ZyPpme/QuQxLarX3e67ImCQ+ +prunmgcNEOAdK71wFby2tqYJUlHLcB2q63iBLamoMXB6L1lKBGhEMg/lewEMOE2A +2ZjjayRT7IyeRp3zklhQSoN336HkDqHFop6CJRIV/s+nIZaj0juvt84avOlMj0/1 +iuFG7f0uZ61XijYDrNfNPFILdeR0NsWPxR35tycEaL8CEwXG7voSoHaE4cMvAsWA +0PquB95gladaCAFPcgAcEOnpl430n4Pdu32YHNaRRr6mF9iodh9L+/EbV4FNL0J8 +i05opuR47YePnyo= -----END CERTIFICATE----- diff --git a/test/test_encryption.py b/test/test_encryption.py index 56648d3e00..02d50238d1 100644 --- a/test/test_encryption.py +++ b/test/test_encryption.py @@ -3021,10 +3021,9 @@ 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) + 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",