Home | History | Annotate | Download | only in cryptotoken
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /** @fileoverview Various string utility functions */
      6 'use strict';
      7 
      8 /**
      9  * Converts a string to an array of bytes.
     10  * @param {string} s The string to convert.
     11  * @param {(Array|Uint8Array)=} bytes The Array-like object into which to store
     12  *     the bytes. A new Array will be created if not provided.
     13  * @return {(Array|Uint8Array)} An array of bytes representing the string.
     14  */
     15 function UTIL_StringToBytes(s, bytes) {
     16   bytes = bytes || new Array(s.length);
     17   for (var i = 0; i < s.length; ++i)
     18     bytes[i] = s.charCodeAt(i);
     19   return bytes;
     20 }
     21 
     22 /**
     23  * Converts a byte array to a string.
     24  * @param {(Uint8Array|Array.<number>)} b input byte array.
     25  * @return {string} result.
     26  */
     27 function UTIL_BytesToString(b) {
     28   return String.fromCharCode.apply(null, b);
     29 }
     30 
     31 /**
     32  * Converts a byte array to a hex string.
     33  * @param {(Uint8Array|Array.<number>)} b input byte array.
     34  * @return {string} result.
     35  */
     36 function UTIL_BytesToHex(b) {
     37   if (!b) return '(null)';
     38   var hexchars = '0123456789ABCDEF';
     39   var hexrep = new Array(b.length * 2);
     40 
     41   for (var i = 0; i < b.length; ++i) {
     42     hexrep[i * 2 + 0] = hexchars.charAt((b[i] >> 4) & 15);
     43     hexrep[i * 2 + 1] = hexchars.charAt(b[i] & 15);
     44   }
     45   return hexrep.join('');
     46 }
     47 
     48 function UTIL_BytesToHexWithSeparator(b, sep) {
     49   var hexchars = '0123456789ABCDEF';
     50   var stride = 2 + (sep ? 1 : 0);
     51   var hexrep = new Array(b.length * stride);
     52 
     53   for (var i = 0; i < b.length; ++i) {
     54     if (sep) hexrep[i * stride + 0] = sep;
     55     hexrep[i * stride + stride - 2] = hexchars.charAt((b[i] >> 4) & 15);
     56     hexrep[i * stride + stride - 1] = hexchars.charAt(b[i] & 15);
     57   }
     58   return (sep ? hexrep.slice(1) : hexrep).join('');
     59 }
     60 
     61 function UTIL_HexToBytes(h) {
     62   var hexchars = '0123456789ABCDEFabcdef';
     63   var res = new Uint8Array(h.length / 2);
     64   for (var i = 0; i < h.length; i += 2) {
     65     if (hexchars.indexOf(h.substring(i, i + 1)) == -1) break;
     66     res[i / 2] = parseInt(h.substring(i, i + 2), 16);
     67   }
     68   return res;
     69 }
     70 
     71 function UTIL_HexToArray(h) {
     72   var hexchars = '0123456789ABCDEFabcdef';
     73   var res = new Array(h.length / 2);
     74   for (var i = 0; i < h.length; i += 2) {
     75     if (hexchars.indexOf(h.substring(i, i + 1)) == -1) break;
     76     res[i / 2] = parseInt(h.substring(i, i + 2), 16);
     77   }
     78   return res;
     79 }
     80 
     81 function UTIL_equalArrays(a, b) {
     82   if (!a || !b) return false;
     83   if (a.length != b.length) return false;
     84   var accu = 0;
     85   for (var i = 0; i < a.length; ++i)
     86     accu |= a[i] ^ b[i];
     87   return accu === 0;
     88 }
     89 
     90 function UTIL_ltArrays(a, b) {
     91   if (a.length < b.length) return true;
     92   if (a.length > b.length) return false;
     93   for (var i = 0; i < a.length; ++i) {
     94     if (a[i] < b[i]) return true;
     95     if (a[i] > b[i]) return false;
     96   }
     97   return false;
     98 }
     99 
    100 function UTIL_gtArrays(a, b) {
    101   return UTIL_ltArrays(b, a);
    102 }
    103 
    104 function UTIL_geArrays(a, b) {
    105   return !UTIL_ltArrays(a, b);
    106 }
    107 
    108 function UTIL_unionArrays(a, b) {
    109   var obj = {};
    110   for (var i = 0; i < a.length; i++) {
    111     obj[a[i]] = a[i];
    112   }
    113   for (var i = 0; i < b.length; i++) {
    114     obj[b[i]] = b[i];
    115   }
    116   var union = [];
    117   for (var k in obj) {
    118     union.push(obj[k]);
    119   }
    120   return union;
    121 }
    122 
    123 function UTIL_getRandom(a) {
    124   var tmp = new Array(a);
    125   var rnd = new Uint8Array(a);
    126   window.crypto.getRandomValues(rnd);  // Yay!
    127   for (var i = 0; i < a; ++i) tmp[i] = rnd[i] & 255;
    128   return tmp;
    129 }
    130 
    131 function UTIL_setFavicon(icon) {
    132   // Construct a new favion link tag
    133   var faviconLink = document.createElement('link');
    134   faviconLink.rel = 'Shortcut Icon';
    135   faviconLink.type = 'image/x-icon';
    136   faviconLink.href = icon;
    137 
    138   // Remove the old favion, if it exists
    139   var head = document.getElementsByTagName('head')[0];
    140   var links = head.getElementsByTagName('link');
    141   for (var i = 0; i < links.length; i++) {
    142     var link = links[i];
    143     if (link.type == faviconLink.type && link.rel == faviconLink.rel) {
    144       head.removeChild(link);
    145     }
    146   }
    147 
    148   // Add in the new one
    149   head.appendChild(faviconLink);
    150 }
    151 
    152 // Erase all entries in array
    153 function UTIL_clear(a) {
    154   if (a instanceof Array) {
    155     for (var i = 0; i < a.length; ++i)
    156       a[i] = 0;
    157   }
    158 }
    159 
    160 /**
    161  * Parse SEQ(INT, INT) from ASN1 byte array.
    162  * @param {(Uint8Array|Array.<number>)} a input to parse from.
    163  * @return {{'r': !Array.<number>, 's': !Array.<number>}|null}
    164  */
    165 function UTIL_Asn1SignatureToJson(a) {
    166   if (a.length < 6) return null;  // Too small to be valid
    167   if (a[0] != 0x30) return null;  // Not SEQ
    168   var l = a[1] & 255;
    169   if (l & 0x80) return null;  // SEQ.size too large
    170   if (a.length != 2 + l) return null;  // SEQ size does not match input
    171 
    172   function parseInt(off) {
    173     if (a[off] != 0x02) return null;  // Not INT
    174     var l = a[off + 1] & 255;
    175     if (l & 0x80) return null;  // INT.size too large
    176     if (off + 2 + l > a.length) return null;  // Out of bounds
    177     return a.slice(off + 2, off + 2 + l);
    178   }
    179 
    180   var r = parseInt(2);
    181   if (!r) return null;
    182 
    183   var s = parseInt(2 + 2 + r.length);
    184   if (!s) return null;
    185 
    186   return {'r': r, 's': s};
    187 }
    188 
    189 // hr:min:sec.milli string
    190 function UTIL_time() {
    191   var d = new Date();
    192   var m = '000' + d.getMilliseconds();
    193   var s = d.toTimeString().substring(0, 8) + '.' + m.substring(m.length - 3);
    194   return s;
    195 }
    196 var UTIL_events = [];
    197 var UTIL_max_events = 500;
    198 
    199 function UTIL_fmt(s) {
    200   var line = UTIL_time() + ' ' + s;
    201   if (UTIL_events.push(line) > UTIL_max_events) {
    202     // Drop from head.
    203     UTIL_events.splice(0, UTIL_events.length - UTIL_max_events);
    204   }
    205   return line;
    206 }
    207