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 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..3d18704bca 100644 --- a/test/asynchronous/test_encryption.py +++ b/test/asynchronous/test_encryption.py @@ -3045,10 +3045,14 @@ 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() + if sys.platform == "darwin": + # Python 3.14 sets OpenSSL's X509_V_FLAG_X509_STRICT via ssl.VERIFY_X509_STRICT + # in create_default_context, which requires SKI on the root CA cert. The CA cert + # intentionally omits SKI to prevent macOS SecTrust OCSP revocation checks. + ctx.verify_flags &= ~getattr(ssl, "VERIFY_X509_STRICT", 0) + 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..11b3284c2f --- /dev/null +++ b/test/certificates/README.md @@ -0,0 +1,78 @@ +# 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 | 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. + +The MongoDB certs and CA cert intentionally carry no AKI or SKI: 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. 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 and macOS +works without `--tls-allow-invalid-certificates`. + +KMS connections use `ssl.create_default_context()`, which sets OpenSSL's `X509_V_FLAG_X509_STRICT` +via `ssl.VERIFY_X509_STRICT`. On macOS that flag is cleared so that the missing CA SKI does not +cause a verification failure. KMS leaf certs carry AKI and SKI for non-macOS strict-mode +verification. + +> **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..f4dba4cbb6 100644 --- a/test/certificates/ca.pem +++ b/test/certificates/ca.pem @@ -1,21 +1,21 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/test/certificates/client.pem b/test/certificates/client.pem index 5b07001092..706dffe137 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 +CQYDVQQGEwJVUzAeFw0yNjA2MTAxNDI0MTRaFw00NjA2MDYxNDI0MTRaMGkxDzAN +BgNVBAMMBmNsaWVudDEQMA4GA1UECwwHRHJpdmVyczEMMAoGA1UECgwDTURCMRYw +FAYDVQQHDA1OZXcgWW9yayBDaXR5MREwDwYDVQQIDAhOZXcgWW9yazELMAkGA1UE +BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYfKhiRqljCuyS +3H+hMhSBFPjhEC4KKLsIhrXX5tb/UIsFofgKHRASgdg/Ksf4wpJiz8+qLH8yoIEw +4Y0fh8n6r2WHUUE/PAFma6AoP7EPYKHK8MAx98S+QSRxq47iM3MQLOxL9uGVjRCJ +/D0Q4uXOMvJFjFdx9iRExZ1Obj/mojMgClbOglwz2gRiqr8rHMDqOOYMV5atstY6 +3fPdw5NPj5KCEDEKbBNCm7+c+3HvDfp0MgqTS32Aqk3Axh4Opj345Td9yiQlWSQE +lWPaYgxKjNytfldnB1j67YGiQ49lXT2ZJGzF33VlmEKU52z1hN0L+F5AOFrX7izS +pALbX8dxAgMBAAGjJDAiMAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD +AjANBgkqhkiG9w0BAQsFAAOCAQEAt5EMv5zKAaVqNUHZB7YO904T+D0SuMt4q+ht +ORKhypKVf2LKAz+qkzfsN42u0p7C4zuDGzpIm9vMHZABrvPsn9ArllIa0IbPsXdl +qiKqH+4q1IlsAIvy/Dg/HWDTJb09ZBwBIbmpQ7qW0nvQr6nGFEta1egXB8ha8FIs +w6lo03w22qq4hKp60THeeHXhQ9TTymKvAn2dz5wqOw810kv910FlkDjQxP2QZlC8 +b9FCfa4c+ymKXbdaZDBNEerxwR0Bs5LRX52SR4aptYNAuOhFY+S84qmviqM1RqMh +rkyeIoMD428quauaeJijdoUlIfrda0L4pDwutL3Nbn4xfvrzNQ== -----END CERTIFICATE----- diff --git a/test/certificates/crl.pem b/test/certificates/crl.pem index 733a0acdc0..76b7016545 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 +EwJVUxcNMjYwNjExMTQyNDE0WhcNNDYwNjA2MTQyNDE0WjAUMBICAQEXDTI2MDYx +MTE0MjQxNFowDQYJKoZIhvcNAQELBQADggEBALxwgEodLFDTraRqWM6MPOeSUruy +Z7hmOnqncS0bgnrq5PEjVEvwoFPcdXBxkkkOTMzqH96HINOVTBnnhRkFC0wLKkyq +UmqWkU43iHwNKrI03kuFd0lRc4C8w+0aBSeDvXKTfe9W4r5iwltnWIg3INfOA6ft +T8xPAQFbviMhMDTx+SdMdgZJE/BUCbTMPq0nh/15UdQBS80tokgqtQRH4PPzOrUC +QcxLzJn3mnjeYC1pVJxdFi19zfyEySv1NlptsTYfMJj1WE3fIDRDu3b1EuSTdV2l +WUhBjE0Oy5TU2KZ4/43OGHaDl6mOafiWRsPBaV3aFYG8MOGg48tCOTU/OFA= -----END X509 CRL----- diff --git a/test/certificates/gen-certs.py b/test/certificates/gen-certs.py new file mode 100644 index 0000000000..33e04671c2 --- /dev/null +++ b/test/certificates/gen-certs.py @@ -0,0 +1,463 @@ +# /// 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 (kms-server.pem, kms-wrong-host.pem, kms-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, Subject Key Identifier (SKI), or 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 only basicConstraints (critical, CA:TRUE). No keyUsage, no SKI, +# no AKI, no SAN. +# +# keyUsage is intentionally omitted: on Windows Python 3.13, OpenSSL 3.3+ +# raises "certificate signature failure" when a CA cert has a critical +# keyUsage with digital_signature=False, even though keyCertSign is set. +# Python 3.14 strict mode only requires keyUsage to include keyCertSign +# IF keyUsage is present — it does not require keyUsage to be present. +# +# SKI/AKI are intentionally omitted: adding them causes macOS SecTrust to +# trigger OCSP revocation checks on the MongoDB server startup path, +# causing ~67-second connection timeouts. +# --------------------------------------------------------------------------- +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) + .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 / "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: 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 / "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_cert), 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; must NOT have keyUsage, AKI, SKI, 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 +for ext in ( + "Key Usage", + "Authority Key Identifier", + "Subject 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") + +# 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 ("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 + 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/kms-expired.pem b/test/certificates/kms-expired.pem new file mode 100644 index 0000000000..1e96728a16 --- /dev/null +++ b/test/certificates/kms-expired.pem @@ -0,0 +1,52 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvtzo0bK+Y4O6Y+R9yv1fq3ZLiu4LIEZGirYbj3U2t9Bwfhm/ +U6IoYxyjf2eErcQg8v/gUsBcll9bYXPhN8wRjDyrqv9XAPwyvlyJGk8/0sxD7s5q +TjB4I04AVVGU7oTjUvlnyRuJU8FZXbliIT5RR8P+3sKpYr6+UexvF7Ir83yVoD4X +bAYiBmky14CuH+KyJYB7Q6UVWGXQdigarVq6cdx7gyMe4Paaau9YoEfr1P1pLHvf +khCa8ZeoRPBst+yWUQsC33C/3tVayMfbKmztgWXJLNSl5InGa1vQkXH5sneY4Zte +bTJcWy55/TIWQi1nOU2u2recYDxiQqrjfIwafQIDAQABAoIBAB/AU1DzSd33P443 +qD+ZKA23p7iMgjhTyI9x3SLf7oLkv5oSwXPx0YMvc/mRaI6Zxpt2OsS5cI2pfmO3 +aduk7LRmMW7IfJpS2kQ1068XSPhR9+kl2KR6Rrok00ReRobpf4HBsOTRWmafDzVa +zjrWiaIFNoSrYI9nSPUK/q4z+0DNiu6K5Ig0I6X4oGl9QNDCRgkmod7lx3NL5pKM +3299c4FMaqvkFYvxOAbgUK9f/NuVqPQyHff8Ks9GK4itTChdXfevGdEfrs1G0X1k +TjxvmnPu2DMOOwmRutAU9hA7P/mAR0qhUpk5deHj98/qbm15yQPJRbyk0ew7Ifn5 +71sMpRcCgYEA4KpKbbk6beizTHaBE3BP0d/De8ghZLHEn+iWupDurUAT+Z6RGfZR +pzD1PoG/1Lhh+WGvm69JePIT6j3jueNoQxA5czCppwgkHO3ZA6+IOCQAW6J+hFXI +ZhIabiM5FgW04zJD8sT7Cx6iFkqh2z5xL44Gzw9R7pIhOI8g2uCFm/cCgYEA2Xuz +7yEIx99iysxEUFVbs2z+i1Vvyyi0kH816vfgdT52+IjNHDiAKAVcLhvWx+i80FZL +xiq+VRIBmqtBUrIa6W9/NsFl5lgRq9WnkwcW78XI+80tJKBoHd32dyXbznE4DGPf +EGXMkiQevafHrCjFchZ1z9db/dOfb/oZ6p/yWCsCgYEAhWV3dfjycYom0/LVJzab +nlEPoDKvaTuINS6EONiPbz1J3wBAxbqUtwIBzBB8V5D3U3ymKXmF1ZNfMcl3qssV +ACTlB7lQMoZJ8wdiwKZ76mGt+LreBjNtHvYGzXiKj8HpqrEQ2VgOe4a/1R6RRj2o +NQVOk6lUC6Smpw+NAYkoq/cCgYEAsp0l6f73dy+/s06PzGpOJc4eP9CrP+7uXL4d +ShzJ+4CRtQylZ8f/eN7uFfBHNWevqms1UEtKhhODvcNoosIj2BP6Jr4vMj6iRL30 +IoxwCfwmVKbtrGcRG3ZwNOqi26mgnoxnZtA0ctG3bYueMYZKoqhPmaMFqjFjgFOn +dUpnfoECgYBQ16YU2MdG4ECF6gOifI5gFZoOIjdxB1sGdQhdNKwei6Tm8Acbz5QL +25K3lxO9FSW6KKK3Ktl7AkCJTjwrAK4Si6JbqDpM7LWtH1Gy4Fch/Q0KWd/3feKn +kGZzbqCq+VPWKEqZOJ74kKm1UpUW7AQ8xjupxvSj25l4p0u8lhptaA== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIBBDANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0wMDAxMDEwMDAwMDBaFw0wMTAxMDEwMDAwMDBaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtzo +0bK+Y4O6Y+R9yv1fq3ZLiu4LIEZGirYbj3U2t9Bwfhm/U6IoYxyjf2eErcQg8v/g +UsBcll9bYXPhN8wRjDyrqv9XAPwyvlyJGk8/0sxD7s5qTjB4I04AVVGU7oTjUvln +yRuJU8FZXbliIT5RR8P+3sKpYr6+UexvF7Ir83yVoD4XbAYiBmky14CuH+KyJYB7 +Q6UVWGXQdigarVq6cdx7gyMe4Paaau9YoEfr1P1pLHvfkhCa8ZeoRPBst+yWUQsC +33C/3tVayMfbKmztgWXJLNSl5InGa1vQkXH5sneY4ZtebTJcWy55/TIWQi1nOU2u +2recYDxiQqrjfIwafQIDAQABo4HiMIHfMCwGA1UdEQQlMCOCCWxvY2FsaG9zdIcE +fwAAAYcQAAAAAAAAAAAAAAAAAAAAATCBjwYDVR0jBIGHMIGEoX2kezB5MRswGQYD +VQQDDBJEcml2ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNV +BAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5l +dyBZb3JrMQswCQYDVQQGEwJVU4IDB1MGMB0GA1UdDgQWBBSu5jZYXvn+lt03Lnf8 +25wjf+ZMbzANBgkqhkiG9w0BAQsFAAOCAQEAKhaZBqq6ZcupcNNhBpMVlZzuH9V0 +OOqhlzkLs5gMzm5vzFrOTU7gmmdY68+dg7H11kplq2rDRfuW6mOLhScMAaL6voey +yUsY0QLvGqPASHnluPbv3h6y4vJuo2WG5u4/AHR7M/bzZ/IN3rCZTfMvrsrWCwVq +PHnL4sfsdF5SEbyDi6YOxNTIodyV+YDMnAL3RSL8ib+Qoxq2qI8APu40d6S8gTWH +w36+Ps/44OIY4ZIDBwH5CriEAg4mesbiH7/0Cop1mZO1QfXFq4/+xvgc85lKxUg2 +4h30inBpOs9QNjIgDMxKooA0il+Xc/bss8pJBNAMTtim/K3tmMp0S7kmjw== +-----END CERTIFICATE----- diff --git a/test/certificates/kms-server.pem b/test/certificates/kms-server.pem new file mode 100644 index 0000000000..85bf9a157e --- /dev/null +++ b/test/certificates/kms-server.pem @@ -0,0 +1,52 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAp2Lbuh/CLbd6Obeq4k5MYSHSHVTmtqIvXrF6H0Vlazc6uTSj +hGdwbH4+nrR4v5Nq5wYo70KDyds0T3B2Xf8200LIbacF6r1Gi9xPGIrXcPuFqb9N +YVtCJdk9+Y3iKGUYOOyRJ4qM760bf6YHS7xmKJCw6+floXAQ2khSRdvZOvm1/ehZ +WlLA0FwERLEJExlyp8URI2ic+vgyjrN/6TWADBzveqpmb87oRgAxgGkk55oV/geU +Gi0c4/+EVaf6LPEzykyFQrWxQxDjXy/3fLWoDmYp8KxIAom8tX/q3/GYKTR9znEK +0LJOd/wthDeez6gSuL0z4BSC1DeMiOLBJz47cwIDAQABAoIBAANkTW+IFTc38JIa +1qufSoztUoSlo8cvoiYZEpBvp450oAwAtQ+JyQ1pwXsVzRyUsCXeShYPEvyUJIs3 +jC57bXD6eXU/XS9Uholu/WtR5Ou1LRAzgC3o235I2Kil519KLSN6J7bVZ+WzbEs5 +4gv21VsdE3i0SkLrMmw56vDfc5duT40iQhOWhn27rj5BR1+a2OwmRxkJzUulvKz8 +LfYylxX0ze7OI5Qan9TR4lcnOkNVDdpOb3ltKEDzqUl30vJkPdOeZkW8bJXjweyo +nMqck/mY/xiHfFQ96A/2cahkGvch3ZKWmWC5T7YORJW7+OwrjvGI8+Z+h3PvNqaL +x1SRKAECgYEA1U76goR2FwePdlV943RrmZsuJFyoctfsKHv0f05qJqhEUXLWrnvc +0260OgG/NGj0/mVcK+iH29l0BG++KqnlcXZX5wb3EEtVaOEHAonSZS8lSTVIpdW3 +k1aPAydhjlAUBKCXPdyXTGhxuNsn/7VM746J9zzgP9pauwAAX1UbR8ECgYEAyOMD +lO/2erLKPukfjlEkfkEtbnNM0rmYUHz9qcjz+CDIcidtedVy3W4ZPLFAzIgHkAJA +p3MQ4cqPsc0GQr9Y01GZQ/2Jv11zCErHhUqHAOkXGwpQMODS38HtgimSec1mgZLU +aNfT/AOX04DbclpDZ5ShOajnjIZ0/rCDLVIK8DMCgYAxGFh4Kdy0OD1A0zSCYY1S +cXERVXI/3IqyVrVTh8zO0PPIe1IGHuQYleZNY5GKko2w78tjH8YFR+t4CfAPCcOR +ddeNiQDcczpZRVHDt80BFPTUALuTz7jM5KNN6oZ9pti0p/Gnf1ojb/acwXRXWnc2 +u+vtR8mlaLBxUfLD/malAQKBgBpsIZB5b4X79jYIG6pwachhckRQzg35c1tC1Wp7 +j/tW9IZvQSsBNDaDwLYG6mr8iWIbqb1cmR/ZsMTGHsiwulIxLWOP+Yo+FF9G1q9l +ehRYlD1uQdXr/FCKBV9VcHqs1Yq9cUrI+IzxPAsJq9OCo9L/7aTT3oDRPpoxRU+0 +ttOZAoGAPiwxV36Nkf4k2pw/l+kAPg2E6tvSYJPXifVsfvVPSEaAIn6ZuQnutK81 +mIRvaSgcxDv6Bhwaj3a2e/SKSKlxoLG7mth6jR9tCBw/RG0wN0fX3BfS/gfzYpFv +Svb2vB8lzyXpFjA1nj6TsUW8s6iTnJ+kh8cBbjSJqbAl+HvVot4= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIBBTANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTAxNDI0MTRaFw00NjA2MDYxNDI0MTRaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2Lb +uh/CLbd6Obeq4k5MYSHSHVTmtqIvXrF6H0Vlazc6uTSjhGdwbH4+nrR4v5Nq5wYo +70KDyds0T3B2Xf8200LIbacF6r1Gi9xPGIrXcPuFqb9NYVtCJdk9+Y3iKGUYOOyR +J4qM760bf6YHS7xmKJCw6+floXAQ2khSRdvZOvm1/ehZWlLA0FwERLEJExlyp8UR +I2ic+vgyjrN/6TWADBzveqpmb87oRgAxgGkk55oV/geUGi0c4/+EVaf6LPEzykyF +QrWxQxDjXy/3fLWoDmYp8KxIAom8tX/q3/GYKTR9znEK0LJOd/wthDeez6gSuL0z +4BSC1DeMiOLBJz47cwIDAQABo4HiMIHfMCwGA1UdEQQlMCOCCWxvY2FsaG9zdIcE +fwAAAYcQAAAAAAAAAAAAAAAAAAAAATCBjwYDVR0jBIGHMIGEoX2kezB5MRswGQYD +VQQDDBJEcml2ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNV +BAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5l +dyBZb3JrMQswCQYDVQQGEwJVU4IDB1MGMB0GA1UdDgQWBBQOfGHq0KN5Z/z0Wwqz +SbIdxU8XwDANBgkqhkiG9w0BAQsFAAOCAQEAr8bI2OjuqgkfSS/6KR5BoqP/paza +9qEbtQn7wvA9Rmv5/O5LsGQmBA++k+rrQId8EvEJ7lwV/pi6Y/s/wWWd61DBMH2b +2EZF+b5I8nNysYiWAy/OdkBEB8d11lzFqMSiC+PrPO37owo96d0S5wOKiblPqmtz +QfLlUOHUDwGCBaUhKmJ+Eu9GeCtbttr++fA48s/H9ws2/yGriMTyAA2PFY2lCQ+8 +H7Bo8P/f66YLsd9A9BSED9yDkNw4f1OUPmGnsqaRq3CgguuExFETgin0Nj6uWp4R +uJxFlCpc/4c4A+HwFIYF12qBh+c6qJ/UhGBYpFThFsJ60U3Amus23rM02Q== +-----END CERTIFICATE----- diff --git a/test/certificates/kms-wrong-host.pem b/test/certificates/kms-wrong-host.pem new file mode 100644 index 0000000000..c0d97a7d26 --- /dev/null +++ b/test/certificates/kms-wrong-host.pem @@ -0,0 +1,52 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA0XL5jO8Fka8RklvgS/PWVBR7nvylF1nHPefgG18Br25ZB2ip +Hf9Uke5ZNwQWnoO9p+81CPR+ssppxo+6q9/6BwRf0+ZVEIWYdh3DOrndm0Ydl5Pw +ZOy2vQj6gPLDT+rMybVY/2S0gEMaf184IEFookh982G9RX3OHkEMOcQUkdunrNO9 ++Ua1mNKomp+XiEKVIjqBBEAQyvHR+L2Hj+HNGnUSXwX/PSl1XVsoSg2HOBbBfW48 +2rcNmxtTgCLn8iA4mMq4x+/Zu7jPRgt9OeN5OToJfzvOkvTRTV93xCj2G2H/JaFt +S+HYrmXvZy6beuxw6UT25h0ywx3nD+s6Ku69lQIDAQABAoIBAAFPRvCZQ59zYpiL +F7r1DZKj0iYRwSjrnphSs9vX9NdXYrOHwjVcaSrEb8bG5F4dx5JrDeZxb1b7Q9Z1 +amuatru5sxOzIM/Xb52fEAWoL3kofHtIwu8On96zIkXeJSSByY5u70O7KhNg2Aos +QUCXLoO23YeN3xrpIq0DwRzQ9UP4Nb7MHHbkor6EG7oXz5YD51tiGVW96Glyqci7 +S1CjO909rDJITFeNKlZlXgktvFhMeVm5+GaI3ZdNGiO6hc5rDre5/A9HfikLGsuy +dX009fm+PCbpnLhKPrM38KFsZmaEp/QSnAtWqlsGV0dWKZLO6GOYqf5LgliBLVnZ ++2R5kcECgYEA+ljYdDk1MGPOqgEzC2qF28iCFohPkCfQMD4yg6GPJcoeCtFxIVjt +XG8uwJ4FTnCoCJ/4eTOn9u3a1QBygS/m71P3sXU8HNIzVvXl7HOJ6D9jhuzQhUia +Zyx9ntEKTDnTDxj7bO69pyaxByqIu8TKkrGQEFKQhigx0bzmGlvJZCUCgYEA1i23 +CGeMj9tmy1+duVPnmG/ssQyXkyflBC8P69w9GbYUaeh6XUxd5nqqEt9GXT1c8zYX +WyNU+dYsentG/li8QygmPyGBfNu8yyWCJ2j9P1NpoPcEcPUKta1J5BeVNzz6dyco +nVHUDH3msXcX/9bQyMm6J5H8eB9H4PT7mfbGgLECgYBOLMpC2M5sMu6JFeDLstLk +A+Pjh2NY/6W6OuHpStz5jvj8pdRu9mcAk1OFIJNFoFZIgzPDHUdZC4NnOkGHZ970 +Y0MYriQ8V8NiZ10KDjZFSO4aZv7ib/6PM0xy+JH/pZrrvwBcTtz4QlPLihOylswv +LLVw82dgDVMpTJSKLJlh5QKBgHCCZULx+mHblF1DZjxjuiZWrVS4U6uG6oRPIKL6 +99HY11JnQFhgdHdNeqgdR/5U7M4KXSyQG+R+QLE6rymPfZ4dqjHBrR7k44Enu/5t +5ZLtg3B+MoQQBUc4t7ctOEJjMwOCu5Ag2y6QuK4C7MWFl/nSFosQ4jpL3Fts9fqE +KvSRAoGAKgD4Ra6DhMfxmV/EVweXrLsEDoiA2HFXK9JEWtHnOiwMXMwfOVZVR2MW +h3lwwerDGjw475YGz1e39HIQddrIoVXDzw6GYunMNGw/iFrAs8MQ/lOL7iOxwq22 +dYCHEGDqM3K6MRl2wo120r4g6Rnr57hRoq1n7x52BQZoEXkjcUg= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTAxNDI0MTRaFw00NjA2MDYxNDI0MTRaMHwxHjAc +BgNVBAMMFXdyb25naG9zdC5leGFtcGxlLmNvbTEQMA4GA1UECwwHRHJpdmVyczEQ +MA4GA1UECgwHTW9uZ29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UE +CAwITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA0XL5jO8Fka8RklvgS/PWVBR7nvylF1nHPefgG18Br25ZB2ipHf9U +ke5ZNwQWnoO9p+81CPR+ssppxo+6q9/6BwRf0+ZVEIWYdh3DOrndm0Ydl5PwZOy2 +vQj6gPLDT+rMybVY/2S0gEMaf184IEFookh982G9RX3OHkEMOcQUkdunrNO9+Ua1 +mNKomp+XiEKVIjqBBEAQyvHR+L2Hj+HNGnUSXwX/PSl1XVsoSg2HOBbBfW482rcN +mxtTgCLn8iA4mMq4x+/Zu7jPRgt9OeN5OToJfzvOkvTRTV93xCj2G2H/JaFtS+HY +rmXvZy6beuxw6UT25h0ywx3nD+s6Ku69lQIDAQABo4HWMIHTMCAGA1UdEQQZMBeC +FXdyb25naG9zdC5leGFtcGxlLmNvbTCBjwYDVR0jBIGHMIGEoX2kezB5MRswGQYD +VQQDDBJEcml2ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNV +BAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5l +dyBZb3JrMQswCQYDVQQGEwJVU4IDB1MGMB0GA1UdDgQWBBRA8vf/bKBCfO6UANAh +06FCA7IkcjANBgkqhkiG9w0BAQsFAAOCAQEABl2NHQJ66JTqF7+gj00XtUUuDzi4 +xU7y9QR80KvPaKHdhEOQNgI50Y570NVsgVE7dhND0L6KN/S9h+S4MwubHuQb96rN +eESqXrYc3FwLuqzX6RFX5qlyY0J0gaYFd42DY8aLzx+ypIXqSskFbpuxRhZudYjb +R1tntN0I03Yqrnkiwhpu4W4BMBZJ4pmeb2KzXjJs7j/TQDZLRvQyOC4kvh9U1zd/ +QB6Z5S0oxVGXNFXKNVYnMz+k3BFKwtk9zkWqE0/Bmy8b32zElJA+NZrtHCq4+SY8 +4xrPwOXkLX05tFmsOow7caub0XoOj5ZzlJCkNm2NnY4pWOCab3fcc1GzEg== +-----END CERTIFICATE----- diff --git a/test/certificates/password_protected.pem b/test/certificates/password_protected.pem index cc9e124703..adfd250558 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,86A8C3BB99639A23421793877096BABB + +fbUZkk8c9a095dDrPfp3zxX51FMSenSslRp7WTYhCK0xq7mc2DHZa3sL0MbqWWzA +Rsa2Me0eWwOp2nOM1R0LHwvL9yCRBjIS/fKKW6ARZhjctzALQ0tqG5I0TK+xoMs6 +tHfQX/qXDKL7AuEyfJEUIyeRBqSQQxyLsUaybDcnnenlJRLcPvw68woY5sDyFjIl +EwZxd6znv0M2gOYhnJgovVr1Kf54hb0gFaoBffHk9eMczDo9oe85ri39BB3wfy+Q +W69Tr0MUGmz/cqhMsiv9lhlSi+C8KYgzO/TFQo9kOpR24iYBMRWuoM4hPfdPRCxE +uO0jWd7WR82cHZg+/wm0OgaQeK6gpHwrs7QBih4pBcxiQh+lg8QUNfdS58NHzhm/ +6KqwIH/vg2wB0efIr4JFt0U9sGW2M5UJvVFGQWD9aInyTV4fj+DQuWDu/Xczqkti +sSnhrV8LBBmB6Bp87e0q44VPOSZDvDYArSZLL74wavNWorv6wK8qdcokxDPj8dME +PvUfRuwoqAubeblG7NDOz5Obo5M0ua4lcKzagK34N3fRwXIUDvSLdgdXYvR5oLxB +tAxoifj6caq77+WvCuSoRPGY73sDjryHLy1T6ZUqBWZdDWRWOMlypqunal+CbtVc ++nRLvkcLOqZyoAkU+Nk+T4t8M+1wlclMHPXqVoEoUdiNFp2Xg6bWea8pEhNP+YFK +02+hscSUtq8dGgfQ4Ht7hdB7MKI2SvvG0IZPObrbOneD46eXHwPUa6H/+ay7z+PC +0nt/8ZGtGaq6aYbnGnV50+NnFhX7x4FvvqvB/Nj++i/c1kfebzB+Tuz39m466rE5 +6Vi9hl0ZrBKcnqNE66l3B8gSsD9CFZzpRwTCLv2R6fvq75qr1fV5eSb1pseEnoXg +reXd3X3U4H7U3PJPB1Ug7pC+Y6DrGhkPerfGeA7xwcqBRW3DBbWwcKbZM3rtTwoj +lzG+YkEKKhZ8/d1aSmhult6q/Cth60pHVOVimpqNxYlhbDU4Ie2LkmcEu/t1VHdp +xb4Ycbt03l6UNEOZ/tjVjP5oXhROD0mis5+lMhj+6TgaHVcHhZEN4Mlrs4OLP68p +oU5UR/UCmXtNJe782UK5gr1aMrMdI0jHotm8P5444RaGfww/8Z03k25sO6DV1ssE +uyXMhg36A8EUITP36AYQF8YBB8VnGVEIAjlb5G3llXCPMzMNACFuD/3JH4KY2/bC +mz9EIda41yX2gNrW61coSzbdRlUYuJxLhTxaA3WBGZ+hbBEbH467jvmf+gZ9ZVRV +HPEPfHP7MiNPZK0wxFBK9MPFm/BGv3RXz9qQX9OiZIlEzI5AH0X5XD4o1WLfKZPL +D5pwJ+wM46iRKJ0YVDOFQp3sfSvbjaz9GuG5gEd3DwQvX9w453iG0QLCAKqPGpKg +0v4ajAXGmFkBHh+6lYYVvtAS/vOqsUhQUyNyPnB1BlJqheVUTMvJKiqOE2EJAo9T +RGNlxLaSRtAa0et73X32BJZf8jG7UJXgajVUd3R+TGv5ttvbz+zFxXfZMswRVxaG +joxhs/qeO3tSSXLAy2nXl1b7Z/5l42iIQTTcMyHDQX+iqS9H4E/lvK6J7geOpEaE +-----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..45e79dda73 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----- +MIIEoAIBAAKCAQEApBxkSab/OKr9+jTty/mxxwiLO0PgPdAbbSaK+NKk2cJKe/3u +HMWqA+yM4ZhDrgGNcEXC4eQCYQSVmoABSfZEuHI9JIevg6KgEJVUu+hebAAg+7so +N1N9WwxbJFI1UDfAXGnsUpiecNNwWL5VRCmgwlttGE++RcC2+zzTyRwAnrllapAy +GhqPpHyF9+E923z7Mqfhr7U2IvxzvPJHBHhj5Zyp9wUgMDoz119oJLb18QvX39g8 +Bc6W89CvSUofcXmMoROKaPP6jYxHLXE9OXUE75qhmlevGRA7yrAiZdhwYGA7dGDi +vNNlIXOaPh5FCRsJzA5EYh1Bn8859kLkVMK9pQIDAQABAoH/Vs8DPZ0t5Avkd4sH +6UhrgZzuCVYeMpRNQwTgU5PDymxmegVtrvU1ZF38fQN4yX0zaUV9kNUgwlu/xw9u +9HC7E9YErGNvCXKSDjOaXst2fCqVR+ii8qEh7hzbGUYNwsu639In795LRo3nH7Tj +5ZUfia+oRZ6TnNIT+KcfCtfafBqSBc7m0ORpUYtvHNq5Y1derI4qL0jTMCy3J20f +ILueAOm4vOIMh9ugaxgusBGZfc8gwmR3ChpdQ/XOZTrj2KBLaDS1ivY4ui+0/E63 +hDQfGQH71GfPxjlHkff4nO6eXQdP/ShtwpZDcBGAA7Fp6HGM3FR4Jcj7id8rOTA/ +yAWxAoGBANL8dM/xJ4oVfa7gnC8gMNOfPY9o+PLpQWIGgDgExjVA/I0BrO6eh/iC +ZrfpvY4+TfijbpLGqx1HmuHTaRmLupvy7cVbu4E2dJX+MxEyZrvLoCslE7w4QNXm +ljDGnZfCv5/UHW8yhppreI3or3uz+5KxhtfJ/KKM/D/nlFeVukpRAoGBAMcfuYmf +9ykUMtKyh7CJtOcdFoAjiu9PKBxGzEecP9GQPvVyO3O9qwCtkAzNU0n3meKSjDXm +UN7nTcU58iCxQUYA2rgiy5ZxQqq3K9R0OQhz69C4RWocIqJNf3peWXF/47OyR2NP +qnuUbYnkldWWTHFUaiDcVU7nnnCBAmmDwhUVAoGAeQf/joXdU7YOWjJZBiOmPs+b +hdgG73nlWvE1vmzmswfrmIv8gwoIIAPWHuyEI8QUAGzocmRrJqm77I3VPaVNUEak +JVIBFxeA+8ZNzzClhFdEM1vanV97ufjD8YkOQE+kk3AfznkihBTgnC998y2FRFp4 +avNg7HKKBbK4AyJOMnECgYAdFs9eAZZz09WQ3i/gZF2fHaq50Xdsel3bs6QIGhVg +offwl12EDQM8OB7BIAW42okKhmohPaI2zgeYdlye1gY5GcrZ94tSUP1yPwwSH2Bt +kbGzbhgF5lJQ741d7QaYBBzZlYPESFEZeJd/+3rAFxLXw4M1hbqYqlGFEfOuQmdJ ++QKBgFytF8rQ8NIh986MUYL0nRFNcCs6MXUZoSyVVPQbBgCjgtkQb5oBxCgRCFum +ss/xfD6KmJkPPC6mCMJ7xriP8r1PeBIDGLK/COuXVZtZwbfVm+mLmGAnbppaLCEV +YroU+lITWeJso+eudB0Z1/GcE6bbFyXo5noJMtbOFy2eGTib +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA2MTAxNDI0MTRaFw00NjA2MDYxNDI0MTRaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApBxk +Sab/OKr9+jTty/mxxwiLO0PgPdAbbSaK+NKk2cJKe/3uHMWqA+yM4ZhDrgGNcEXC +4eQCYQSVmoABSfZEuHI9JIevg6KgEJVUu+hebAAg+7soN1N9WwxbJFI1UDfAXGns +UpiecNNwWL5VRCmgwlttGE++RcC2+zzTyRwAnrllapAyGhqPpHyF9+E923z7Mqfh +r7U2IvxzvPJHBHhj5Zyp9wUgMDoz119oJLb18QvX39g8Bc6W89CvSUofcXmMoROK +aPP6jYxHLXE9OXUE75qhmlevGRA7yrAiZdhwYGA7dGDivNNlIXOaPh5FCRsJzA5E +Yh1Bn8859kLkVMK9pQIDAQABozAwLjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggEBAMZgBeNwLwpS +BZ7cIYFH2e0IoTo3ZjaYsAfCC3SUxusZIstaCOvuD/xLTzVUe4jJ5446bR/tb9Bj +/y1cM20D+i5mJg9wZyxNIG/ryqm8Mh+9jX7+KDkr2l7aZ0Iuic+vhKKVgNuPnHRb +yld8YvKkoV0kA5JFPUYehH+9dD2jOpAPIrz6Re24p1KtfB9kdpkhAK976YJLbwGJ +2kJIlUZdM1ApEVTCLijhD0FtirmXQZB9IkSUJGFudvhZnGHX2JFMOIlPGSEtVDMU +VbTk1xntBanaFkuHaMGrmlhxic0lo9ZHEghNfpV/+PjGMmjafkK728ZaOutYX5Fw +2OwGbj0ScXQ= +-----END CERTIFICATE----- diff --git a/test/certificates/trusted-ca.pem b/test/certificates/trusted-ca.pem index a6f6f312d0..84990d9335 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 +azELMAkGA1UEBhMCVVMwHhcNMjYwNjEwMTQyNDE0WhcNNDYwNjA2MTQyNDE0WjB8 +MR8wHQYDVQQDDBZUcnVzdGVkIEtlcm5lbCBUZXN0IENBMQ8wDQYDVQQLDAZLZXJu +ZWwxEDAOBgNVBAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAP +BgNVBAgMCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAJrwAm+refCuWdBhvzqFNz8LFXyav2V12jXp3zUw6xEju68M +FlV4K27QUk6LuTFUVNKpPkl/xJKQHUebJkMKQQ/24OdTTV2z7OEhSJiipr/rbWnA +O6BCe/k8z9n+/QwpORXQD5dS2WzXHr8fnGKNNNbYtnfHH2HqFQnxxG+0PVFfq4Js +zL0VMpjK8mmX/rscec9VWVX06zQm0nGM/QAI1aBrDiMbJ1M1bmSHBk1LTFh/skMY +5o0D/MnhCHhEbEEy/lNx5B+8iYpIaU4nyn5JIZ+acT5jftDOuXz3LvVOtqBRty4f +Z7R0dMnokSXoIKtxWob3XYTdCWkRWzVW60EXLPMCAwEAAaMjMCEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABdFi949 +6O3yuXW0oC2219dBupGVPR8Yjn6GurQDJ8zrEFWMpYO80wNHnzO+xRj/4VQAcDu3 +TRiwwkM/6/aPJfdhZqLXsImQL0CcQl2tHRPP91OtGoDrA3PAHar+schI+7ofq7/O +JjXhjpB1wkQ8wMH5sV+FW08/9RVGm/UU4PiL3r75eu2wBkW0Vv6E4C33wCkVLax5 +3FZoQeoOuN6lzAsxb7lI9aYorh5oW0oXEatSF/1Ew5uB1JnUur+T5eZJuHXORTf6 +Lb5ZaAkJlMZgGU/4K2giniUK7G1bMfr75HyHNg0wacEz3T4r/4YvAtO/H3SU3S7M +7TWtD7AzBnKJpE4= -----END CERTIFICATE----- diff --git a/test/test_encryption.py b/test/test_encryption.py index 7df9e7ac38..246a4625d9 100644 --- a/test/test_encryption.py +++ b/test/test_encryption.py @@ -3027,10 +3027,14 @@ 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() + if sys.platform == "darwin": + # Python 3.14 sets OpenSSL's X509_V_FLAG_X509_STRICT via ssl.VERIFY_X509_STRICT + # in create_default_context, which requires SKI on the root CA cert. The CA cert + # intentionally omits SKI to prevent macOS SecTrust OCSP revocation checks. + ctx.verify_flags &= ~getattr(ssl, "VERIFY_X509_STRICT", 0) + 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",