diff options
Diffstat (limited to 'netwerk/test/unit/test_tls_server_multiple_clients.js')
-rw-r--r-- | netwerk/test/unit/test_tls_server_multiple_clients.js | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_tls_server_multiple_clients.js b/netwerk/test/unit/test_tls_server_multiple_clients.js new file mode 100644 index 0000000000..d1fad1ba68 --- /dev/null +++ b/netwerk/test/unit/test_tls_server_multiple_clients.js @@ -0,0 +1,152 @@ +/* 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 { PromiseUtils } = ChromeUtils.import( + "resource://gre/modules/PromiseUtils.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 getCert() { + return new Promise((resolve, reject) => { + certService.getOrCreateCert("tls-test", { + handleCert(c, rv) { + if (rv) { + reject(rv); + return; + } + resolve(c); + }, + }); + }); +} + +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(socket, transport) { + info("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(socket, status) { + info("TLS handshake done"); + + input.asyncWait( + { + onInputStreamReady(input) { + NetUtil.asyncCopy(input, output); + }, + }, + 0, + 0, + Services.tm.currentThread + ); + }, + onStopListening() {}, + }; + + 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"], + "127.0.0.1", + port, + null + ); + let input; + let output; + + let inputDeferred = PromiseUtils.defer(); + let outputDeferred = PromiseUtils.defer(); + + let handler = { + onTransportStatus(transport, status) { + if (status === Ci.nsISocketTransport.STATUS_CONNECTED_TO) { + output.asyncWait(handler, 0, 0, Services.tm.currentThread); + } + }, + + onInputStreamReady(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(output) { + try { + output.write("HELLO", 5); + info("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(async function() { + let cert = await getCert(); + ok(!!cert, "Got self-signed cert"); + let port = startServer(cert); + storeCertOverride(port, cert); + await startClient(port); + await startClient(port); +}); |