PageSourceSearch

https://hoadon.benhvien108.vn/Content/js/hwcrypto.js

js benhvien108.vn collected 2026-10-02 05:50:22 UTC 22,210 bytes, 589 lines download raw bytes

1/*
2 * This is hwcrypto.js 0.0.10 generated on 2015-04-17
3 *
4 * Modified by Tran Ha on 29/03/2016
5 * Copyright (c) 2016 VNPT-CA. All rights reserved.
6 * 
7 */
8if (!window.atob) {
9    var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10    var table = tableStr.split("");
11
12    window.atob = function(base64) {
13        if (/(=[^=]+|={3,})$/.test(base64)) throw new Error("String contains an invalid character");
14        base64 = base64.replace(/=/g, "");
15        var n = base64.length & 3;
16        if (n === 1) throw new Error("String contains an invalid character");
17        for (var i = 0, j = 0, len = base64.length / 4, bin = []; i < len; ++i) {
18            var a = tableStr.indexOf(base64[j++] || "A"),
19                b = tableStr.indexOf(base64[j++] || "A");
20            var c = tableStr.indexOf(base64[j++] || "A"),
21                d = tableStr.indexOf(base64[j++] || "A");
22            if ((a | b | c | d) < 0) throw new Error("String contains an invalid character");
23            bin[bin.length] = ((a << 2) | (b >> 4)) & 255;
24            bin[bin.length] = ((b << 4) | (c >> 2)) & 255;
25            bin[bin.length] = ((c << 6) | d) & 255;
26        };
27        return String.fromCharCode.apply(null, bin).substr(0, bin.length + n - 4);
28    };
29
30    window.btoa = function(bin) {
31        for (var i = 0, j = 0, len = bin.length / 3, base64 = []; i < len; ++i) {
32            var a = bin.charCodeAt(j++),
33                b = bin.charCodeAt(j++),
34                c = bin.charCodeAt(j++);
35            if ((a | b | c) > 255) throw new Error("String contains an invalid character");
36            base64[base64.length] = table[a >> 2] + table[((a << 4) & 63) | (b >> 4)] +
37                (isNaN(b) ? "=" : table[((b << 2) & 63) | (c >> 6)]) +
38                (isNaN(b + c) ? "=" : table[c & 63]);
39        }
40        return base64.join("");
41    };
42
43}
44
45function hexToBase64(str) {
46    return btoa(String.fromCharCode.apply(null,
47        str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
48}
49
50function hexToPem(s) {
51    var b = hexToBase64(s);
52    var pem = b.match(/.{1,64}/g).join("\n");
53    return "-----BEGIN CERTIFICATE-----\n" + pem + "\n-----END CERTIFICATE-----";
54}
55
56/* EDIT BY TRAN HA (use src/hwcrypto.js) */
57var hwcrypto = function hwcrypto() {
58    "use strict";
59    var _debug = function(x) {};
60    _debug("hwcrypto.js activated");
61
62    // Get browser name
63    var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
64    var isChrome = !!window.chrome && !isOpera;
65    var isFirefox = typeof InstallTrigger !== 'undefined';
66
67    function hasAddonForFirefox() {
68        return new Promise(function(resolve, reject) {
69            var listener = function(result) {
70                window.parent.removeEventListener('message', listener, false);
71                if (result.data === "ok") {
72                    console.log("HAS ADDON");
73                    resolve("ok");
74                } else {
75                    console.log("REJECT BY BROWSER");
76                    reject("undefined");
77                }
78            }
79            window.parent.addEventListener('message', listener, false);
80            var event = document.createEvent('CustomEvent');
81            event.initCustomEvent("addon_require_message", true, true, {
82                type: "TEST",
83                lang: "",
84                cert: "",
85                hash: "",
86                nonce: ""
87            });
88            window.parent.document.dispatchEvent(event);
89
90            setTimeout(function() {
91                reject("undefined");
92            }, 2000);
93        });
94    }
95
96    top.window.addEventListener = top.window.addEventListener || top.window.attachEvent;
97
98    function hasPluginFor(mime) {
99        if (navigator.mimeTypes && mime in navigator.mimeTypes) {
100            return true;
101        }
102        return false;
103    }
104
105    function hasExtensionFor(cls) {
106        if (typeof top.window[cls] === "function") return true;
107        if (typeof window[cls] === "function") return true;
108        return false;
109    }
110
111    function _hex2array(str) {
112        if (typeof str == "string") {
113            var len = Math.floor(str.length / 2);
114            var ret = new Uint8Array(len);
115            for (var i = 0; i < len; i++) {
116                ret[i] = parseInt(str.substr(i * 2, 2), 16);
117            }
118            return ret;
119        }
120    }
121
122    function _array2hex(args) {
123        var ret = "";
124        for (var i = 0; i < args.length; i++) ret += (args[i] < 16 ? "0" : "") + args[i].toString(16);
125        return ret.toLowerCase();
126    }
127
128    function _mimeid(mime) {
129        return "hwc" + mime.replace("/", "").replace("-", "");
130    }
131
132    function loadPluginFor(mime) {
133        var element = _mimeid(mime);
134        if (document.getElementById(element)) {
135            _debug("Plugin element already loaded");
136            return document.getElementById(element);
137        }
138        _debug("Loading plugin for " + mime + " into " + element);
139        var objectTag = '<object id="' + element + '" type="' + mime + '" style="width: 1px; height: 1px; position: absolute; visibility: hidden;"></object>';
140        var div = document.createElement("div");
141        div.setAttribute("id", "pluginLocation" + element);
142        document.body.appendChild(div);
143        document.getElementById("pluginLocation" + element).innerHTML = objectTag;
144        return document.getElementById(element);
145    }
146    var digidoc_mime = "application/x-digidoc";
147    var digidoc_chrome = "TokenSigning";
148    var USER_CANCEL = "user_cancel";
149    var NO_CERTIFICATES = "no_certificates";
150    var INVALID_ARGUMENT = "invalid_argument";
151    var TECHNICAL_ERROR = "technical_error";
152    var NO_IMPLEMENTATION = "no_implementation";
153    var NOT_ALLOWED = "not_allowed";
154
155    function probe() {
156        var msg = "probe() detected ";
157        if (hasExtensionFor(digidoc_chrome)) {
158            _debug(msg + digidoc_chrome);
159        }
160        if (hasPluginFor(digidoc_mime)) {
161            _debug(msg + digidoc_mime);
162        }
163    }
164    top.window.addEventListener("load", function(event) {
165        probe();
166    });
167
168    function DigiDocPlugin() {
169        this._name = "NPAPI/BHO for application/x-digidoc";
170        var p = loadPluginFor(digidoc_mime);
171        var certificate_ids = {};
172
173        function code2str(err) {
174            _debug("Error: " + err + " with: " + p.errorMessage);
175            switch (parseInt(err)) {
176                case 1:
177                    return USER_CANCEL;
178                case 2:
179                    return INVALID_ARGUMENT;
180                case 17:
181                    return INVALID_ARGUMENT;
182                case 19:
183                    return NOT_ALLOWED;
184                default:
185                    _debug("Unknown error: " + err + " with: " + p.errorMessage);
186                    return TECHNICAL_ERROR;
187            }
188        }
189
190        function code2err(err) {
191            return new Error(code2str(err));
192        }
193        this.check = function() {
194            return new Promise(function(resolve, reject) {
195                setTimeout(function() {
196                    resolve(typeof p.version !== "undefined");
197                }, 0);
198            });
199        };
200        this.getVersion = function() {
201            return new Promise(function(resolve, reject) {
202                var v = p.version;
203                resolve(v);
204            });
205        };
206
207        this.selectCertSerial = function(options) {
208            if (options && options.lang) {
209                p.pluginLanguage = options.lang;
210            }
211            return new Promise(function(resolve, reject) {
212                try {
213                    var v = p.selectCertSerial();
214                    if (parseInt(p.errorCode) !== 0) {
215                        reject(code2err(p.errorCode));
216                    } else {
217                        certificate_ids[v.cert] = v.id;
218                        resolve({
219                            hex: v
220                        });
221                    }
222                } catch (ex) {
223                    _debug(ex);
224                    reject(code2err(p.errorCode));
225                }
226            });
227        };
228        this.signHashData = function(cert, hash, options) {
229            return new Promise(function(resolve, reject) {
230                var cid = certificate_ids[cert.hex];
231                if (cid) {
232                    try {
233                        var language = options.lang || "en";
234                        var v = p.signHashData(cid, hash.hex, language);
235                        resolve({
236                            hex: v
237                        });
238                    } catch (ex) {
239                        _debug(JSON.stringify(ex));
240                        reject(code2err(p.errorCode));
241                    }
242                } else {
243                    _debug("invalid certificate: " + cert);
244                    reject(new Error(INVALID_ARGUMENT));
245                }
246            });
247        };
248
249
250        this.signXMLData = function(hash, options) {
251            return new Promise(function(resolve, reject) {
252                try {
253                    var language = options.lang || "en";
254                    var v = p.signXMLData(hash.value, language);
255                    resolve({
256                        hex: v
257                    });
258                } catch (ex) {
259                    _debug(JSON.stringify(ex));
260                    reject(code2err(p.errorCode));
261                }
262            });
263        };
264
265    }
266
267    function DigiDocExtension() {
268        this._name = "Chrome native messaging extension";
269        var p = null;
270        this.check = function() {
271            return new Promise(function(resolve, reject) {
272                if (!hasExtensionFor(digidoc_chrome)) {
273                    return resolve(false);
274                }
275                p = new top.window[digidoc_chrome]();
276                if (p) {
277                    resolve(true);
278                } else {
279                    resolve(false);
280                }
281            });
282        };
283        this.getVersion = function() {
284            return p.getVersion();
285        };
286        this.selectCertSerial = function(options) {
287            return p.selectCertSerial(options);
288        };
289        this.signHashData = function(cert, hash, options) {
290            return p.signHashData(cert, hash, options);
291        };
292        this.signXMLData = function(hash, options) {
293            return p.signXMLData(hash, options);
294        };
295    }
296
297    function NoBackend() {
298        this._name = "No implementation";
299        this.check = function() {
300            return new Promise(function(resolve, reject) {
301                resolve(true);
302            });
303        };
304        this.getVersion = function() {
305            return Promise.reject(new Error(NO_IMPLEMENTATION));
306        };
307        this.selectCertSerial = function() {
308            return Promise.reject(new Error(NO_IMPLEMENTATION));
309        };
310        this.signHashData = function() {
311            return Promise.reject(new Error(NO_IMPLEMENTATION));
312        };
313        this.signXMLData = function() {
314            return Promise.reject(new Error(NO_IMPLEMENTATION));
315        };
316    }
317    var _backend = null;
318    var fields = {};
319
320    function _testAndUse(Backend) {
321        return new Promise(function(resolve, reject) {
322            var b = new Backend();
323            b.check().then(function(isLoaded) {
324                if (isLoaded) {
325                    _debug("Using backend: " + b._name);
326                    _backend = b;
327                    resolve(true);
328                } else {
329                    _debug(b._name + " check() failed");
330                    resolve(false);
331                }
332            });
333        });
334    }
335
336    function _autodetect(force) {
337        return new Promise(function(resolve, reject) {
338            _debug("Autodetecting best backend");
339            if (typeof force === "undefined") {
340                force = false;
341            }
342            if (_backend !== null && !force) {
343                return resolve(true);
344            }
345
346            function tryDigiDocPlugin() {
347                _testAndUse(DigiDocPlugin).then(function(result) {
348                    if (result) {
349                        resolve(true);
350                    } else {
351                        resolve(_testAndUse(NoBackend));
352                    }
353                });
354            }
355            if (navigator.userAgent.indexOf("MSIE") != -1 || navigator.userAgent.indexOf("Trident") != -1) {
356                _debug("Assuming IE BHO, testing");
357                return tryDigiDocPlugin();
358            }
359            if (navigator.userAgent.indexOf("Chrome") != -1 && hasExtensionFor(digidoc_chrome)) {
360                _testAndUse(DigiDocExtension).then(function(result) {
361                    if (result) {
362                        resolve(true);
363                    } else {
364                        tryDigiDocPlugin();
365                    }
366                });
367                return;
368            }
369
370            if (navigator.userAgent.indexOf("Firefox") != -1) {
371                _testAndUse(DigiDocExtension).then(function(result) {
372                    if (result) {
373                        resolve(true);
374                    } else {
375                        tryDigiDocPlugin();
376                    }
377                });
378                return;
379            }
380
381            if (hasPluginFor(digidoc_mime)) {
382                return tryDigiDocPlugin();
383            }
384            resolve(_testAndUse(NoBackend));
385        });
386    }
387    fields.use = function(backend) {
388        return new Promise(function(resolve, reject) {
389            if (typeof backend === "undefined" || backend === "auto") {
390                _autodetect().then(function(result) {
391                    resolve(result);
392                });
393            } else {
394                if (backend === "chrome") {
395                    resolve(_testAndUse(DigiDocExtension));
396                } else if (backend === "npapi") {
397                    resolve(_testAndUse(DigiDocPlugin));
398                } else {
399                    resolve(false);
400                }
401            }
402        });
403    };
404
405    fields.debug = function() {
406        return new Promise(function(resolve, reject) {
407            var hwversion = "hwcrypto.js 0.0.10";
408            _autodetect().then(function(result) {
409                _backend.getVersion().then(function(version) {
410                    resolve(hwversion + " with " + _backend._name + " " + version);
411                }, function(error) {
412                    resolve(hwversion + " with failing backend " + _backend._name);
413                });
414            });
415        });
416    };
417
418    fields.selectCertSerial = function(options) {
419        if (typeof options !== "object") {
420            _debug("getSerialCert options parameter must be an object");
421            return Promise.reject(new Error(INVALID_ARGUMENT));
422        }
423        if (options && !options.lang) {
424            options.lang = "en";
425        }
426
427        if (isChrome) {
428            return _autodetect().then(function(result) {
429                return _backend.selectCertSerial(options).then(function(certificate) {
430                    if (certificate.hex && !certificate.encoded) certificate.encoded = _hex2array(certificate.hex);
431                    return certificate;
432                });
433            });
434        } else if (isFirefox) {
435            return new Promise(function(resolve, reject) {
436                hasAddonForFirefox().then(function(response) {
437                    var event = document.createEvent('CustomEvent');
438                    event.initCustomEvent("addon_require_message", true, true, {
439                        type: "SERIAL_CERT",
440                        lang: options.lang,
441                        cert: "",
442                        hash: "",
443                        nonce: "260906"
444                    });
445                    window.parent.document.dispatchEvent(event);
446                    var listener = function(result) {
447                        window.parent.removeEventListener('message', listener, false);
448                        var end_result = JSON.parse(result.data);
449                        if (end_result.result === 'ok') {
450                            resolve(({
451                                hex: end_result,
452                                value: end_result
453                            }));
454                        } else {
455                            reject(end_result);
456                        }
457                    };
458                    window.parent.addEventListener('message', listener, false);
459                }, function(err) {
460                    reject(new Error(NO_IMPLEMENTATION));
461                });
462            });
463        } else {
464            reject(new Error("unsupported_browser"));
465        }
466    };
467
468    fields.signXMLData = function(hash, options) {
469        if (arguments.length < 2) return Promise.reject(new Error(INVALID_ARGUMENT));
470        if (options && !options.lang) {
471            options.lang = "en";
472        }
473        if (!hash.type || !hash.value && !hash.hex) return Promise.reject(new Error(INVALID_ARGUMENT));
474        if (hash.hex && !hash.value) hash.value = hash.hex;
475        if (hash.value && !hash.hex) hash.hex = hash.value;
476
477        if (isChrome) {
478            return _autodetect().then(function(result) {
479                return _backend.signXMLData(hash, options).then(function(signature) {
480                    if (signature.hex && !signature.value) signature.value = _hex2array(signature.hex);
481                    return signature;
482                });
483            });
484        } else if (isFirefox) {
485            return new Promise(function(resolve, reject) {
486                hasAddonForFirefox().then(function(response) {
487                    var event = window.parent.document.createEvent('CustomEvent');
488                    event.initCustomEvent("addon_require_message", true, true, {
489                        type: "SIGN",
490                        lang: "en",
491                        cert: "",
492                        hash: hash,
493                        nonce: "25251325"
494                    });
495                    window.parent.document.dispatchEvent(event);
496                    var endlistener = function(result) {
497                        window.parent.removeEventListener('message', endlistener, false);
498                        var end_result = JSON.parse(result.data);
499                        if (end_result.result === 'ok') {
500                            resolve(({
501                                hex: end_result,
502                                value: end_result
503                            }));
504                        } else {
505                            reject(end_result);
506                        }
507                    }
508                    window.parent.addEventListener('message', endlistener, false);
509                }, function(err) {
510                    reject(new Error(NO_IMPLEMENTATION));
511                });
512            });
513        } else {
514            reject(new Error("unsupported_browser"));
515        }
516    };
517
518    fields.signHashData = function(cert, hash, options) {
519        if (arguments.length < 2) return Promise.reject(new Error(INVALID_ARGUMENT));
520        if (options && !options.lang) {
521            options.lang = "en";
522        }
523        if (!hash.type || !hash.value && !hash.hex) return Promise.reject(new Error(INVALID_ARGUMENT));
524        if (hash.hex && !hash.value) hash.value = hash.hex;
525        if (hash.value && !hash.hex) hash.hex = hash.value;
526        if (isChrome) {
527
528            return new Promise(function(resolve, reject) {
529                setTimeout(function() {
530                    resolve(_autodetect().then(function(result) {
531                        return _backend.signHashData(cert, hash, options).then(function(signature) {
532                            if (signature.hex && !signature.value) signature.value = _hex2array(signature.hex);
533                            return signature;
534                        });
535                    }));
536                }, 700);
537            });
538
539            /*
540            // Original hwcrypto method; do not remove
541			return _autodetect().then(function(result) {
542                return _backend.signHashData(cert, hash, options).then(function(signature) {
543                    if (signature.hex && !signature.value) signature.value = _hex2array(signature.hex);
544                    return signature;
545                });
546            });
547			*/
548        } else if (isFirefox) {
549            return new Promise(function(resolve, reject) {
550                hasAddonForFirefox().then(function(response) {
551                    var event = window.parent.document.createEvent('CustomEvent');
552                    event.initCustomEvent("addon_require_message", true, true, {
553                        type: "SIGN",
554                        lang: "en",
555                        cert: cert,
556                        hash: hash,
557                        nonce: "190119"
558                    });
559                    window.parent.document.dispatchEvent(event);
560                    var endlistener = function(result) {
561                        window.parent.removeEventListener('message', endlistener, false);
562                        var end_result = JSON.parse(result.data);
563                        if (end_result.result === 'ok') {
564                            resolve(({
565                                hex: end_result,
566                                value: end_result
567                            }));
568                        } else {
569                            reject(end_result);
570                        }
571                    }
572                    window.parent.addEventListener('message', endlistener, false);
573                }, function(err) {
574                    reject(new Error(NO_IMPLEMENTATION));
575                });
576            });
577        } else {
578            reject(new Error("unsupported_browser"));
579        }
580    };
581
582    fields.NO_IMPLEMENTATION = NO_IMPLEMENTATION;
583    fields.USER_CANCEL = USER_CANCEL;
584    fields.NOT_ALLOWED = NOT_ALLOWED;
585    fields.NO_CERTIFICATES = NO_CERTIFICATES;
586    fields.TECHNICAL_ERROR = TECHNICAL_ERROR;
587    fields.INVALID_ARGUMENT = INVALID_ARGUMENT;
588    return fields;
589}();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.