mirror of https://github.com/mongodb/mongo
121 lines
4.3 KiB
JavaScript
121 lines
4.3 KiB
JavaScript
// Test server's adherence to serverAuth and clientAuth EKUs on X.509 certs.
|
|
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
import {isMacOS} from "jstests/ssl/libs/ssl_helpers.js";
|
|
|
|
const kServerAuthClientCert = "jstests/libs/client_with_serverAuth_eku.pem";
|
|
const kBothEKUsClientCert = "jstests/libs/client_with_serverAuth_and_clientAuth_eku.pem";
|
|
const kNoEKUsClientCert = "jstests/libs/client_without_eku.pem";
|
|
const kClientAuthClientCert = "jstests/libs/client.pem";
|
|
|
|
const kClientAuthServerCert = "jstests/libs/server_with_clientAuth_eku.pem";
|
|
const kBothEKUsServerCert = "jstests/libs/server.pem";
|
|
const kNoEKUsServerCert = "jstests/libs/server_without_eku.pem";
|
|
const kServerAuthServerCert = "jstests/libs/server_with_serverAuth_eku.pem";
|
|
|
|
const kCACert = "jstests/libs/ca.pem";
|
|
|
|
function testClientAuthEKU(conn, clientCert, shouldFail) {
|
|
clearRawMongoProgramOutput();
|
|
const exitCode = runMongoProgram(
|
|
"mongo",
|
|
"--tls",
|
|
"--tlsAllowInvalidHostnames",
|
|
"--tlsCertificateKeyFile",
|
|
clientCert,
|
|
"--tlsCAFile",
|
|
"jstests/libs/ca.pem",
|
|
"--port",
|
|
conn.port,
|
|
"--eval",
|
|
";",
|
|
);
|
|
|
|
let expectedFailureRegex = /unsuitable|unsupported certificate purpose/;
|
|
|
|
if (isMacOS()) {
|
|
expectedFailureRegex = /Certificate trust failure: Invalid Extended Key Usage for policy/;
|
|
} else if (_isWindows()) {
|
|
expectedFailureRegex = /The certificate is not valid for the requested usage./;
|
|
}
|
|
|
|
assert.soon(function () {
|
|
const output = rawMongoProgramOutput(".*");
|
|
clearRawMongoProgramOutput();
|
|
|
|
const isRegexPresent = expectedFailureRegex.test(output);
|
|
return (shouldFail && isRegexPresent) || (!shouldFail && !isRegexPresent);
|
|
});
|
|
}
|
|
|
|
function testServerAuthEKU(serverCert, shouldFail) {
|
|
const origSkipCheck = TestData.skipCheckDBHashes;
|
|
const rst = new ReplSetTest({
|
|
nodes: 2,
|
|
});
|
|
rst.startSet({
|
|
tlsMode: "requireTLS",
|
|
tlsCertificateKeyFile: serverCert,
|
|
tlsCAFile: kCACert,
|
|
tlsClusterFile: kBothEKUsServerCert,
|
|
tlsAllowInvalidHostnames: "",
|
|
});
|
|
|
|
if (shouldFail) {
|
|
const oldTimeout = ReplSetTest.kDefaultTimeoutMS;
|
|
const shortTimeout = 5 * 1000;
|
|
ReplSetTest.kDefaultTimeoutMS = shortTimeout;
|
|
rst.timeoutMS = shortTimeout;
|
|
MongoRunner.runHangAnalyzer.disable();
|
|
try {
|
|
assert.throws(function () {
|
|
rst.initiate();
|
|
});
|
|
} finally {
|
|
ReplSetTest.kDefaultTimeoutMS = oldTimeout;
|
|
MongoRunner.runHangAnalyzer.enable();
|
|
}
|
|
TestData.skipCheckDBHashes = true;
|
|
} else {
|
|
rst.initiate();
|
|
assert.commandWorked(rst.getPrimary().getDB("admin").runCommand({hello: 1}));
|
|
}
|
|
|
|
rst.stopSet();
|
|
TestData.skipCheckDBHashes = origSkipCheck;
|
|
}
|
|
|
|
// clientAuth tests against standalone.
|
|
{
|
|
const mongod = MongoRunner.runMongod({
|
|
auth: "",
|
|
tlsMode: "requireTLS",
|
|
// Server PEM file is server.pem to match the shell's ca.pem.
|
|
tlsCertificateKeyFile: "jstests/libs/server.pem",
|
|
tlsCAFile: "jstests/libs/ca.pem",
|
|
tlsAllowInvalidCertificates: "",
|
|
});
|
|
testClientAuthEKU(mongod, kClientAuthClientCert, false /* shouldFail */);
|
|
testClientAuthEKU(mongod, kNoEKUsClientCert, false /* shouldFail */);
|
|
testClientAuthEKU(mongod, kBothEKUsClientCert, false /* shouldFail */);
|
|
testClientAuthEKU(mongod, kServerAuthClientCert, true /* shouldFail */);
|
|
MongoRunner.stopMongod(mongod);
|
|
}
|
|
|
|
// serverAuth tests via replica set setup.
|
|
{
|
|
testServerAuthEKU(kServerAuthServerCert, false /* shouldFail */);
|
|
testServerAuthEKU(kBothEKUsServerCert, false /* shouldFail */);
|
|
testServerAuthEKU(kClientAuthServerCert, true /* shouldFail */);
|
|
|
|
// MacOS/Secure Transport's standard SSL cert verification policy is stricter than
|
|
// Windows and OpenSSL in that it requires server certificates to include the serverAuth
|
|
// EKU extension. Windows and OpenSSL accept server certificates that omit the EKU extension
|
|
// entirely and only care that serverAuth is specified if any EKU exists.
|
|
let shouldFailNoEKUsServerCert = false;
|
|
if (isMacOS()) {
|
|
shouldFailNoEKUsServerCert = true;
|
|
}
|
|
testServerAuthEKU(kNoEKUsServerCert, shouldFailNoEKUsServerCert /* shouldFail */);
|
|
}
|