mirror of https://github.com/mongodb/mongo
SERVER-94767 Expand testing of Certificate Revocation Lists (#27819)
GitOrigin-RevId: bacc7b90914150c845321184ad2ea66d17066bec
This commit is contained in:
parent
8040ebd63e
commit
8236b73d96
|
|
@ -0,0 +1,12 @@
|
||||||
|
-----BEGIN X509 CRL-----
|
||||||
|
MIIBvTCBpjANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJVUzERMA8GA1UECAwI
|
||||||
|
TmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNVBAoMB01vbmdv
|
||||||
|
REIxDzANBgNVBAsMBktlcm5lbDEaMBgGA1UEAwwRSW50ZXJtZWRpYXRlIENBIEIX
|
||||||
|
DTI0MTAwNDE1MzM1NVoXDTI3MDEwNTE1MzM1NVowDQYJKoZIhvcNAQELBQADggEB
|
||||||
|
ALHascvQiwxAIYAMuE2kP/SnEErR7uMxVteHN8HNUbfAX5k070mnGKlixsJ0I26Q
|
||||||
|
/ZcERRIGFZRrpp0u4m1Sak6Kb1oGjrM91d+8N4szjgj4FSFD07siY6kuIbYVet6M
|
||||||
|
ALR+Ww5uOqhOv54di1xvsETvuLOakvV7BTy2jv13SvC7+59EzamVBXUNgWUI8DX9
|
||||||
|
tpew9KH7JXYzvjMvVbdr0QfoH/PYDKZmlK7vPG14VpBc4BvO6jpclKjmvOxO7rhA
|
||||||
|
+11Vp8Bij3IiHLTZtvofk7Fn+HiI5Zd5sLPHLQjRWWDt6g0FmuIqebJJTMGzzFtv
|
||||||
|
bIDCUryP2KJ0BsxQG/5Rumc=
|
||||||
|
-----END X509 CRL-----
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0A41FB5894DAB67FB8D5B57506FE35DE926BE5B9
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
5A78E0DB3DA5C54F97E83B1C041095EF36DFCBCBC7B6BEB1B28986CD8268ADDD
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
-----BEGIN X509 CRL-----
|
||||||
|
MIIBwjCBqzANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzERMA8GA1UECAwI
|
||||||
|
TmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNVBAoMB01vbmdv
|
||||||
|
REIxDzANBgNVBAsMBktlcm5lbDEfMB0GA1UEAwwWVHJ1c3RlZCBLZXJuZWwgVGVz
|
||||||
|
dCBDQRcNMjQxMDA0MTUzMzU1WhcNMjcwMTA1MTUzMzU1WjANBgkqhkiG9w0BAQsF
|
||||||
|
AAOCAQEAJ+Tz2mzrlYMH0C6csdRwpG3xAMzvn5nFOuWdHDDWbtBKGYx0Jsds1fc1
|
||||||
|
ccCthhYAvEFzCBCjiNm5VVplMGaSkxGZ+yHqXjssDslD7KDQ/4zj2nGme+p1kXHE
|
||||||
|
ai5Q+gvHY1dJ4wDqtELQugDy737XHnPm98DqLuZjD31PhdOJt/NaO93L6A1kFrvQ
|
||||||
|
fpL9XuCumhk1z7kCZiU/4ysjBshWAkx+9vGwlcxXkwq2zEYulf4FqsV2hShklp7z
|
||||||
|
AdI2AQPkWov47h08XDWRbC/aQnCJyC3UXn/pqzwPtEH1gBE/ry2Fv0OUxrvHfB2q
|
||||||
|
ACDic7GrdkKOrE8/m7RJPhsmd8VwTQ==
|
||||||
|
-----END X509 CRL-----
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
520F782BCF4CF6DB791C0420A71E4C9127F59039
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
42CA4384684DCDFC82D9A22BAA5485661E0849F00E42E8E1CEE6F83A96D57A4C
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
-----BEGIN X509 CRL-----
|
||||||
|
MIIB0zCBvDANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJVUzERMA8GA1UECAwI
|
||||||
|
TmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNVBAoMB01vbmdv
|
||||||
|
REIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVsIFRlc3QgQ0EXDTI0
|
||||||
|
MTAwMTE3MDQwMVoXDTI3MDEwMjE3MDQwMVowFzAVAgQQP6lYFw0yNDEwMDExNzA0
|
||||||
|
MDFaMA0GCSqGSIb3DQEBCwUAA4IBAQC6XLhZfKBhniiRGvZ5W6OI5IjW436WWzoA
|
||||||
|
tfF3uheYqSL6CSfHKzmHBUcdQHv63qOgUTW6axRZmTY/7nTFi/XU93ICAdQaqSo6
|
||||||
|
Hb/8XkgzAP6uElH/e9UA3H6EN8Htr/FqcszcRsn0DhZzVgt4lGjZ3sZOKyIXfH+X
|
||||||
|
4/SkHR5vTAl3WsjhsXv1Vgcpa4K8FXocm27nTzByu3/nAM7dVg5Tbv4NZ43aChRD
|
||||||
|
e5Hbaha5IO/vOR/p+JqzLcztjMibVWE49kTu83YhJgBmXHmMVvxu6Or3DWBP31S6
|
||||||
|
8WpuVZgFDJ6WIEQo2jRwSQxVXf+NXu18/U6Ky6akCR/mpzHNRbPj
|
||||||
|
-----END X509 CRL-----
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
EB6AC7435EEC30A81FBCD1D9964245F0F24EE089
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
2928A1FCB9268902A63005544ADAC00A228B008C21703E116145524E34DB9143
|
||||||
|
|
@ -4,12 +4,26 @@ set -e
|
||||||
# This script uses the openssl command line tool to create CRLs.
|
# This script uses the openssl command line tool to create CRLs.
|
||||||
|
|
||||||
OUTPUT_PATH="jstests/libs/"
|
OUTPUT_PATH="jstests/libs/"
|
||||||
|
CA_PEM_PATH="${OUTPUT_PATH}/ca.pem"
|
||||||
|
TRUSTED_CA_PEM_PATH="${OUTPUT_PATH}/trusted-ca.pem"
|
||||||
|
|
||||||
|
die () {
|
||||||
|
[ $# -gt 0 ] && [ ! -z "$1" ] && echo "$1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# crl <ca_pem_file> <output_crl_file> {empty|expired|revoked} [pem_file_to_revoke]
|
||||||
crl() {
|
crl() {
|
||||||
|
[ $# -lt 3 ] && die "Error: too few arguments"
|
||||||
|
[ -z "$1" ] && die "Error: must supply a CA file"
|
||||||
|
[ -z "$2" ] && die "Error: must supply an output filename"
|
||||||
|
[ "$3" = "revoked" ] && [ -z "$4" ] && die "Error: must supply a certificate file to revoke"
|
||||||
|
|
||||||
CADB=$(mktemp -d)
|
CADB=$(mktemp -d)
|
||||||
CA="jstests/libs/ca.pem"
|
CA="$1"
|
||||||
CONFIG="${CADB}/config"
|
CONFIG="${CADB}/config"
|
||||||
DEST="${OUTPUT_PATH}/$1"
|
DEST="${OUTPUT_PATH}/$2"
|
||||||
echo '01' > "$CADB/serial"
|
echo '01' > "$CADB/serial"
|
||||||
touch "$CADB/index.txt" "$CADB/index.txt.attr"
|
touch "$CADB/index.txt" "$CADB/index.txt.attr"
|
||||||
echo -e "[ ca ]\ndefault_ca = CA_default\n" > "$CONFIG"
|
echo -e "[ ca ]\ndefault_ca = CA_default\n" > "$CONFIG"
|
||||||
|
|
@ -17,18 +31,22 @@ crl() {
|
||||||
echo -e "certificate = $CA\nprivate_key = $CA\ndefault_md = sha256" >> "$CONFIG"
|
echo -e "certificate = $CA\nprivate_key = $CA\ndefault_md = sha256" >> "$CONFIG"
|
||||||
|
|
||||||
VALIDITY_OPTIONS="-days 824 -crldays 823"
|
VALIDITY_OPTIONS="-days 824 -crldays 823"
|
||||||
if [ "$2" = "expired" ]; then
|
if [ "$3" = "expired" ]; then
|
||||||
# -enddate 010101000000Z = expires on 0:00:00, Jan 1, 2000.
|
# -enddate 010101000000Z = expires on 0:00:00, Jan 1, 2000.
|
||||||
# -crlsec 1 = valid for 1 second from now.
|
# -crlsec 1 = valid for 1 second from now.
|
||||||
# i.e. this certificate will be completely invalid very soon.
|
# i.e. this certificate will be completely invalid very soon.
|
||||||
VALIDITY_OPTIONS="-enddate 010101000000Z -crlsec 1"
|
VALIDITY_OPTIONS="-enddate 010101000000Z -crlsec 1"
|
||||||
elif [ "$2" = "revoked" ]; then
|
elif [ "$3" = "revoked" ]; then
|
||||||
openssl ca -config "$CADB/config" -revoke "jstests/libs/client_revoked.pem"
|
openssl ca -config "$CADB/config" -revoke "$4"
|
||||||
fi
|
fi
|
||||||
openssl ca -config "$CADB/config" -gencrl -out "$DEST" -md sha256 $VALIDITY_OPTIONS
|
openssl ca -config "$CADB/config" -gencrl -out "$DEST" -md sha256 $VALIDITY_OPTIONS
|
||||||
jstests/ssl/x509/mkdigest.py crl sha256 "$DEST"
|
jstests/ssl/x509/mkdigest.py crl sha256 "$DEST"
|
||||||
jstests/ssl/x509/mkdigest.py crl sha1 "$DEST"
|
jstests/ssl/x509/mkdigest.py crl sha1 "$DEST"
|
||||||
}
|
}
|
||||||
crl crl.pem empty
|
|
||||||
crl crl_expired.pem expired
|
crl $CA_PEM_PATH crl.pem empty
|
||||||
crl crl_client_revoked.pem revoked
|
crl $CA_PEM_PATH crl_expired.pem expired
|
||||||
|
crl $CA_PEM_PATH crl_client_revoked.pem revoked "jstests/libs/client_revoked.pem"
|
||||||
|
crl $CA_PEM_PATH crl_intermediate_ca_B_revoked.pem revoked "jstests/libs/intermediate-ca-B.pem"
|
||||||
|
crl $TRUSTED_CA_PEM_PATH crl_from_trusted_ca.pem empty
|
||||||
|
crl "jstests/libs/intermediate-ca-B.pem" crl_from_intermediate_ca_B.pem empty
|
||||||
|
|
|
||||||
|
|
@ -62,20 +62,27 @@ namespace mongo {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#define TEST_CERTS_DIR "jstests/libs/"
|
#define TEST_CERTS_DIR "jstests/libs/"
|
||||||
// certs rooted in ca.pem
|
// certs & CRLs rooted in ca.pem
|
||||||
constexpr const char* caFile = TEST_CERTS_DIR "ca.pem";
|
constexpr const char* caFile = TEST_CERTS_DIR "ca.pem";
|
||||||
constexpr const char* serverKeyFile = TEST_CERTS_DIR "server.pem";
|
constexpr const char* serverKeyFile = TEST_CERTS_DIR "server.pem";
|
||||||
constexpr const char* clientKeyFile = TEST_CERTS_DIR "client.pem";
|
constexpr const char* clientKeyFile = TEST_CERTS_DIR "client.pem";
|
||||||
|
constexpr const char* revokedClientKeyFile = TEST_CERTS_DIR "client_revoked.pem";
|
||||||
|
|
||||||
constexpr const char* intermediateACaFile = TEST_CERTS_DIR "intermediate-ca.pem";
|
constexpr const char* intermediateACaFile = TEST_CERTS_DIR "intermediate-ca.pem";
|
||||||
constexpr const char* intermediateALeafKeyFile = TEST_CERTS_DIR "server-intermediate-leaf.pem";
|
constexpr const char* intermediateALeafKeyFile = TEST_CERTS_DIR "server-intermediate-leaf.pem";
|
||||||
constexpr const char* intermediateBCaFile = TEST_CERTS_DIR "intermediate-ca-B.pem";
|
constexpr const char* intermediateBCaFile = TEST_CERTS_DIR "intermediate-ca-B.pem";
|
||||||
constexpr const char* intermediateBLeafKeyFile = TEST_CERTS_DIR "intermediate-ca-B-leaf.pem";
|
constexpr const char* intermediateBLeafKeyFile = TEST_CERTS_DIR "intermediate-ca-B-leaf.pem";
|
||||||
|
constexpr const char* emptyCRL = TEST_CERTS_DIR "crl.pem";
|
||||||
|
constexpr const char* expiredCRL = TEST_CERTS_DIR "crl_expired.pem";
|
||||||
|
constexpr const char* clientRevokedCRL = TEST_CERTS_DIR "crl_client_revoked.pem";
|
||||||
|
constexpr const char* intermediateBRevokedCRL = TEST_CERTS_DIR "crl_intermediate_ca_B_revoked.pem";
|
||||||
|
constexpr const char* intermediateBCRL = TEST_CERTS_DIR "crl_from_intermediate_ca_B.pem";
|
||||||
|
|
||||||
// certs rooted in trusted-ca.pem
|
// certs & CRLs rooted in trusted-ca.pem
|
||||||
constexpr const char* trustedCaFile = TEST_CERTS_DIR "trusted-ca.pem";
|
constexpr const char* trustedCaFile = TEST_CERTS_DIR "trusted-ca.pem";
|
||||||
constexpr const char* trustedServerKeyFile = TEST_CERTS_DIR "trusted-server.pem";
|
constexpr const char* trustedServerKeyFile = TEST_CERTS_DIR "trusted-server.pem";
|
||||||
constexpr const char* trustedClientKeyFile = TEST_CERTS_DIR "trusted-client.pem";
|
constexpr const char* trustedClientKeyFile = TEST_CERTS_DIR "trusted-client.pem";
|
||||||
|
constexpr const char* trustedEmptyCRL = TEST_CERTS_DIR "crl_from_trusted_ca.pem";
|
||||||
|
|
||||||
// Test implementation needed by ASIO transport.
|
// Test implementation needed by ASIO transport.
|
||||||
class SessionManagerUtil : public transport::SessionManager {
|
class SessionManagerUtil : public transport::SessionManager {
|
||||||
|
|
@ -1582,6 +1589,213 @@ TEST(SSLManager, intermediateCATests) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that validation fails if configured CRL for the issuer of the peer certificate being
|
||||||
|
// validated has expired.
|
||||||
|
// Caveats:
|
||||||
|
// - Apple: CRL unsupported; test disabled
|
||||||
|
// - Windows: validation fails, but with misleading error message
|
||||||
|
#if MONGO_CONFIG_SSL_PROVIDER != MONGO_CONFIG_SSL_PROVIDER_APPLE
|
||||||
|
TEST(SSLManager, expiredCRLTest) {
|
||||||
|
SSLParams clientParams;
|
||||||
|
clientParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
clientParams.sslAllowInvalidHostnames = true;
|
||||||
|
clientParams.sslCAFile = caFile;
|
||||||
|
clientParams.sslPEMKeyFile = clientKeyFile;
|
||||||
|
clientParams.sslCRLFile = expiredCRL;
|
||||||
|
|
||||||
|
SSLParams serverParams;
|
||||||
|
serverParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
serverParams.sslAllowInvalidHostnames = true;
|
||||||
|
serverParams.sslCAFile = caFile;
|
||||||
|
serverParams.sslPEMKeyFile = serverKeyFile;
|
||||||
|
serverParams.sslCRLFile = expiredCRL;
|
||||||
|
|
||||||
|
SSLTestFixture tf(serverParams, clientParams);
|
||||||
|
tf.doHandshake();
|
||||||
|
auto result = tf.runIngressEgressValidation();
|
||||||
|
checkValidationResults(result, false /*expectIngressPass*/, false /*expectEgressPass*/);
|
||||||
|
|
||||||
|
#if MONGO_CONFIG_SSL_PROVIDER == MONGO_CONFIG_SSL_PROVIDER_WINDOWS
|
||||||
|
constexpr const char* cause = "revocation server was offline";
|
||||||
|
#else
|
||||||
|
constexpr const char* cause = "expired";
|
||||||
|
#endif
|
||||||
|
ASSERT_NE(result.ingress.getStatus().reason().find(cause), std::string::npos);
|
||||||
|
ASSERT_NE(result.egress.getStatus().reason().find(cause), std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests peer cert validation behavior if multiple CRLs from the same issuer are included
|
||||||
|
// in the CRL PEM file.
|
||||||
|
// Caveats:
|
||||||
|
// - Apple: CRL unsupported; test disabled
|
||||||
|
// - Windows: not allowed; setup fails with "The object or property already exists"
|
||||||
|
// - OpenSSL: allowed, even with some CRLs having already expired
|
||||||
|
TEST(SSLManager, multipleCRLsFromSameIssuerTests) {
|
||||||
|
// Combine two CRLs from the same issuer, one is valid and the other is expired.
|
||||||
|
const auto expiredCRLWithNonExpiredCRL = combinePEMFiles({{clientRevokedCRL}, {expiredCRL}});
|
||||||
|
|
||||||
|
SSLParams serverParams;
|
||||||
|
serverParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
serverParams.sslAllowInvalidHostnames = true;
|
||||||
|
serverParams.sslCAFile = caFile;
|
||||||
|
serverParams.sslPEMKeyFile = serverKeyFile;
|
||||||
|
serverParams.sslCRLFile = expiredCRLWithNonExpiredCRL;
|
||||||
|
|
||||||
|
SSLParams clientParams;
|
||||||
|
clientParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
clientParams.sslAllowInvalidHostnames = true;
|
||||||
|
clientParams.sslCAFile = caFile;
|
||||||
|
|
||||||
|
#if MONGO_CONFIG_SSL_PROVIDER == MONGO_CONFIG_SSL_PROVIDER_WINDOWS
|
||||||
|
ASSERT_THROWS_CODE_AND_WHAT(
|
||||||
|
SSLManagerInterface::create(serverParams, true),
|
||||||
|
DBException,
|
||||||
|
ErrorCodes::InvalidSSLConfiguration,
|
||||||
|
"CertAddCRLContextToStore Failed The object or property already exists.");
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
clientParams.sslPEMKeyFile = clientKeyFile;
|
||||||
|
LOGV2(9476700, "Running with client key file", "keyfile"_attr = clientKeyFile);
|
||||||
|
SSLTestFixture tf(serverParams, clientParams);
|
||||||
|
tf.doHandshake();
|
||||||
|
auto result = tf.runIngressEgressValidation();
|
||||||
|
checkValidationResults(result, true /*expectIngressPass*/, true);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
clientParams.sslPEMKeyFile = revokedClientKeyFile;
|
||||||
|
LOGV2(9476701, "Running with client key file", "keyfile"_attr = revokedClientKeyFile);
|
||||||
|
SSLTestFixture tf(serverParams, clientParams);
|
||||||
|
tf.doHandshake();
|
||||||
|
auto result = tf.runIngressEgressValidation();
|
||||||
|
checkValidationResults(result, false, true);
|
||||||
|
ASSERT_NE(result.ingress.getStatus().reason().find("revoked"), std::string::npos);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests basic CRL revocation works on ingress if the client is configured with a revoked key.
|
||||||
|
// Caveats:
|
||||||
|
// - Apple: CRL unsupported; test disabled
|
||||||
|
TEST(SSLManager, basicCRLRevocationTests) {
|
||||||
|
struct TestCase {
|
||||||
|
std::string serverCRLFile;
|
||||||
|
bool serverPass;
|
||||||
|
void serialize(BSONObjBuilder* bob) const {
|
||||||
|
bob->append("serverCRLFile", serverCRLFile);
|
||||||
|
bob->append("serverPass", serverPass);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SSLParams clientParams;
|
||||||
|
clientParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
clientParams.sslAllowInvalidHostnames = true;
|
||||||
|
clientParams.sslCAFile = trustedCaFile;
|
||||||
|
clientParams.sslPEMKeyFile = revokedClientKeyFile;
|
||||||
|
|
||||||
|
SSLParams serverParams;
|
||||||
|
serverParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
serverParams.sslAllowInvalidHostnames = true;
|
||||||
|
serverParams.sslCAFile = caFile;
|
||||||
|
serverParams.sslPEMKeyFile = trustedServerKeyFile;
|
||||||
|
|
||||||
|
{
|
||||||
|
serverParams.sslCRLFile = emptyCRL;
|
||||||
|
LOGV2(9476702, "Running test case", "CRLFile"_attr = emptyCRL, "pass"_attr = true);
|
||||||
|
SSLTestFixture tf(serverParams, clientParams);
|
||||||
|
tf.doHandshake();
|
||||||
|
auto result = tf.runIngressEgressValidation();
|
||||||
|
checkValidationResults(result, true, true /*expectEgressPass*/);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
serverParams.sslCRLFile = clientRevokedCRL;
|
||||||
|
LOGV2(9476703, "Running test case", "CRLFile"_attr = clientRevokedCRL, "pass"_attr = false);
|
||||||
|
SSLTestFixture tf(serverParams, clientParams);
|
||||||
|
tf.doHandshake();
|
||||||
|
auto result = tf.runIngressEgressValidation();
|
||||||
|
checkValidationResults(result, false, true /*expectEgressPass*/);
|
||||||
|
ASSERT_NE(result.ingress.getStatus().reason().find("revoked"), std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests validation behavior on ingress (or egress) if CRL checking is enabled, but no suitable
|
||||||
|
// CRL is found from same issuer of the peer cert being validated.
|
||||||
|
// Caveats:
|
||||||
|
// - Apple: CRL unsupported; test disabled
|
||||||
|
// - Windows: validation passes if no CRL is found
|
||||||
|
// - OpenSSL: validation fails if no CRL is found
|
||||||
|
TEST(SSLManager, noCRLFoundTests) {
|
||||||
|
SSLParams clientParams;
|
||||||
|
clientParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
clientParams.sslAllowInvalidHostnames = true;
|
||||||
|
clientParams.sslCAFile = caFile;
|
||||||
|
clientParams.sslPEMKeyFile = clientKeyFile;
|
||||||
|
clientParams.sslCRLFile = trustedEmptyCRL; // CRL issued by trusted-ca.pem, not ca.pem
|
||||||
|
|
||||||
|
SSLParams serverParams;
|
||||||
|
serverParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
serverParams.sslAllowInvalidHostnames = true;
|
||||||
|
serverParams.sslCAFile = caFile;
|
||||||
|
serverParams.sslPEMKeyFile = serverKeyFile;
|
||||||
|
serverParams.sslCRLFile = trustedEmptyCRL;
|
||||||
|
|
||||||
|
SSLTestFixture tf(serverParams, clientParams);
|
||||||
|
tf.doHandshake();
|
||||||
|
auto result = tf.runIngressEgressValidation();
|
||||||
|
#if MONGO_CONFIG_SSL_PROVIDER == MONGO_CONFIG_SSL_PROVIDER_WINDOWS
|
||||||
|
checkValidationResults(result, true, true);
|
||||||
|
#else
|
||||||
|
checkValidationResults(result, false, false);
|
||||||
|
constexpr const char* expectedError = "unable to get certificate CRL";
|
||||||
|
ASSERT_NE(result.ingress.getStatus().reason().find(expectedError), std::string::npos);
|
||||||
|
ASSERT_NE(result.egress.getStatus().reason().find(expectedError), std::string::npos);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests whether validation passes if an intermediate CA issuer cert is revoked, but
|
||||||
|
// the end-entity cert is not.
|
||||||
|
// Caveats:
|
||||||
|
// - Apple: CRL unsupported; test disabled
|
||||||
|
// - Windows: multiple CRLs (root CRL + intermediate CRL) is not allowed
|
||||||
|
// TODO: SERVER-95583 investigate why windows behaves like this.
|
||||||
|
// - OpenSSL: passes; only leaf cert is checked against CRL
|
||||||
|
// TODO: SERVER-95445 should fix this openssl issue.
|
||||||
|
TEST(SSLManager, revocationWithCRLsIntermediateTests) {
|
||||||
|
// intermediate-ca-B.pem + intermediate-ca-B-leaf.pem bundle
|
||||||
|
const std::string intermediateBLeafWithIssuerCertKeyFile = combinePEMFiles(
|
||||||
|
{{intermediateBLeafKeyFile, true /*includePrivKey*/}, {intermediateBCaFile}});
|
||||||
|
// crl_from_intermediate_ca_B.pem + crl_intermediate_ca_B_revoked.pem
|
||||||
|
const std::string crlsFromRootAndIntermediateB =
|
||||||
|
combinePEMFiles({{intermediateBRevokedCRL}, {intermediateBCRL}});
|
||||||
|
|
||||||
|
SSLParams clientParams;
|
||||||
|
clientParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
clientParams.sslAllowInvalidHostnames = true;
|
||||||
|
clientParams.sslCAFile = caFile;
|
||||||
|
clientParams.sslPEMKeyFile = clientKeyFile;
|
||||||
|
clientParams.sslCRLFile = crlsFromRootAndIntermediateB;
|
||||||
|
|
||||||
|
SSLParams serverParams;
|
||||||
|
serverParams.sslMode.store(::mongo::sslGlobalParams.SSLMode_requireSSL);
|
||||||
|
serverParams.sslAllowInvalidHostnames = true;
|
||||||
|
serverParams.sslCAFile = caFile;
|
||||||
|
serverParams.sslPEMKeyFile = intermediateBLeafWithIssuerCertKeyFile;
|
||||||
|
|
||||||
|
#if MONGO_CONFIG_SSL_PROVIDER == MONGO_CONFIG_SSL_PROVIDER_WINDOWS
|
||||||
|
ASSERT_THROWS_CODE_AND_WHAT(
|
||||||
|
SSLManagerInterface::create(clientParams, true),
|
||||||
|
DBException,
|
||||||
|
ErrorCodes::InvalidSSLConfiguration,
|
||||||
|
"CertAddCRLContextToStore Failed The object or property already exists.");
|
||||||
|
#else
|
||||||
|
SSLTestFixture tf(serverParams, clientParams);
|
||||||
|
tf.doHandshake();
|
||||||
|
auto result = tf.runIngressEgressValidation();
|
||||||
|
checkValidationResults(result, true, true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MONGO_CONFIG_SSL_PROVIDER != MONGO_CONFIG_SSL_PROVIDER_APPLE
|
||||||
|
|
||||||
#endif // MONGO_CONFIG_SSL
|
#endif // MONGO_CONFIG_SSL
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace mongo
|
} // namespace mongo
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue