diff --git a/.evergreen/scripts/run_server.py b/.evergreen/scripts/run_server.py index f81964f367..ff39f22562 100644 --- a/.evergreen/scripts/run_server.py +++ b/.evergreen/scripts/run_server.py @@ -67,6 +67,10 @@ def start_server(): set_env("TLS_CERT_KEY_FILE", certs / "client.pem") set_env("TLS_PEM_KEY_FILE", certs / "server.pem") set_env("TLS_CA_FILE", certs / "ca.pem") + if sys.platform == "darwin": + # macOS SecTrust requires a positive OCSP response but our test + # CA has no OCSP responder. See test/certificates/README.md. + 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 5199fe3959..5846a664dd 100644 --- a/.evergreen/scripts/setup_tests.py +++ b/.evergreen/scripts/setup_tests.py @@ -373,10 +373,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": @@ -429,6 +427,24 @@ 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 + # through 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") + # The KMS failpoint server (port 9003) must also present a cert signed + # by our test CA so the driver's own TLS verification succeeds. + os.environ["CSFLE_TLS_FAILPOINT_CERT_FILE"] = str(certs / "kms-server.pem") + os.environ["CSFLE_TLS_FAILPOINT_CA_FILE"] = str(certs / "ca.pem") + # Opt in to corporate Azure credentials (DRIVERS-3392) os.environ["FLE_AZURE_USE_CORPORATE"] = "YES" run_command(f"bash {csfle_dir.as_posix()}/setup-secrets.sh", cwd=csfle_dir) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 73d5513a16..ed431b10f6 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -193,12 +193,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 + # through 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 d15ce194d4..a781efc4cc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -115,7 +115,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"] exclude: ^pymongo/public_suffix_list\.dat$ - repo: local diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ef90224c2..5c1f7cf498 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -248,7 +248,17 @@ 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`. +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 && uv run gen-certs.py +``` + +See `test/certificates/README.md` for full details and constraints on certificate subjects/Subject Alternative Names that must be preserved. ### Encryption tests diff --git a/test/asynchronous/test_encryption.py b/test/asynchronous/test_encryption.py index fa41116db2..d708dcfa7f 100644 --- a/test/asynchronous/test_encryption.py +++ b/test/asynchronous/test_encryption.py @@ -3102,8 +3102,6 @@ async def http_post(self, path, data=None): # each request because the server is single threaded. ctx = ssl.create_default_context(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..efc66ab8b3 --- /dev/null +++ b/test/certificates/README.md @@ -0,0 +1,83 @@ +# 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, [uv](https://docs.astral.sh/uv/), and the OpenSSL CLI (`openssl`) available on PATH (used by the script’s verification step). The script declares its own dependency on `cryptography` using 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. +AKI (Authority Key Identifier) and SKI (Subject Key Identifier) are X.509 extensions that +identify the key used to sign a certificate and the certificate's own key, respectively. + +**MongoDB certs**: presented to MongoDB Enterprise, verified by Apple SecTrust on macOS. +No AKI or SKI. Adding AKI triggers SecTrust OCSP checks; our CA has no OCSP responder, so those +fail with `CSSMERR_TP_CERT_SUSPENDED`. See Background below. + +**KMS certs**: presented by KMS mock servers and verified by Python's ssl module (OpenSSL). +Carry both AKI (keyid form) and SKI. These extensions are required by the strict mode that +`ssl.create_default_context()` enables on Python 3.13+; see Background below for the full +version history. + +| 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` | N/A | Drivers Testing CA | N/A | 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 `ssl.VERIFY_X509_STRICT` (OpenSSL's `X509_V_FLAG_X509_STRICT`) in + `ssl.create_default_context()`, which additionally requires **SKI** on non-root certs and + **keyUsage** on CA certs. + +The generated MongoDB certs carry no AKI: AKI on any leaf cert triggers Apple SecTrust OCSP checks, which fail +(`CSSMERR_TP_CERT_SUSPENDED`) because our CA has no OCSP responder. MongoDB Enterprise on macOS +uses `kSecRevocationRequirePositiveResponse`, so even without AKI the server startup fails; that is +why `.evergreen/scripts/run_server.py` passes `--tls-allow-invalid-certificates` on macOS. The CA +carries SKI (but no AKI), which enables keyid-form AKI on KMS leaf certs without re-triggering +macOS OCSP. As long as `pymongo.ssl_support.get_ssl_context` uses `PROTOCOL_SSLv23` (not +`create_default_context`), `X509_V_FLAG_X509_STRICT` is not set and no AKI is required on MongoDB +leaf certs. + +KMS connections use `ssl.create_default_context()`, which sets `X509_V_FLAG_X509_STRICT`. +OpenSSL 3.3+ strict mode requires the `keyIdentifier` field within AKI; issuer/serial form is not +sufficient, so KMS leaf certs use keyid-form AKI derived from the CA's SKI. + +> **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..5983c085a1 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..ce71c4762b 100644 --- a/test/certificates/client.pem +++ b/test/certificates/client.pem @@ -1,48 +1,48 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsNS8UEuin7/K29jXfIOLpIoh1jEyWVqxiie2Onx7uJJKcoKo -khA3XeUnVN0k6X5MwYWcN52xcns7LYtyt06nRpTG2/emoV44w9uKTuHsvUbiOwSV -m/ToKQQ4FUFZoqorXH+ZmJuIpJNfoW+3CkE1vEDCIecIq6BNg5ySsPtvSuSJHGjp -mc7/5ZUDvFE2aJ8QbJU3Ws0HXiEb6ymi048LlzEL2VKX3w6mqqh+7dcZGAy7qYk2 -5FZ9ktKvCeQau7mTyU1hsPrKFiKtMN8Q2ZAItX13asw5/IeSTq2LgLFHlbj5Kpq4 -GmLdNCshzH5X7Ew3IYM8EHmsX8dmD6mhv7vpVwIDAQABAoIBABOdpb4qhcG+3twA -c/cGCKmaASLnljQ/UU6IFTjrsjXJVKTbRaPeVKX/05sgZQXZ0t3s2mV5AsQ2U1w8 -Cd+3w+qaemzQThW8hAOGCROzEDX29QWi/o2sX0ydgTMqaq0Wv3SlWv6I0mGfT45y -/BURIsrdTCvCmz2erLqa1dL4MWJXRFjT9UTs5twlecIOM2IHKoGGagFhymRK4kDe -wTRC9fpfoAgyfus3pCO/wi/F8yKGPDEwY+zgkhrJQ+kSeki7oKdGD1H540vB8gRt -EIqssE0Y6rEYf97WssQlxJgvoJBDSftOijS6mwvoasDUwfFqyyPiirawXWWhHXkc -DjIi/XECgYEA5xfjilw9YyM2UGQNESbNNunPcj7gDZbN347xJwmYmi9AUdPLt9xN -3XaMqqR22k1DUOxC/5hH0uiXir7mDfqmC+XS/ic/VOsa3CDWejkEnyGLiwSHY502 -wD/xWgHwUiGVAG9HY64vnDGm6L3KGXA2oqxanL4V0+0+Ht49pZ16i8sCgYEAw+Ox -CHGtpkzjCP/z8xr+1VTSdpc/4CP2HONnYopcn48KfQnf7Nale69/1kZpypJlvQSG -eeA3jMGigNJEkb8/kaVoRLCisXcwLc0XIfCTeiK6FS0Ka30D/84Qm8UsHxRdpGkM -kYITAa2r64tgRL8as4/ukeXBKE+oOhX43LeEfyUCgYBkf7IX2Ndlhsm3GlvIarxy -NipeP9PGdR/hKlPbq0OvQf9R1q7QrcE7H7Q6/b0mYNV2mtjkOQB7S2WkFDMOP0P5 -BqDEoKLdNkV/F9TOYH+PCNKbyYNrodJOt0Ap6Y/u1+Xpw3sjcXwJDFrO+sKqX2+T -PStG4S+y84jBedsLbDoAEwKBgQCTz7/KC11o2yOFqv09N+WKvBKDgeWlD/2qFr3w -UU9K5viXGVhqshz0k5z25vL09Drowf1nAZVpFMO2SPOMtq8VC6b+Dfr1xmYIaXVH -Gu1tf77CM9Zk/VSDNc66e7GrUgbHBK2DLo+A+Ld9aRIfTcSsMbNnS+LQtCrQibvb -cG7+MQKBgQCY11oMT2dUekoZEyW4no7W5D74lR8ztMjp/fWWTDo/AZGPBY6cZoZF -IICrzYtDT/5BzB0Jh1f4O9ZQkm5+OvlFbmoZoSbMzHL3oJCBOY5K0/kdGXL46WWh -IRJSYakNU6VIS7SjDpKgm9D8befQqZeoSggSjIIULIiAtYgS80vmGA== +MIIEowIBAAKCAQEA4GCcDOaDX8C9ysldwrtQn+rxrFSyzlCzqh15OBFTN8gKcC2P +fHaZsep1Nl47YfwL8vQwh9rvYyWf0zu0dkX3CzJdRW8i5jt1FOG20n6bQIjqOHa6 +WrMBU8wva2ncpRabGWZziySqDsqRZywgZzrKbTILuSifzjFLrGOmZIhT6Mjgfcwf +lSLkLOHo8pJZXNAmOV2w63/165poP1EwpUkSqyWZnZLTXALBhAGD32lFVfzE34o+ +OtzyiXpTB0Mggqfg5JLgqjefODktMDKVZ303oeNBmOOpucyLJwrPA8M6LnrHSZIf +ZNePy3SdTYhlvs0SajbXr94asT7yUPU5KVhVrQIDAQABAoIBACQohXVRv3mSjLNN +fInZWE6RFMWd95umZzGiosp9hkDewInf2bfnv/BrNVzf1id97+oE3n5CMqIyab1n +aXdG4p8gDGZYWNIr4jwNfMISq4+8kKwtO+5KWwwnQzwG2QsUp8Vx3GxfqfUMwV5U +PtuL3pu2vStnR8t5Z7W98E5Spt0EFsB6mHYjo7WBvxXL4tVxRwQ4Wsc1XuMTU5PE +deDbwq1dVB+d4mTCP07/tithhBJmch4dZQOwd5sIjWqps7MBmjWSUjhoEG1T1CK6 +0q+NbpeY3fON8FVlGPJv6mOF+ghNA0cXU8AKKOSBQd30M5PJZR+TzZoPXJIkpsjO +m8/okBkCgYEA/ouD+9kianeilsz9ArHTIBLHEepOgSYJ/UNUqE8z7Od5ryZp94qU +uqSqJGCxgZ7T0w15pscKX7Y+/jbDq+TgKwWq4OmIanroXZGq3X3rMCeN0MGclUfU +i2tOCJxpPQ4c3DCXJmNSp3GOAaZQRKug8qVB4wFEVr16INcS2HTNF7UCgYEA4ajy +31GQQxe9Y3ogJKjpx2BcQ7FWoyY9CUQu3MqP+wh1CzuMXJ4X0sN3H213hlfLh+9F +7wWX956Ga6xV7KVDSNZFKanU67VXOSgoQ9zLF3gd6CNHAoYpdq6b5GhfcoexZDOy +JImPTtsz/WZv+Ga1ZqPzTyjUWWnHnqQFcxKGERkCgYBZyz+pBWUVp9RsXC3Y2IBA +7T7afAxrlM6rUCg6I46OwO11MxjooTNsUBBROucDcdMJvdQvWEG5l+HK7ejC57+I +jbxFETz1SxxTfcKH1ha0aw+lF9ez9Z3t/NGPShX52tOlfWKkwR70QKO2w0PHpb/m +ORPwD49bBgZiNVzJjRKYjQKBgQCWPTaeSh6DHN4hyeB2p+Mls9kZ1Ir7Cm1eqv+M +Tmy31LSgauATlcoEr9Cyot4OGovOkBZ+gbngybFzJIT8jjcS2l2n1IOG/u/4hOzx +6aFpmbZHpJ0VaB9Y/f2af4b0qLUJIoX7X36DINwnXLk1p6QklwlZ7bQbZ5rY2xkp +uO57mQKBgAR/7pWJJAzyuc6d14GLE+bYBlEZL+551YVjaSjWwnIJLtNGIamteR8c +e1FRykIEJRi823FIpvF9AvZSqu75fm4KkKrJNB7X+pH1PWJS2QfvrSwdrBX1CTWU +fswdRmq5bhyiQyVY3jYs0Zqd6NBLbhQu29uJJEgNeK/I23nfLp9z -----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 +CQYDVQQGEwJVUzAeFw0yNjA5MDgxMzQzMzlaFw00NjA5MDQxMzQzMzlaMGkxDzAN +BgNVBAMMBmNsaWVudDEQMA4GA1UECwwHRHJpdmVyczEMMAoGA1UECgwDTURCMRYw +FAYDVQQHDA1OZXcgWW9yayBDaXR5MREwDwYDVQQIDAhOZXcgWW9yazELMAkGA1UE +BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDgYJwM5oNfwL3K +yV3Cu1Cf6vGsVLLOULOqHXk4EVM3yApwLY98dpmx6nU2Xjth/Avy9DCH2u9jJZ/T +O7R2RfcLMl1FbyLmO3UU4bbSfptAiOo4drpaswFTzC9radylFpsZZnOLJKoOypFn +LCBnOsptMgu5KJ/OMUusY6ZkiFPoyOB9zB+VIuQs4ejykllc0CY5XbDrf/Xrmmg/ +UTClSRKrJZmdktNcAsGEAYPfaUVV/MTfij463PKJelMHQyCCp+DkkuCqN584OS0w +MpVnfTeh40GY46m5zIsnCs8DwzouesdJkh9k14/LdJ1NiGW+zRJqNtev3hqxPvJQ +9TkpWFWtAgMBAAGjJDAiMAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD +AjANBgkqhkiG9w0BAQsFAAOCAQEAedO3g7tzgmhg/hnJMxH88OTd757o2zZSJnLH +0tzfLqz961gKt2KnBKYXg1i5CMnew1hCxkwUIXYWhzwACgJwv8x79uRlrvq3j0DE +OqXeMdFBIHQhkEV2vipaNGq3VTMurvL0EHghi9M1/YGcmdMuHNPIq/882n1B6yet +wGviRON2OMkKa65J4t31HGq5FeGOAWuyOuRGqgg8uexN55AzYjvd7VYWblrjsxm1 +W3HDQWaZYyv1cwbpfWYrJpnUBHcYYApvJBJpJPnM8EDpNA0HtTd/cBQiFvp0P4ss +SyyhFXDMJT9OpgTotIKPHdhZvOuy2pzRrQj2xSTUPWrRnKMJPQ== -----END CERTIFICATE----- diff --git a/test/certificates/crl.pem b/test/certificates/crl.pem index 733a0acdc0..e536caa47b 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 +EwJVUxcNMjYwOTA5MTM0MzM5WhcNNDYwOTA0MTM0MzM5WjAUMBICAQEXDTI2MDkw +OTEzNDMzOVowDQYJKoZIhvcNAQELBQADggEBAB59jdr1fKfc8oUUrCe+JfcDyEEO +Xf8gKSj4y+0O+QiybzWRJsyk6etTIxCPVQR1YlTJ38mBhFNFloaz1vdpBW2u2qpY +Jm2G1qeeUsDPHHK6e5oJydzgulhQgEkkXxPzUv/cMv2b2XVZ3kpLjBZaXynKwdlu +DtFq3f5LYcYluQCeUrsaIhdgTx+W12vDEQCyaRya5Z5WDwOjUhQYxpi4jb+a8+Y5 +s1eGP1SrdXqwHBGGJ/ONGksZwHSZXTv+JU7EX8lb6C1hZ5WY+vRYykKJ1sG7hOWw +q4CJ7kNFGkSa5bfI5+41gIc8/dxtVq2q4EmoUbLm/VVNyl/eWIg/oX23qYQ= -----END X509 CRL----- diff --git a/test/certificates/gen-certs.py b/test/certificates/gen-certs.py new file mode 100644 index 0000000000..fe46f3d041 --- /dev/null +++ b/test/certificates/gen-certs.py @@ -0,0 +1,491 @@ +# /// 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 subprocess +import sys +from pathlib import Path + +from cryptography import x509 +from cryptography.hazmat.primitives import hashes +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) + +CA_KEY_USAGE = 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, +) + +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"), + ] +) + + +def make_key() -> rsa.RSAPrivateKey: + return rsa.generate_private_key(public_exponent=65537, key_size=2048) + + +def key_pem(key, password=None) -> bytes: + if password: + # PKCS#8 keeps a password-protected key loadable under OpenSSL FIPS mode, + # whereas TraditionalOpenSSL uses EVP_BytesToKey/MD5 and may be rejected. + return key.private_bytes( + Encoding.PEM, PrivateFormat.PKCS8, BestAvailableEncryption(password) + ) + return key.private_bytes(Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption()) + + +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")), + ] + ) + + +def cert_text(path: Path) -> str: + return subprocess.check_output( + ["openssl", "x509", "-noout", "-text", "-in", str(path)], + stderr=subprocess.DEVNULL, + ).decode() + + +def aki_key_identifier(path: Path) -> bytes | None: + # The .pem files are key+cert concatenated; load_pem_x509_certificate skips + # to the CERTIFICATE block. Returns the AKI's keyIdentifier, or None when + # the extension is absent or only carries issuer/serial form. + cert = x509.load_pem_x509_certificate(path.read_bytes()) + try: + aki = cert.extensions.get_extension_for_class(x509.AuthorityKeyIdentifier) + except x509.ExtensionNotFound: + return None + return aki.value.key_identifier + + +def subject_key_identifier(path: Path) -> bytes | None: + # Returns the certificate's SKI, or None when the extension is absent. + cert = x509.load_pem_x509_certificate(path.read_bytes()) + try: + ski = cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier) + except x509.ExtensionNotFound: + return None + return ski.value.digest + + +def gen_ca() -> rsa.RSAPrivateKey: + 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(CA_KEY_USAGE, 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(), ")") + return ca_key + + +def gen_server(ca_key: rsa.RSAPrivateKey) -> None: + # Serial 1 is 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") + + +def gen_kms_server(ca_key: rsa.RSAPrivateKey) -> None: + # 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") + + +def gen_client(ca_key: rsa.RSAPrivateKey) -> None: + # 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") + + 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)") + + +def gen_crl(ca_key: rsa.RSAPrivateKey) -> None: + 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") + + +def gen_kms_wrong_host(ca_key: rsa.RSAPrivateKey) -> None: + 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)") + + +def gen_kms_expired(ca_key: rsa.RSAPrivateKey) -> None: + 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)") + + +def gen_trusted_ca() -> None: + # Separate CA unrelated to the main Drivers Testing CA; used in CA-bundle tests only. + 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(CA_KEY_USAGE, 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") + + +def verify() -> int: + print() + print("==> Verifying cert properties...") + 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") + prev_errors = errors + 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, + ) + 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, + ) + 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, + ) + 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, + ) + errors += 1 + if errors == prev_errors: + print(" ca.pem: OK (has basicConstraints critical, keyUsage critical, SKI; no AKI/SAN)") + + # Trusted CA (separate root used only by CA-bundle tests) must have critical basicConstraints + # and critical keyUsage; must NOT have AKI or SAN. + trusted_ca_text = cert_text(SCRIPT_DIR / "trusted-ca.pem") + prev_errors = errors + if "Basic Constraints: critical" not in trusted_ca_text: + print(" trusted-ca.pem: ERROR: basicConstraints not critical", file=sys.stderr) + errors += 1 + if "Key Usage: critical" not in trusted_ca_text: + print(" trusted-ca.pem: ERROR: missing critical keyUsage", file=sys.stderr) + errors += 1 + for ext in ("Authority Key Identifier", "Subject Alternative Name"): + if ext in trusted_ca_text: + print( + f" trusted-ca.pem: ERROR: has {ext} (unexpected on a bare CA-bundle cert)", + file=sys.stderr, + ) + errors += 1 + if errors == prev_errors: + print( + " trusted-ca.pem: OK (has basicConstraints critical, keyUsage critical; no AKI/SAN)" + ) + + # MongoDB certs must NOT have AKI or SKI. + for name in ("server.pem", "client.pem"): + path = SCRIPT_DIR / name + text = cert_text(path) + prev_errors = errors + 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 + if "Subject Key Identifier" in text: + print( + f" {name}: ERROR: has SKI (MongoDB certs are expected to carry no AKI or SKI)", + file=sys.stderr, + ) + errors += 1 + if errors == prev_errors: + print(f" {name}: OK (no AKI or SKI)") + + # KMS certs MUST have keyid-form AKI and SKI. The AKI keyIdentifier must + # equal the CA's SKI, since it is derived from the CA's public key. + ca_ski = subject_key_identifier(SCRIPT_DIR / "ca.pem") + for name in ("kms-server.pem", "kms-wrong-host.pem", "kms-expired.pem"): + path = SCRIPT_DIR / name + text = cert_text(path) + prev_errors = errors + aki_key_id = aki_key_identifier(path) + if aki_key_id is None: + print( + f" {name}: ERROR: missing keyid-form AKI (OpenSSL 3.3+ strict mode requires keyid form)", + file=sys.stderr, + ) + errors += 1 + elif aki_key_id != ca_ski: + print( + f" {name}: ERROR: AKI keyIdentifier does not match the CA SKI", + file=sys.stderr, + ) + errors += 1 + if "Subject Key Identifier" not in text: + print(f" {name}: ERROR: missing SKI (required for Python 3.14+)", file=sys.stderr) + errors += 1 + if errors == prev_errors: + print(f" {name}: OK (has keyid-form AKI + SKI)") + + return errors + + +def main() -> None: + ca_key = gen_ca() + gen_server(ca_key) + gen_kms_server(ca_key) + gen_client(ca_key) + gen_crl(ca_key) + gen_kms_wrong_host(ca_key) + gen_kms_expired(ca_key) + gen_trusted_ca() + + if verify(): + sys.exit(1) + + print() + print("Done. All certificates regenerated.") + + +if __name__ == "__main__": + main() diff --git a/test/certificates/gen-certs.sh b/test/certificates/gen-certs.sh new file mode 100755 index 0000000000..2d60766b53 --- /dev/null +++ b/test/certificates/gen-certs.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# 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..ddfa818846 --- /dev/null +++ b/test/certificates/kms-expired.pem @@ -0,0 +1,50 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuiKQPto48Vv2PzIlhl31nVU9ly+VAXcmKl6LbLJeGYkSaPaG +KxRnzxwDCU/9COYZX5gFe8cjA2rjyr1x01lk9bu/XqWnU293auHUi3XLxBpASvLe +22DJI8Vi5GSsD2phvQ3oQ2BhyAneDfD612QmOgdoj5tbIbw/1l+ApPI8vZBdqJT3 +dReValQBnjBeKAEBwmX1Zk5ZbtTyyA5wDpgjWl1TrB6qDHY1Vgpc4irxdr2ww2GP +DTTg5/Of0fULXHvdrQ56nhUM+X7sY0T3iRlxdiACCbdAijwIunlY+2xxMVQondCk +II7iWLMtRMNqd55V/bpuBrYHCogtDybWAg2QiQIDAQABAoIBAAj1XjzLu/ZQFzX2 +GpIGUscMo6jlWdDMPXtWVgI00bcLlBCWiVMFBi2UxAClZ5KBLs9ykvgZrQ4sm7kr +KXUU1iP/XNRQ49ffvDD2gDL35Gq+6LMIFzKosBPQODgGvphaAmXMwKpWYaWDEIKv +tSL0SwDtUJNxuA7o7zYP5U7ulGJCS7ZUiVIgZlhb44vjEKJ3ElHNX/hmr8fM+9sJ +WkzVylLcNqzQIiGrREMo4w5qP5saaQF+3gG0xcwCjjgd8MuUUwQnv/HWfLAoLoyf +91T7uagS1ukqwe81x3jJCt3w5zKpQt2oilpItPyPg3/uBnLjmbZYOwrN/zIRfefp +rR96HVECgYEA/CCJu15PailJMx4SyHCGgq1RDk7f5nteq5mcENUxal0cbSSh6FjR +Li4R7mow2qU9poNOBBUVUn8zrk17mk8kv60n6UMj6x8my6poR+Mc/HefCek4Bdtt +x9ZSYNWyp0pwQz8+i9pbvgHDvDq2hYDPdhnrn/xJVfSchgUFnti7Xy8CgYEAvP6E +0wNFlm7sn1ZG6qY5XA7dtq8BSBzPZxpmrzvYxu6nsCh/1hSHE3neLAJiyQKutTN/ +ZrTy52gJKw0ZvefOoMrUz/2uDO7oFhZxqk4MS2uCBo4XYUOWjscuWyyZFmi17NDS +TSRw4jCM9hSRVieXRok3/DfvSfOh/xWiaXW13ccCgYA6DH/JnPgp2CGbXFQ0w/uk +QKVF5xET7tmoJrDRC1TaSV/PHT0N0s0ulbrZKqfe32anXNnshLIpEVJj0kEgERLD +8ukagrPVYZG8GJrz2i2FT0FVtdWJO7E17nl/BBSjAbeBNCGBb5/pylw3jUkSycp6 +RZODfUGhQbV8AdH+daYGTwKBgGmI5rq+NPmP72n6T5dwQs95La15hAm0rMwyHez0 +SlSrp8/ijaAJznO9taZ1npwId26P1zCPEqTNn3D+28UD0IpROQz751kpf0f2OHqV +IqBq5Cys47lYeJY5+1TGTqYIyq323bheBPsJiW1QhufJK9wje7PHuENfXLKIbizd +ojS5AoGBAJMpLaEJbrd845y+EnTlnwr0OLGk841aKnFIuBMpKIb+A6rHn84wsH5M +lRDKgfmVZszwGMnkIcFzwb0iEUvc+3UkprAmMXXTuRbVA0D8JdDI4AWrpQnp1bi6 +00FUaOizMX0kCmfmKbCAoTCs+M9vAjvvKpdBJZVeJT1UmhVQtrTi +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID1DCCArygAwIBAgIBBDANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0wMDAxMDEwMDAwMDBaFw0wMTAxMDEwMDAwMDBaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuiKQ +Pto48Vv2PzIlhl31nVU9ly+VAXcmKl6LbLJeGYkSaPaGKxRnzxwDCU/9COYZX5gF +e8cjA2rjyr1x01lk9bu/XqWnU293auHUi3XLxBpASvLe22DJI8Vi5GSsD2phvQ3o +Q2BhyAneDfD612QmOgdoj5tbIbw/1l+ApPI8vZBdqJT3dReValQBnjBeKAEBwmX1 +Zk5ZbtTyyA5wDpgjWl1TrB6qDHY1Vgpc4irxdr2ww2GPDTTg5/Of0fULXHvdrQ56 +nhUM+X7sY0T3iRlxdiACCbdAijwIunlY+2xxMVQondCkII7iWLMtRMNqd55V/bpu +BrYHCogtDybWAg2QiQIDAQABo3AwbjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwHwYDVR0jBBgwFoAUFtf/EcyWYjdrv/gYQqMu +JQjs1h4wHQYDVR0OBBYEFD8JIj6iF3NOoswCMhUVADKP3Vf7MA0GCSqGSIb3DQEB +CwUAA4IBAQBQWxn1t4Qfa1ygwdSCZHuZQ73EayhiEbl+wpjSwwLX4Ks2u/HRm+aH +N4mBgjDDVjCale/09MTaKaUkf5Z4uc7HDyAUI6Ls1eibIz8p8XKRK0ShIbw6gR2n +fVnvqsYbEoW8P+P9O9bUJsGCQN1LC+ZeXzPcHq0No6PmRCfnlKe7xfmemSV8p+I1 +1yZs7a12jYzLC8dg8v+was+7p5ETt8Hva06FeJPsnR9yyHYQGD99fqBUe37Du+/l +oX9AaNHKbMUOl1vVhYr9gNrIKv287LYdiQj0LrfZoSDvgF8WqPN9ii04VlIy4YEG +OdRIjF1mxG/HcydHaNYF7o0IJl6y941j +-----END CERTIFICATE----- diff --git a/test/certificates/kms-server.pem b/test/certificates/kms-server.pem new file mode 100644 index 0000000000..25e77e33fe --- /dev/null +++ b/test/certificates/kms-server.pem @@ -0,0 +1,50 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuKw7lwxJ1wnTwUFvyVqMWghy+mTLYwG/alLBJTZ7XSzRhLan +5mWwtdxDmwu5R6y4cTEaDFhkh+6p4ybg+WFsqxHgWC90wep8c/uDyKnd5hFdcvLL +hSBa+EV5pUjR2KzjTGFc1kvWPUnDcxKF+/Jt6sQ6RskuV+y0Q80q+9R0NnjxWDtP +sPnINi1I6mbSVMEGSepkhTBkzODLXQSKMifHntq5GILL/ezFRHmAoj5Dgql9I6e0 +1hL7cty7rxHRlfKS8/O13fA9XkVC7xCk8cHjivZyuYgNKZlFt3GY75D5PWF6ISi/ +U+mYgVX4Qb+GMOo/m91dXA2zCxmzRfDc8yb76wIDAQABAoIBAC8mooxdcdj6xFs6 +du1FNkKil6DA7YEY6COgf3od3/+ZOuGUtWfJHQZB9+z1YFghjHIyJEF0rC5czHmX +6qchrdo71TkO3NPKJ/6BAFPSszpTwrVfsoEKEtADBR0ja5jUA7Dzxv1cHZZGaCXQ +W+9JJbFkarC6GyAN6rTJBKmJxCZH6QxeQwLqZzkFy2d8WzmUw0/g6BVjH2GwrMMQ +hv1rqErq3uFa43hv5dh4szZPRM0iEqN7ZV7cJk/03A1OiUC2vhZP38LIV4z+qIvj +BroNqFIwmfCNW0BqV7CjngTzdsxZuqQvAfqlbvYMt1/UjRYrpjlT29M9fdnzpLwh +EGPb3rECgYEA9iJ7j9g4cPhRFFMr4PBaGmN504VQOAplWWVGzqqSvhm57HVdbAdX +ZMQZosOLF3I4GfZ0ibtTxW+n6nXmZI8992pHg2ECN2PSvcNatjeiKxULuXkiaD7U +NQUZJUm1we/XtPjc12oxljYn2Kka5q9gNq63Rv5Q23EvrGEu+j9YXDkCgYEAwBMb +anWr/xTneW604Zq+oga3rV/3W0WYPxoo4vygMdMLQuVdNDfUHUGYCNhQE/4Z6Ryd +eAZEzNhGPiptdq0VWM1fLi3NHCBTIilwCWw68n4Sj394gtGfz25SK0Y+qgDOGJmf +VFfR9lZx+9lj2RDGBEKvUWtRhH1bw+rlN/M/oUMCgYBcGZ0YvzSneROFwnV5zxY4 +J57vekQBJEq2P8JWFNeiEKhUhbo2cSzPhN1+3SLP3CqH9IO5AgKfr18qyYEzgbIT +QY6O557XsR+raE0qP/kLm+1uMpigX1oymLzHCiTb8+5IRpMEfDUf2xXf6a8qQNeE +vq3P/9ursVfAbgERHODoaQKBgQCnWn6SvcCE2qPszCbSQ1BCQHQdnfYaEoNax+JE +FDVH9Ehlmw8ghlxMuXBMlJ0BLm9JC2OwxlV/3hkl5TXHJ3voCdkalVGXZhrJMy2p +KCIcUvi9CyXnZdpGlCsIBYZn/ZeVG5UVmgcZCaz68SjsYo8F+0xiNo2qUMd55tqd +a1ZPnQKBgEjQ8aXx5QQ7YBt/Blm4LXLXTtMSV8Y+61szZVOxqYsFhRpu9/ZCaLl4 +pLisacbqVtP5muPDgu+v9RJwb2DoUeCDvNzI2h/9snigUb2vvMPf6/h0d7Ip9Uui +GDfDYDa4ieG+ELqioyPHHPiX2Qsjx+rTZXutjFkVc1zOJ55U81ZR +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID1DCCArygAwIBAgIBBTANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA5MDgxMzQzMzlaFw00NjA5MDQxMzQzMzlaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKw7 +lwxJ1wnTwUFvyVqMWghy+mTLYwG/alLBJTZ7XSzRhLan5mWwtdxDmwu5R6y4cTEa +DFhkh+6p4ybg+WFsqxHgWC90wep8c/uDyKnd5hFdcvLLhSBa+EV5pUjR2KzjTGFc +1kvWPUnDcxKF+/Jt6sQ6RskuV+y0Q80q+9R0NnjxWDtPsPnINi1I6mbSVMEGSepk +hTBkzODLXQSKMifHntq5GILL/ezFRHmAoj5Dgql9I6e01hL7cty7rxHRlfKS8/O1 +3fA9XkVC7xCk8cHjivZyuYgNKZlFt3GY75D5PWF6ISi/U+mYgVX4Qb+GMOo/m91d +XA2zCxmzRfDc8yb76wIDAQABo3AwbjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwHwYDVR0jBBgwFoAUFtf/EcyWYjdrv/gYQqMu +JQjs1h4wHQYDVR0OBBYEFPQRv7GDSFtDENZA+5lD7by6EWQ9MA0GCSqGSIb3DQEB +CwUAA4IBAQBxii46h3mrwz7Adq+VkM34QGJ1oXBBshhZsC9gD/wcXqR8GFf6yrP/ +Kr8sl5DmF9SelZsl6hbRvhJeTyaW8uotxzb+7VYC/WSCbFK/FUqucAwlzbCA8s6/ +tuNO1QRhX0/zEwZ8m2/9d8WZ55lyDaosTzGK0uK3qQjAO8gGVKaZ3QEjHnoGFcMV +0KkFr/wQ5IFaB7YM/zuQlboPCWVh+8gqPTS1WziBjBHYWLRTSGLPyCf9hZMiGdju +NU9wQc2N2hgsqT8nFyWtlF4O0OgJwUQl11G5by/B1ef533yVkAq1A8cEbG2rbyZq +5TISt2AFM7yWmJo0y2WL5HX6aXpRhN/O +-----END CERTIFICATE----- diff --git a/test/certificates/kms-wrong-host.pem b/test/certificates/kms-wrong-host.pem new file mode 100644 index 0000000000..27ba1449de --- /dev/null +++ b/test/certificates/kms-wrong-host.pem @@ -0,0 +1,50 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAnmZRzrVWF3asaoZueTlxWRSg9q//sYcTvP4DT3ItuJ1cVdyC +1sv9DXygyZFPfh1Y0dhncXdLmfewuOlyf0WBJfzcMJLQTBzPQAQSNEfQEAk2gIDw +oqZjw6xe79jhOd5K+nagQG7bwtEqdEWTBwLlzKzs3i7rXj6af/oFSI+7AfcdF0MA +ASQndu2hthIAAcxYcyghdxm3EaG4JRTo1qam8fCJuNT31tb3rI0sVGPJr5Mr1apg +bHx8B5N42wzoYIV+mHWOA8NKbfNHb50ODTf8D96mRXNEqG8mBQjUGRDaAjE+75Tt +uwHH4197mZ5hM3bsPfkeNELxNV1B3qs9LyFAXQIDAQABAoIBAAj6Jw5GSDINu4FR +C59KsmIYUXQRrvXegC+gnMrqn208W+CQ3ghy6K1UQB+UYPM2khNYhqpPVsVL3KPq +NR9B7usafNcy5uO9aUCJSofUfxX9k61uQVUShYpwMTQ6MC+RqeGuifAE6GcO6C9N +RyMpVqFGNqlz8sp1VVfF8Xk2jiRzCEOh5Ild3WbKzoPriviO5c3oZTFH6yFLRSV7 +lwSjradMb+oDzPBVbFjaRojei5+zP5ttB12XXYVdKdrZXsWd5MAvIhEAn0iXSxi0 +vIWVVgKQBlydml8Lac5ymNBzko0iNK0uXNRnA5D3mpKzJfITrAojhh8wPlYkOTTu +K9A3BfkCgYEA1BaIMdmsj2H+jFTOcSIAtvyCMphu6uI1spUa67zS5CwGfYEYQeyr +3CL1NPD9hijCYSH//Rm+zp0dKMZ+wssCs9SsE9XV2J4BY2FnYYnLUGLEtffSZyZe +DY6p4v0qvy9aFJmXVC5vD4N8ZwkZ5VVGjzS+68nUpU6DylxJPdFHP8UCgYEAvzIa +TgHOoFMWulm632MsUq4IKOQ1OEcJBFJTPq7ptchWamfDH6tAIlMeQTrmuIrOA4AM +sAbtFtYOf6MFuJ3ScUvijFlEfib0r8J5V17aX6A1zmrjkS6dbz84p2RGzfoF7Q2i +nqX/4V5F2GPxbM9Pfd+/gw8iJrmu3X0Vhu4jL7kCgYAHKIuIQzST0lbpHaOqJd+o +TXWHh6WWv/PYBzhVZJYppWLCsazD7N0QHQ3xr4CfGpkU9jTRsiDCkIL/cVOt93Qr +5a25Lap+GTcqx4rZu/Dk0bCaA7dSS/U4t+v8AVeEBHEh6N02tiqBd4qnX6NEHlC3 +XKxlAPbwbWn9VogSUhH5kQKBgCzKVwE5SSej72oehTm56PNBk+XIeHNDqOgbRScl +INkWIrBwuHRd0Pt5j1fmrZBD7DlDsTU3milEYkcicL+sMVWbWmpYq0QGakIWhAik +zvGh/Zjqz37+daFPJT2Jr1CnpuW+0P7rkoNAa4pi93bvJgct+JaCYBTEYSPAHt/q +P9H5AoGAdFc0zYkefKrmPAyMsFbRelWpUH/CLqHB7VaqSSBWYe9pw9CfKtWCF3Nx +jS5fpcH5XeJmYp0LPhy2VlnbH5LxC2WyjLsX3TCxjcPGz/4iTIf1yLw4pW5mCvLI +r+mwP/QK2I4zuLk0jKvZVAFo4dsKfJeZHFFGAaTbg9m0mvtWX3Y= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID1DCCArygAwIBAgIBAzANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA5MDgxMzQzMzlaFw00NjA5MDQxMzQzMzlaMHwxHjAc +BgNVBAMMFXdyb25naG9zdC5leGFtcGxlLmNvbTEQMA4GA1UECwwHRHJpdmVyczEQ +MA4GA1UECgwHTW9uZ29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UE +CAwITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAnmZRzrVWF3asaoZueTlxWRSg9q//sYcTvP4DT3ItuJ1cVdyC1sv9 +DXygyZFPfh1Y0dhncXdLmfewuOlyf0WBJfzcMJLQTBzPQAQSNEfQEAk2gIDwoqZj +w6xe79jhOd5K+nagQG7bwtEqdEWTBwLlzKzs3i7rXj6af/oFSI+7AfcdF0MAASQn +du2hthIAAcxYcyghdxm3EaG4JRTo1qam8fCJuNT31tb3rI0sVGPJr5Mr1apgbHx8 +B5N42wzoYIV+mHWOA8NKbfNHb50ODTf8D96mRXNEqG8mBQjUGRDaAjE+75TtuwHH +4197mZ5hM3bsPfkeNELxNV1B3qs9LyFAXQIDAQABo2QwYjAgBgNVHREEGTAXghV3 +cm9uZ2hvc3QuZXhhbXBsZS5jb20wHwYDVR0jBBgwFoAUFtf/EcyWYjdrv/gYQqMu +JQjs1h4wHQYDVR0OBBYEFJQIAa046MLSPHTkP1YmXWtPuaZkMA0GCSqGSIb3DQEB +CwUAA4IBAQAF67EovBwjfifOdNUhQAtfwWv51Kyon3AEFFWnIQZx6YqCZHgL/nXF +qESB2Jg+bcFrL7mrgHGJZN0Hm3umT79F+ptHUrGS7mAAdX+X7t4qIC2BgXrqr14h +21xhjfOPlL8AnersPQjBhIbbJTxQNw3AKN/+guYeSuD6FsFyHWLLGbfZx5+uU+cl +plxiJh11PV3bh1alYzmt6gCwKNxq0pV7wdHK9DLS2mDvEWuupGvdohxPCkAHA382 +3SfYuffKJTRgOVPwWDxmfL6TYCfo/eqsRp4wiRDXgK0yDs8LJ9ekjQb6Tau4s82u +YZuUyc4VMjZBe47L49tWyL5Zj/NDqJ1u +-----END CERTIFICATE----- diff --git a/test/certificates/password_protected.pem b/test/certificates/password_protected.pem index cc9e124703..723f979543 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== +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQwMUl8vKzZ5LgUPnf +xCXkNwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEMzOmfC1zf4FJbhY +4YFpiwcEggTQmhDc0AGSBdsVGXexFQfo1J2gkg5mkSmNfv+ufAw0mgY93hPLu5Ps +Gy9hVIYXTLDweuuD+4S4UztwktSWlpUEkw5V8okzgpUKvZdjsk06QdD3OAOJbt3q +joAoRtlwuSMrIZFQinQm/ymg5Vh5WGRl2olEHw2bOC8Yg9U2NS6VtlqSTzo8nPfa +va3Cy7+lWdDfVCyafpxIXfy1M7Q/cFwqhkkyQyi/efHqd+aboUQ5HzAKMHHUtaVc +RZ+mfjiNB/QUJdnWN3iNbBf2NpoYpcXNrN3A0oUfibVV4zm7rhVUFe99Oc8P5C9s +yRanbf8BBmOTtUbYFNduNHjwFEuxiCbgzW9SxqP2qpPEaIId2OgiTKORV4EmN1Eb +jzUMNZ5NnC3YeaaLEYG+rv+PA1vVCNJnnP5ooobObMhxubMaGXlHgafMNdeDsWmM +vv22IWQpYNsMAGfO35YFBqiuPQl6sxaBGSkamaHael4+qo0Ml4WeT+tkTn6DupkU +9VcD0rHPB3L3KxvVioaJUxRYSfOtPE5Ym5d+6zBemp/qMliAU9pCeUvKVyZ3rB2B +J8No4sHfkWvfWQkHql4TBdC8Y99sYQCW0XDG1HQ9I04gxVKt24gMYwd44cFRfqhl +uyTf4s38Ps6BX5o5vp8PA389DHLGCZqA5SCxtzre7iIttv9zpSXhCfikOn0T6jif +Y3DFJoZZO4QXuwSEaGwL5J+w4fsIKIMGkQ9Vv0CI18uxv+ongb5yvSxttA7wnZC6 +EWIrTDAlzjueZeHH1x/p27wQa7ChIlL+wIetnvRw4+bHQMkHY18KYPAwYwcOyO9T +C7giMX/IQHY8LyskrT6baTMrsTb0Y4k1+X+hBjdffHHOA94phV8uVAN7AxL0P6rl +UZEvEIsK4BFiQDI7Ez/ildabUUTCIR7CnVfSNuerOSkfoITlgPG75XTlRqqfGNji +e41rW3qtpPmEYYF9PVnlr3AwcGmFHjEZq2hpcykNAlt0G3kTqyZJRmrbmV0NHQTt +2DardFcfb7EVNKaq35tFbcd4X9ALfcee3+iFrN3fYVinw3RsatBopveA+/2+9KLJ +gi0Qpf7ByNxe7s0hQQ1fXgDpPQVjJKEuPqwpvmKpWMP4qR6sa6APzHVuzYEIct+K +1Ub43wAQ217YOeDj2AeTlKqdcyuVq/qnHlyLhzQwKxAA6y2VjgDLKp3cWRgUplPA +LJfZAf1rnm3vGDGwroIAnFO/FUSQ70IEnAnAu12uk4fioumYoXk69VVDzMo6vy2y +M+ii6lgEJsKtVkY4nhCyEjp0Jx0YxTG7ZzQQUYkji1PkUVUS244sP4mM/BJc86r3 +tZnTrkhjgCpmJil67mQg1z/+ToUH2F84zpCEkHllEJrnci5u+tN3SrAm8/kKd4UL +M8RKSuFJvJInSsnChpRWaT1LOwnRtPOadSJv/7u5SJtg+xXMPDGepEuXFMAkcOzJ +pz/6A6am7Lm2hNsXF9JFbYpjhT7BtZUQ77ia4BsnZPMH7ykmRmvpIepvdzXEP5o8 +FuDyNpDedlcuwzgFu2lF3gXQ4DROr2Kndl+ZMkaMFhMHfdtwBGKgVqUhBeGMMq4r +83T20rLcBIiRL3ZrtvhWxG60VvKwmDU96PBu+2fP2Xx0Y+DcYvZSxU8= -----END ENCRYPTED PRIVATE KEY----- -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/test/certificates/server.pem b/test/certificates/server.pem index e745e037fc..df1ef59433 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----- +MIIEowIBAAKCAQEAtorAbPejUA7f/FmnDhapk8wgQQtm4pZg/sR4Hz0ZxTVZ8e0Y +1wvkKeo1PVqw1rxDQZ4l2FM21yZa0GjsEfswsVaDTD0sPk71EMKl/2pt0xugWep4 +yptqYbyQV6vJC2sQB6uXkSDSR4T0qycZIM0VnjS06UzVKs0kKATfpVj/NPmklkeh +WZ/QN3T04khOp5wY0AHrLaaiyv6668km+0EoYNuLsgDTdjj44UWXyK1ThjX8WIdv +s8i7zJqfjzxiqOCEIiY3DSFIFukudWN7OYN0f9rzV8jQ4brHzC0ZDRTiuhME7C/p +URdW/n4pOgrylgJkdxB3l6IkL/8Qbxws3CKtMwIDAQABAoIBACqx5FT4TNXeTMxI +qdaVPV+IyGh+QrevpYshJ9lioKLsGhgINR2jNeAJ3B74FdF74h04YLCqsfJ7kZUa +XVDNWDO6QOZ1jmIadJ5RcKL/YSWV2hj9yvfUhvrKMFaZIuJNTcgFfeNfcl9w/QsF +D48I+MvylvfUVS14IsNLdIXHfZWFgzZI4YAyekuqjd+o9/CbIKzutKVErCvGH1+g +TKTIMAPJnXeSYH5+w+sy7W5nA9lDRj9k2FAi1T+iR/9b7QnUOkVEJZGxe7VFs9DF +Qf5e+7RUshC58o5HJtDdaVtfcSsWiAbyHShMYqqHhp4aahmgiNOmWUnEDNHBzbsA +TjehsHECgYEA2NHMzcEgygvrCA68yktEjSMUQiEVh6CQbvceY46dum7yLLMV5Z9O +TLMN87+/cGhku61aE8E2kqNX5UQkvmUyUr2Mg0CZ+d/U6ZfilYHgGPkUHCInz66X +O8447stfdscXsKv+crWAF4kavCUpbMf9RgQzS1LlCFJ1i7AdNcASi3ECgYEA14dA +r5ZTT0A5sXe7/WH18NT6qSQxfGynRxu6RAL/4567A3AvmAHd+zfdXJ3CpxSUaTc2 +e5Z2g6wexLiAV2cKSdoAOUI17pTZFFl7Red0Bp9DDjLU0IeO+3ZFj8bcLw6eUdzn +ZsBwz7KLPzofmt0qXN2DWRvKb0xLrN1spzrtiOMCgYB+eMKSMllCAfmy1YXiKk1u +Vkv21v2MA2i8kYE0aXgvy4+P61aWfnpZ2wgEapDsrLg1kUS9yTJgDs+yeDFGrhjQ +kqhn10L5skqrh2Ev/HYPmxrT3kiCqECnLf+fqxmgWznCYFEn8B8rm1nw7Wxge7eN +I94Xzd6zIAZY2P3w4HzwwQKBgQCm3OUczCKVweCo4E1gH96cZRfnqcjSTwC3UeVE +0JmybWrWf52pbxCgdaDhGpbgalN4njGFP3lj+fccUMe0Y2cYxDnWGsfMfdsPITQK +a+ZtVhJBRON0yu7NCsVSSiCgIg46zO8uoyDz/IRIIETlzgMFQM53R8fToVsZa5i6 +ZCoRBwKBgGl7pBeE6IhlmoTMflTSOVFBRNvTcdg08GJXM56bkhUpPteoAzsrzfaK +mMTtA6b1EhGKri6yIZyOF2hibTrmz6WgwgqzxFgSFxOq6m/w4gJzHS5HF1wkweeo +7cvsDHBdorIIsbPT7RHq9Fq7lR8PfrV2gKVmFrveV+b5dlj/0n62 +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDDBJEcml2 +ZXJzIFRlc3RpbmcgQ0ExEDAOBgNVBAsMB0RyaXZlcnMxEDAOBgNVBAoMB01vbmdv +REIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQsw +CQYDVQQGEwJVUzAeFw0yNjA5MDgxMzQzMzlaFw00NjA5MDQxMzQzMzlaMHAxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECwwHRHJpdmVyczEQMA4GA1UECgwHTW9u +Z29EQjEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtorA +bPejUA7f/FmnDhapk8wgQQtm4pZg/sR4Hz0ZxTVZ8e0Y1wvkKeo1PVqw1rxDQZ4l +2FM21yZa0GjsEfswsVaDTD0sPk71EMKl/2pt0xugWep4yptqYbyQV6vJC2sQB6uX +kSDSR4T0qycZIM0VnjS06UzVKs0kKATfpVj/NPmklkehWZ/QN3T04khOp5wY0AHr +Laaiyv6668km+0EoYNuLsgDTdjj44UWXyK1ThjX8WIdvs8i7zJqfjzxiqOCEIiY3 +DSFIFukudWN7OYN0f9rzV8jQ4brHzC0ZDRTiuhME7C/pURdW/n4pOgrylgJkdxB3 +l6IkL/8Qbxws3CKtMwIDAQABozAwLjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A +AAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggEBACJs3NYY9mkz +ePQMe0QTV+9K8nrmmkc8nSp+XXnUGLil66QfxgYxr5t7kLrHaOvwcItEgGj2Uimd +UmT4+RqI5cV0YwjcAkVmQKIm3lr4vmVq+5YCoyBx/7hx5/324UQQ/hLU3OwerDct +CYGBOV/gVRIXc0H0xWWg10fNOSFGfpFryVrgawe8dw5aiVEWCRjzkfg7aiLCxlLD +qX+Rqg/qlaymy/KZGWKwgdZwozRp7tT4a7HHNjkaNAdZUGaxtbj+8S+XCLXlojx2 +ffl1/7/iZONtJMKjrhBleoW4MPb3+kxQRKcuRp/73eo5TSW942f6H7ivfKUu9bzY +6XsyLCGwkwA= +-----END CERTIFICATE----- diff --git a/test/certificates/trusted-ca.pem b/test/certificates/trusted-ca.pem index a6f6f312d0..1c4d9f040e 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 +azELMAkGA1UEBhMCVVMwHhcNMjYwOTA4MTM0MzM5WhcNNDYwOTA0MTM0MzM5WjB8 +MR8wHQYDVQQDDBZUcnVzdGVkIEtlcm5lbCBUZXN0IENBMQ8wDQYDVQQLDAZLZXJu +ZWwxEDAOBgNVBAoMB01vbmdvREIxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxETAP +BgNVBAgMCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN31CB0eFzMcKSHXqe/y86aeemo9+njEeNGtCxxNfTdP1RwA +Jlz1PqroaiAi/Ai0pUJSQ1F1Ebyd0csYabcEQEMbAocCRywx5rlGhfJAr0odlUOT +fQECbazX4707DvA+nFsBhLi1Zl9XR6p8CHZOIDYG6YfFqM0b03mdr41MtKMa52uB +8n/IUw8p0FskUKV0v52Md4EOV7p18hEvePZVyJuD8G9B4V6Aw5HCKqbqF6w0uWC6 +5OgnT4p1o+CFpJzX0+sgb7qeTBAP1WGmS1ToDVbm27DtFPUMpEuZVAt3uxxkrq6G +JNwMnbwlyzf0ovq9MNh2OZOO13HoXKJoIR+zUO8CAwEAAaMjMCEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBACbG/IK3 +YSUT4NO5llCbS9K1vrEbrMt+br/XkTVfXf4+qllNd+3Gz8eSy0mOgdEXBIFh82rM +pwqOXr8n2LgJlFOFOzyTOp5v2YJFMKrK6yayX61WaxECKU+18GcWCAxBG8n4VVdR +Y4wCvrIRTeKNo7gNkX1Z+vjqe0i8k5ohtzk/qZdhAl1y1uLfHnwF8J6P4mDQ5N7J +dlI6hKJT4+3PchDcAYfCQYhOLh73hinxREXgwICQmmLmDa9oLHyFWftpUYuXP5hs +Th1GUK2EBdeKql/TUjLFOI61Wbu2aRWhF8SodXsRfzRI86pLN7MSzeM0LAtDknX0 +/fqeu8xWgizhyUw= -----END CERTIFICATE----- diff --git a/test/test_encryption.py b/test/test_encryption.py index a358b900e2..ac45cb0894 100644 --- a/test/test_encryption.py +++ b/test/test_encryption.py @@ -3084,8 +3084,6 @@ def http_post(self, path, data=None): # each request because the server is single threaded. ctx = ssl.create_default_context(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: