1/*global Hex, Base64, ASN1 */
2"use strict";
3
4var maxLength = 10240,
5 reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/,
6 tree = id('tree'),
7 dump = id('dump'),
8 wantHex = id('wantHex'),
9 area = id('area'),
10 file = id('file'),
11 hash = null;
12function id(elem) {
13 return document.getElementById(elem);
14}
15function text(el, string) {
16 if ('textContent' in el)
17 el.textContent = string;
18 else
19 el.innerText = string;
20}
21function decode(der) {
22 tree.innerHTML = '';
23 dump.innerHTML = '';
24 try {
25 var asn1 = ASN1.decode(der);
26 tree.appendChild(asn1.toDOM());
27 if (wantHex.checked)
28 dump.appendChild(asn1.toHexDOM());
29 var b64 = (der.length < maxLength) ? asn1.toB64String() : '';
30 if (area.value === '')
31 area.value = Base64.pretty(b64);
32 try {
33 window.location.hash = hash = '#' + b64;
34 } catch (e) { // fails with "Access Denied" on IE with URLs longer than ~2048 chars
35 window.location.hash = hash = '#';
36 }
37 } catch (e) {
38 text(tree, e);
39 }
40}
41function decodeText(val) {
42 try {
43 var der = reHex.test(val) ? Hex.decode(val) : Base64.unarmor(val);
44 decode(der);
45 } catch (e) {
46 text(tree, e);
47 dump.innerHTML = '';
48 }
49}
50function decodeBinaryString(str) {
51 var der;
52 try {
53 if (reHex.test(str))
54 der = Hex.decode(str);
55 else if (Base64.re.test(str))
56 der = Base64.unarmor(str);
57 else
58 der = str;
59 decode(der);
60 } catch (e) {
61 text(tree, 'Cannot decode file.');
62 dump.innerHTML = '';
63 }
64}
65// set up buttons
66id('butDecode').onclick = function () { decodeText(area.value); };
67id('butClear').onclick = function () {
68 area.value = '';
69 tree.innerHTML = '';
70 dump.innerHTML = '';
71 hash = window.location.hash = '';
72}
73id('butExample').onclick = function () {
74 var demo = 'MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIAwggHvMIIBWKADAgECAhAvoXazbunwSfREtACZZhlFMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNVBAMMAWEwHhcNMDgxMDE1MTUwMzQxWhcNMDkxMDE1MTUwMzQxWjAMMQowCAYDVQQDDAFhMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJUwlwhu5hR8X01f-vG0mKPRHsVRjpZNxSEmsmFPdDiD9kylE3ertTDf0gRkpIvWfNJ-eymuxoXF0Qgl5gXAVuSrjupGD6J-VapixJiwLXJHokmDihLs3zfGARz08O3qnO5ofBy0pRxq5isu_bAAcjoByZ1sI_g0iAuotC1UFObwIDAQABo1IwUDAOBgNVHQ8BAf8EBAMCBPAwHQYDVR0OBBYEFEIGXQB4h-04Z3y_n7Nv94-CqPitMB8GA1UdIwQYMBaAFEIGXQB4h-04Z3y_n7Nv94-CqPitMA0GCSqGSIb3DQEBBQUAA4GBAE0G7tAiaacJxvP3fhEj-yP9VDxL0omrRRAEaMXwWaBf_Ggk1T_u-8_CDAdjuGNCiF6ctooKc8u8KpnZJsGqnpGQ4n6L2KjTtRUDh-hija0eJRBFdirPQe2HAebQGFnmOk6Mn7KiQfBIsOzXim_bFqaBSbf06bLTQNwFouSO-jwOAAAxggElMIIBIQIBATAgMAwxCjAIBgNVBAMMAWECEC-hdrNu6fBJ9ES0AJlmGUUwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTA4MTAxNTE1MDM0M1owIwYJKoZIhvcNAQkEMRYEFAAAAAAAAAAAAAAAAAAAAAAAAAAAMA0GCSqGSIb3DQEBAQUABIGAdB7ShyMGf5lVdZtvwKlnYLHMUqJWuBnFk7aQwHAmg3JnH6OcgId2F-xfg6twXm8hhUBkhHPlHGoWa5kQtN9n8rz3NorzvcM_1Xv9-0Eal7NYSn2Hb0C0DMj2XNIYH2C6CLIHkmy1egzUvzsomZPTkx5nGDWm-8WHCjWb9A6lyrMAAAAAAAA';
75 decodeText(demo);
76};
77// this is only used if window.FileReader
78function read(f) {
79 area.value = ''; // clear text area, will get b64 content
80 var r = new FileReader();
81 r.onloadend = function () {
82 if (r.error)
83 alert("Your browser couldn't read the specified file (error code " + r.error.code + ").");
84 else
85 decodeBinaryString(r.result);
86 };
87 r.readAsBinaryString(f);
88}
89function load() {
90 if (file.files.length === 0)
91 alert("Select a file to load first.");
92 else
93 read(file.files[0]);
94}
95function loadFromHash() {
96 if (window.location.hash && window.location.hash != hash) {
97 hash = window.location.hash;
98 // Firefox is not consistent with other browsers and return an
99 // already-decoded hash string so we risk double-decoding here,
100 // but since % is not allowed in base64 nor hexadecimal, it's ok
101 var val = decodeURIComponent(hash.substr(1));
102 decodeText(val);
103 }
104}
105function stop(e) {
106 e.stopPropagation();
107 e.preventDefault();
108}
109function dragAccept(e) {
110 stop(e);
111 if (e.dataTransfer.files.length > 0)
112 read(e.dataTransfer.files[0]);
113}
114// main
115if ('onhashchange' in window)
116 window.onhashchange = loadFromHash;
117loadFromHash();
118document.ondragover = stop;
119document.ondragleave = stop;
120if ('FileReader' in window) {
121 file.style.display = 'block';
122 file.onchange = load;
123 document.ondrop = dragAccept;
124}