tor-browser

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

test_cert_storage_direct.js (10786B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 "use strict";
      6 
      7 // This file consists of unit tests for cert_storage (whereas test_cert_storage.js is more of an
      8 // integration test).
      9 
     10 do_get_profile();
     11 
     12 this.certStorage = Cc["@mozilla.org/security/certstorage;1"].getService(
     13  Ci.nsICertStorage
     14 );
     15 
     16 async function addCerts(certInfos) {
     17  let result = await new Promise(resolve => {
     18    certStorage.addCerts(certInfos, resolve);
     19  });
     20  Assert.equal(result, Cr.NS_OK, "addCerts should succeed");
     21 }
     22 
     23 async function removeCertsByHashes(hashesBase64) {
     24  let result = await new Promise(resolve => {
     25    certStorage.removeCertsByHashes(hashesBase64, resolve);
     26  });
     27  Assert.equal(result, Cr.NS_OK, "removeCertsByHashes should succeed");
     28 }
     29 
     30 function getLongString(uniquePart, length) {
     31  return String(uniquePart).padStart(length, "0");
     32 }
     33 
     34 class CertInfo {
     35  constructor(cert, subject) {
     36    this.cert = btoa(cert);
     37    this.subject = btoa(subject);
     38    this.trust = Ci.nsICertStorage.TRUST_INHERIT;
     39  }
     40 }
     41 CertInfo.prototype.QueryInterface = ChromeUtils.generateQI(["nsICertInfo"]);
     42 
     43 add_task(async function test_common_subject() {
     44  let someCert1 = new CertInfo(
     45    "some certificate bytes 1",
     46    "some common subject"
     47  );
     48  let someCert2 = new CertInfo(
     49    "some certificate bytes 2",
     50    "some common subject"
     51  );
     52  let someCert3 = new CertInfo(
     53    "some certificate bytes 3",
     54    "some common subject"
     55  );
     56  await addCerts([someCert1, someCert2, someCert3]);
     57  let storedCerts = certStorage.findCertsBySubject(
     58    stringToArray("some common subject")
     59  );
     60  let storedCertsAsStrings = storedCerts.map(arrayToString);
     61  let expectedCerts = [
     62    "some certificate bytes 1",
     63    "some certificate bytes 2",
     64    "some certificate bytes 3",
     65  ];
     66  Assert.deepEqual(
     67    storedCertsAsStrings.sort(),
     68    expectedCerts.sort(),
     69    "should find expected certs"
     70  );
     71 
     72  await addCerts([
     73    new CertInfo("some other certificate bytes", "some other subject"),
     74  ]);
     75  storedCerts = certStorage.findCertsBySubject(
     76    stringToArray("some common subject")
     77  );
     78  storedCertsAsStrings = storedCerts.map(arrayToString);
     79  Assert.deepEqual(
     80    storedCertsAsStrings.sort(),
     81    expectedCerts.sort(),
     82    "should still find expected certs"
     83  );
     84 
     85  let storedOtherCerts = certStorage.findCertsBySubject(
     86    stringToArray("some other subject")
     87  );
     88  let storedOtherCertsAsStrings = storedOtherCerts.map(arrayToString);
     89  let expectedOtherCerts = ["some other certificate bytes"];
     90  Assert.deepEqual(
     91    storedOtherCertsAsStrings,
     92    expectedOtherCerts,
     93    "should have other certificate"
     94  );
     95 });
     96 
     97 add_task(async function test_many_entries() {
     98  const NUM_CERTS = 500;
     99  const CERT_LENGTH = 3000;
    100  const SUBJECT_LENGTH = 40;
    101  let certs = [];
    102  for (let i = 0; i < NUM_CERTS; i++) {
    103    certs.push(
    104      new CertInfo(
    105        getLongString(i, CERT_LENGTH),
    106        getLongString(i, SUBJECT_LENGTH)
    107      )
    108    );
    109  }
    110  await addCerts(certs);
    111  for (let i = 0; i < NUM_CERTS; i++) {
    112    let subject = stringToArray(getLongString(i, SUBJECT_LENGTH));
    113    let storedCerts = certStorage.findCertsBySubject(subject);
    114    Assert.equal(
    115      storedCerts.length,
    116      1,
    117      "should have 1 certificate (lots of data test)"
    118    );
    119    let storedCertAsString = arrayToString(storedCerts[0]);
    120    Assert.equal(
    121      storedCertAsString,
    122      getLongString(i, CERT_LENGTH),
    123      "certificate should be as expected (lots of data test)"
    124    );
    125  }
    126 });
    127 
    128 add_task(async function test_removal() {
    129  // As long as cert_storage is given valid base64, attempting to delete some nonexistent
    130  // certificate will "succeed" (it'll do nothing).
    131  await removeCertsByHashes([btoa("thishashisthewrongsize")]);
    132 
    133  let removalCert1 = new CertInfo(
    134    "removal certificate bytes 1",
    135    "common subject to remove"
    136  );
    137  let removalCert2 = new CertInfo(
    138    "removal certificate bytes 2",
    139    "common subject to remove"
    140  );
    141  let removalCert3 = new CertInfo(
    142    "removal certificate bytes 3",
    143    "common subject to remove"
    144  );
    145  await addCerts([removalCert1, removalCert2, removalCert3]);
    146 
    147  let storedCerts = certStorage.findCertsBySubject(
    148    stringToArray("common subject to remove")
    149  );
    150  let storedCertsAsStrings = storedCerts.map(arrayToString);
    151  let expectedCerts = [
    152    "removal certificate bytes 1",
    153    "removal certificate bytes 2",
    154    "removal certificate bytes 3",
    155  ];
    156  Assert.deepEqual(
    157    storedCertsAsStrings.sort(),
    158    expectedCerts.sort(),
    159    "should find expected certs before removing them"
    160  );
    161 
    162  // echo -n "removal certificate bytes 2" | sha256sum | xxd -r -p | base64
    163  await removeCertsByHashes(["2nUPHwl5TVr1mAD1FU9FivLTlTb0BAdnVUhsYgBccN4="]);
    164  storedCerts = certStorage.findCertsBySubject(
    165    stringToArray("common subject to remove")
    166  );
    167  storedCertsAsStrings = storedCerts.map(arrayToString);
    168  expectedCerts = [
    169    "removal certificate bytes 1",
    170    "removal certificate bytes 3",
    171  ];
    172  Assert.deepEqual(
    173    storedCertsAsStrings.sort(),
    174    expectedCerts.sort(),
    175    "should only have first and third certificates now"
    176  );
    177 
    178  // echo -n "removal certificate bytes 1" | sha256sum | xxd -r -p | base64
    179  await removeCertsByHashes(["8zoRqHYrklr7Zx6UWpzrPuL+ol8KL1Ml6XHBQmXiaTY="]);
    180  storedCerts = certStorage.findCertsBySubject(
    181    stringToArray("common subject to remove")
    182  );
    183  storedCertsAsStrings = storedCerts.map(arrayToString);
    184  expectedCerts = ["removal certificate bytes 3"];
    185  Assert.deepEqual(
    186    storedCertsAsStrings.sort(),
    187    expectedCerts.sort(),
    188    "should only have third certificate now"
    189  );
    190 
    191  // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64
    192  await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]);
    193  storedCerts = certStorage.findCertsBySubject(
    194    stringToArray("common subject to remove")
    195  );
    196  Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now");
    197 
    198  // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64
    199  // Again, removing a nonexistent certificate should "succeed".
    200  await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]);
    201 });
    202 
    203 function base64ToArray(base64String) {
    204  let binaryString = atob(base64String);
    205  return stringToArray(binaryString);
    206 }
    207 
    208 add_task(async function test_lookup_by_hash_succeed() {
    209  let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1");
    210  let someCert2 = new CertInfo(
    211    "some certificate bytes 2",
    212    "some common subject 2"
    213  );
    214  let someCert3 = new CertInfo(
    215    "some certificate bytes 3",
    216    "some common subject 3"
    217  );
    218  await addCerts([someCert1, someCert2, someCert3]);
    219  // echo -n "some certificate bytes 2" | sha256sum | xxd -r -p | base64
    220  let foundCert = certStorage.findCertByHash(
    221    base64ToArray("j1vIqpiU0HMmx3zPNujlfGs/pY1vFBJCKpJEeVseeW0=")
    222  );
    223 
    224  Assert.deepEqual(
    225    arrayToString(foundCert),
    226    atob(someCert2.cert),
    227    "should find expected cert"
    228  );
    229 });
    230 
    231 add_task(async function test_lookup_by_hash_fail() {
    232  let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1");
    233  let someCert2 = new CertInfo(
    234    "some certificate bytes 2",
    235    "some common subject 2"
    236  );
    237  let someCert3 = new CertInfo(
    238    "some certificate bytes 3",
    239    "some common subject 3"
    240  );
    241  await addCerts([someCert1, someCert2, someCert3]);
    242  Assert.throws(
    243    () =>
    244      certStorage.findCertByHash(
    245        base64ToArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=")
    246      ),
    247    /NS_ERROR_FAILURE/
    248  );
    249 });
    250 
    251 add_task(async function test_lookup_by_hashes_succeed() {
    252  let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1");
    253  let someCert2 = new CertInfo(
    254    "some certificate bytes 2",
    255    "some common subject 2"
    256  );
    257  let someCert3 = new CertInfo(
    258    "some certificate bytes 3",
    259    "some common subject 3"
    260  );
    261  await addCerts([someCert1, someCert2, someCert3]);
    262  // echo -n "some certificate bytes 2" | sha256sum | xxd -r -p | base64
    263  // echo -n "some certificate bytes 1" | sha256sum | xxd -r -p | base64
    264  let foundCerts = certStorage.hasAllCertsByHash([
    265    base64ToArray("j1vIqpiU0HMmx3zPNujlfGs/pY1vFBJCKpJEeVseeW0="),
    266    base64ToArray("c0iy21PfFlGAqqLnQYeSYYUoaF/JEc41lICBdZ7VFtk="),
    267  ]);
    268  Assert.equal(foundCerts, true);
    269 });
    270 
    271 add_task(async function test_lookup_by_hashes_fail() {
    272  let someCert1 = new CertInfo("some certificate bytes 1", "common subject 1");
    273  let someCert2 = new CertInfo(
    274    "some certificate bytes 2",
    275    "some common subject 2"
    276  );
    277  let someCert3 = new CertInfo(
    278    "some certificate bytes 3",
    279    "some common subject 3"
    280  );
    281  await addCerts([someCert1, someCert2, someCert3]);
    282  // echo -n "some certificate bytes 2" | sha256sum | xxd -r -p | base64
    283  // echo -n "some certificate bytes 1" | sha256sum | xxd -r -p | base64
    284  let foundCerts = certStorage.hasAllCertsByHash([
    285    base64ToArray("j1vIqpiU0HMmx3zPNujlfGs/pY1vFBJCKpJEeVseeW0="),
    286    base64ToArray("c0iy21PfFlGAqqLnQYeSYYUoaF/JEc41lICBdZ7VFtk="),
    287    base64ToArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa="),
    288  ]);
    289  Assert.equal(foundCerts, false);
    290 });
    291 
    292 add_task(async function test_batched_removal() {
    293  let removalCert1 = new CertInfo(
    294    "batch removal certificate bytes 1",
    295    "batch subject to remove"
    296  );
    297  let removalCert2 = new CertInfo(
    298    "batch removal certificate bytes 2",
    299    "batch subject to remove"
    300  );
    301  let removalCert3 = new CertInfo(
    302    "batch removal certificate bytes 3",
    303    "batch subject to remove"
    304  );
    305  await addCerts([removalCert1, removalCert2, removalCert3]);
    306  let storedCerts = certStorage.findCertsBySubject(
    307    stringToArray("batch subject to remove")
    308  );
    309  let storedCertsAsStrings = storedCerts.map(arrayToString);
    310  let expectedCerts = [
    311    "batch removal certificate bytes 1",
    312    "batch removal certificate bytes 2",
    313    "batch removal certificate bytes 3",
    314  ];
    315  Assert.deepEqual(
    316    storedCertsAsStrings.sort(),
    317    expectedCerts.sort(),
    318    "should find expected certs before removing them"
    319  );
    320  // echo -n "batch removal certificate bytes 1" | sha256sum | xxd -r -p | base64
    321  // echo -n "batch removal certificate bytes 2" | sha256sum | xxd -r -p | base64
    322  // echo -n "batch removal certificate bytes 3" | sha256sum | xxd -r -p | base64
    323  await removeCertsByHashes([
    324    "EOEEUTuanHZX9NFVCoMKVT22puIJC6g+ZuNPpJgvaa8=",
    325    "Xz6h/Kvn35cCLJEZXkjPqk1GG36b56sreLyAXpO+0zg=",
    326    "Jr7XdiTT8ZONUL+ogNNMW2oxKxanvYOLQPKBPgH/has=",
    327  ]);
    328  storedCerts = certStorage.findCertsBySubject(
    329    stringToArray("batch subject to remove")
    330  );
    331  Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now");
    332 });