summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2020-11-17 14:47:08 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-20 22:54:43 +0000
commitb0b5daf545bc71b30304619947ee5bad02ccddb4 (patch)
tree34ad1895fd8b71682d9f08be69950ef470c4c6bb
parentd9ba623f77b9c42b3917bd3090fc37e143bcf3d0 (diff)
downloadmongo-b0b5daf545bc71b30304619947ee5bad02ccddb4.tar.gz
SERVER-47963 Support intermediate certs in the ca file on Windows
-rw-r--r--jstests/libs/intermediate-ca-chain.pem49
-rw-r--r--jstests/libs/server-intermediate-leaf.pem54
-rw-r--r--jstests/ssl/ssl_intermediate_ca.js37
-rw-r--r--jstests/ssl/x509/certs.yml16
-rw-r--r--src/mongo/util/net/ssl_manager_windows.cpp22
5 files changed, 177 insertions, 1 deletions
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