tor-browser

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

util.js (2888B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 var util = {
      6  // Compare the contents of two ArrayBuffer(View)s
      7  memcmp: function util_memcmp(x, y) {
      8    if (!x || !y) {
      9      return false;
     10    }
     11 
     12    var xb = new Uint8Array(x);
     13    var yb = new Uint8Array(y);
     14    if (x.byteLength !== y.byteLength) {
     15      return false;
     16    }
     17 
     18    for (var i = 0; i < xb.byteLength; ++i) {
     19      if (xb[i] !== yb[i]) {
     20        return false;
     21      }
     22    }
     23    return true;
     24  },
     25 
     26  // Convert an ArrayBufferView to a hex string
     27  abv2hex: function util_abv2hex(abv) {
     28    var b = new Uint8Array(abv);
     29    var hex = "";
     30    for (var i = 0; i < b.length; ++i) {
     31      var zeropad = b[i] < 0x10 ? "0" : "";
     32      hex += zeropad + b[i].toString(16);
     33    }
     34    return hex;
     35  },
     36 
     37  // Convert a hex string to an ArrayBufferView
     38  hex2abv: function util_hex2abv(hex) {
     39    if (hex.length % 2 !== 0) {
     40      hex = "0" + hex;
     41    }
     42 
     43    var abv = new Uint8Array(hex.length / 2);
     44    for (var i = 0; i < abv.length; ++i) {
     45      abv[i] = parseInt(hex.substr(2 * i, 2), 16);
     46    }
     47    return abv;
     48  },
     49 
     50  clone(obj) {
     51    return new Promise(resolve => {
     52      let { port1, port2 } = new MessageChannel();
     53 
     54      // Wait for the cloned object to arrive.
     55      port1.onmessage = msg => resolve(msg.data);
     56 
     57      // Clone the object.
     58      port2.postMessage(obj);
     59    });
     60  },
     61 
     62  cloneExportCompareKeys(key) {
     63    return util.clone(key).then(clone => {
     64      var exports = [];
     65 
     66      if (key instanceof CryptoKey) {
     67        exports.push(crypto.subtle.exportKey("raw", key));
     68        exports.push(crypto.subtle.exportKey("raw", clone));
     69      } else {
     70        exports.push(crypto.subtle.exportKey("spki", key.publicKey));
     71        exports.push(crypto.subtle.exportKey("spki", clone.publicKey));
     72        exports.push(crypto.subtle.exportKey("pkcs8", key.privateKey));
     73        exports.push(crypto.subtle.exportKey("pkcs8", clone.privateKey));
     74      }
     75 
     76      return Promise.all(exports).then(pairs => {
     77        for (var i = 0; i < pairs.length; i += 2) {
     78          if (!util.memcmp(pairs[i], pairs[i + 1])) {
     79            throw new Error("keys don't match");
     80          }
     81        }
     82 
     83        return clone;
     84      });
     85    });
     86  },
     87 };
     88 
     89 function exists(x) {
     90  return x !== undefined;
     91 }
     92 
     93 function hasFields(object, fields) {
     94  return fields.map(x => exists(object[x])).reduce((x, y) => x && y);
     95 }
     96 
     97 function hasKeyFields(x) {
     98  return hasFields(x, ["algorithm", "extractable", "type", "usages"]);
     99 }
    100 
    101 function hasBaseJwkFields(x) {
    102  return hasFields(x, ["kty", "alg", "ext", "key_ops"]);
    103 }
    104 
    105 function shallowArrayEquals(x, y) {
    106  if (x.length != y.length) {
    107    return false;
    108  }
    109 
    110  for (let i in x) {
    111    if (x[i] != y[i]) {
    112      return false;
    113    }
    114  }
    115 
    116  return true;
    117 }