Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / cryptotoken / util.js
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 // Type tags used for ASN.1 encoding of ECDSA signatures
161 /** @const */
162 var UTIL_ASN_INT = 0x02;
163 /** @const */
164 var UTIL_ASN_SEQUENCE = 0x30;
165
166 /**
167  * Parse SEQ(INT, INT) from ASN1 byte array.
168  * @param {(Uint8Array|Array.<number>)} a input to parse from.
169  * @return {{'r': !Array.<number>, 's': !Array.<number>}|null}
170  */
171 function UTIL_Asn1SignatureToJson(a) {
172   if (a.length < 6) return null;  // Too small to be valid
173   if (a[0] != UTIL_ASN_SEQUENCE) return null;
174   var l = a[1] & 255;
175   if (l & 0x80) return null;  // SEQ.size too large
176   if (a.length != 2 + l) return null;  // SEQ size does not match input
177
178   function parseInt(off) {
179     if (a[off] != UTIL_ASN_INT) return null;
180     var l = a[off + 1] & 255;
181     if (l & 0x80) return null;  // INT.size too large
182     if (off + 2 + l > a.length) return null;  // Out of bounds
183     return a.slice(off + 2, off + 2 + l);
184   }
185
186   var r = parseInt(2);
187   if (!r) return null;
188
189   var s = parseInt(2 + 2 + r.length);
190   if (!s) return null;
191
192   return {'r': r, 's': s};
193 }
194
195 /**
196  * Encode a JSON signature {r,s} as an ASN1 SEQ(INT, INT). May modify sig
197  * @param {{'r': (!Array.<number>|undefined), 's': !Array.<number>}} sig
198  * @return {!Uint8Array}
199  */
200 function UTIL_JsonSignatureToAsn1(sig) {
201   var rbytes = sig.r;
202   var sbytes = sig.s;
203
204   // ASN.1 integers are arbitrary length msb first and signed.
205   // sig.r and sig.s are 256 bits msb first but _unsigned_, so we must
206   // prepend a zero byte in case their high bit is set.
207   if (rbytes[0] & 0x80)
208     rbytes.unshift(0);
209   if (sbytes[0] & 0x80)
210     sbytes.unshift(0);
211
212   var len = 4 + rbytes.length + sbytes.length;
213   var buf = new Uint8Array(2 + len);
214   var i = 0;
215   buf[i++] = UTIL_ASN_SEQUENCE;
216   buf[i++] = len;
217
218   buf[i++] = UTIL_ASN_INT;
219   buf[i++] = rbytes.length;
220   buf.set(rbytes, i);
221   i += rbytes.length;
222
223   buf[i++] = UTIL_ASN_INT;
224   buf[i++] = sbytes.length;
225   buf.set(sbytes, i);
226
227   return buf;
228 }
229
230 // hr:min:sec.milli string
231 function UTIL_time() {
232   var d = new Date();
233   var m = '000' + d.getMilliseconds();
234   var s = d.toTimeString().substring(0, 8) + '.' + m.substring(m.length - 3);
235   return s;
236 }
237 var UTIL_events = [];
238 var UTIL_max_events = 500;
239
240 function UTIL_fmt(s) {
241   var line = UTIL_time() + ' ' + s;
242   if (UTIL_events.push(line) > UTIL_max_events) {
243     // Drop from head.
244     UTIL_events.splice(0, UTIL_events.length - UTIL_max_events);
245   }
246   return line;
247 }