tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_pkcs11_module_client_auth.js (3930B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
      2 // Any copyright is dedicated to the Public Domain.
      3 // http://creativecommons.org/publicdomain/zero/1.0/
      4 "use strict";
      5 
      6 // Tests using a client authentication certificate via a PKCS#11 module.
      7 
      8 // Ensure that the appropriate initialization has happened.
      9 do_get_profile();
     10 
     11 const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
     12  Ci.nsIX509CertDB
     13 );
     14 
     15 var gPrompt = {
     16  QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]),
     17 
     18  // This intentionally does not use arrow function syntax to avoid an issue
     19  // where in the context of the arrow function, |this != gPrompt| due to
     20  // how objects get wrapped when going across xpcom boundaries.
     21  alert(_title, text) {
     22    const EXPECTED_PROMPT_TEXT =
     23      "Please authenticate to the token “Test PKCS11 Tokeñ 2 Label”. How to do so depends on the token (for example, using a fingerprint reader or entering a code with a keypad).";
     24    equal(text, EXPECTED_PROMPT_TEXT, "expecting alert() to be called");
     25  },
     26 
     27  promptPassword() {
     28    ok(false, "not expecting promptPassword() to be called");
     29  },
     30 };
     31 
     32 const gPromptFactory = {
     33  QueryInterface: ChromeUtils.generateQI(["nsIPromptFactory"]),
     34  getPrompt: () => gPrompt,
     35 };
     36 
     37 MockRegistrar.register("@mozilla.org/prompter;1", gPromptFactory);
     38 
     39 // Replace the UI dialog that prompts the user to pick a client certificate.
     40 const gClientAuthDialogService = {
     41  set certificateNameToUse(name) {
     42    this._certificateNameToUse = name;
     43  },
     44 
     45  chooseCertificate(hostname, certArray, loadContext, caNames, callback) {
     46    for (let cert of certArray) {
     47      if (cert.subjectName == this._certificateNameToUse) {
     48        callback.certificateChosen(cert, false);
     49        return;
     50      }
     51    }
     52    callback.certificateChosen(null, false);
     53  },
     54 
     55  QueryInterface: ChromeUtils.generateQI([Ci.nsIClientAuthDialogService]),
     56 };
     57 
     58 MockRegistrar.register(
     59  "@mozilla.org/security/ClientAuthDialogService;1",
     60  gClientAuthDialogService
     61 );
     62 
     63 function run_test() {
     64  let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
     65  libraryFile.append("pkcs11testmodule");
     66  libraryFile.append(ctypes.libraryName("pkcs11testmodule"));
     67  loadPKCS11Module(libraryFile, "PKCS11 Test Module", true);
     68 
     69  Services.prefs.setCharPref(
     70    "network.dns.localDomains",
     71    "requireclientauth.example.com"
     72  );
     73 
     74  add_tls_server_setup("BadCertAndPinningServer", "bad_certs");
     75  add_test(function set_up_rsa_client_certificate() {
     76    gClientAuthDialogService.certificateNameToUse = "CN=client cert rsa";
     77    run_next_test();
     78  });
     79  add_connection_test("requireclientauth.example.com", PRErrorCodeSuccess);
     80  add_test(function set_up_ecdsa_client_certificate() {
     81    gClientAuthDialogService.certificateNameToUse = "CN=client cert ecdsa";
     82    run_next_test();
     83  });
     84  add_connection_test("requireclientauth.example.com", PRErrorCodeSuccess);
     85 
     86  // The test module currently has a slot that uses a protected authentication
     87  // path (i.e., when Firefox wants to authenticate to it, it opens a dialog
     88  // that says "okay, authenticate to your token by using an external keypad or
     89  // something" and waits for that to happen). For some reason, if this
     90  // authentication happens as a result of the socket thread looking for client
     91  // auth certificates, it results in an assertion failure ("Assertion
     92  // failure: mSleep == AWAKE") in profiler_thread_sleep(). This probably has
     93  // something to do with the fact that the socket thread is synchronously
     94  // waiting on the main thread, which is spinning a nested event loop (which
     95  // tends to cause problems like this).
     96  // Since this is an uncommon configuration and since this issue hasn't been
     97  // reproduced outside of this test infrastructure, this works around it for
     98  // the time being by authenticating to all tokens on the main thread so that
     99  // the socket thread doesn't have to.
    100  gCertDB.getCerts();
    101 
    102  run_next_test();
    103 }