emv

package
v0.331.0 Latest Latest
Warning

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

Go to latest
Published: May 21, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package emv decodes EMV BER-TLV structures from contactless and contact payment card APDU responses. Pure offline parser — no hardware, no network — so the same code paths run in unit tests and in any host-side tooling that consumes captured EMV data (saved NFC reads, debugger transcripts, EMV Co specification examples).

Wrap-vs-native judgement: EMV BER-TLV is a well-documented public format (EMV Book 3 §B Annex B). The walker is ~100 lines of bit-twiddling over a byte slice. Wrapping a FAP for this would add an SD-card install step + a firmware-fork dependency for what is, ultimately, a recursive descent parser. We implement natively here so operators can decode an EMV transcript they pasted from a forum post without a Flipper attached.

What this package covers:

  • BER-TLV walker with multi-byte tag + length support
  • Constructed vs primitive recognition (per the BER class+P/C bit)
  • Curated tag-name table for the ~80 most-common EMV tags

What this package does NOT cover (deliberately out of scope):

  • Cryptogram verification (Application Cryptogram derivation, CDA, DDA — these need issuer public keys we don't have)
  • Online authorisation flow (issuer scripting, ARPC)
  • TLV write / re-encode (round-tripping a tree back to bytes — happy to add if a caller materialises)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TagName

func TagName(tag uint32) string

TagName returns the canonical EMV name for a tag, or the empty string when the tag isn't in the curated table. Lookups are case-insensitive on the encoded form because the input is a uint32 (no character-case ambiguity).

Types

type TLV

type TLV struct {
	// Tag is the BER tag as a uint32 — the encoded big-endian bytes
	// of the tag identifier. Single-byte tags use the low byte;
	// multi-byte tags pack into successively higher bytes (so 0x9F02
	// is the most common Amount Authorised tag, 0x5F2A is the
	// Transaction Currency Code, etc.). Stored as uint32 so the
	// tag-name lookup map can key on it without a string conversion.
	Tag uint32 `json:"tag"`
	// TagHex is the operator-facing rendering of Tag — always
	// uppercase, no 0x prefix, no leading zeros. Matches the format
	// every EMV book / forum post uses ("9F02", "5F2A").
	TagHex string `json:"tag_hex"`
	// Name is the canonical EMV name for the tag, or "" when the
	// tag isn't in the curated lookup table.
	Name string `json:"name,omitempty"`
	// Constructed reports whether the value bytes contain nested
	// TLVs (per BER class+P/C bit). When true, Children holds the
	// parsed sub-tree and Value is the raw bytes (kept for callers
	// that want to re-emit the original structure).
	Constructed bool   `json:"constructed"`
	Value       []byte `json:"value,omitempty"`
	// ValueHex is the operator-facing hex rendering of Value.
	// Convenient for JSON output without forcing every caller to
	// re-encode.
	ValueHex string `json:"value_hex,omitempty"`
	// Children is non-nil iff Constructed is true. May be empty
	// when a constructed tag's body is zero-length (legal per the
	// spec, occasionally seen in templated responses).
	Children []TLV `json:"children,omitempty"`
}

TLV is one decoded BER-TLV entry. Constructed entries carry their child TLVs in Children; primitive entries carry the raw value bytes in Value (Children is nil).

func Parse

func Parse(hexBlob string) ([]TLV, error)

Parse decodes a hex-encoded EMV BER-TLV blob (the common form operator-supplied EMV captures take) into a flat list of top-level TLVs. Constructed tags are walked recursively into each TLV's Children. Returns an error on malformed input (truncated tag/length, length-exceeds-buffer, length-encoding reserved value).

func ParseBytes

func ParseBytes(b []byte) ([]TLV, error)

ParseBytes is the byte-slice variant of Parse for callers that already have raw EMV bytes (e.g. from a PC/SC reader). Same recursive walker; same error contract.

Jump to

Keyboard shortcuts

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