From e34ad9af0fc21c6816e6a7c49df977bb9de7b5c2 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Sun, 28 Jan 2024 18:17:45 +0100 Subject: [PATCH 1/9] hex copy on click --- dom.js | 15 +++++++++++++++ index.js | 3 +++ 2 files changed, 18 insertions(+) diff --git a/dom.js b/dom.js index 4c0b32d..88aa258 100644 --- a/dom.js +++ b/dom.js @@ -57,6 +57,10 @@ const class ASN1DOM extends ASN1 { + buf2hex(buffer) { + return [...new Uint8Array(buffer)].map((x) => x.toString(16).padStart(2, '0')).join(' '); + } + toDOM(spaces) { spaces = spaces || ''; let isOID = (typeof oids === 'object') && (this.tag.isUniversal() && (this.tag.tagNumber == 0x06) || (this.tag.tagNumber == 0x0D)); @@ -187,6 +191,14 @@ class ASN1DOM extends ASN1 { this.className = 'hex'; } }; + // handler to copy the complete hex dump into the clipboard + node.onclick = function (event) { + const pos = parseInt(this.getAttribute('pos')); + const end = parseInt(this.getAttribute('end')); + const hex = this.asn1.buf2hex(window.derBuffer.subarray(pos, end)); + navigator.clipboard.writeText(hex); + event.stopPropagation(); + }; if (root == node) { let lineStart = this.posStart() & 0xF; if (lineStart != 0) { @@ -200,6 +212,9 @@ class ASN1DOM extends ASN1 { node.appendChild(skip); } } + // set the current start and end position as an attribute at the node to know the selected area + node.setAttribute('pos', this.posStart()); + node.setAttribute('end', this.posEnd()); this.toHexDOM_sub(node, 'tag', this.stream, this.posStart(), this.posLen()); this.toHexDOM_sub(node, (this.length >= 0) ? 'dlen' : 'ulen', this.stream, this.posLen(), this.posContent()); if (this.sub === null) { diff --git a/index.js b/index.js index fc468e0..a353101 100644 --- a/index.js +++ b/index.js @@ -50,6 +50,9 @@ function show(asn1) { if (wantHex.checked) dump.appendChild(asn1.toHexDOM(undefined, trimHex.checked)); } function decode(der, offset) { + // store the DER buffer of asn1 in window to copy it completely into clipboard on dumpcopy + window.derBuffer = der; + offset = offset || 0; try { const asn1 = ASN1DOM.decode(der, offset); From bd7e240688ab51c1bc888befafdb1b5719f505c3 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Sun, 28 Jan 2024 22:08:09 +0100 Subject: [PATCH 2/9] Context menu and copyAsString added --- dom.js | 9 +++++---- index.css | 20 ++++++++++++++++++++ index.html | 1 + index.js | 25 +++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/dom.js b/dom.js index 88aa258..9191218 100644 --- a/dom.js +++ b/dom.js @@ -193,10 +193,11 @@ class ASN1DOM extends ASN1 { }; // handler to copy the complete hex dump into the clipboard node.onclick = function (event) { - const pos = parseInt(this.getAttribute('pos')); - const end = parseInt(this.getAttribute('end')); - const hex = this.asn1.buf2hex(window.derBuffer.subarray(pos, end)); - navigator.clipboard.writeText(hex); + let contextMenu = document.getElementById('contextmenu'); + contextMenu.style.left = event.clientX + "px"; + contextMenu.style.top = event.clientY + "px"; + contextMenu.style.visibility = 'visible'; + document.getElementById('contextmenu').node = this; event.stopPropagation(); }; if (root == node) { diff --git a/index.css b/index.css index c57b12d..d858361 100644 --- a/index.css +++ b/index.css @@ -212,3 +212,23 @@ header { #dump .hexCurrent .dlen { color: #004040; } #file { display: none; } #area { width: 100%; } + +#contextmenu { + position: absolute; + top: 0; + left: 0; + padding: 2px; + background-color: var(--button-bg-color); + border: 1px solid var(--button-bg-color); + z-index: 2; +} + +#contextmenu > button { + width: 120px; + background-color: var(--button-bg-color); + color: var(--main-text-color); + border: 1px solid var(--button-border-color); +} +#contextmenu > button:hover { + background-color: var(--button-bghover-color); +} diff --git a/index.html b/index.html index 7b7a9f3..3691676 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,7 @@ +

ASN.1 JavaScript decoder

diff --git a/index.js b/index.js index a353101..d473c39 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ 'use strict'; const + ASN1 = require('./asn1'), ASN1DOM = require('./dom'), Base64 = require('./base64'), Hex = require('./hex'), @@ -239,4 +240,28 @@ selectTag.onchange = function (ev) { window.location.href = 'https://rawcdn.githack.com/lapo-luchini/asn1js/' + tag + '/index.html'; }; +// register context menu function +document.getElementById('btnCopyHex').onclick = function (event) { + let contextMenu = document.getElementById('contextmenu'); + let node = contextMenu.node; + const pos = parseInt(node.getAttribute('pos')); + const end = parseInt(node.getAttribute('end')); + const hex = node.asn1.buf2hex(window.derBuffer.subarray(pos, end)); + navigator.clipboard.writeText(hex); + contextMenu.style.visibility = 'hidden'; + event.stopPropagation(); +}; + +document.getElementById('btnCopyString').onclick = function (event) { + let contextMenu = document.getElementById('contextmenu'); + let node = contextMenu.node; + const pos = parseInt(node.getAttribute('pos')); + const end = parseInt(node.getAttribute('end')); + // const hex = node.asn1.buf2hex(window.derBuffer.subarray(pos, end)); + let result = ASN1.decode(window.derBuffer.subarray(pos, end)); + // navigator.clipboard.writeText(hex); + contextMenu.style.visibility = 'hidden'; + event.stopPropagation(); +}; + }); From 932a08619a2d24c30b2bbe29c2a593f9f70a83ce Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Mon, 29 Jan 2024 08:26:40 +0100 Subject: [PATCH 3/9] Context menu initially hidden --- index.css | 1 + 1 file changed, 1 insertion(+) diff --git a/index.css b/index.css index d858361..0742992 100644 --- a/index.css +++ b/index.css @@ -215,6 +215,7 @@ header { #contextmenu { position: absolute; + visibility: hidden; top: 0; left: 0; padding: 2px; From ae5f079b78432b0c06fad227ef65492a699ae278 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Mon, 29 Jan 2024 13:28:54 +0100 Subject: [PATCH 4/9] Fix: Copy the string to clipboard --- index.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index d473c39..6644723 100644 --- a/index.js +++ b/index.js @@ -242,7 +242,7 @@ selectTag.onchange = function (ev) { // register context menu function document.getElementById('btnCopyHex').onclick = function (event) { - let contextMenu = document.getElementById('contextmenu'); + let contextMenu = document.getElementById('contextmenu'); let node = contextMenu.node; const pos = parseInt(node.getAttribute('pos')); const end = parseInt(node.getAttribute('end')); @@ -250,18 +250,28 @@ document.getElementById('btnCopyHex').onclick = function (event) { navigator.clipboard.writeText(hex); contextMenu.style.visibility = 'hidden'; event.stopPropagation(); -}; +}; document.getElementById('btnCopyString').onclick = function (event) { - let contextMenu = document.getElementById('contextmenu'); + let contextMenu = document.getElementById('contextmenu'); let node = contextMenu.node; const pos = parseInt(node.getAttribute('pos')); const end = parseInt(node.getAttribute('end')); - // const hex = node.asn1.buf2hex(window.derBuffer.subarray(pos, end)); let result = ASN1.decode(window.derBuffer.subarray(pos, end)); - // navigator.clipboard.writeText(hex); + let type = result.typeName(); + switch (type) { + case 'UTF8String': + case 'PrintableString': + case 'TeletexString': + case 'VideotexString': + case 'IA5String': + case 'UniversalString': + navigator.clipboard.writeText(result.content()); + break; + default: alert('Selected value is not a String!'); + } contextMenu.style.visibility = 'hidden'; event.stopPropagation(); -}; +}; }); From 9e1d0012efed08b670e7c5ab1fb839b3c642726d Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Mon, 29 Jan 2024 13:31:51 +0100 Subject: [PATCH 5/9] New: Copy as pretty --- index.html | 2 +- index.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 3691676..11c610a 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ -

+


ASN.1 JavaScript decoder

diff --git a/index.js b/index.js index 6644723..a7f528d 100644 --- a/index.js +++ b/index.js @@ -274,4 +274,15 @@ document.getElementById('btnCopyString').onclick = function (event) { event.stopPropagation(); }; +document.getElementById('btnCopyPretty').onclick = function (event) { + let contextMenu = document.getElementById('contextmenu'); + let node = contextMenu.node; + const pos = parseInt(node.getAttribute('pos')); + const end = parseInt(node.getAttribute('end')); + let result = ASN1.decode(window.derBuffer.subarray(pos, end)); + navigator.clipboard.writeText(result.toPrettyString()); + contextMenu.style.visibility = 'hidden'; + event.stopPropagation(); +}; + }); From b2223c588afb2a5cbbad3a754c06dab508cfc3dd Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Mon, 29 Jan 2024 13:33:13 +0100 Subject: [PATCH 6/9] New: Align context menu to left --- index.css | 1 + 1 file changed, 1 insertion(+) diff --git a/index.css b/index.css index 0742992..b3601b1 100644 --- a/index.css +++ b/index.css @@ -229,6 +229,7 @@ header { background-color: var(--button-bg-color); color: var(--main-text-color); border: 1px solid var(--button-border-color); + text-align: left; } #contextmenu > button:hover { background-color: var(--button-bghover-color); From 0118d521b1ef9042792f4c965a73a9d856170800 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Mon, 29 Jan 2024 18:48:31 +0100 Subject: [PATCH 7/9] Negative list for set and sequence --- index.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index a7f528d..fc3d4a2 100644 --- a/index.js +++ b/index.js @@ -260,15 +260,12 @@ document.getElementById('btnCopyString').onclick = function (event) { let result = ASN1.decode(window.derBuffer.subarray(pos, end)); let type = result.typeName(); switch (type) { - case 'UTF8String': - case 'PrintableString': - case 'TeletexString': - case 'VideotexString': - case 'IA5String': - case 'UniversalString': - navigator.clipboard.writeText(result.content()); + case 'SET': + case 'SEQUENCE': + alert('Selected value is not a String!'); break; - default: alert('Selected value is not a String!'); + default: + navigator.clipboard.writeText(result.content()); } contextMenu.style.visibility = 'hidden'; event.stopPropagation(); From 86b101f97aec0d58fd02b381885bf8e7e0162de0 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Mon, 29 Jan 2024 18:52:28 +0100 Subject: [PATCH 8/9] Fix: Show context menu at correct position --- dom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom.js b/dom.js index 9191218..5e4d228 100644 --- a/dom.js +++ b/dom.js @@ -194,8 +194,8 @@ class ASN1DOM extends ASN1 { // handler to copy the complete hex dump into the clipboard node.onclick = function (event) { let contextMenu = document.getElementById('contextmenu'); - contextMenu.style.left = event.clientX + "px"; - contextMenu.style.top = event.clientY + "px"; + contextMenu.style.left = event.pageX + "px"; + contextMenu.style.top = event.pageY + "px"; contextMenu.style.visibility = 'visible'; document.getElementById('contextmenu').node = this; event.stopPropagation(); From d66311c4c258a3b615c349b6e8cdec4c1c5a7830 Mon Sep 17 00:00:00 2001 From: Oliver Burgmaier Date: Wed, 31 Jan 2024 19:50:58 +0100 Subject: [PATCH 9/9] Indention fixed --- index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index fc3d4a2..70c2a52 100644 --- a/index.js +++ b/index.js @@ -260,12 +260,12 @@ document.getElementById('btnCopyString').onclick = function (event) { let result = ASN1.decode(window.derBuffer.subarray(pos, end)); let type = result.typeName(); switch (type) { - case 'SET': - case 'SEQUENCE': - alert('Selected value is not a String!'); - break; - default: - navigator.clipboard.writeText(result.content()); + case 'SET': + case 'SEQUENCE': + alert('Selected value is not a String!'); + break; + default: + navigator.clipboard.writeText(result.content()); } contextMenu.style.visibility = 'hidden'; event.stopPropagation();