tenfourfox/devtools/shared/security/tests/unit/test_oob_cert_auth.js
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

264 lines
7.9 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var cert = require("devtools/shared/security/cert");
// Test basic functionality of DevTools client and server OOB_CERT auth (used
// with WiFi debugging)
function run_test() {
// Need profile dir to store the key / cert
do_get_profile();
// Ensure PSM is initialized
Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
run_next_test();
}
function connectClient(client) {
let deferred = promise.defer();
client.connect(() => {
client.listTabs(deferred.resolve);
});
return deferred.promise;
}
add_task(function*() {
initTestDebuggerServer();
});
// Client w/ OOB_CERT auth connects successfully to server w/ OOB_CERT auth
add_task(function*() {
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
// Grab our cert, instead of relying on a discovery advertisement
let serverCert = yield cert.local.getOrCreate();
let oobData = promise.defer();
let AuthenticatorType = DebuggerServer.Authenticators.get("OOB_CERT");
let serverAuth = new AuthenticatorType.Server();
serverAuth.allowConnection = () => {
return DebuggerServer.AuthenticationResult.ALLOW;
};
serverAuth.receiveOOB = () => oobData.promise; // Skip prompt for tests
let listener = DebuggerServer.createListener();
ok(listener, "Socket listener created");
listener.portOrPath = -1 /* any available port */;
listener.encryption = true /* required for OOB_CERT */;
listener.authenticator = serverAuth;
yield listener.open();
equal(DebuggerServer.listeningSockets, 1, "1 listening socket");
let clientAuth = new AuthenticatorType.Client();
clientAuth.sendOOB = ({ oob }) => {
do_print(oob);
// Pass to server, skipping prompt for tests
oobData.resolve(oob);
};
let transport = yield DebuggerClient.socketConnect({
host: "127.0.0.1",
port: listener.port,
encryption: true,
authenticator: clientAuth,
cert: {
sha256: serverCert.sha256Fingerprint
}
});
ok(transport, "Client transport created");
let client = new DebuggerClient(transport);
let onUnexpectedClose = () => {
do_throw("Closed unexpectedly");
};
client.addListener("closed", onUnexpectedClose);
yield connectClient(client);
// Send a message the server will echo back
let message = "secrets";
let reply = yield client.request({
to: "root",
type: "echo",
message
});
equal(reply.message, message, "Encrypted echo matches");
client.removeListener("closed", onUnexpectedClose);
transport.close();
listener.close();
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
});
// Client w/o OOB_CERT auth fails to connect to server w/ OOB_CERT auth
add_task(function*() {
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
let oobData = promise.defer();
let AuthenticatorType = DebuggerServer.Authenticators.get("OOB_CERT");
let serverAuth = new AuthenticatorType.Server();
serverAuth.allowConnection = () => {
return DebuggerServer.AuthenticationResult.ALLOW;
};
serverAuth.receiveOOB = () => oobData.promise; // Skip prompt for tests
let listener = DebuggerServer.createListener();
ok(listener, "Socket listener created");
listener.portOrPath = -1 /* any available port */;
listener.encryption = true /* required for OOB_CERT */;
listener.authenticator = serverAuth;
yield listener.open();
equal(DebuggerServer.listeningSockets, 1, "1 listening socket");
// This will succeed, but leaves the client in confused state, and no data is
// actually accessible
let transport = yield DebuggerClient.socketConnect({
host: "127.0.0.1",
port: listener.port,
encryption: true
// authenticator: PROMPT is the default
});
// Attempt to use the transport
let deferred = promise.defer();
let client = new DebuggerClient(transport);
client.onPacket = packet => {
// Client did not authenticate, so it ends up seeing the server's auth data
// which is effectively malformed data from the client's perspective
ok(!packet.from && packet.authResult, "Got auth packet instead of data");
deferred.resolve();
};
client.connect();
yield deferred.promise;
// Try to send a message the server will echo back
let message = "secrets";
try {
yield client.request({
to: "root",
type: "echo",
message
});
} catch(e) {
ok(true, "Sending a message failed");
transport.close();
listener.close();
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
return;
}
do_throw("Connection unexpectedly succeeded");
});
// Client w/ invalid K value fails to connect
add_task(function*() {
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
// Grab our cert, instead of relying on a discovery advertisement
let serverCert = yield cert.local.getOrCreate();
let oobData = promise.defer();
let AuthenticatorType = DebuggerServer.Authenticators.get("OOB_CERT");
let serverAuth = new AuthenticatorType.Server();
serverAuth.allowConnection = () => {
return DebuggerServer.AuthenticationResult.ALLOW;
};
serverAuth.receiveOOB = () => oobData.promise; // Skip prompt for tests
let clientAuth = new AuthenticatorType.Client();
clientAuth.sendOOB = ({ oob }) => {
do_print(oob);
do_print("Modifying K value, should fail");
// Pass to server, skipping prompt for tests
oobData.resolve({
k: oob.k + 1,
sha256: oob.sha256
});
};
let listener = DebuggerServer.createListener();
ok(listener, "Socket listener created");
listener.portOrPath = -1 /* any available port */;
listener.encryption = true /* required for OOB_CERT */;
listener.authenticator = serverAuth;
yield listener.open();
equal(DebuggerServer.listeningSockets, 1, "1 listening socket");
try {
yield DebuggerClient.socketConnect({
host: "127.0.0.1",
port: listener.port,
encryption: true,
authenticator: clientAuth,
cert: {
sha256: serverCert.sha256Fingerprint
}
});
} catch(e) {
ok(true, "Client failed to connect as expected");
listener.close();
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
return;
}
do_throw("Connection unexpectedly succeeded");
});
// Client w/ invalid cert hash fails to connect
add_task(function*() {
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
// Grab our cert, instead of relying on a discovery advertisement
let serverCert = yield cert.local.getOrCreate();
let oobData = promise.defer();
let AuthenticatorType = DebuggerServer.Authenticators.get("OOB_CERT");
let serverAuth = new AuthenticatorType.Server();
serverAuth.allowConnection = () => {
return DebuggerServer.AuthenticationResult.ALLOW;
};
serverAuth.receiveOOB = () => oobData.promise; // Skip prompt for tests
let clientAuth = new AuthenticatorType.Client();
clientAuth.sendOOB = ({ oob }) => {
do_print(oob);
do_print("Modifying cert hash, should fail");
// Pass to server, skipping prompt for tests
oobData.resolve({
k: oob.k,
sha256: oob.sha256 + 1
});
};
let listener = DebuggerServer.createListener();
ok(listener, "Socket listener created");
listener.portOrPath = -1 /* any available port */;
listener.encryption = true /* required for OOB_CERT */;
listener.authenticator = serverAuth;
yield listener.open();
equal(DebuggerServer.listeningSockets, 1, "1 listening socket");
try {
yield DebuggerClient.socketConnect({
host: "127.0.0.1",
port: listener.port,
encryption: true,
authenticator: clientAuth,
cert: {
sha256: serverCert.sha256Fingerprint
}
});
} catch(e) {
ok(true, "Client failed to connect as expected");
listener.close();
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
return;
}
do_throw("Connection unexpectedly succeeded");
});
add_task(function*() {
DebuggerServer.destroy();
});