From b0b5daf545bc71b30304619947ee5bad02ccddb4 Mon Sep 17 00:00:00 2001 From: Mark Benvenuto Date: Tue, 17 Nov 2020 14:47:08 -0500 Subject: SERVER-47963 Support intermediate certs in the ca file on Windows --- jstests/libs/intermediate-ca-chain.pem | 49 +++++++++++++++++++++++++++ jstests/libs/server-intermediate-leaf.pem | 54 ++++++++++++++++++++++++++++++ jstests/ssl/ssl_intermediate_ca.js | 37 ++++++++++++++++++++ jstests/ssl/x509/certs.yml | 16 ++++++++- src/mongo/util/net/ssl_manager_windows.cpp | 22 ++++++++++++ 5 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 jstests/libs/intermediate-ca-chain.pem create mode 100644 jstests/libs/server-intermediate-leaf.pem diff --git a/jstests/libs/intermediate-ca-chain.pem b/jstests/libs/intermediate-ca-chain.pem new file mode 100644 index 00000000000..0feef1d7390 --- /dev/null +++ b/jstests/libs/intermediate-ca-chain.pem @@ -0,0 +1,49 @@ +# Autogenerated file, do not edit. +# Generate using jstests/ssl/x509/mkcert.py --config jstests/ssl/x509/certs.yml intermediate-ca-chain.pem +# +# CA pem including intermediate certs. + +# Certificate from ca.pem +-----BEGIN CERTIFICATE----- +MIIDdDCCAlwCBBmRIxIwDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCVVMxETAP +BgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAwDgYDVQQK +DAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxFzAVBgNVBAMMDktlcm5lbCBUZXN0 +IENBMB4XDTE5MDkyNTIzMjczOVoXDTM5MDkyNzIzMjczOVowdDELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAw +DgYDVQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxFzAVBgNVBAMMDktlcm5l +bCBUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAupVkx8+n +AqzsANKwNPeCYlf2q0WgF4kSUMNJdpmMelrr7hh7EOnAU0hTAQx9BKTEbExeCzH6 +OArFNGjewjWVXwaOpCjK8FMvK6/lGVEpmoHNF9XuiQVmaQ4bJD6rC73YjpgNIPeL +5PyoFLEZv+X2cRBPpTcSRcf87tk8HL7v0eyk1JBhkeKK68SYdWwZlHaa1jqwmliW +WvVMkHVH3lx0VOgQwWtOgs0K1zpcZ0sH5MGpYRQOiidIRZj3PkKeTPQe2D6VQQtv +2yDs9dWfCxJJP9QiWclL2rF/xqlFSNEIfNZpZhk6I1DHQpA2uyJfzRH62pFasJuB +CVh5Tr0EDoVreQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQARdNCYYWxi2fyhJwzGHwIT261d/pTlOSYLlm84c72aEneFUnfp8/H5 +JjuFbnhiX+5+h3M7eDQhra9s+H3vKr7o38EIVf5OKXvpNLwv1UUmomBvKqccioYh +bxrfwCzfBRuUmW05kcAVn8iKovqyxL7npEZbckwtT+BqZ4kOL4Uzre+S1HMx0zOu +xulSYA/sBoJ2BB93ZIAqB+f/+InS9yggzyhhaQqS7QEl1L4nZE4Oy0jKcxdCzysm +TqiyH+OI5SVRTfXh4XvHmdWBBaQyaTmQzXYUxUi7jg1jEAiebCGrEJv9plwq4KfC +cze9NLBjaXR3GzonT8kICyVT/0UvhuJg +-----END CERTIFICATE----- +# Certificate from intermediate-ca.pem +-----BEGIN CERTIFICATE----- +MIIDcjCCAloCBFNvXv0wDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCVVMxETAP +BgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAwDgYDVQQK +DAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxFzAVBgNVBAMMDktlcm5lbCBUZXN0 +IENBMB4XDTE5MTAxNjE3NTc0OVoXDTM5MTAxODE3NTc0OVowdTELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAw +DgYDVQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxGDAWBgNVBAMMD0ludGVy +bWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOcrt0K/ +K8ueq9lQ9wVtA+rka82FPaHXpZkH7ii/ZJlNcDXLaJPdRb7XgAabAS3gru+Hpm/g +kAofoL7cDmGZRAbiW0I6X5Nlmjh4/0E6RxSs0urhU34m8sM3OPmAgbq7oLlFINZ6 +GbVR2RzMWhK5HPld8WApDkIVpBFbRGV7dt/LVKY34Nab9hu15WRSH3wzSHJvt8e1 +alYxaRUoE27Fk3zdHPw9Z91/XvfIThTsNXEQVOeaieyQLwoKx8tpMa/ck/mFmSkD +nH4h37ev0ZABB04iTBfLGCpUCKd5LerYIqEu4UPp9r9czbco7twp+k8875pJ3bpV +wMH0/jF68GTC8HsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsF +AAOCAQEAaL61HT6JD19Ok2LY6b5KkZ4oRhiV73l2/82X88GcV63Bl0rN6AF+W0ut +GuHzSqcHV4qZkt9ezNoDYq41BsV4I8Cxvyaz8is956uyrzQAsVCzidZSGeq2GIfV +9y+IRISBRdzXQHrB0ni93b16MJO1KoJxZbXcb8W9ll2URp+YEnHIrhWpDcMcHN3O +mjoy1+WpHDXpNK2D3Xk5tT5pwxJZWRPB9wvPfTux5Vp07+Rkef9YjXL2ZZxt4vKu +WU0HJWfK905HpbHjwFNRlbT39WWaF8VeJ2nT6OrXTpE8tDdPoeZt5u76eaWEmsf5 +gX2ClrsSmegOKT52V+2NAlKDjQkaDg== +-----END CERTIFICATE----- diff --git a/jstests/libs/server-intermediate-leaf.pem b/jstests/libs/server-intermediate-leaf.pem new file mode 100644 index 00000000000..93d9d599f70 --- /dev/null +++ b/jstests/libs/server-intermediate-leaf.pem @@ -0,0 +1,54 @@ +# Autogenerated file, do not edit. +# Generate using jstests/ssl/x509/mkcert.py --config jstests/ssl/x509/certs.yml server-intermediate-leaf.pem +# +# Server certificate signed by intermediate CA. +-----BEGIN CERTIFICATE----- +MIIDmTCCAoGgAwIBAgIEBR9TszANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJV +UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO +BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEYMBYGA1UEAwwPSW50ZXJt +ZWRpYXRlIENBMB4XDTIwMTExMDIxNTQ1MloXDTQwMTExMjIxNTQ1MlowgYIxCzAJ +BgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEWMBQGA1UEBwwNTmV3IFlvcmsg +Q2l0eTEQMA4GA1UECgwHTW9uZ29EQjEPMA0GA1UECwwGS2VybmVsMSUwIwYDVQQD +DBxTZXJ2ZXIgTGVhZiBWaWEgSW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAu3VIsuH00IN+R3RYAPRFvQs2RpvZ7JJAwLhU9xhsPbxB +oHbuFardap21A56PzL4NE6/sLTZfSYvpEwtdCT1Hz0AEDKFh/lU8xJyFPYX6RfRn +tQJ7KVks3w3uXbpPFdHmZk1CQjKTiRZwcGpLRl4bNTyxSFJtEaZ9d969UkU/PQlg +zc1N13k3tJJ8syOnzL6WzH0ci8sykunyJb0tiu+JPJ3bX8xVBjDVggAMXY6JuE+g +WZdCi7QZLBDFrDLUgJPNpfIyUdn/31vaDME48rvPJnQznmHAZb0jm6wPHIjMGRTA +5haLWa4fQYteNCtpqZz0YK2lsiljH770RVEcNxzEbQIDAQABoyMwITAfBgNVHREE +GDAWgglsb2NhbGhvc3SCCTEyNy4wLjAuMTANBgkqhkiG9w0BAQsFAAOCAQEApwEP +FUWMH9BI/i3sj7zC1/7G0kSMMWhzZTBia3sgaxopdNQITA3X7jg8PX6NVVxK/vJY +3mS1UN0qwWQv+ECun8u0ZelL35MbzpO1pxFF35glc/gqHIaWpJbWtMOmtZ5c65C2 +7PyGeKvIv7DtkzcYBMtqhru/Rx0pzpPRS1iq4TgfE5JUNmQ1hVrmaf6+VGbOpdcf +vjWyoxOcuGeNG/J4qLX1CRseVB2VPZf36VsaWZY9/FTOFnTHrjyFXzMYEGcSMqsP +8EkougXlce78328krmOOZNqU+mt9nnf5EZvHHuvAAYurfhvdfFD5mjSS/O+MQ/oF +JcXWm2XdfzUa5G7zYw== +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7dUiy4fTQg35H +dFgA9EW9CzZGm9nskkDAuFT3GGw9vEGgdu4Vqt1qnbUDno/Mvg0Tr+wtNl9Ji+kT +C10JPUfPQAQMoWH+VTzEnIU9hfpF9Ge1AnspWSzfDe5duk8V0eZmTUJCMpOJFnBw +aktGXhs1PLFIUm0Rpn133r1SRT89CWDNzU3XeTe0knyzI6fMvpbMfRyLyzKS6fIl +vS2K74k8ndtfzFUGMNWCAAxdjom4T6BZl0KLtBksEMWsMtSAk82l8jJR2f/fW9oM +wTjyu88mdDOeYcBlvSObrA8ciMwZFMDmFotZrh9Bi140K2mpnPRgraWyKWMfvvRF +URw3HMRtAgMBAAECggEAeHRkwo1vQo08F64q3nIYXeFWfwimf916vlu0PRL0erb9 +dJ73XfTtUhUEu86nmGiG/p+Mo4DMufWtTw9+OPGnswTvlS4eSc97vNrWwzHUIB9s +hGOTwH4M10ecY53UM7Es24/Jg7/8DZrdpV6oAA94bD0TreVJMI5LETuPa84TVKQW +Jwf05xqnTUKRC8Cz2vh5N5oPbUYJ+qPDeoILHYWqElGheivBougcuPF/Hf8j2mpv +eBck/LOL4t/MbOm5RHiBgInx+G4kzn0v/0yHoqF2R3RMg8LGJz4NZaw6iqX5S/3L +xuhNYSkxLgVeBekGe0MxafAr8xYpf0twxM6qaptwAQKBgQD5c2dKlDIq7T6J3ZMz +0XkJxrj2p6jUc6oMKENEaBqXnB9PnmLv54PnidTXlu6Eexm+bqE59pCo9AMzvXcj +pOaoWQTQxZvBUgiCcHUvic/i1LazH7Oc1kutJxYn/3iOPxX3UeEZI5c6qEx/SCo0 +CGr1octQ+nyUGEKGjjQ5pFaWNQKBgQDAYTfvIoCK+tFuFBg8kS2yFG7m0bfRqwhG +St15rHTM6OKboph/GPmTgc8MOD2T3jGK8rO3ibTkzMvrukUvaP2k9CcLKZ3GWoqY +/lxVxH1Hf8d+/KRaKXwJTVRYYoHSjpJ8ILsonzE8xgtxI5jd3v8lYIcoiiR2+MTj +49ugFdncWQKBgDEFU8QdMWqsKsEPERF61c1tBwY51nzBqiYvd2CnEKrAnIqZ9pls +pshGltQzLfZM9rcsqHRqlu0M3uA5GIOhsU5eCAs6+ivYgiGYFf9clsTdxnWXAkYM ++twxNTJxCvDxRtDOf2zgSKTXVAkjVl/ZU6OnwvvL7dVwmwo0QeEeAYINAoGBALV3 +PubAedYfD4wxQkdnfl4bbh0mN6l8FnsPxWgvZ6GeD5tVPVmuOkWMzbwuFM+1aLAz +jZiUOeEU2UoLU5WMCK4fa/DYma3v3ArC7GAuzymxe4HqWDGALjMsEWKp0OHHgJ+7 +1C9WMoCsI0DeniSzY6NjMTrpS8o5kKeSWKnh0rZJAoGBAPH4jJRiKPQSohBF+2Y0 +1U6KoW/BrpEEXutjTqCgWB4Tgo0xuVeH0tWtTetDQvwr9IXdu61vVF/CW5sRu1cV +yBBNy5UFB2C+l2fTtn9e5LGQ1aVOYuz+9GM2hPJ1nuBfneC6+PD2zVdpXI3p5U6J +NJEQxPTe7cRq8wdX8zoY0ffU +-----END PRIVATE KEY----- diff --git a/jstests/ssl/ssl_intermediate_ca.js b/jstests/ssl/ssl_intermediate_ca.js index 048bdf782ec..51c44bb86da 100644 --- a/jstests/ssl/ssl_intermediate_ca.js +++ b/jstests/ssl/ssl_intermediate_ca.js @@ -19,6 +19,7 @@ function runTest(inbound, outbound) { sslClusterCAFile: inbound, }); assert(mongod); + assert.commandWorked(mongod.getDB('admin').runCommand('serverStatus')); assert.eq(mongod.getDB('admin').system.users.find({}).toArray(), []); MongoRunner.stopMongod(mongod); } @@ -56,4 +57,40 @@ runTest(VALID_CA, INVALID_CA); MongoRunner.stopMongod(mongod); } + +// Validate we can make a chain with intermediate certs in ca file instead of key file +if (determineSSLProvider() === 'apple') { + // TODO SERVER-52923 + print("Skipping test with Apple pending SERVER-52923"); + return; +} + +// Validate the server can build a certificate chain when the chain is split across the CA and PEM +// files. +{ + const mongod = MongoRunner.runMongod({ + sslMode: 'requireSSL', + sslAllowConnectionsWithoutCertificates: '', + sslPEMKeyFile: 'jstests/libs/server-intermediate-leaf.pem', + sslCAFile: 'jstests/libs/intermediate-ca-chain.pem', + }); + assert(mongod); + assert.eq(mongod.getDB('admin').system.users.find({}).toArray(), []); + + const smoke = runMongoProgram("mongo", + "--host", + "localhost", + "--port", + mongod.port, + "--ssl", + "--sslCAFile", + VALID_CA, + "--sslPEMKeyFile", + "jstests/libs/client.pem", + "--eval", + "1;"); + assert.eq(smoke, 0, "Could not connect with intermediate certificate"); + + MongoRunner.stopMongod(mongod); +} })(); diff --git a/jstests/ssl/x509/certs.yml b/jstests/ssl/x509/certs.yml index ba303ffb5c6..6b071dc883f 100644 --- a/jstests/ssl/x509/certs.yml +++ b/jstests/ssl/x509/certs.yml @@ -529,11 +529,25 @@ certs: Issuer: 'ca.pem' - name: 'server-intermediate-ca.pem' - description: Server certificate signed by intermediate CA, including root CA in bundle. + description: Server certificate signed by intermediate CA, including intermediate CA in bundle. Subject: {CN: 'Server Via Intermediate'} Issuer: 'intermediate-ca.pem' append_cert: 'intermediate-ca.pem' +- name: 'server-intermediate-leaf.pem' + description: Server certificate signed by intermediate CA. + Subject: {CN: 'Server Leaf Via Intermediate'} + extensions: + subjectAltName: + DNS: ['localhost', '127.0.0.1'] + Issuer: 'intermediate-ca.pem' + +- name: 'intermediate-ca-chain.pem' + description: CA pem including intermediate certs. + append_cert: + - 'ca.pem' + - 'intermediate-ca.pem' + ### # Split Horizon ### diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp index 3c13e7a630f..8d434e52416 100644 --- a/src/mongo/util/net/ssl_manager_windows.cpp +++ b/src/mongo/util/net/ssl_manager_windows.cpp @@ -1298,6 +1298,16 @@ Status SSLManagerWindows::_loadCertificates(const SSLParams& params) { return swChain.getStatus(); } + // Dump the CA cert chain into the memory store for the client cert. This ensures Windows + // can build a complete chain to send to the remote side. + if (std::get<0>(_pemCertificate)) { + auto status = + readCAPEMFile(std::get<0>(_pemCertificate).get()->hCertStore, params.sslCAFile); + if (!status.isOK()) { + return status; + } + } + _clientEngine.CAstore = std::move(swChain.getValue()); } _clientEngine.hasCRL = !params.sslCRLFile.empty(); @@ -1310,6 +1320,16 @@ Status SSLManagerWindows::_loadCertificates(const SSLParams& params) { return swChain.getStatus(); } + // Dump the CA cert chain into the memory store for the cluster cert. This ensures Windows + // can build a complete chain to send to the remote side. + if (std::get<0>(_clusterPEMCertificate)) { + auto status = + readCAPEMFile(std::get<0>(_clusterPEMCertificate).get()->hCertStore, serverCAFile); + if (!status.isOK()) { + return status; + } + } + _serverEngine.CAstore = std::move(swChain.getValue()); } _serverEngine.hasCRL = !params.sslCRLFile.empty(); @@ -1372,6 +1392,8 @@ Status SSLManagerWindows::initSSLContext(SCHANNEL_CRED* cred, cred->dwFlags = cred->dwFlags // flags | SCH_CRED_REVOCATION_CHECK_CHAIN // Check certificate revocation | SCH_CRED_SNI_CREDENTIAL // Pass along SNI creds + | SCH_CRED_MEMORY_STORE_CERT // Read intermediate certificates from memory + // store associated with client certificate. | SCH_CRED_NO_SYSTEM_MAPPER // Do not map certificate to user account | SCH_CRED_DISABLE_RECONNECTS; // Do not support reconnects -- cgit v1.2.1