2022-12-22 06:57:51 +00:00
|
|
|
(typeof define != 'undefined' ? define : function (factory) { 'use strict';
|
|
|
|
if (typeof module == 'object') factory(function (name) { return require(name); });
|
|
|
|
else factory(function (name) { return window[name.substring(2)]; });
|
|
|
|
})(function (require) {
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
var ASN1 = require('./asn1'),
|
|
|
|
Base64 = require('./base64'),
|
|
|
|
Hex = require('./hex'),
|
|
|
|
maxLength = 10240,
|
|
|
|
reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/,
|
|
|
|
tree = id('tree'),
|
|
|
|
dump = id('dump'),
|
|
|
|
wantHex = id('wantHex'),
|
|
|
|
area = id('area'),
|
|
|
|
file = id('file'),
|
|
|
|
examples = id('examples'),
|
|
|
|
hash = null;
|
|
|
|
|
|
|
|
require('./dom'); // side effect: augment ASN1
|
|
|
|
if (!window.console || !window.console.log) // IE8 with closed developer tools
|
|
|
|
window.console = { log: function () {} };
|
|
|
|
function id(elem) {
|
|
|
|
return document.getElementById(elem);
|
|
|
|
}
|
|
|
|
function text(el, string) {
|
|
|
|
if ('textContent' in el)
|
|
|
|
el.textContent = string;
|
|
|
|
else
|
|
|
|
el.innerText = string;
|
|
|
|
}
|
|
|
|
function decode(der, offset) {
|
2023-09-27 07:17:58 +00:00
|
|
|
|
|
|
|
console.log("der", der)
|
|
|
|
|
2022-12-22 06:57:51 +00:00
|
|
|
offset = offset || 0;
|
|
|
|
tree.innerHTML = '';
|
|
|
|
dump.innerHTML = '';
|
|
|
|
try {
|
|
|
|
var asn1 = ASN1.decode(der, offset);
|
|
|
|
tree.appendChild(asn1.toDOM());
|
|
|
|
if (wantHex.checked)
|
|
|
|
dump.appendChild(asn1.toHexDOM());
|
|
|
|
var b64 = (der.length < maxLength) ? asn1.toB64String() : '';
|
|
|
|
if (area.value === '')
|
|
|
|
area.value = Base64.pretty(b64);
|
|
|
|
try {
|
|
|
|
window.location.hash = hash = '#' + b64;
|
|
|
|
} catch (e) { // fails with "Access Denied" on IE with URLs longer than ~2048 chars
|
|
|
|
window.location.hash = hash = '#';
|
|
|
|
}
|
|
|
|
var endOffset = asn1.posEnd();
|
|
|
|
if (endOffset < der.length) {
|
|
|
|
var p = document.createElement('p');
|
|
|
|
p.innerText = 'Input contains ' + (der.length - endOffset) + ' more bytes to decode.';
|
|
|
|
var button = document.createElement('button');
|
|
|
|
button.innerText = 'try to decode';
|
|
|
|
button.onclick = function () {
|
|
|
|
decode(der, endOffset);
|
|
|
|
};
|
|
|
|
p.appendChild(button);
|
|
|
|
tree.insertBefore(p, tree.firstChild);
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
text(tree, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function decodeText(val) {
|
|
|
|
try {
|
|
|
|
var der = reHex.test(val) ? Hex.decode(val) : Base64.unarmor(val);
|
|
|
|
decode(der);
|
|
|
|
} catch (e) {
|
|
|
|
text(tree, e);
|
|
|
|
dump.innerHTML = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function decodeBinaryString(str) {
|
|
|
|
var der;
|
|
|
|
try {
|
2023-09-27 07:17:58 +00:00
|
|
|
|
2022-12-22 06:57:51 +00:00
|
|
|
if (reHex.test(str))
|
|
|
|
der = Hex.decode(str);
|
|
|
|
else if (Base64.re.test(str))
|
|
|
|
der = Base64.unarmor(str);
|
|
|
|
else
|
2023-09-27 07:17:58 +00:00
|
|
|
try {
|
|
|
|
der = Base64.decode(str)
|
|
|
|
return decode(der);
|
|
|
|
} catch (e) {}
|
|
|
|
|
2022-12-22 06:57:51 +00:00
|
|
|
der = str;
|
2023-09-27 07:17:58 +00:00
|
|
|
|
2022-12-22 06:57:51 +00:00
|
|
|
decode(der);
|
|
|
|
} catch (e) {
|
|
|
|
text(tree, 'Cannot decode file.');
|
|
|
|
dump.innerHTML = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// set up buttons
|
|
|
|
id('butDecode').onclick = function () { decodeText(area.value); };
|
|
|
|
id('butClear').onclick = function () {
|
|
|
|
area.value = '';
|
|
|
|
file.value = '';
|
|
|
|
tree.innerHTML = '';
|
|
|
|
dump.innerHTML = '';
|
|
|
|
hash = window.location.hash = '';
|
|
|
|
};
|
|
|
|
id('butExample').onclick = function () {
|
|
|
|
console.log('Loading example:', examples.value);
|
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
request.open('GET', 'examples/' + examples.value, true);
|
|
|
|
request.onreadystatechange = function() {
|
|
|
|
if (this.readyState !== 4)
|
|
|
|
return;
|
|
|
|
if (this.status >= 200 && this.status < 400) {
|
|
|
|
area.value = this.responseText;
|
|
|
|
decodeText(this.responseText);
|
|
|
|
} else {
|
|
|
|
console.log('Error loading example.');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
request.send();
|
|
|
|
};
|
|
|
|
// this is only used if window.FileReader
|
|
|
|
function read(f) {
|
|
|
|
area.value = ''; // clear text area, will get b64 content
|
|
|
|
var r = new FileReader();
|
|
|
|
r.onloadend = function () {
|
|
|
|
if (r.error)
|
|
|
|
alert("Your browser couldn't read the specified file (error code " + r.error.code + ").");
|
|
|
|
else
|
|
|
|
decodeBinaryString(r.result);
|
|
|
|
};
|
|
|
|
r.readAsBinaryString(f);
|
|
|
|
}
|
|
|
|
function load() {
|
|
|
|
if (file.files.length === 0)
|
|
|
|
alert("Select a file to load first.");
|
|
|
|
else
|
|
|
|
read(file.files[0]);
|
|
|
|
}
|
|
|
|
function loadFromHash() {
|
|
|
|
if (window.location.hash && window.location.hash != hash) {
|
|
|
|
hash = window.location.hash;
|
|
|
|
// Firefox is not consistent with other browsers and returns an
|
|
|
|
// already-decoded hash string so we risk double-decoding here,
|
|
|
|
// but since % is not allowed in base64 nor hexadecimal, it's ok
|
|
|
|
var val = decodeURIComponent(hash.substr(1));
|
|
|
|
if (val.length)
|
|
|
|
decodeText(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function stop(e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
e.preventDefault();
|
|
|
|
}
|
|
|
|
function dragAccept(e) {
|
|
|
|
stop(e);
|
|
|
|
if (e.dataTransfer.files.length > 0)
|
|
|
|
read(e.dataTransfer.files[0]);
|
|
|
|
}
|
|
|
|
// main
|
|
|
|
if ('onhashchange' in window)
|
|
|
|
window.onhashchange = loadFromHash;
|
|
|
|
loadFromHash();
|
|
|
|
document.ondragover = stop;
|
|
|
|
document.ondragleave = stop;
|
|
|
|
if ('FileReader' in window && 'readAsBinaryString' in (new FileReader())) {
|
|
|
|
file.style.display = 'block';
|
|
|
|
file.onchange = load;
|
|
|
|
document.ondrop = dragAccept;
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|