1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | (function (global, factory) {
|
7 | if (typeof define === 'function' && define.amd) {
|
8 |
|
9 | define([], function () {
|
10 | return factory(global);
|
11 | });
|
12 | } else if (typeof module === 'object' && module.exports) {
|
13 |
|
14 | module.exports = factory(global);
|
15 | } else {
|
16 | factory(global);
|
17 | }
|
18 | }(typeof self !== 'undefined' ? self : this, function (global) {
|
19 | 'use strict';
|
20 |
|
21 | if ( typeof Promise !== 'function' )
|
22 | throw "Promise support required";
|
23 |
|
24 | var _crypto = global.crypto || global.msCrypto;
|
25 | if ( !_crypto ) return;
|
26 |
|
27 | var _subtle = _crypto.subtle || _crypto.webkitSubtle;
|
28 | if ( !_subtle ) return;
|
29 |
|
30 | var _Crypto = global.Crypto || _crypto.constructor || Object,
|
31 | _SubtleCrypto = global.SubtleCrypto || _subtle.constructor || Object,
|
32 | _CryptoKey = global.CryptoKey || global.Key || Object;
|
33 |
|
34 | var isEdge = global.navigator.userAgent.indexOf('Edge/') > -1;
|
35 | var isIE = !!global.msCrypto && !isEdge;
|
36 | var isWebkit = !_crypto.subtle && !!_crypto.webkitSubtle;
|
37 | if ( !isIE && !isWebkit ) return;
|
38 |
|
39 | function s2a ( s ) {
|
40 | return btoa(s).replace(/\=+$/, '').replace(/\+/g, '-').replace(/\//g, '_');
|
41 | }
|
42 |
|
43 | function a2s ( s ) {
|
44 | s += '===', s = s.slice( 0, -s.length % 4 );
|
45 | return atob( s.replace(/-/g, '+').replace(/_/g, '/') );
|
46 | }
|
47 |
|
48 | function s2b ( s ) {
|
49 | var b = new Uint8Array(s.length);
|
50 | for ( var i = 0; i < s.length; i++ ) b[i] = s.charCodeAt(i);
|
51 | return b;
|
52 | }
|
53 |
|
54 | function b2s ( b ) {
|
55 | if ( b instanceof ArrayBuffer ) b = new Uint8Array(b);
|
56 | return String.fromCharCode.apply( String, b );
|
57 | }
|
58 |
|
59 | function alg ( a ) {
|
60 | var r = { 'name': (a.name || a || '').toUpperCase().replace('V','v') };
|
61 | switch ( r.name ) {
|
62 | case 'SHA-1':
|
63 | case 'SHA-256':
|
64 | case 'SHA-384':
|
65 | case 'SHA-512':
|
66 | break;
|
67 | case 'AES-CBC':
|
68 | case 'AES-GCM':
|
69 | case 'AES-KW':
|
70 | if ( a.length ) r['length'] = a.length;
|
71 | break;
|
72 | case 'HMAC':
|
73 | if ( a.hash ) r['hash'] = alg(a.hash);
|
74 | if ( a.length ) r['length'] = a.length;
|
75 | break;
|
76 | case 'RSAES-PKCS1-v1_5':
|
77 | if ( a.publicExponent ) r['publicExponent'] = new Uint8Array(a.publicExponent);
|
78 | if ( a.modulusLength ) r['modulusLength'] = a.modulusLength;
|
79 | break;
|
80 | case 'RSASSA-PKCS1-v1_5':
|
81 | case 'RSA-OAEP':
|
82 | if ( a.hash ) r['hash'] = alg(a.hash);
|
83 | if ( a.publicExponent ) r['publicExponent'] = new Uint8Array(a.publicExponent);
|
84 | if ( a.modulusLength ) r['modulusLength'] = a.modulusLength;
|
85 | break;
|
86 | default:
|
87 | throw new SyntaxError("Bad algorithm name");
|
88 | }
|
89 | return r;
|
90 | };
|
91 |
|
92 | function jwkAlg ( a ) {
|
93 | return {
|
94 | 'HMAC': {
|
95 | 'SHA-1': 'HS1',
|
96 | 'SHA-256': 'HS256',
|
97 | 'SHA-384': 'HS384',
|
98 | 'SHA-512': 'HS512',
|
99 | },
|
100 | 'RSASSA-PKCS1-v1_5': {
|
101 | 'SHA-1': 'RS1',
|
102 | 'SHA-256': 'RS256',
|
103 | 'SHA-384': 'RS384',
|
104 | 'SHA-512': 'RS512',
|
105 | },
|
106 | 'RSAES-PKCS1-v1_5': {
|
107 | '': 'RSA1_5',
|
108 | },
|
109 | 'RSA-OAEP': {
|
110 | 'SHA-1': 'RSA-OAEP',
|
111 | 'SHA-256': 'RSA-OAEP-256',
|
112 | },
|
113 | 'AES-KW': {
|
114 | '128': 'A128KW',
|
115 | '192': 'A192KW',
|
116 | '256': 'A256KW',
|
117 | },
|
118 | 'AES-GCM': {
|
119 | '128': 'A128GCM',
|
120 | '192': 'A192GCM',
|
121 | '256': 'A256GCM',
|
122 | },
|
123 | 'AES-CBC': {
|
124 | '128': 'A128CBC',
|
125 | '192': 'A192CBC',
|
126 | '256': 'A256CBC',
|
127 | },
|
128 | }[a.name][ ( a.hash || {} ).name || a.length || '' ];
|
129 | }
|
130 |
|
131 | function b2jwk ( k ) {
|
132 | if ( k instanceof ArrayBuffer || k instanceof Uint8Array ) k = JSON.parse( decodeURIComponent( escape( b2s(k) ) ) );
|
133 | var jwk = { 'kty': k.kty, 'alg': k.alg, 'ext': k.ext || k.extractable };
|
134 | switch ( jwk.kty ) {
|
135 | case 'oct':
|
136 | jwk.k = k.k;
|
137 | case 'RSA':
|
138 | [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi', 'oth' ].forEach( function ( x ) { if ( x in k ) jwk[x] = k[x] } );
|
139 | break;
|
140 | default:
|
141 | throw new TypeError("Unsupported key type");
|
142 | }
|
143 | return jwk;
|
144 | }
|
145 |
|
146 | function jwk2b ( k ) {
|
147 | var jwk = b2jwk(k);
|
148 | if ( isIE ) jwk['extractable'] = jwk.ext, delete jwk.ext;
|
149 | return s2b( unescape( encodeURIComponent( JSON.stringify(jwk) ) ) ).buffer;
|
150 | }
|
151 |
|
152 | function pkcs2jwk ( k ) {
|
153 | var info = b2der(k), prv = false;
|
154 | if ( info.length > 2 ) prv = true, info.shift();
|
155 | var jwk = { 'ext': true };
|
156 | switch ( info[0][0] ) {
|
157 | case '1.2.840.113549.1.1.1':
|
158 | var rsaComp = [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ],
|
159 | rsaKey = b2der( info[1] );
|
160 | if ( prv ) rsaKey.shift();
|
161 | for ( var i = 0; i < rsaKey.length; i++ ) {
|
162 | if ( !rsaKey[i][0] ) rsaKey[i] = rsaKey[i].subarray(1);
|
163 | jwk[ rsaComp[i] ] = s2a( b2s( rsaKey[i] ) );
|
164 | }
|
165 | jwk['kty'] = 'RSA';
|
166 | break;
|
167 | default:
|
168 | throw new TypeError("Unsupported key type");
|
169 | }
|
170 | return jwk;
|
171 | }
|
172 |
|
173 | function jwk2pkcs ( k ) {
|
174 | var key, info = [ [ '', null ] ], prv = false;
|
175 | switch ( k.kty ) {
|
176 | case 'RSA':
|
177 | var rsaComp = [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ],
|
178 | rsaKey = [];
|
179 | for ( var i = 0; i < rsaComp.length; i++ ) {
|
180 | if ( !( rsaComp[i] in k ) ) break;
|
181 | var b = rsaKey[i] = s2b( a2s( k[ rsaComp[i] ] ) );
|
182 | if ( b[0] & 0x80 ) rsaKey[i] = new Uint8Array(b.length + 1), rsaKey[i].set( b, 1 );
|
183 | }
|
184 | if ( rsaKey.length > 2 ) prv = true, rsaKey.unshift( new Uint8Array([0]) );
|
185 | info[0][0] = '1.2.840.113549.1.1.1';
|
186 | key = rsaKey;
|
187 | break;
|
188 | default:
|
189 | throw new TypeError("Unsupported key type");
|
190 | }
|
191 | info.push( new Uint8Array( der2b(key) ).buffer );
|
192 | if ( !prv ) info[1] = { 'tag': 0x03, 'value': info[1] };
|
193 | else info.unshift( new Uint8Array([0]) );
|
194 | return new Uint8Array( der2b(info) ).buffer;
|
195 | }
|
196 |
|
197 | var oid2str = { 'KoZIhvcNAQEB': '1.2.840.113549.1.1.1' },
|
198 | str2oid = { '1.2.840.113549.1.1.1': 'KoZIhvcNAQEB' };
|
199 |
|
200 | function b2der ( buf, ctx ) {
|
201 | if ( buf instanceof ArrayBuffer ) buf = new Uint8Array(buf);
|
202 | if ( !ctx ) ctx = { pos: 0, end: buf.length };
|
203 |
|
204 | if ( ctx.end - ctx.pos < 2 || ctx.end > buf.length ) throw new RangeError("Malformed DER");
|
205 |
|
206 | var tag = buf[ctx.pos++],
|
207 | len = buf[ctx.pos++];
|
208 |
|
209 | if ( len >= 0x80 ) {
|
210 | len &= 0x7f;
|
211 | if ( ctx.end - ctx.pos < len ) throw new RangeError("Malformed DER");
|
212 | for ( var xlen = 0; len--; ) xlen <<= 8, xlen |= buf[ctx.pos++];
|
213 | len = xlen;
|
214 | }
|
215 |
|
216 | if ( ctx.end - ctx.pos < len ) throw new RangeError("Malformed DER");
|
217 |
|
218 | var rv;
|
219 |
|
220 | switch ( tag ) {
|
221 | case 0x02:
|
222 | rv = buf.subarray( ctx.pos, ctx.pos += len );
|
223 | break;
|
224 | case 0x03:
|
225 | if ( buf[ctx.pos++] ) throw new Error( "Unsupported bit string" );
|
226 | len--;
|
227 | case 0x04:
|
228 | rv = new Uint8Array( buf.subarray( ctx.pos, ctx.pos += len ) ).buffer;
|
229 | break;
|
230 | case 0x05:
|
231 | rv = null;
|
232 | break;
|
233 | case 0x06:
|
234 | var oid = btoa( b2s( buf.subarray( ctx.pos, ctx.pos += len ) ) );
|
235 | if ( !( oid in oid2str ) ) throw new Error( "Unsupported OBJECT ID " + oid );
|
236 | rv = oid2str[oid];
|
237 | break;
|
238 | case 0x30:
|
239 | rv = [];
|
240 | for ( var end = ctx.pos + len; ctx.pos < end; ) rv.push( b2der( buf, ctx ) );
|
241 | break;
|
242 | default:
|
243 | throw new Error( "Unsupported DER tag 0x" + tag.toString(16) );
|
244 | }
|
245 |
|
246 | return rv;
|
247 | }
|
248 |
|
249 | function der2b ( val, buf ) {
|
250 | if ( !buf ) buf = [];
|
251 |
|
252 | var tag = 0, len = 0,
|
253 | pos = buf.length + 2;
|
254 |
|
255 | buf.push( 0, 0 );
|
256 |
|
257 | if ( val instanceof Uint8Array ) {
|
258 | tag = 0x02, len = val.length;
|
259 | for ( var i = 0; i < len; i++ ) buf.push( val[i] );
|
260 | }
|
261 | else if ( val instanceof ArrayBuffer ) {
|
262 | tag = 0x04, len = val.byteLength, val = new Uint8Array(val);
|
263 | for ( var i = 0; i < len; i++ ) buf.push( val[i] );
|
264 | }
|
265 | else if ( val === null ) {
|
266 | tag = 0x05, len = 0;
|
267 | }
|
268 | else if ( typeof val === 'string' && val in str2oid ) {
|
269 | var oid = s2b( atob( str2oid[val] ) );
|
270 | tag = 0x06, len = oid.length;
|
271 | for ( var i = 0; i < len; i++ ) buf.push( oid[i] );
|
272 | }
|
273 | else if ( val instanceof Array ) {
|
274 | for ( var i = 0; i < val.length; i++ ) der2b( val[i], buf );
|
275 | tag = 0x30, len = buf.length - pos;
|
276 | }
|
277 | else if ( typeof val === 'object' && val.tag === 0x03 && val.value instanceof ArrayBuffer ) {
|
278 | val = new Uint8Array(val.value), tag = 0x03, len = val.byteLength;
|
279 | buf.push(0); for ( var i = 0; i < len; i++ ) buf.push( val[i] );
|
280 | len++;
|
281 | }
|
282 | else {
|
283 | throw new Error( "Unsupported DER value " + val );
|
284 | }
|
285 |
|
286 | if ( len >= 0x80 ) {
|
287 | var xlen = len, len = 4;
|
288 | buf.splice( pos, 0, (xlen >> 24) & 0xff, (xlen >> 16) & 0xff, (xlen >> 8) & 0xff, xlen & 0xff );
|
289 | while ( len > 1 && !(xlen >> 24) ) xlen <<= 8, len--;
|
290 | if ( len < 4 ) buf.splice( pos, 4 - len );
|
291 | len |= 0x80;
|
292 | }
|
293 |
|
294 | buf.splice( pos - 2, 2, tag, len );
|
295 |
|
296 | return buf;
|
297 | }
|
298 |
|
299 | function CryptoKey ( key, alg, ext, use ) {
|
300 | Object.defineProperties( this, {
|
301 | _key: {
|
302 | value: key
|
303 | },
|
304 | type: {
|
305 | value: key.type,
|
306 | enumerable: true,
|
307 | },
|
308 | extractable: {
|
309 | value: (ext === undefined) ? key.extractable : ext,
|
310 | enumerable: true,
|
311 | },
|
312 | algorithm: {
|
313 | value: (alg === undefined) ? key.algorithm : alg,
|
314 | enumerable: true,
|
315 | },
|
316 | usages: {
|
317 | value: (use === undefined) ? key.usages : use,
|
318 | enumerable: true,
|
319 | },
|
320 | });
|
321 | }
|
322 |
|
323 | function isPubKeyUse ( u ) {
|
324 | return u === 'verify' || u === 'encrypt' || u === 'wrapKey';
|
325 | }
|
326 |
|
327 | function isPrvKeyUse ( u ) {
|
328 | return u === 'sign' || u === 'decrypt' || u === 'unwrapKey';
|
329 | }
|
330 |
|
331 | [ 'generateKey', 'importKey', 'unwrapKey' ]
|
332 | .forEach( function ( m ) {
|
333 | var _fn = _subtle[m];
|
334 |
|
335 | _subtle[m] = function ( a, b, c ) {
|
336 | var args = [].slice.call(arguments),
|
337 | ka, kx, ku;
|
338 |
|
339 | switch ( m ) {
|
340 | case 'generateKey':
|
341 | ka = alg(a), kx = b, ku = c;
|
342 | break;
|
343 | case 'importKey':
|
344 | ka = alg(c), kx = args[3], ku = args[4];
|
345 | if ( a === 'jwk' ) {
|
346 | b = b2jwk(b);
|
347 | if ( !b.alg ) b.alg = jwkAlg(ka);
|
348 | if ( !b.key_ops ) b.key_ops = ( b.kty !== 'oct' ) ? ( 'd' in b ) ? ku.filter(isPrvKeyUse) : ku.filter(isPubKeyUse) : ku.slice();
|
349 | args[1] = jwk2b(b);
|
350 | }
|
351 | break;
|
352 | case 'unwrapKey':
|
353 | ka = args[4], kx = args[5], ku = args[6];
|
354 | args[2] = c._key;
|
355 | break;
|
356 | }
|
357 |
|
358 | if ( m === 'generateKey' && ka.name === 'HMAC' && ka.hash ) {
|
359 | ka.length = ka.length || { 'SHA-1': 512, 'SHA-256': 512, 'SHA-384': 1024, 'SHA-512': 1024 }[ka.hash.name];
|
360 | return _subtle.importKey( 'raw', _crypto.getRandomValues( new Uint8Array( (ka.length+7)>>3 ) ), ka, kx, ku );
|
361 | }
|
362 |
|
363 | if ( isWebkit && m === 'generateKey' && ka.name === 'RSASSA-PKCS1-v1_5' && ( !ka.modulusLength || ka.modulusLength >= 2048 ) ) {
|
364 | a = alg(a), a.name = 'RSAES-PKCS1-v1_5', delete a.hash;
|
365 | return _subtle.generateKey( a, true, [ 'encrypt', 'decrypt' ] )
|
366 | .then( function ( k ) {
|
367 | return Promise.all([
|
368 | _subtle.exportKey( 'jwk', k.publicKey ),
|
369 | _subtle.exportKey( 'jwk', k.privateKey ),
|
370 | ]);
|
371 | })
|
372 | .then( function ( keys ) {
|
373 | keys[0].alg = keys[1].alg = jwkAlg(ka);
|
374 | keys[0].key_ops = ku.filter(isPubKeyUse), keys[1].key_ops = ku.filter(isPrvKeyUse);
|
375 | return Promise.all([
|
376 | _subtle.importKey( 'jwk', keys[0], ka, true, keys[0].key_ops ),
|
377 | _subtle.importKey( 'jwk', keys[1], ka, kx, keys[1].key_ops ),
|
378 | ]);
|
379 | })
|
380 | .then( function ( keys ) {
|
381 | return {
|
382 | publicKey: keys[0],
|
383 | privateKey: keys[1],
|
384 | };
|
385 | });
|
386 | }
|
387 |
|
388 | if ( ( isWebkit || ( isIE && ( ka.hash || {} ).name === 'SHA-1' ) )
|
389 | && m === 'importKey' && a === 'jwk' && ka.name === 'HMAC' && b.kty === 'oct' ) {
|
390 | return _subtle.importKey( 'raw', s2b( a2s(b.k) ), c, args[3], args[4] );
|
391 | }
|
392 |
|
393 | if ( isWebkit && m === 'importKey' && ( a === 'spki' || a === 'pkcs8' ) ) {
|
394 | return _subtle.importKey( 'jwk', pkcs2jwk(b), c, args[3], args[4] );
|
395 | }
|
396 |
|
397 | if ( isIE && m === 'unwrapKey' ) {
|
398 | return _subtle.decrypt( args[3], c, b )
|
399 | .then( function ( k ) {
|
400 | return _subtle.importKey( a, k, args[4], args[5], args[6] );
|
401 | });
|
402 | }
|
403 |
|
404 | var op;
|
405 | try {
|
406 | op = _fn.apply( _subtle, args );
|
407 | }
|
408 | catch ( e ) {
|
409 | return Promise.reject(e);
|
410 | }
|
411 |
|
412 | if ( isIE ) {
|
413 | op = new Promise( function ( res, rej ) {
|
414 | op.onabort =
|
415 | op.onerror = function ( e ) { rej(e) };
|
416 | op.oncomplete = function ( r ) { res(r.target.result) };
|
417 | });
|
418 | }
|
419 |
|
420 | op = op.then( function ( k ) {
|
421 | if ( ka.name === 'HMAC' ) {
|
422 | if ( !ka.length ) ka.length = 8 * k.algorithm.length;
|
423 | }
|
424 | if ( ka.name.search('RSA') == 0 ) {
|
425 | if ( !ka.modulusLength ) ka.modulusLength = (k.publicKey || k).algorithm.modulusLength;
|
426 | if ( !ka.publicExponent ) ka.publicExponent = (k.publicKey || k).algorithm.publicExponent;
|
427 | }
|
428 | if ( k.publicKey && k.privateKey ) {
|
429 | k = {
|
430 | publicKey: new CryptoKey( k.publicKey, ka, kx, ku.filter(isPubKeyUse) ),
|
431 | privateKey: new CryptoKey( k.privateKey, ka, kx, ku.filter(isPrvKeyUse) ),
|
432 | };
|
433 | }
|
434 | else {
|
435 | k = new CryptoKey( k, ka, kx, ku );
|
436 | }
|
437 | return k;
|
438 | });
|
439 |
|
440 | return op;
|
441 | }
|
442 | });
|
443 |
|
444 | [ 'exportKey', 'wrapKey' ]
|
445 | .forEach( function ( m ) {
|
446 | var _fn = _subtle[m];
|
447 |
|
448 | _subtle[m] = function ( a, b, c ) {
|
449 | var args = [].slice.call(arguments);
|
450 |
|
451 | switch ( m ) {
|
452 | case 'exportKey':
|
453 | args[1] = b._key;
|
454 | break;
|
455 | case 'wrapKey':
|
456 | args[1] = b._key, args[2] = c._key;
|
457 | break;
|
458 | }
|
459 |
|
460 | if ( ( isWebkit || ( isIE && ( b.algorithm.hash || {} ).name === 'SHA-1' ) )
|
461 | && m === 'exportKey' && a === 'jwk' && b.algorithm.name === 'HMAC' ) {
|
462 | args[0] = 'raw';
|
463 | }
|
464 |
|
465 | if ( isWebkit && m === 'exportKey' && ( a === 'spki' || a === 'pkcs8' ) ) {
|
466 | args[0] = 'jwk';
|
467 | }
|
468 |
|
469 | if ( isIE && m === 'wrapKey' ) {
|
470 | return _subtle.exportKey( a, b )
|
471 | .then( function ( k ) {
|
472 | if ( a === 'jwk' ) k = s2b( unescape( encodeURIComponent( JSON.stringify( b2jwk(k) ) ) ) );
|
473 | return _subtle.encrypt( args[3], c, k );
|
474 | });
|
475 | }
|
476 |
|
477 | var op;
|
478 | try {
|
479 | op = _fn.apply( _subtle, args );
|
480 | }
|
481 | catch ( e ) {
|
482 | return Promise.reject(e);
|
483 | }
|
484 |
|
485 | if ( isIE ) {
|
486 | op = new Promise( function ( res, rej ) {
|
487 | op.onabort =
|
488 | op.onerror = function ( e ) { rej(e) };
|
489 | op.oncomplete = function ( r ) { res(r.target.result) };
|
490 | });
|
491 | }
|
492 |
|
493 | if ( m === 'exportKey' && a === 'jwk' ) {
|
494 | op = op.then( function ( k ) {
|
495 | if ( ( isWebkit || ( isIE && ( b.algorithm.hash || {} ).name === 'SHA-1' ) )
|
496 | && b.algorithm.name === 'HMAC') {
|
497 | return { 'kty': 'oct', 'alg': jwkAlg(b.algorithm), 'key_ops': b.usages.slice(), 'ext': true, 'k': s2a( b2s(k) ) };
|
498 | }
|
499 | k = b2jwk(k);
|
500 | if ( !k.alg ) k['alg'] = jwkAlg(b.algorithm);
|
501 | if ( !k.key_ops ) k['key_ops'] = ( b.type === 'public' ) ? b.usages.filter(isPubKeyUse) : ( b.type === 'private' ) ? b.usages.filter(isPrvKeyUse) : b.usages.slice();
|
502 | return k;
|
503 | });
|
504 | }
|
505 |
|
506 | if ( isWebkit && m === 'exportKey' && ( a === 'spki' || a === 'pkcs8' ) ) {
|
507 | op = op.then( function ( k ) {
|
508 | k = jwk2pkcs( b2jwk(k) );
|
509 | return k;
|
510 | });
|
511 | }
|
512 |
|
513 | return op;
|
514 | }
|
515 | });
|
516 |
|
517 | [ 'encrypt', 'decrypt', 'sign', 'verify' ]
|
518 | .forEach( function ( m ) {
|
519 | var _fn = _subtle[m];
|
520 |
|
521 | _subtle[m] = function ( a, b, c, d ) {
|
522 | if ( isIE && ( !c.byteLength || ( d && !d.byteLength ) ) )
|
523 | throw new Error("Empy input is not allowed");
|
524 |
|
525 | var args = [].slice.call(arguments),
|
526 | ka = alg(a);
|
527 |
|
528 | if ( isIE && m === 'decrypt' && ka.name === 'AES-GCM' ) {
|
529 | var tl = a.tagLength >> 3;
|
530 | args[2] = (c.buffer || c).slice( 0, c.byteLength - tl ),
|
531 | a.tag = (c.buffer || c).slice( c.byteLength - tl );
|
532 | }
|
533 |
|
534 | args[1] = b._key;
|
535 |
|
536 | var op;
|
537 | try {
|
538 | op = _fn.apply( _subtle, args );
|
539 | }
|
540 | catch ( e ) {
|
541 | return Promise.reject(e);
|
542 | }
|
543 |
|
544 | if ( isIE ) {
|
545 | op = new Promise( function ( res, rej ) {
|
546 | op.onabort =
|
547 | op.onerror = function ( e ) {
|
548 | rej(e);
|
549 | };
|
550 |
|
551 | op.oncomplete = function ( r ) {
|
552 | var r = r.target.result;
|
553 |
|
554 | if ( m === 'encrypt' && r instanceof AesGcmEncryptResult ) {
|
555 | var c = r.ciphertext, t = r.tag;
|
556 | r = new Uint8Array( c.byteLength + t.byteLength );
|
557 | r.set( new Uint8Array(c), 0 );
|
558 | r.set( new Uint8Array(t), c.byteLength );
|
559 | r = r.buffer;
|
560 | }
|
561 |
|
562 | res(r);
|
563 | };
|
564 | });
|
565 | }
|
566 |
|
567 | return op;
|
568 | }
|
569 | });
|
570 |
|
571 | if ( isIE ) {
|
572 | var _digest = _subtle.digest;
|
573 |
|
574 | _subtle['digest'] = function ( a, b ) {
|
575 | if ( !b.byteLength )
|
576 | throw new Error("Empy input is not allowed");
|
577 |
|
578 | var op;
|
579 | try {
|
580 | op = _digest.call( _subtle, a, b );
|
581 | }
|
582 | catch ( e ) {
|
583 | return Promise.reject(e);
|
584 | }
|
585 |
|
586 | op = new Promise( function ( res, rej ) {
|
587 | op.onabort =
|
588 | op.onerror = function ( e ) { rej(e) };
|
589 | op.oncomplete = function ( r ) { res(r.target.result) };
|
590 | });
|
591 |
|
592 | return op;
|
593 | };
|
594 |
|
595 | global.crypto = Object.create( _crypto, {
|
596 | getRandomValues: { value: function ( a ) { return _crypto.getRandomValues(a) } },
|
597 | subtle: { value: _subtle },
|
598 | });
|
599 |
|
600 | global.CryptoKey = CryptoKey;
|
601 | }
|
602 |
|
603 | if ( isWebkit ) {
|
604 | _crypto.subtle = _subtle;
|
605 |
|
606 | global.Crypto = _Crypto;
|
607 | global.SubtleCrypto = _SubtleCrypto;
|
608 | global.CryptoKey = CryptoKey;
|
609 | }
|
610 | }));
|
611 |
|
612 | export default {}
|