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 }