summaryrefslogtreecommitdiff
path: root/jstests/ssl/ssl_hostname_validation.js
blob: d52d430dd26141c89038125d54fe05c55102c9fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Test SSL server certificate hostname validation
// for client-server and server-server connections
var CA_CERT = "jstests/libs/ca.pem";
var SERVER_CERT = "jstests/libs/server.pem";
var CN_CERT = "jstests/libs/localhostnameCN.pem";
var SAN_CERT = "jstests/libs/localhostnameSAN.pem";
var CLIENT_CERT = "jstests/libs/client.pem";
var BAD_SAN_CERT = "jstests/libs/badSAN.pem";
var NOSUBJ_CERT = "jstests/libs/server_no_subject.pem";
var NOSUBJ_NOSAN_CERT = "jstests/libs/server_no_subject_no_SAN.pem";

function testCombination(certPath, allowInvalidHost, allowInvalidCert, shouldSucceed) {
    jsTestLog("Testing certificate: " + JSON.stringify(arguments));
    var mongod =
        MongoRunner.runMongod({sslMode: "requireSSL", sslPEMKeyFile: certPath, sslCAFile: CA_CERT});

    var mongo;
    if (allowInvalidCert) {
        mongo = runMongoProgram("mongo",
                                "--port",
                                mongod.port,
                                "--ssl",
                                "--sslCAFile",
                                CA_CERT,
                                "--sslPEMKeyFile",
                                CLIENT_CERT,
                                "--sslAllowInvalidCertificates",
                                "--eval",
                                ";");
    } else if (allowInvalidHost) {
        mongo = runMongoProgram("mongo",
                                "--port",
                                mongod.port,
                                "--ssl",
                                "--sslCAFile",
                                CA_CERT,
                                "--sslPEMKeyFile",
                                CLIENT_CERT,
                                "--sslAllowInvalidHostnames",
                                "--eval",
                                ";");
    } else {
        mongo = runMongoProgram("mongo",
                                "--port",
                                mongod.port,
                                "--ssl",
                                "--sslCAFile",
                                CA_CERT,
                                "--sslPEMKeyFile",
                                CLIENT_CERT,
                                "--eval",
                                ";");
    }

    if (shouldSucceed) {
        // runMongoProgram returns 0 on success
        assert.eq(
            0, mongo, "Connection attempt failed when it should succeed certPath: " + certPath);
    } else {
        // runMongoProgram returns 1 on failure
        assert.eq(
            1, mongo, "Connection attempt succeeded when it should fail certPath: " + certPath);
    }
    MongoRunner.stopMongod(mongod);
}

// 1. Test client connections with different server certificates
// and allowInvalidCertificates
testCombination(CN_CERT, false, false, true);
testCombination(SAN_CERT, false, false, true);

// SERVER_CERT has SAN=localhost
testCombination(SERVER_CERT, false, false, true);
testCombination(SERVER_CERT, false, true, true);
testCombination(SERVER_CERT, true, false, true);
testCombination(SERVER_CERT, true, true, true);

// BAD_SAN_CERT has SAN=BadSAN.
testCombination(BAD_SAN_CERT, false, false, false);

// NOSUBJ_CERT has SAN=localhost but empty Subject
testCombination(NOSUBJ_CERT, false, false, true);

// NOSUBJ_NOSAN_CERT has neither Subject nor SANs
testCombination(NOSUBJ_NOSAN_CERT, false, false, false);

// Skip db hash check because replset cannot initiate.
TestData.skipCheckDBHashes = true;

// 2. Initiate ReplSetTest with invalid certs
ssl_options = {
    sslMode: "requireSSL",
    // SERVER_CERT has SAN=localhost. CLIENT_CERT is exact same except no SANS
    sslPEMKeyFile: CLIENT_CERT,
    sslCAFile: CA_CERT
};

replTest = new ReplSetTest({nodes: {node0: ssl_options, node1: ssl_options}});

// We don't want to invoke the hang analyzer because we
// expect this test to fail by timing out
MongoRunner.runHangAnalyzer.disable();

replTest.startSet();
assert.throws(function() {
    replTest.initiate();
});
replTest.stopSet();

// Re-enable the hang analyzer for the test
MongoRunner.runHangAnalyzer.enable();

TestData.skipCheckDBHashes = false;

// 3. Initiate ReplSetTest with invalid certs but set allowInvalidHostnames
ssl_options = {
    sslMode: "requireSSL",
    sslPEMKeyFile: SERVER_CERT,
    sslCAFile: CA_CERT,
    sslAllowInvalidHostnames: ""
};

var replTest = new ReplSetTest({nodes: {node0: ssl_options, node1: ssl_options}});
replTest.startSet();
replTest.initiate();
replTest.stopSet();

// 4. Initiate ReplSetTest with invalid certs but set allowInvalidCertificates
ssl_options = {
    sslMode: "requireSSL",
    // SERVER_CERT has SAN=localhost. CLIENT_CERT is exact same except no SANS
    sslPEMKeyFile: SERVER_CERT,
    sslCAFile: CA_CERT,
    sslAllowInvalidCertificates: ""
};

var replTest = new ReplSetTest({nodes: {node0: ssl_options, node1: ssl_options}});
replTest.startSet();
replTest.initiate();
replTest.stopSet();