CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lapo--asn1js

Generic ASN.1 parser/decoder that can decode any valid ASN.1 DER or BER structures.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

dom-visualization.mddocs/

DOM Visualization

Browser-specific functionality for creating interactive ASN.1 structure visualizations with DOM elements and context menus.

Capabilities

ASN1DOM Class

Extended ASN.1 parser with DOM rendering capabilities for web browsers, providing interactive tree views of ASN.1 structures.

/**
 * ASN.1 parser with DOM rendering capabilities
 * Extends ASN1 class with browser-specific visualization methods
 */
class ASN1DOM extends ASN1 {
  /**
   * Generate DOM element representation of ASN.1 structure
   * Creates an interactive tree view with expandable/collapsible nodes
   * @param spaces - Indentation string for formatting (optional)
   * @returns HTML list item element representing the ASN.1 structure
   */
  toDOM(spaces?: string): HTMLLIElement;
  
  /**
   * Generate hexadecimal DOM display with formatting and highlighting
   * @param start - Starting position for hex display (optional)
   * @param trimmedHex - Whether to trim hex display for large content (optional)
   * @returns HTML element containing formatted hex dump
   */
  toHexDOM(start?: number, trimmedHex?: boolean): HTMLElement;
}

Usage Examples:

import { ASN1DOM } from '@lapo/asn1js/dom.js';
import { Base64 } from '@lapo/asn1js/base64.js';

// Parse certificate and create DOM visualization
const certPem = `-----BEGIN CERTIFICATE-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3YkQOL4OqPlzJGPbhUKZ
...
-----END CERTIFICATE-----`;

const certData = Base64.unarmor(certPem);
const cert = ASN1DOM.decode(certData);

// Create DOM tree view
const treeContainer = document.getElementById('asn1-tree');
const ul = document.createElement('ul');
ul.className = 'treecollapse';
ul.appendChild(cert.toDOM());
treeContainer.appendChild(ul);

// Create hex dump view
const hexContainer = document.getElementById('hex-dump');
hexContainer.appendChild(cert.toHexDOM(undefined, true));

// Access the ASN1 object from DOM elements
ul.addEventListener('click', (event) => {
  const listItem = event.target.closest('li');
  if (listItem && listItem.asn1) {
    console.log('Clicked ASN.1 element:', listItem.asn1.typeName());
    console.log('Content:', listItem.asn1.content(100));
  }
});

Context Menu Integration

Utility function for binding context menus to ASN.1 DOM elements.

/**
 * Bind context menu functionality to DOM nodes
 * Adds right-click context menu with ASN.1-specific options
 * @param node - DOM node to bind context menu to
 */
function bindContextMenu(node: HTMLElement): void;

Usage Examples:

import { ASN1DOM } from '@lapo/asn1js/dom.js';
import { bindContextMenu } from '@lapo/asn1js/context.js';
import { Hex } from '@lapo/asn1js/hex.js';

// Create ASN.1 structure with context menu
const data = Hex.decode('300C06032B6570050000');
const asn1 = ASN1DOM.decode(data);

const domElement = asn1.toDOM();
bindContextMenu(domElement);

// Add to page
document.body.appendChild(domElement);

// Context menu will provide options like:
// - Copy hex value
// - Copy base64 value
// - Show OID description (for OID elements)
// - Export structure

Complete Web Interface Example

Example showing how to build a complete ASN.1 viewer web interface.

import { ASN1DOM } from '@lapo/asn1js/dom.js';
import { Base64 } from '@lapo/asn1js/base64.js';
import { Hex } from '@lapo/asn1js/hex.js';
import { bindContextMenu } from '@lapo/asn1js/context.js';

class ASN1Viewer {
  constructor(containerElement) {
    this.container = containerElement;
    this.setupUI();
  }
  
  setupUI() {
    this.container.innerHTML = `
      <div class="asn1-viewer">
        <div class="controls">
          <textarea id="input" placeholder="Paste PEM, Base64, or Hex data here..."></textarea>
          <button id="decode">Decode</button>
          <button id="clear">Clear</button>
        </div>
        <div class="output">
          <div id="tree-view" class="tree-container"></div>
          <div id="hex-view" class="hex-container"></div>
        </div>
      </div>
    `;
    
    this.inputArea = this.container.querySelector('#input');
    this.treeView = this.container.querySelector('#tree-view');
    this.hexView = this.container.querySelector('#hex-view');
    
    this.container.querySelector('#decode').onclick = () => this.decode();
    this.container.querySelector('#clear').onclick = () => this.clear();
  }
  
  decode() {
    try {
      const input = this.inputArea.value.trim();
      if (!input) return;
      
      let binaryData;
      
      // Auto-detect format
      if (/^[0-9A-Fa-f\s]+$/.test(input)) {
        binaryData = Hex.decode(input);
      } else {
        binaryData = Base64.unarmor(input);
      }
      
      const asn1 = ASN1DOM.decode(binaryData);
      this.displayStructure(asn1);
      
    } catch (error) {
      this.showError(error.message);
    }
  }
  
  displayStructure(asn1) {
    // Clear previous content
    this.treeView.innerHTML = '';
    this.hexView.innerHTML = '';
    
    // Create tree view
    const ul = document.createElement('ul');
    ul.className = 'treecollapse';
    const li = asn1.toDOM();
    bindContextMenu(li);
    ul.appendChild(li);
    this.treeView.appendChild(ul);
    
    // Create hex view
    const hexElement = asn1.toHexDOM(undefined, true);
    this.hexView.appendChild(hexElement);
    
    // Add click handlers for tree navigation
    this.addTreeInteractivity(ul);
  }
  
  addTreeInteractivity(treeElement) {
    treeElement.addEventListener('click', (event) => {
      const target = event.target;
      
      // Toggle collapse/expand
      if (target.classList.contains('toggle')) {
        const li = target.closest('li');
        li.classList.toggle('collapsed');
        event.stopPropagation();
        return;
      }
      
      // Highlight selected element
      treeElement.querySelectorAll('li.selected').forEach(el => {
        el.classList.remove('selected');
      });
      
      const li = target.closest('li');
      if (li && li.asn1) {
        li.classList.add('selected');
        this.showElementDetails(li.asn1);
      }
    });
  }
  
  showElementDetails(asn1) {
    // Show detailed information about the selected element
    const details = {
      type: asn1.typeName(),
      position: `${asn1.posStart()}-${asn1.posEnd()}`,
      length: asn1.length,
      content: asn1.content(200)
    };
    
    console.log('Selected ASN.1 element:', details);
    
    // Could update a details panel in the UI
    // this.updateDetailsPanel(details);
  }
  
  showError(message) {
    this.treeView.innerHTML = `<div class="error">Error: ${message}</div>`;
    this.hexView.innerHTML = '';
  }
  
  clear() {
    this.inputArea.value = '';
    this.treeView.innerHTML = '';
    this.hexView.innerHTML = '';
  }
}

// Usage
const viewerContainer = document.getElementById('asn1-viewer-container');
const viewer = new ASN1Viewer(viewerContainer);

CSS Styling for ASN.1 DOM Elements

Recommended CSS classes for styling ASN.1 DOM visualizations.

/* Tree view styling */
.treecollapse {
  font-family: monospace;
  font-size: 12px;
  list-style: none;
  padding-left: 0;
}

.treecollapse li {
  margin: 2px 0;
  padding-left: 16px;
  position: relative;
}

.treecollapse li:before {
  content: "▼";
  position: absolute;
  left: 0;
  cursor: pointer;
  color: #666;
}

.treecollapse li.collapsed:before {
  content: "▶";
}

.treecollapse li.collapsed > ul {
  display: none;
}

/* ASN.1 element styling */
.head {
  cursor: pointer;
}

.head:hover {
  background-color: #f0f0f0;
}

.selected .head {
  background-color: #e6f3ff;
}

/* Type and content styling */
.name.id {
  color: #0066cc;
  font-weight: bold;
}

.name.type {
  color: #006600;
}

.preview {
  color: #666;
  font-style: italic;
}

.oid.description {
  color: #8b4513;
  font-size: 11px;
}

/* Hex view styling */
.hex-container {
  font-family: monospace;
  font-size: 11px;
  white-space: pre;
  background-color: #f8f8f8;
  padding: 10px;
  border: 1px solid #ddd;
  overflow: auto;
}

.hex-address {
  color: #666;
}

.hex-bytes {
  color: #000;
}

.hex-ascii {
  color: #0066cc;
}

/* Error styling */
.error {
  color: #cc0000;
  background-color: #ffe6e6;
  padding: 10px;
  border: 1px solid #cc0000;
  border-radius: 4px;
}

docs

cli-usage.md

core-parsing.md

dom-visualization.md

format-support.md

index.md

stream-processing.md

tile.json