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

core-parsing.mddocs/

Core ASN.1 Parsing

Comprehensive ASN.1 parsing capabilities that can decode any valid ASN.1 DER or BER structure with complete type support and detailed content extraction.

Capabilities

ASN.1 Decoder

Main decoder function that creates ASN.1 structure representations from binary data.

/**
 * Main ASN.1 decoder function
 * @param stream - Stream, binary array, or string to decode
 * @param offset - Starting position in the data (optional, defaults to 0)
 * @param type - ASN1 class or subclass to use for parsing (optional, defaults to ASN1)
 * @returns ASN1 instance representing the parsed structure
 */
function ASN1.decode(stream: Stream | ArrayLike<number> | string, offset?: number, type?: typeof ASN1): ASN1;

Usage Examples:

import { ASN1 } from '@lapo/asn1js';
import { Hex } from '@lapo/asn1js/hex.js';

// Parse from binary array
const binaryData = [0x30, 0x0C, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x05, 0x00];
const asn1 = ASN1.decode(binaryData);

// Parse from hex string
const hexData = Hex.decode('300C06032B6570050000');
const parsed = ASN1.decode(hexData);
console.log(parsed.typeName()); // "SEQUENCE"

// Parse with offset
const asn1WithOffset = ASN1.decode(binaryData, 4);
console.log(asn1WithOffset.typeName()); // "NULL"

ASN.1 Structure

The main ASN.1 class that represents parsed ASN.1 structures with complete metadata and content access.

class ASN1 {
  constructor(stream: Stream, header: number, length: number, tag: ASN1Tag, tagLen: number, sub: ASN1[] | null);
  
  /** Stream containing the raw data */
  stream: Stream;
  /** Header length in bytes */
  header: number;
  /** Content length (-1 for indefinite length) */
  length: number;
  /** ASN.1 tag information */
  tag: ASN1Tag;
  /** Tag length in bytes */
  tagLen: number;
  /** Sub-elements for constructed types, null for primitive types */
  sub: ASN1[] | null;
  /** Definition information when matched against RFC definitions */
  def?: any;
  
  /**
   * Get human-readable type name for this ASN.1 element
   * @returns Type name string (e.g., "SEQUENCE", "INTEGER", "OCTET_STRING")
   */
  typeName(): string;
  
  /**
   * Get human-readable content preview
   * @param maxLength - Maximum length for content display (optional)
   * @returns Content string or null if no displayable content
   */
  content(maxLength?: number): string | null;
  
  /**
   * String representation for debugging
   * @returns Debug string with position and structure info
   */
  toString(): string;
  
  /**
   * Pretty formatted string representation with indentation
   * @param indent - Indentation string (optional, defaults to empty)
   * @returns Multi-line formatted string showing structure hierarchy
   */
  toPrettyString(indent?: string): string;
  
  /**
   * Get starting position in stream
   * @returns Starting byte position
   */
  posStart(): number;
  
  /**
   * Get content starting position (after tag and length)
   * @returns Content starting byte position
   */
  posContent(): number;
  
  /**
   * Get ending position
   * @returns Ending byte position
   */
  posEnd(): number;
  
  /**
   * Get position of the length field
   * @returns Length field byte position
   */
  posLen(): number;
  
  /**
   * Convert to hexadecimal string representation
   * @param type - Output format: 'raw', 'byte', or 'dump' (optional, defaults to 'raw')
   * @returns Hexadecimal string representation
   */
  toHexString(type?: 'raw' | 'byte' | 'dump'): string;
  
  /**
   * Convert to Base64url string representation
   * @param type - Output format: 'url' (no padding) or 'std' (with padding) (optional, defaults to 'url')
   * @returns Base64url string representation
   */
  toB64String(type?: 'url' | 'std'): string;
}

Usage Examples:

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

// Parse a certificate
const certData = Base64.unarmor(`-----BEGIN CERTIFICATE-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA...
-----END CERTIFICATE-----`);

const cert = ASN1.decode(certData);

// Examine structure
console.log(cert.typeName()); // "SEQUENCE"
console.log(cert.sub.length); // Number of sub-elements
console.log(cert.toPrettyString());

// Access specific elements
const tbsCertificate = cert.sub[0];
const signatureAlgorithm = cert.sub[1];
const signatureValue = cert.sub[2];

// Get content preview
console.log(signatureValue.content(100)); // First 100 chars of signature

// Position information
console.log(`Certificate starts at ${cert.posStart()}`);
console.log(`Certificate content at ${cert.posContent()}`);
console.log(`Certificate ends at ${cert.posEnd()}`);

// Export formats
console.log(cert.toHexString('dump')); // Hex dump format
console.log(cert.toB64String('std')); // Standard Base64

Length Decoding

Static method for decoding ASN.1 length fields according to DER/BER rules.

/**
 * Decode ASN.1 length field from stream
 * @param stream - Stream positioned at length field
 * @returns Length value or null for indefinite length
 * @throws Error if length encoding is invalid or exceeds 48 bits
 */
static ASN1.decodeLength(stream: Stream): number | null;

Usage Examples:

import { ASN1, Stream } from '@lapo/asn1js';

// Manual length decoding (typically not needed as ASN1.decode handles this)
const data = [0x82, 0x01, 0x00]; // Length = 256 in long form
const stream = new Stream(data, 0);
const length = ASN1.decodeLength(stream);
console.log(length); // 256

ASN.1 Tag

Internal class representing ASN.1 tag information including class, construction, and tag number. This class is not exported from the module but instances are accessible via the tag property of ASN1 objects.

interface ASN1Tag {
  /** Tag class: 0=Universal, 1=Application, 2=Context, 3=Private */
  tagClass: number;
  /** Whether tag is constructed (true) or primitive (false) */
  tagConstructed: boolean;
  /** Tag number within the class */
  tagNumber: number;
  
  /**
   * Check if tag is Universal class
   * @returns true if Universal class (tagClass === 0)
   */
  isUniversal(): boolean;
  
  /**
   * Check if tag is End-of-Contents
   * @returns true if EOC tag (class=0, number=0, primitive)
   */
  isEOC(): boolean;
  
}

Usage Examples:

import { ASN1 } from '@lapo/asn1js';
import { Hex } from '@lapo/asn1js/hex.js';

const data = Hex.decode('30060403010203'); // SEQUENCE containing OCTET STRING
const asn1 = ASN1.decode(data);

// Examine tag
const tag = asn1.tag;
console.log(tag.tagClass); // 0 (Universal)
console.log(tag.tagConstructed); // true
console.log(tag.tagNumber); // 0x10 (SEQUENCE)
console.log(tag.isUniversal()); // true

// Check sub-element
const octetString = asn1.sub[0];
console.log(octetString.tag.tagNumber); // 0x04 (OCTET STRING)
console.log(octetString.tag.tagConstructed); // false

docs

cli-usage.md

core-parsing.md

dom-visualization.md

format-support.md

index.md

stream-processing.md

tile.json