JavaScript generic ASN.1 parser (mirror)
at github-56 164 lines 5.1 kB view raw
1(typeof define != 'undefined' ? define : function (factory) { 'use strict'; 2 if (typeof module == 'object') factory(function (name) { return require(name); }); 3 else factory(function (name) { return window[name.substring(2)]; }); 4})(function (require) { 5"use strict"; 6 7var ASN1 = require('./asn1'), 8 Base64 = require('./base64'), 9 Hex = require('./hex'), 10 maxLength = 10240, 11 reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/, 12 tree = id('tree'), 13 dump = id('dump'), 14 wantHex = id('wantHex'), 15 area = id('area'), 16 file = id('file'), 17 examples = id('examples'), 18 hash = null; 19 20require('./dom'); // side effect: augment ASN1 21if (!window.console || !window.console.log) // IE8 with closed developer tools 22 window.console = { log: function () {} }; 23function id(elem) { 24 return document.getElementById(elem); 25} 26function text(el, string) { 27 if ('textContent' in el) 28 el.textContent = string; 29 else 30 el.innerText = string; 31} 32function decode(der, offset) { 33 offset = offset || 0; 34 tree.innerHTML = ''; 35 dump.innerHTML = ''; 36 try { 37 var asn1 = ASN1.decode(der, offset); 38 tree.appendChild(asn1.toDOM()); 39 if (wantHex.checked) 40 dump.appendChild(asn1.toHexDOM()); 41 var b64 = (der.length < maxLength) ? asn1.toB64String() : ''; 42 if (area.value === '') 43 area.value = Base64.pretty(b64); 44 try { 45 window.location.hash = hash = '#' + b64; 46 } catch (e) { // fails with "Access Denied" on IE with URLs longer than ~2048 chars 47 window.location.hash = hash = '#'; 48 } 49 var endOffset = asn1.posEnd(); 50 if (endOffset < der.length) { 51 var p = document.createElement('p'); 52 p.innerText = 'Input contains ' + (der.length - endOffset) + ' more bytes to decode.'; 53 var button = document.createElement('button'); 54 button.innerText = 'try to decode'; 55 button.onclick = function () { 56 decode(der, endOffset); 57 }; 58 p.appendChild(button); 59 tree.insertBefore(p, tree.firstChild); 60 } 61 } catch (e) { 62 text(tree, e); 63 } 64} 65function decodeText(val) { 66 try { 67 var der = reHex.test(val) ? Hex.decode(val) : Base64.unarmor(val); 68 decode(der); 69 } catch (e) { 70 text(tree, e); 71 dump.innerHTML = ''; 72 } 73} 74function decodeBinaryString(str) { 75 var der; 76 try { 77 if (reHex.test(str)) 78 der = Hex.decode(str); 79 else if (Base64.re.test(str)) 80 der = Base64.unarmor(str); 81 else 82 der = str; 83 decode(der); 84 } catch (e) { 85 text(tree, 'Cannot decode file.'); 86 dump.innerHTML = ''; 87 } 88} 89// set up buttons 90id('butDecode').onclick = function () { decodeText(area.value); }; 91id('butClear').onclick = function () { 92 area.value = ''; 93 file.value = ''; 94 tree.innerHTML = ''; 95 dump.innerHTML = ''; 96 hash = window.location.hash = ''; 97}; 98id('butExample').onclick = function () { 99 console.log('Loading example:', examples.value); 100 var request = new XMLHttpRequest(); 101 request.open('GET', 'examples/' + examples.value, true); 102 request.onreadystatechange = function() { 103 if (this.readyState !== 4) 104 return; 105 if (this.status >= 200 && this.status < 400) { 106 area.value = this.responseText; 107 decodeText(this.responseText); 108 } else { 109 console.log('Error loading example.'); 110 } 111 }; 112 request.send(); 113}; 114// this is only used if window.FileReader 115function read(f) { 116 area.value = ''; // clear text area, will get b64 content 117 var r = new FileReader(); 118 r.onloadend = function () { 119 if (r.error) 120 alert("Your browser couldn't read the specified file (error code " + r.error.code + ")."); 121 else 122 decodeBinaryString(r.result); 123 }; 124 r.readAsBinaryString(f); 125} 126function load() { 127 if (file.files.length === 0) 128 alert("Select a file to load first."); 129 else 130 read(file.files[0]); 131} 132function loadFromHash() { 133 if (window.location.hash && window.location.hash != hash) { 134 hash = window.location.hash; 135 // Firefox is not consistent with other browsers and returns an 136 // already-decoded hash string so we risk double-decoding here, 137 // but since % is not allowed in base64 nor hexadecimal, it's ok 138 var val = decodeURIComponent(hash.substr(1)); 139 if (val.length) 140 decodeText(val); 141 } 142} 143function stop(e) { 144 e.stopPropagation(); 145 e.preventDefault(); 146} 147function dragAccept(e) { 148 stop(e); 149 if (e.dataTransfer.files.length > 0) 150 read(e.dataTransfer.files[0]); 151} 152// main 153if ('onhashchange' in window) 154 window.onhashchange = loadFromHash; 155loadFromHash(); 156document.ondragover = stop; 157document.ondragleave = stop; 158if ('FileReader' in window && 'readAsBinaryString' in (new FileReader())) { 159 file.style.display = 'block'; 160 file.onchange = load; 161 document.ondrop = dragAccept; 162} 163 164});