2008-02-27 00:51:02 -08:00
|
|
|
var gClientKeyRaw="TESTCLIENTKEY";
|
|
|
|
// no btoa() available in xpcshell, precalculated for TESTCLIENTKEY.
|
|
|
|
var gClientKey = "VEVTVENMSUVOVEtFWQ==";
|
|
|
|
|
|
|
|
function MAC(content, clientKey)
|
|
|
|
{
|
|
|
|
var hmac = Cc["@mozilla.org/security/hmac;1"].createInstance(Ci.nsICryptoHMAC);
|
|
|
|
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
|
|
|
createInstance(Ci.nsIScriptableUnicodeConverter);
|
|
|
|
converter.charset = "UTF-8";
|
|
|
|
|
2008-03-18 12:45:40 -07:00
|
|
|
var keyObject = Cc["@mozilla.org/security/keyobjectfactory;1"]
|
|
|
|
.getService(Ci.nsIKeyObjectFactory).keyFromString(Ci.nsIKeyObject.HMAC, clientKey);
|
|
|
|
hmac.init(Ci.nsICryptoHMAC.SHA1, keyObject);
|
|
|
|
|
2009-11-12 02:07:00 -08:00
|
|
|
var data = converter.convertToByteArray(content);
|
2008-02-27 00:51:02 -08:00
|
|
|
hmac.update(data, data.length);
|
|
|
|
return hmac.finish(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function doTest(updates, assertions, expectError, clientKey)
|
2008-01-12 14:22:03 -08:00
|
|
|
{
|
|
|
|
if (expectError) {
|
2008-02-27 00:51:02 -08:00
|
|
|
doUpdateTest(updates, assertions, updateError, runNextTest, clientKey);
|
2008-01-12 14:22:03 -08:00
|
|
|
} else {
|
2008-02-27 00:51:02 -08:00
|
|
|
doUpdateTest(updates, assertions, runNextTest, updateError, clientKey);
|
2008-01-12 14:22:03 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function testSimpleForward() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
var add2Urls = [ "foo.com/b" ];
|
|
|
|
var add3Urls = [ "bar.com/d" ];
|
|
|
|
|
|
|
|
var update = "n:1000\n";
|
2008-01-29 12:57:18 -08:00
|
|
|
update += "i:test-phish-simple\n";
|
2008-01-12 14:22:03 -08:00
|
|
|
|
2008-01-29 12:57:18 -08:00
|
|
|
var update1 = buildBareUpdate(
|
2008-01-12 14:22:03 -08:00
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update1) + "\n";
|
|
|
|
|
2008-01-29 12:57:18 -08:00
|
|
|
var update2 = buildBareUpdate(
|
2008-01-12 14:22:03 -08:00
|
|
|
[{ "chunkNum" : 2,
|
|
|
|
"urls" : add2Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update2) + "\n";
|
|
|
|
|
2008-01-29 12:57:18 -08:00
|
|
|
var update3 = buildBareUpdate(
|
2008-01-12 14:22:03 -08:00
|
|
|
[{ "chunkNum" : 3,
|
|
|
|
"urls" : add3Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update3) + "\n";
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "test-phish-simple;a:1-3",
|
|
|
|
"urlsExist" : add1Urls.concat(add2Urls).concat(add3Urls)
|
|
|
|
};
|
|
|
|
|
|
|
|
doTest([update], assertions, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure that a nested forward (a forward within a forward) causes
|
|
|
|
// the update to fail.
|
|
|
|
function testNestedForward() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
var add2Urls = [ "foo.com/b" ];
|
|
|
|
|
|
|
|
var update = "n:1000\n";
|
2008-01-29 12:57:18 -08:00
|
|
|
update += "i:test-phish-simple\n";
|
2008-01-12 14:22:03 -08:00
|
|
|
|
2008-01-29 12:57:18 -08:00
|
|
|
var update1 = buildBareUpdate(
|
2008-01-12 14:22:03 -08:00
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update1) + "\n";
|
|
|
|
|
2008-01-29 12:57:18 -08:00
|
|
|
var update2 = buildBareUpdate(
|
2008-01-12 14:22:03 -08:00
|
|
|
[{ "chunkNum" : 2 }]);
|
2008-01-29 12:57:18 -08:00
|
|
|
var update3 = buildBareUpdate(
|
2008-01-12 14:22:03 -08:00
|
|
|
[{ "chunkNum" : 3,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
|
|
|
|
update2 += "u:data:," + encodeURIComponent(update3) + "\n";
|
|
|
|
|
|
|
|
update += "u:data:," + encodeURIComponent(update2) + "\n";
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "",
|
|
|
|
"urlsDontExist" : add1Urls.concat(add2Urls)
|
|
|
|
};
|
|
|
|
|
|
|
|
doTest([update], assertions, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// An invalid URL forward causes the update to fail.
|
|
|
|
function testInvalidUrlForward() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
|
|
|
|
var update = buildPhishingUpdate(
|
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:asdf://blah/blah\n"; // invalid URL scheme
|
|
|
|
|
2008-05-06 18:51:11 -07:00
|
|
|
// The first part of the update should have succeeded.
|
|
|
|
|
2008-01-12 14:22:03 -08:00
|
|
|
var assertions = {
|
2008-05-06 18:51:11 -07:00
|
|
|
"tableData" : "test-phish-simple;a:1",
|
|
|
|
"urlsExist" : add1Urls
|
2008-01-12 14:22:03 -08:00
|
|
|
};
|
|
|
|
|
2008-05-06 18:51:11 -07:00
|
|
|
doTest([update], assertions, false);
|
2008-01-12 14:22:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// A failed network request causes the update to fail.
|
|
|
|
function testErrorUrlForward() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
|
|
|
|
var update = buildPhishingUpdate(
|
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:http://test.invalid/asdf/asdf\n"; // invalid URL scheme
|
|
|
|
|
2008-05-06 18:51:11 -07:00
|
|
|
// The first part of the update should have succeeded
|
|
|
|
|
2008-01-12 14:22:03 -08:00
|
|
|
var assertions = {
|
2008-05-06 18:51:11 -07:00
|
|
|
"tableData" : "test-phish-simple;a:1",
|
|
|
|
"urlsExist" : add1Urls
|
2008-01-12 14:22:03 -08:00
|
|
|
};
|
|
|
|
|
2008-05-06 18:51:11 -07:00
|
|
|
doTest([update], assertions, false);
|
2008-01-12 14:22:03 -08:00
|
|
|
}
|
|
|
|
|
2008-01-29 12:57:18 -08:00
|
|
|
function testMultipleTables() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
var add2Urls = [ "foo.com/b" ];
|
|
|
|
var add3Urls = [ "bar.com/d" ];
|
|
|
|
|
|
|
|
var update = "n:1000\n";
|
|
|
|
update += "i:test-phish-simple\n";
|
|
|
|
|
|
|
|
var update1 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update1) + "\n";
|
|
|
|
|
|
|
|
var update2 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 2,
|
|
|
|
"urls" : add2Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update2) + "\n";
|
|
|
|
|
|
|
|
update += "i:test-malware-simple\n";
|
|
|
|
|
|
|
|
var update3 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 3,
|
|
|
|
"urls" : add3Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update3) + "\n";
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "test-malware-simple;a:3\ntest-phish-simple;a:1-2",
|
|
|
|
"urlsExist" : add1Urls.concat(add2Urls),
|
|
|
|
"malwareUrlsExist" : add3Urls
|
|
|
|
};
|
|
|
|
|
|
|
|
doTest([update], assertions, false);
|
|
|
|
}
|
|
|
|
|
2008-02-27 00:51:02 -08:00
|
|
|
// Test a simple update with a valid message authentication code.
|
|
|
|
function testValidMAC() {
|
|
|
|
var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
|
|
|
|
var update = buildPhishingUpdate(
|
|
|
|
[
|
|
|
|
{ "chunkNum" : 1,
|
|
|
|
"urls" : addUrls
|
|
|
|
}]);
|
|
|
|
update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "test-phish-simple;a:1",
|
|
|
|
"urlsExist" : addUrls
|
|
|
|
};
|
|
|
|
|
|
|
|
doTest([update], assertions, false, gClientKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test a simple update with an invalid message authentication code.
|
|
|
|
function testInvalidMAC() {
|
|
|
|
var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
|
|
|
|
var update = buildPhishingUpdate(
|
|
|
|
[
|
|
|
|
{ "chunkNum" : 1,
|
|
|
|
"urls" : addUrls
|
|
|
|
}]);
|
|
|
|
update = "m:INVALIDMAC\n" + update;
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "",
|
|
|
|
"urlsDontExist" : addUrls
|
|
|
|
};
|
|
|
|
|
|
|
|
doTest([update], assertions, true, gClientKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test a simple update without a message authentication code, when it is
|
|
|
|
// expecting one.
|
|
|
|
function testNoMAC() {
|
|
|
|
var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
|
|
|
|
var update = buildPhishingUpdate(
|
|
|
|
[
|
|
|
|
{ "chunkNum" : 1,
|
|
|
|
"urls" : addUrls
|
|
|
|
}]);
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "",
|
|
|
|
"urlsDontExist" : addUrls
|
|
|
|
};
|
|
|
|
|
|
|
|
doTest([update], assertions, true, gClientKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test an update with a valid message authentication code, with forwards.
|
|
|
|
function testValidForwardMAC() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
var add2Urls = [ "foo.com/b" ];
|
|
|
|
var add3Urls = [ "bar.com/d" ];
|
|
|
|
|
|
|
|
var update = "n:1000\n";
|
|
|
|
update += "i:test-phish-simple\n";
|
|
|
|
|
|
|
|
var update1 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update1) +
|
|
|
|
"," + MAC(update1, gClientKeyRaw) + "\n";
|
|
|
|
|
|
|
|
var update2 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 2,
|
|
|
|
"urls" : add2Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update2) +
|
|
|
|
"," + MAC(update2, gClientKeyRaw) + "\n";
|
|
|
|
|
|
|
|
|
|
|
|
var update3 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 3,
|
|
|
|
"urls" : add3Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update3) +
|
|
|
|
"," + MAC(update3, gClientKeyRaw) + "\n";
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "test-phish-simple;a:1-3",
|
|
|
|
"urlsExist" : add1Urls.concat(add2Urls).concat(add3Urls)
|
|
|
|
};
|
|
|
|
|
|
|
|
update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
|
|
|
|
|
|
|
|
doTest([update], assertions, false, gClientKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test an update with a valid message authentication code, but with
|
|
|
|
// invalid MACs on the forwards.
|
|
|
|
function testInvalidForwardMAC() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
var add2Urls = [ "foo.com/b" ];
|
|
|
|
var add3Urls = [ "bar.com/d" ];
|
|
|
|
|
|
|
|
var update = "n:1000\n";
|
|
|
|
update += "i:test-phish-simple\n";
|
|
|
|
|
|
|
|
var update1 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update1) +
|
|
|
|
",BADMAC\n";
|
|
|
|
|
|
|
|
var update2 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 2,
|
|
|
|
"urls" : add2Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update2) +
|
|
|
|
",BADMAC\n";
|
|
|
|
|
|
|
|
|
|
|
|
var update3 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 3,
|
|
|
|
"urls" : add3Urls }]);
|
|
|
|
update += "u:data:," + encodeURIComponent(update3) +
|
|
|
|
",BADMAC\n";
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "",
|
|
|
|
"urlsDontExist" : add1Urls.concat(add2Urls).concat(add3Urls)
|
|
|
|
};
|
|
|
|
|
|
|
|
update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
|
|
|
|
|
|
|
|
doTest([update], assertions, true, gClientKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test an update with a valid message authentication code, but no MAC
|
|
|
|
// specified for sub-urls.
|
|
|
|
function testNoForwardMAC() {
|
|
|
|
var add1Urls = [ "foo.com/a", "bar.com/c" ];
|
|
|
|
var add2Urls = [ "foo.com/b" ];
|
|
|
|
var add3Urls = [ "bar.com/d" ];
|
|
|
|
|
|
|
|
var update = "n:1000\n";
|
|
|
|
update += "i:test-phish-simple\n";
|
|
|
|
|
|
|
|
// XXX : This test presents invalid data: urls as forwards. A valid
|
|
|
|
// data url requires a comma, which the code will interpret as the
|
|
|
|
// separator for a MAC.
|
|
|
|
|
|
|
|
// Unfortunately this means that the update will fail even if the code
|
|
|
|
// isn't properly detecting a missing MAC update. I'm not sure how to
|
|
|
|
// test that :/
|
|
|
|
|
|
|
|
var update1 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 1,
|
|
|
|
"urls" : add1Urls }]);
|
|
|
|
update += "u:data:" + encodeURIComponent(update1) + "\n";
|
|
|
|
|
|
|
|
var update2 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 2,
|
|
|
|
"urls" : add2Urls }]);
|
|
|
|
update += "u:data:" + encodeURIComponent(update2) + "\n";
|
|
|
|
|
|
|
|
var update3 = buildBareUpdate(
|
|
|
|
[{ "chunkNum" : 3,
|
|
|
|
"urls" : add3Urls }]);
|
|
|
|
update += "u:data:" + encodeURIComponent(update3) + "\n";
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "",
|
|
|
|
"urlsDontExist" : add1Urls.concat(add2Urls).concat(add3Urls)
|
|
|
|
};
|
|
|
|
|
|
|
|
update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
|
|
|
|
|
|
|
|
doTest([update], assertions, true, gClientKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
function Observer(callback) {
|
|
|
|
this.observe = callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
Observer.prototype =
|
|
|
|
{
|
|
|
|
QueryInterface: function(iid)
|
|
|
|
{
|
|
|
|
if (!iid.equals(Ci.nsISupports) &&
|
|
|
|
!iid.equals(Ci.nsIObserver)) {
|
|
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var gGotRekey;
|
|
|
|
|
|
|
|
gAssertions.gotRekey = function(data, cb)
|
|
|
|
{
|
|
|
|
do_check_eq(gGotRekey, data);
|
|
|
|
cb();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests a rekey request.
|
|
|
|
function testRekey() {
|
|
|
|
var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
|
|
|
|
var update = buildPhishingUpdate(
|
|
|
|
[
|
|
|
|
{ "chunkNum" : 1,
|
|
|
|
"urls" : addUrls
|
|
|
|
}]);
|
|
|
|
update = "e:pleaserekey\n" + update;
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "",
|
|
|
|
"urlsDontExist" : addUrls,
|
|
|
|
"gotRekey" : true
|
|
|
|
};
|
|
|
|
|
|
|
|
gGotRekey = false;
|
|
|
|
var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
|
|
|
|
|
|
|
observerService.addObserver(new Observer(function(subject, topic, data) {
|
|
|
|
if (topic == "url-classifier-rekey-requested") {
|
|
|
|
gGotRekey = true;
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
"url-classifier-rekey-requested",
|
|
|
|
false);
|
|
|
|
|
|
|
|
doTest([update], assertions, true, gClientKey);
|
|
|
|
}
|
|
|
|
|
2008-02-29 16:46:43 -08:00
|
|
|
// Tests a database reset request.
|
|
|
|
function testReset() {
|
|
|
|
var addUrls1 = [ "foo.com/a", "foo.com/b" ];
|
|
|
|
var update1 = buildPhishingUpdate(
|
|
|
|
[
|
|
|
|
{ "chunkNum" : 1,
|
|
|
|
"urls" : addUrls1
|
|
|
|
}]);
|
|
|
|
|
|
|
|
var update2 = "n:1000\nr:pleasereset\n";
|
|
|
|
|
|
|
|
var addUrls3 = [ "bar.com/a", "bar.com/b" ];
|
|
|
|
var update3 = buildPhishingUpdate(
|
|
|
|
[
|
|
|
|
{ "chunkNum" : 3,
|
|
|
|
"urls" : addUrls3
|
|
|
|
}]);
|
|
|
|
|
|
|
|
var assertions = {
|
|
|
|
"tableData" : "test-phish-simple;a:3",
|
|
|
|
"urlsExist" : addUrls3,
|
|
|
|
"urlsDontExist" : addUrls1
|
|
|
|
};
|
|
|
|
|
|
|
|
doTest([update1, update2, update3], assertions, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-12 14:22:03 -08:00
|
|
|
function run_test()
|
|
|
|
{
|
|
|
|
runTests([
|
|
|
|
testSimpleForward,
|
|
|
|
testNestedForward,
|
|
|
|
testInvalidUrlForward,
|
2008-01-29 12:57:18 -08:00
|
|
|
testErrorUrlForward,
|
2008-02-27 00:51:02 -08:00
|
|
|
testMultipleTables,
|
|
|
|
testValidMAC,
|
|
|
|
testInvalidMAC,
|
|
|
|
testNoMAC,
|
|
|
|
testValidForwardMAC,
|
|
|
|
testInvalidForwardMAC,
|
|
|
|
testNoForwardMAC,
|
|
|
|
testRekey,
|
2008-02-29 16:46:43 -08:00
|
|
|
testReset,
|
2008-01-12 14:22:03 -08:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
do_test_pending();
|