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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
// Check that OCSP ignores statuses of irrelevant certificates in the response
// @tags: [requires_http_client, requires_ocsp_stapling]
load("jstests/ocsp/lib/mock_ocsp.js");
(function() {
"use strict";
if (determineSSLProvider() === "apple") {
return;
}
const INCLUDE_EXTRA_STATUS = true;
/**
* Tests OCSP status verification in the client-side ignores the statuses
* of irrelevant certificates. No stapling is performed server-side.
*/
function testClient(serverCert, caCert, responderCertPair, issuerDigest) {
jsTestLog("Running client test with params: " + JSON.stringify(arguments));
clearOCSPCache();
let mock_ocsp =
new MockOCSPServer("", 1, responderCertPair, 0, INCLUDE_EXTRA_STATUS, issuerDigest);
let ocsp_options = {
sslMode: "requireSSL",
sslPEMKeyFile: serverCert,
sslCAFile: caCert,
sslAllowInvalidHostnames: "",
setParameter: {
"failpoint.disableStapling": "{'mode':'alwaysOn'}",
"ocspEnabled": "true",
},
waitForConnect: false,
};
const conn = MongoRunner.runMongod(ocsp_options);
waitForServer(conn);
jsTestLog(
"Testing client can connect if OCSP response has extraneous statuses and the matching CertID is Good");
mock_ocsp.start();
assertClientConnectSucceeds(conn);
mock_ocsp.stop();
jsTestLog(
"Testing client can't connect if OCSP response has extraneous statuses and the matching CertID is Revoked");
mock_ocsp = new MockOCSPServer(
FAULT_REVOKED, 1, responderCertPair, 0, INCLUDE_EXTRA_STATUS, issuerDigest);
mock_ocsp.start();
assertClientConnectFails(conn);
MongoRunner.stopMongod(conn);
// The mongoRunner spawns a new Mongo Object to validate the collections which races
// with the shutdown logic of the mock_ocsp responder on some platforms. We need this
// sleep to make sure that the threads don't interfere with each other.
sleep(1000);
mock_ocsp.stop();
}
/**
* Tests OCSP status verification in the server-side (for stapling) ignores
* the statuses of irrelevant certificates. The server certificate must have
* the status_request TLS Feature (aka MustStaple) extension for the assertions
* in this test to work.
*/
function testStapling(serverCert, caCert, responderCertPair, issuerDigest) {
jsTestLog("Running stapling test with params: " + JSON.stringify(arguments));
clearOCSPCache();
let mock_ocsp =
new MockOCSPServer("", 32400, responderCertPair, 0, INCLUDE_EXTRA_STATUS, issuerDigest);
let ocsp_options = {
sslMode: "requireSSL",
sslPEMKeyFile: serverCert,
sslCAFile: caCert,
sslAllowInvalidHostnames: "",
setParameter: {
"ocspEnabled": "true",
},
waitForConnect: false,
};
let conn = null;
jsTestLog(
"Testing server staples a Good status if OCSP response has extraneous statuses and the matching CertID is Good");
mock_ocsp.start();
conn = MongoRunner.runMongod(ocsp_options);
waitForServer(conn);
assertClientConnectSucceeds(conn);
MongoRunner.stopMongod(conn);
sleep(1000);
mock_ocsp.stop();
jsTestLog(
"Testing server staples a revoked status if OCSP response has extraneous statuses and the matching CertID is Revoked");
Object.extend(ocsp_options, {waitForConnect: false});
mock_ocsp = new MockOCSPServer(
FAULT_REVOKED, 32400, responderCertPair, 0, INCLUDE_EXTRA_STATUS, issuerDigest);
mock_ocsp.start();
conn = MongoRunner.runMongod(ocsp_options);
waitForServer(conn);
assertClientConnectFails(conn, OCSP_REVOKED);
MongoRunner.stopMongod(conn);
// The mongoRunner spawns a new Mongo Object to validate the collections which races
// with the shutdown logic of the mock_ocsp responder on some platforms. We need this
// sleep to make sure that the threads don't interfere with each other.
sleep(1000);
mock_ocsp.stop();
}
let digests = ['sha1'];
if (determineSSLProvider() !== "windows") {
// windows can't handle issuer names & keys hashed
// using sha256, so this is only tested on openssl.
digests.push('sha256');
}
for (const digest of digests) {
testClient(OCSP_SERVER_CERT, OCSP_CA_PEM, OCSP_DELEGATE_RESPONDER, digest);
testClient(OCSP_SERVER_CERT, OCSP_CA_PEM, OCSP_CA_RESPONDER, digest);
testClient(OCSP_SERVER_SIGNED_BY_INTERMEDIATE_CA_PEM,
OCSP_INTERMEDIATE_CA_WITH_ROOT_PEM,
OCSP_INTERMEDIATE_RESPONDER,
digest);
testClient(OCSP_SERVER_AND_INTERMEDIATE_APPENDED_PEM,
OCSP_CA_PEM,
OCSP_INTERMEDIATE_RESPONDER,
digest);
}
if (!supportsStapling()) {
return;
}
for (const digest of digests) {
testStapling(OCSP_SERVER_MUSTSTAPLE_CERT, OCSP_CA_PEM, OCSP_DELEGATE_RESPONDER, digest);
}
}());
|