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

format-support.mddocs/

Format Support

Comprehensive support for hexadecimal and Base64 input formats, including PEM armoring and various encoding standards.

Capabilities

Hexadecimal Decoding

Decode hexadecimal strings and arrays into binary data with flexible whitespace handling.

class Hex {
  /**
   * Decode hexadecimal string or array into binary data
   * @param a - Hexadecimal string or array of character codes representing hex data
   * @returns Uint8Array (when available) or regular array of bytes
   * @throws Error if hex encoding is invalid or incomplete
   */
  static decode(a: string | ArrayLike<number>): Uint8Array | number[];
}

Usage Examples:

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

// Basic hex decoding
const hexString = "48656C6C6F20576F726C64";
const bytes = Hex.decode(hexString);
console.log(bytes); // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

// Lowercase hex
const lowerHex = "deadbeef";
const decoded = Hex.decode(lowerHex);
console.log(decoded); // [222, 173, 190, 239]

// Hex with whitespace (automatically ignored)
const spacedHex = "30 0C 06 03 2B 65 70 05 00";
const result = Hex.decode(spacedHex);
console.log(result); // [48, 12, 6, 3, 43, 101, 112, 5, 0]

// Hex with various whitespace characters (tabs, newlines, etc.)
const formattedHex = `30 0C 06 03
\t2B 65 70 05
\u00A000`;
const cleanResult = Hex.decode(formattedHex);

// From array of character codes
const charCodes = [52, 56, 54, 53, 54, 67]; // "48656C" 
const fromArray = Hex.decode(charCodes);
console.log(fromArray); // [72, 101, 108]

Base64 Decoding

Comprehensive Base64 decoding with support for standard Base64, Base64url, and PEM armoring.

class Base64 {
  /**
   * Decode base64 string or array into binary data
   * Supports both standard Base64 and Base64url (RFC 4648)
   * @param a - Base64 string or array of character codes
   * @returns Uint8Array (when available) or regular array of bytes
   * @throws Error if base64 encoding is invalid
   */
  static decode(a: string | ArrayLike<number>): Uint8Array | number[];
  
  /**
   * Format base64 string with proper padding and line breaks
   * Converts Base64url to standard Base64 and adds proper formatting
   * @param str - Base64 string to format
   * @returns Formatted base64 string with padding and 80-column line breaks
   */
  static pretty(str: string): string;
  
  /**
   * Extract and decode base64 from PEM or other armored formats
   * Automatically detects and handles:
   * - PEM format (-----BEGIN...-----END-----)
   * - begin-base64...==== format
   * - Raw base64 strings
   * @param a - Armored or raw base64 string
   * @returns Decoded binary data
   * @throws Error if no valid base64 content found
   */
  static unarmor(a: string): Uint8Array | number[];
  
  /** Regular expression for detecting armored base64 content */
  static re: RegExp;
}

Usage Examples:

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

// Basic base64 decoding
const base64String = "SGVsbG8gV29ybGQ=";
const bytes = Base64.decode(base64String);
console.log(bytes); // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

// Base64url decoding (automatically handled)
const base64url = "SGVsbG8gV29ybGQ"; // No padding
const urlDecoded = Base64.decode(base64url);

// Decode with whitespace (automatically ignored)
const spacedBase64 = `SGVs
bG8g
V29y
bGQ=`;
const spacedResult = Base64.decode(spacedBase64);

// PEM format decoding
const pemCert = `-----BEGIN CERTIFICATE-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxomBdI7QQ9PbTFKnRkTG
6LMU1Z4YuYcU5xDiIwz8sIBH2Z3f3X3bR0lPb0ZsU4U6z7z8z8z8z8z8z8z8z8z8
-----END CERTIFICATE-----`;
const certData = Base64.unarmor(pemCert);

// begin-base64 format
const beginBase64 = `begin-base64 644 certificate.der
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxomBdI7QQ9PbTFKnRkTG
====`;
const beginData = Base64.unarmor(beginBase64);

// Raw base64 (also works with unarmor)
const rawBase64 = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A";
const rawData = Base64.unarmor(rawBase64);

// Format base64 for display
const longBase64 = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxomBdI7QQ9PbTFKnRkTG6LMU1Z4YuYcU5xDiIwz8sIBH2Z3f3X3bR0lPb0ZsU4U6z7z8z8z8z8z8z8z8z8z8";
const formatted = Base64.pretty(longBase64);
console.log(formatted);
// Output: 80-character lines with proper padding

// Check what format a string uses
if (Base64.re.test(pemCert)) {
  console.log("Contains armored base64");
}

Combined Usage

Examples showing how to use format support with ASN.1 parsing.

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

// Parse from various input formats
function parseASN1FromAnyFormat(input) {
  let binaryData;
  
  // Try to determine format and decode accordingly
  if (typeof input === 'string') {
    if (/^[0-9A-Fa-f\s]+$/.test(input)) {
      // Looks like hex
      binaryData = Hex.decode(input);
    } else if (Base64.re.test(input) || /^[A-Za-z0-9+/=\s]+$/.test(input)) {
      // Looks like base64 or PEM
      binaryData = Base64.unarmor(input);
    } else {
      throw new Error('Unknown input format');
    }
  } else {
    // Assume binary array
    binaryData = input;
  }
  
  return ASN1.decode(binaryData);
}

// Examples of different input formats
const hexInput = "30 0C 06 03 2B 65 70 05 00";
const base64Input = "MAwGAytlcAUA";
const pemInput = `-----BEGIN PUBLIC KEY-----
MAwGAytlcAUA
-----END PUBLIC KEY-----`;

// All parse to the same ASN.1 structure
const fromHex = parseASN1FromAnyFormat(hexInput);
const fromBase64 = parseASN1FromAnyFormat(base64Input);
const fromPem = parseASN1FromAnyFormat(pemInput);

console.log(fromHex.toPrettyString());
console.log(fromBase64.toPrettyString());
console.log(fromPem.toPrettyString());

// Convert between formats
const asn1 = ASN1.decode(Hex.decode("300C06032B6570050000"));
const asHex = asn1.toHexString();
const asBase64 = asn1.toB64String();
const asBase64Std = asn1.toB64String('std');

console.log("Hex:", asHex);
console.log("Base64url:", asBase64);
console.log("Base64 standard:", asBase64Std);

// Create PEM-like output
const pemLike = `-----BEGIN ASN1 STRUCTURE-----
${Base64.pretty(asBase64Std)}
-----END ASN1 STRUCTURE-----`;
console.log(pemLike);

Error Handling

The format support classes provide detailed error information for invalid input.

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

// Hex error examples
try {
  Hex.decode("48656C6C6F2"); // Incomplete hex (odd number of characters)
} catch (e) {
  console.log(e.message); // "Hex encoding incomplete: 4 bits missing"
}

try {
  Hex.decode("48656C6G"); // Invalid hex character 'G'
} catch (e) {
  console.log(e.message); // "Illegal character at offset 6"
}

// Base64 error examples
try {
  Base64.decode("SGVsbG8g!"); // Invalid base64 character '!'
} catch (e) {
  console.log(e.message); // "Illegal character at offset 8"
}

try {
  Base64.decode("SGVsbG8"); // Incomplete base64
} catch (e) {
  console.log(e.message); // "Base64 encoding incomplete: at least 2 bits missing"
}

// PEM error examples
try {
  Base64.unarmor("-----BEGIN CERTIFICATE-----\nInvalid content\n-----END CERTIFICATE-----");
} catch (e) {
  console.log(e.message); // Base64 decoding error
}

docs

cli-usage.md

core-parsing.md

dom-visualization.md

format-support.md

index.md

stream-processing.md

tile.json