summaryrefslogtreecommitdiff
path: root/src/mongo/util/net/ssl_manager_windows.cpp
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2018-07-26 16:15:41 +0000
committerSara Golemon <sara.golemon@mongodb.com>2018-08-29 14:50:33 +0000
commit17ccef2b9f0c71b60d31b84b8824215ff87f03aa (patch)
tree8cc015711f93715bf1373703f3d2017f1d9d3678 /src/mongo/util/net/ssl_manager_windows.cpp
parentd92fe6cd9242a22e8ae56f48e64a20770d9e8291 (diff)
downloadmongo-17ccef2b9f0c71b60d31b84b8824215ff87f03aa.tar.gz
SERVER-35418 Allow specifying CAs for incoming and outgoing connections separately
Diffstat (limited to 'src/mongo/util/net/ssl_manager_windows.cpp')
-rw-r--r--src/mongo/util/net/ssl_manager_windows.cpp69
1 files changed, 48 insertions, 21 deletions
diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp
index c5dcc4c865e..7ac11406796 100644
--- a/src/mongo/util/net/ssl_manager_windows.cpp
+++ b/src/mongo/util/net/ssl_manager_windows.cpp
@@ -297,7 +297,15 @@ private:
SSLX509Name* subjectName,
Date_t* serverCertificateExpirationDate);
- Status _initChainEngines(bool hasCAFile);
+ struct CAEngine {
+ CERT_CHAIN_ENGINE_CONFIG machineConfig;
+ UniqueCertChainEngine machine;
+ CERT_CHAIN_ENGINE_CONFIG userConfig;
+ UniqueCertChainEngine user;
+ UniqueCertStore CAstore;
+ };
+
+ Status _initChainEngines(CAEngine* engine);
private:
bool _weakValidation;
@@ -314,17 +322,21 @@ private:
std::array<PCCERT_CONTEXT, 1> _clientCertificates;
std::array<PCCERT_CONTEXT, 1> _serverCertificates;
- UniqueCertificate _sslCertificate;
- UniqueCertificate _sslClusterCertificate;
-
- UniqueCertStore _certStore;
+ /* _clientEngine represents the CA to use when acting as a client
+ * and validating remotes during outbound connections.
+ * This comes from, in order, --tlsCAFile, or the system CA.
+ */
+ CAEngine _clientEngine;
- std::array<HCERTSTORE, 1> _additionalCertStores;
- CERT_CHAIN_ENGINE_CONFIG _chainEngineConfigMachine;
- UniqueCertChainEngine _chainEngineMachine;
+ /* _serverEngine represents the CA to use when acting as a server
+ * and validating remotes during inbound connections.
+ * This comes from --tlsClusterCAFile, if available,
+ * otherwise it inherits from _clientEngine.
+ */
+ CAEngine _serverEngine;
- CERT_CHAIN_ENGINE_CONFIG _chainEngineConfigUser;
- UniqueCertChainEngine _chainEngineUser;
+ UniqueCertificate _sslCertificate;
+ UniqueCertificate _sslClusterCertificate;
};
MONGO_INITIALIZER(SSLManager)(InitializerContext*) {
@@ -411,7 +423,8 @@ SSLManagerWindows::SSLManagerWindows(const SSLParams& params, bool isServer)
CertificateExpirationMonitor(_sslConfiguration.serverCertificateExpirationDate);
}
- uassertStatusOK(_initChainEngines(!params.sslCAFile.empty()));
+ uassertStatusOK(_initChainEngines(&_serverEngine));
+ uassertStatusOK(_initChainEngines(&_clientEngine));
}
StatusWith<UniqueCertChainEngine> initChainEngine(CERT_CHAIN_ENGINE_CONFIG* chainEngineConfig,
@@ -439,23 +452,23 @@ StatusWith<UniqueCertChainEngine> initChainEngine(CERT_CHAIN_ENGINE_CONFIG* chai
return {chainEngine};
}
-Status SSLManagerWindows::_initChainEngines(bool hasCAFile) {
- auto swMachine =
- initChainEngine(&_chainEngineConfigMachine, _certStore, CERT_CHAIN_USE_LOCAL_MACHINE_STORE);
+Status SSLManagerWindows::_initChainEngines(CAEngine* engine) {
+ auto swMachine = initChainEngine(
+ &engine->machineConfig, engine->CAstore, CERT_CHAIN_USE_LOCAL_MACHINE_STORE);
if (!swMachine.isOK()) {
return swMachine.getStatus();
}
- _chainEngineMachine = std::move(swMachine.getValue());
+ engine->machine = std::move(swMachine.getValue());
- auto swUser = initChainEngine(&_chainEngineConfigUser, _certStore, 0);
+ auto swUser = initChainEngine(&engine->userConfig, engine->CAstore, 0);
if (!swUser.isOK()) {
return swUser.getStatus();
}
- _chainEngineUser = std::move(swUser.getValue());
+ engine->user = std::move(swUser.getValue());
return Status::OK();
}
@@ -1180,7 +1193,18 @@ Status SSLManagerWindows::_loadCertificates(const SSLParams& params) {
return swChain.getStatus();
}
- _certStore = std::move(swChain.getValue());
+ _clientEngine.CAstore = std::move(swChain.getValue());
+ }
+
+ const auto serverCAFile =
+ params.sslClusterCAFile.empty() ? params.sslCAFile : params.sslClusterCAFile;
+ if (!serverCAFile.empty()) {
+ auto swChain = readCertChains(serverCAFile, params.sslCRLFile);
+ if (!swChain.isOK()) {
+ return swChain.getStatus();
+ }
+
+ _serverEngine.CAstore = std::move(swChain.getValue());
}
if (hasCertificateSelector(params.sslCertificateSelector)) {
@@ -1228,7 +1252,6 @@ Status SSLManagerWindows::initSSLContext(SCHANNEL_CRED* cred,
cred->dwVersion = SCHANNEL_CRED_VERSION;
cred->dwFlags = SCH_USE_STRONG_CRYPTO; // Use strong crypto;
- cred->hRootStore = _certStore;
uint32_t supportedProtocols = 0;
@@ -1236,6 +1259,7 @@ Status SSLManagerWindows::initSSLContext(SCHANNEL_CRED* cred,
supportedProtocols = SP_PROT_TLS1_SERVER | SP_PROT_TLS1_0_SERVER | SP_PROT_TLS1_1_SERVER |
SP_PROT_TLS1_2_SERVER;
+ cred->hRootStore = _serverEngine.CAstore;
cred->dwFlags = cred->dwFlags // flags
| SCH_CRED_REVOCATION_CHECK_CHAIN // Check certificate revocation
| SCH_CRED_SNI_CREDENTIAL // Pass along SNI creds
@@ -1246,6 +1270,7 @@ Status SSLManagerWindows::initSSLContext(SCHANNEL_CRED* cred,
supportedProtocols = SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_1_CLIENT |
SP_PROT_TLS1_2_CLIENT;
+ cred->hRootStore = _clientEngine.CAstore;
cred->dwFlags = cred->dwFlags // Flags
| SCH_CRED_REVOCATION_CHECK_CHAIN // Check certificate revocation
| SCH_CRED_NO_SERVERNAME_CHECK // Do not validate server name against cert
@@ -1702,10 +1727,12 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManagerWindows::parseAndValidatePeer
UniqueCertificate certHolder(cert);
SSLX509Name peerSubjectName;
+ auto* engine = remoteHost.empty() ? &_serverEngine : &_clientEngine;
+
// Validate against the local machine store first since it is easier to manage programmatically.
Status validateCertMachine = validatePeerCertificate(remoteHost,
certHolder.get(),
- _chainEngineMachine,
+ engine->machine,
_allowInvalidCertificates,
_allowInvalidHostnames,
&peerSubjectName);
@@ -1714,7 +1741,7 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManagerWindows::parseAndValidatePeer
// manage.
Status validateCertUser = validatePeerCertificate(remoteHost,
certHolder.get(),
- _chainEngineUser,
+ engine->user,
_allowInvalidCertificates,
_allowInvalidHostnames,
&peerSubjectName);