зеркало из https://github.com/mozilla/gecko-dev.git
bug 1273677 - ensure session cache is properly configured and torn down for TLSServerSocket r=mcmanus
MozReview-Commit-ID: 6i7HxTdLcID --HG-- extra : rebase_source : 5a64db198fe582e6057bb58f8f51be3e9a63192b
This commit is contained in:
Родитель
d99040fe43
Коммит
a53c0feecf
|
@ -690,6 +690,7 @@ SSL_SetSockPeerID
|
|||
SSL_SetSRTPCiphers
|
||||
SSL_SetStapledOCSPResponses
|
||||
SSL_SetURL
|
||||
SSL_ShutdownServerSessionIDCache
|
||||
SSL_SNISocketConfigHook
|
||||
SSL_VersionRangeGet
|
||||
SSL_VersionRangeGetDefault
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Need profile dir to store the key / cert
|
||||
do_get_profile();
|
||||
// Ensure PSM is initialized
|
||||
Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
|
||||
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||
const { Promise: promise } =
|
||||
Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
const certService = Cc["@mozilla.org/security/local-cert-service;1"]
|
||||
.getService(Ci.nsILocalCertService);
|
||||
const certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
|
||||
.getService(Ci.nsICertOverrideService);
|
||||
const socketTransportService =
|
||||
Cc["@mozilla.org/network/socket-transport-service;1"]
|
||||
.getService(Ci.nsISocketTransportService);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function getCert() {
|
||||
let deferred = promise.defer();
|
||||
certService.getOrCreateCert("tls-test", {
|
||||
handleCert: function(c, rv) {
|
||||
if (rv) {
|
||||
deferred.reject(rv);
|
||||
return;
|
||||
}
|
||||
deferred.resolve(c);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function startServer(cert) {
|
||||
let tlsServer = Cc["@mozilla.org/network/tls-server-socket;1"]
|
||||
.createInstance(Ci.nsITLSServerSocket);
|
||||
tlsServer.init(-1, true, -1);
|
||||
tlsServer.serverCert = cert;
|
||||
|
||||
let input, output;
|
||||
|
||||
let listener = {
|
||||
onSocketAccepted: function(socket, transport) {
|
||||
do_print("Accept TLS client connection");
|
||||
let connectionInfo = transport.securityInfo
|
||||
.QueryInterface(Ci.nsITLSServerConnectionInfo);
|
||||
connectionInfo.setSecurityObserver(listener);
|
||||
input = transport.openInputStream(0, 0, 0);
|
||||
output = transport.openOutputStream(0, 0, 0);
|
||||
},
|
||||
onHandshakeDone: function(socket, status) {
|
||||
do_print("TLS handshake done");
|
||||
|
||||
input.asyncWait({
|
||||
onInputStreamReady: function(input) {
|
||||
NetUtil.asyncCopy(input, output);
|
||||
}
|
||||
}, 0, 0, Services.tm.currentThread);
|
||||
},
|
||||
onStopListening: function() {}
|
||||
};
|
||||
|
||||
tlsServer.setSessionCache(true);
|
||||
tlsServer.setSessionTickets(false);
|
||||
|
||||
tlsServer.asyncListen(listener);
|
||||
|
||||
return tlsServer.port;
|
||||
}
|
||||
|
||||
function storeCertOverride(port, cert) {
|
||||
let overrideBits = Ci.nsICertOverrideService.ERROR_UNTRUSTED |
|
||||
Ci.nsICertOverrideService.ERROR_MISMATCH;
|
||||
certOverrideService.rememberValidityOverride("127.0.0.1", port, cert,
|
||||
overrideBits, true);
|
||||
}
|
||||
|
||||
function startClient(port) {
|
||||
let transport =
|
||||
socketTransportService.createTransport(["ssl"], 1, "127.0.0.1", port, null);
|
||||
let input;
|
||||
let output;
|
||||
|
||||
let inputDeferred = promise.defer();
|
||||
let outputDeferred = promise.defer();
|
||||
|
||||
let handler = {
|
||||
|
||||
onTransportStatus: function(transport, status) {
|
||||
if (status === Ci.nsISocketTransport.STATUS_CONNECTED_TO) {
|
||||
output.asyncWait(handler, 0, 0, Services.tm.currentThread);
|
||||
}
|
||||
},
|
||||
|
||||
onInputStreamReady: function(input) {
|
||||
try {
|
||||
let data = NetUtil.readInputStreamToString(input, input.available());
|
||||
equal(data, "HELLO", "Echoed data received");
|
||||
input.close();
|
||||
output.close();
|
||||
inputDeferred.resolve();
|
||||
} catch (e) {
|
||||
inputDeferred.reject(e);
|
||||
}
|
||||
},
|
||||
|
||||
onOutputStreamReady: function(output) {
|
||||
try {
|
||||
output.write("HELLO", 5);
|
||||
do_print("Output to server written");
|
||||
outputDeferred.resolve();
|
||||
input = transport.openInputStream(0, 0, 0);
|
||||
input.asyncWait(handler, 0, 0, Services.tm.currentThread);
|
||||
} catch (e) {
|
||||
outputDeferred.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
transport.setEventSink(handler, Services.tm.currentThread);
|
||||
output = transport.openOutputStream(0, 0, 0);
|
||||
|
||||
return promise.all([inputDeferred.promise, outputDeferred.promise]);
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
let cert = yield getCert();
|
||||
ok(!!cert, "Got self-signed cert");
|
||||
let port = startServer(cert);
|
||||
storeCertOverride(port, cert);
|
||||
yield startClient(port);
|
||||
yield startClient(port);
|
||||
});
|
|
@ -336,6 +336,9 @@ skip-if = os != "win"
|
|||
# The local cert service used by this test is not currently shipped on Android
|
||||
skip-if = os == "android"
|
||||
firefox-appdir = browser
|
||||
[test_tls_server_multiple_clients.js]
|
||||
# The local cert service used by this test is not currently shipped on Android
|
||||
skip-if = os == "android"
|
||||
[test_1073747.js]
|
||||
[test_multipart_streamconv_application_package.js]
|
||||
[test_safeoutputstream_append.js]
|
||||
|
|
|
@ -1600,6 +1600,13 @@ nsNSSComponent::InitializeNSS()
|
|||
// dynamic options from prefs
|
||||
setValidationOptions(true, lock);
|
||||
|
||||
// TLSServerSocket may be run with the session cache enabled. It is necessary
|
||||
// to call this once before that can happen. This specifies a maximum of 1000
|
||||
// cache entries (the default number of cache entries is 10000, which seems a
|
||||
// little excessive as there probably won't be that many clients connecting to
|
||||
// any TLSServerSockets the browser runs.)
|
||||
SSL_ConfigServerSessionIDCache(1000, 0, 0, nullptr);
|
||||
|
||||
#ifndef MOZ_NO_SMART_CARDS
|
||||
LaunchSmartCardThreads();
|
||||
#endif
|
||||
|
@ -1650,6 +1657,9 @@ nsNSSComponent::ShutdownNSS()
|
|||
ShutdownSmartCardThreads();
|
||||
#endif
|
||||
SSL_ClearSessionCache();
|
||||
// TLSServerSocket may be run with the session cache enabled. This ensures
|
||||
// those resources are cleaned up.
|
||||
SSL_ShutdownServerSessionIDCache();
|
||||
UnloadLoadableRoots();
|
||||
#ifndef MOZ_NO_EV_CERTS
|
||||
CleanupIdentityInfo();
|
||||
|
|
Загрузка…
Ссылка в новой задаче