pgppacket

package
v0.684.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package pgppacket decodes the OpenPGP (RFC 4880 / RFC 9580) packet stream of a PGP key or message — public/secret keys, user IDs, signatures, and the encrypted/compressed/literal data packets — into a structured per-packet view: tag, length, and for key packets the version, algorithm, creation time, **fingerprint, and 64-bit key ID**. A captured PGP key or message (`.asc`, `.gpg`, an armored block pasted from an email or a key dump) is real credential-forensics / IR loot: identifying a key's fingerprint / key ID, its algorithm and creation time, and the user IDs it certifies is standard triage, and a secret-key packet is the private key itself. Pure offline transform; no network or device.

Wrap-vs-native judgement

Native. The OpenPGP packet framing (old- and new-format headers, partial lengths), the public-key fingerprint formula (RFC 4880 §12.2: SHA-1 over 0x99 ‖ len ‖ body for v4, SHA-256 over 0x9A ‖ len ‖ body for v5), the MPI / ECC-OID layout, and the algorithm/tag tables are a public spec — a TLV walker plus a hash, stdlib only. We do NOT depend on golang.org/x/crypto/openpgp (deprecated and frozen); it is used ONLY in the package test as an independent reference oracle to cross-check every fingerprint / key ID / tag.

What this covers / defers

  • Packet framing for every tag (old + new format, single- and partial-body lengths) with tag names.
  • Public-Key / Public-Subkey / Secret-Key / Secret-Subkey: version, algorithm, creation time, and (v4/v5) the fingerprint + key ID. For a public-key packet the whole body is hashed (correct for every algorithm); for a secret-key packet the public portion is isolated by walking the public MPIs (RSA / DSA / Elgamal) — an ECC secret key's fingerprint is flagged rather than guessed, since that OID/point layout is not exercised by the oracle.
  • User ID text; Signature header fields (version, type, public-key + hash algorithm) plus the v4/v5 subpackets that matter for forensics: signature creation time, issuer key ID + fingerprint (which key signed it), key / signature expiry, and key flags.
  • v3 keys are surfaced (version + creation + algorithm) but their MD5 fingerprint is not computed (legacy, rare); MPI bodies of signatures and session-key packets are not deep-parsed (the recon value is the framing + key identity).

Verifiable / no confidently-wrong output

Cross-checked in-package against golang.org/x/crypto/openpgp: a freshly generated entity (public + secret) is serialized, parsed by BOTH this native walker and the reference implementation, and every fingerprint / key ID / creation time / tag must match byte-for-byte. A truncated packet or a length that overruns the buffer is reported as a warning and the walk stops cleanly rather than panicking; non-OpenPGP input is rejected.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Packet

type Packet struct {
	Tag    int    `json:"tag"`
	Name   string `json:"name"`
	Format string `json:"format"` // old / new
	Length int    `json:"length"`
	Offset int    `json:"offset"`

	// Key packets (tags 5, 6, 7, 14).
	KeyVersion  int    `json:"key_version,omitempty"`
	Algorithm   string `json:"algorithm,omitempty"`
	CreatedUTC  string `json:"created_utc,omitempty"`
	Fingerprint string `json:"fingerprint,omitempty"`
	KeyID       string `json:"key_id,omitempty"`

	// User ID (tag 13).
	UserID string `json:"user_id,omitempty"`

	// Signature (tag 2).
	SignatureType     string `json:"signature_type,omitempty"`
	HashAlgorithm     string `json:"hash_algorithm,omitempty"`
	SigCreatedUTC     string `json:"sig_created_utc,omitempty"`
	IssuerKeyID       string `json:"issuer_key_id,omitempty"`
	IssuerFingerprint string `json:"issuer_fingerprint,omitempty"`
	KeyLifetimeSecs   uint32 `json:"key_lifetime_secs,omitempty"`
	SigLifetimeSecs   uint32 `json:"sig_lifetime_secs,omitempty"`
	KeyFlags          string `json:"key_flags,omitempty"`

	Note string `json:"note,omitempty"`
}

Packet is one decoded OpenPGP packet.

type Result

type Result struct {
	Armored     bool     `json:"armored"`
	PacketCount int      `json:"packet_count"`
	Packets     []Packet `json:"packets"`
	Warnings    []string `json:"warnings,omitempty"`
}

Result is the decoded packet stream.

func Decode

func Decode(input string) (*Result, error)

Decode accepts an ASCII-armored block, a base64 body, a hex string, or raw binary bytes (as a string) and walks the OpenPGP packet stream.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL