diff options
Diffstat (limited to 'security/manager/ssl/tests/unit/test_toolkit_securityreporter.js')
-rw-r--r-- | security/manager/ssl/tests/unit/test_toolkit_securityreporter.js | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/unit/test_toolkit_securityreporter.js b/security/manager/ssl/tests/unit/test_toolkit_securityreporter.js new file mode 100644 index 000000000..d7ffd17bd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_toolkit_securityreporter.js @@ -0,0 +1,133 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* This test is for the TLS error reporting functionality exposed by + * SecurityReporter.js in /toolkit/components/securityreporter. The test is + * here because we make use of the tlsserver functionality that lives with the + * PSM ssl tests. + * + * The testing here will be augmented by the existing mochitests for the + * error reporting functionality in aboutNetError.xhtml and + * aboutCertError.xhtml once these make use of this component. + */ + +"use strict"; +const CC = Components.Constructor; +const Cm = Components.manager; + +Cu.import("resource://testing-common/AppInfo.jsm"); +/*global updateAppInfo:false*/ // Imported via AppInfo.jsm. +updateAppInfo(); + +// We must get the profile before performing operations on the cert db. +do_get_profile(); + +const certdb = Cc["@mozilla.org/security/x509certdb;1"] + .getService(Ci.nsIX509CertDB); +const reporter = Cc["@mozilla.org/securityreporter;1"] + .getService(Ci.nsISecurityReporter); + + +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", "setInputStream"); + +var server; + +// this allows us to create a callback which checks that a report is as +// expected. +function getReportCheck(expectReport, expectedError) { + return function sendReportWithInfo(transportSecurityInfo) { + // register a path handler on the server + server.registerPathHandler("/submit/sslreports", + function(request, response) { + if (expectReport) { + let report = JSON.parse(readDataFromRequest(request)); + do_check_eq(report.errorCode, expectedError); + response.setStatusLine(null, 201, "Created"); + response.write("Created"); + } else { + do_throw("No report should have been received"); + } + }); + + reporter.reportTLSError(transportSecurityInfo, "example.com", -1); + }; +} + +// read the request body from a request +function readDataFromRequest(aRequest) { + if (aRequest.method == "POST" || aRequest.method == "PUT") { + if (aRequest.bodyInputStream) { + let inputStream = new BinaryInputStream(aRequest.bodyInputStream); + let bytes = []; + let available; + + while ((available = inputStream.available()) > 0) { + Array.prototype.push.apply(bytes, inputStream.readByteArray(available)); + } + + return String.fromCharCode.apply(null, bytes); + } + } + return null; +} + +function run_test() { + // start a report server + server = new HttpServer(); + server.start(-1); + + let port = server.identity.primaryPort; + + // Set the reporting URL to ensure any reports are sent to the test server + Services.prefs.setCharPref("security.ssl.errorReporting.url", + `http://localhost:${port}/submit/sslreports`); + // set strict-mode pinning enforcement so we can cause connection failures. + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2); + + // start a TLS server + add_tls_server_setup("BadCertServer", "bad_certs"); + + // Add a user-specified trust anchor. + addCertFromFile(certdb, "bad_certs/other-test-ca.pem", "CTu,u,u"); + + + // Cause a reportable condition with error reporting disabled. No report + // should be sent. + Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", false); + add_connection_test("expired.example.com", + SEC_ERROR_EXPIRED_CERTIFICATE, null, + getReportCheck(false)); + + // Now enable reporting + add_test(function () { + Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", true); + run_next_test(); + }); + + // test calling the component with no transportSecurityInfo. No report should + // be sent even though reporting is enabled. + add_test(function() { + server.registerPathHandler("/submit/sslreports", + function(request, response) { + do_throw("No report should be sent"); + }); + reporter.reportTLSError(null, "example.com", -1); + run_next_test(); + }); + + // Test sending a report with no error. This allows us to check the case + // where there is no failed cert chain + add_connection_test("good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess, null, + getReportCheck(true, PRErrorCodeSuccess)); + + // Test sending a report where there is an error and a failed cert chain. + add_connection_test("expired.example.com", + SEC_ERROR_EXPIRED_CERTIFICATE, null, + getReportCheck(true, SEC_ERROR_EXPIRED_CERTIFICATE)); + + run_next_test(); +} |