token2

package module
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

README

go-ctap/token2

Go Reference Go

Pure-Go Token2 device support over PC/SC, USB HID feature reports and CTAPHID.

[!WARNING] This module is under active development. Its public API may change during v0.x.

Packages

  • token2 contains the transport-independent DeviceInfo, ATR and Configuration types, response parsers and model identification.
  • token2/transport/pcsc opens Token2 devices through github.com/telesma-app/pcsc.
  • token2/transport/hid opens the Token2 HID interface through github.com/telesma-app/hid.
  • token2/transport/ctaphid reads the Token2 ATR through CTAPHID vendor command 0x41, using github.com/telesma-app/ctap.
  • token2/resolver correlates a FIDO attachment with Token2's PC/SC and feature-HID interfaces without guessing between multiple devices.

Transport capabilities

Capability PC/SC Feature HID CTAPHID
Full serial number Yes Yes No
Model identification from the serial number Yes Yes No
ATR-derived product ID and serial suffix Generation-dependent No Yes
Token2 configuration Generation-dependent No No

The HID and PC/SC transports return token2.DeviceInfo. The resolver enriches the same flat type with the ATR-derived product ID, appearance, FIDO version, interface state and all known configuration capabilities. Raw ATR bytes, configuration masks and the ATR serial suffix remain available through the separate low-level ATR and Configuration APIs; they are not nested in DeviceInfo. CTAPHID returns token2.ATR because that command does not reveal the full serial number or model.

The PC/SC serial-number query selects the Token2 OTP application and first reads the serial number there. If the OTP application reports that the instruction is unsupported, the query runs the legacy CTAP compatibility prelude required by R3.1 and retries. Devices that still reject the command are retried through the standard FIDO application. Configuration queries are not available on every Token2 generation. In particular, R3.3 cards reject the configuration command and may expose a generic PIV ATR without the Token2 product ID and serial suffix; ATR then returns ErrInvalidATR. Serial-number retrieval is independent of the optional OTP configuration command and ATR parsing. USB identity resolution can use Token2 feature reports on the matched FIDO HID interface itself, as well as on a separate auxiliary HID interface when the device exposes one.

Token2 reader settings

Compatible Token2 readers expose sound-level and NFC controls through PC/SC:

if err := device.SetReaderSoundLevel(ctx, token2pcsc.ReaderSoundLevel3); err != nil {
	return err
}
if err := device.SetReaderNFC(ctx, false); err != nil {
	return err
}

ReaderSoundOff disables sound; the other sound levels range from 1 through 5. The reader must be physically power-cycled after changing either setting. A successful 9000 response means only that the command was received: an unsupported reader may return success and ignore it.

All concrete device types serialize complete logical operations. Malformed data received from a card or HID device is returned as an error. Callers are expected to pass valid reader names, HID paths and serial-number strings; the package does not add defensive checks for programmer misuse.

Examples

Complete runnable usage is available in the transport examples. Each example is an independent Go module, keeping transport-specific dependencies out of the root module.

Example Purpose Optional configuration
examples/pcsc Read identity and configuration over PC/SC PCSC_READER (reader-name substring)
examples/pcsc-reader-settings Configure Token2 reader sound and NFC over PC/SC -reader (reader-name substring)
examples/hid Read the full serial number over HID feature reports TOKEN2_HID_PATH
examples/ctaphid Read ATR identity over the CTAPHID vendor command TOKEN2_CTAPHID_PATH

The CTAPHID transport sends logical vendor command 0x41; CTAPHID framing adds the init-packet bit, so the on-wire command byte is 0xc1.

Run an example from its directory:

cd examples/pcsc
go run .

Without an environment variable, the read-only examples select the first matching device or reader they find. Set the corresponding variable when multiple Token2 devices are connected or when automatic HID selection is not available on the host.

The reader-settings example requires at least one setting and never changes a reader merely by being run. For example:

cd examples/pcsc-reader-settings
go run . -reader 'TOKEN2' -sound 3 -nfc off

When -reader is omitted, the example prefers Token2 Smart Reader and then falls back to the first PC/SC reader with a card present. An explicit -reader filter never falls back to a different reader.

Hardware tests

Hardware tests are opt-in:

TOKEN2_PCSC_TEST_READER='TOKEN2 FIDO2 Security Key(0016)' go test -run TestHardware -v ./transport/pcsc
TOKEN2_HID_TEST_PATH='platform-specific-path' go test -run TestHardware -v ./transport/hid
TOKEN2_CTAPHID_TEST_PATH='platform-specific-path' go test -run TestHardware -v ./transport/ctaphid

To verify several PC/SC tokens one after another through the unified DeviceInfo API, run the event monitor and insert or present each token:

go run ./cmd/pcsc-serial-monitor

Documentation

Overview

Package token2 provides transport-independent Token2 device information, response parsers and model identification.

Concrete device implementations live under transport. HID and PC/SC devices return DeviceInfo; CTAPHID devices return the partial identity encoded in ATR.

Index

Constants

View Source
const (
	TransferTypeFIDODisabledMask          byte = 0x01
	TransferTypeHOTPKeystrokeDisabledMask byte = 0x02
	TransferTypeCCIDDisabledMask          byte = 0x04

	DeviceConfigurationHOTPSuppressEnterMask    byte = 0x01
	DeviceConfigurationFIDOPINSetMask           byte = 0x02
	DeviceConfigurationHOTPMask                 byte = 0x04
	DeviceConfigurationFingerprintSensorMask    byte = 0x08
	DeviceConfigurationNFCMask                  byte = 0x10
	DeviceConfigurationHOTPLongPressMask        byte = 0x20
	DeviceConfigurationFIDOPINLockedMask        byte = 0x40
	DeviceConfigurationButtonHOTPConfiguredMask byte = 0x80

	DeviceExtensionTOTPMask                        byte = 0x01
	DeviceExtensionFIDO21Mask                      byte = 0x02
	DeviceExtensionFingerprintRegistrationMask     byte = 0x04
	DeviceExtensionHOTPNumericKeypadMask           byte = 0x08
	DeviceExtensionCCIDMask                        byte = 0x10
	DeviceExtensionButtonHOTPUnsupportedMask       byte = 0x20
	DeviceExtensionOTPRequiresFingerprintMask      byte = 0x40
	DeviceExtensionMandatoryFingerprintSupportMask byte = 0x80
)

Variables

View Source
var ErrInvalidATR = errors.New("token2: invalid ATR")

ErrInvalidATR reports an ATR that does not contain the expected Token2 historical bytes.

View Source
var ErrInvalidConfiguration = errors.New("token2: invalid configuration")

ErrInvalidConfiguration reports malformed configuration data received from a Token2 device.

View Source
var ErrInvalidSerialResponse = errors.New("token2: invalid serial-number response")

ErrInvalidSerialResponse reports a malformed serial-number response received from a Token2 device.

Functions

func ParseSerialNumber

func ParseSerialNumber(response []byte) (string, error)

ParseSerialNumber parses the TAG-LENGTH-VALUE response returned by the Token2 serial-number command.

Types

type ATR

type ATR struct {
	Raw          []byte `json:"raw"`
	ProductID    uint16 `json:"productId"`
	SerialSuffix string `json:"serialSuffix"`
}

ATR contains Token2 identity data encoded in a PC/SC answer-to-reset.

func ParseATR

func ParseATR(atr []byte) (ATR, error)

ParseATR extracts the USB product ID and decimal serial suffix from a Token2 ATR. Raw refers to the supplied ATR slice.

type Appearance

type Appearance [4]byte

Appearance identifies the Token2 device appearance reported by its firmware.

type Configuration

type Configuration struct {
	Raw []byte `json:"raw"`

	TransferType        byte        `json:"transferType"`
	DeviceConfiguration byte        `json:"deviceConfiguration"`
	Appearance          Appearance  `json:"appearance"`
	FIDOVersion         FIDOVersion `json:"fidoVersion"`
	DeviceExtension     byte        `json:"deviceExtension"`
}

Configuration describes the Token2 configuration response. Raw retains the complete response, including fields unknown to this version of the package. TransferType is an interface-state mask; DeviceConfiguration and DeviceExtension are capability and configuration masks.

func ParseConfiguration

func ParseConfiguration(response []byte) (Configuration, error)

ParseConfiguration parses either a one-byte legacy response or a modern response of at least ten bytes. Additional bytes are retained in Raw.

type DeviceInfo

type DeviceInfo struct {
	SerialNumber string `json:"serialNumber"`
	Release      string `json:"release"`
	FormFactor   string `json:"formFactor"`
	Branding     string `json:"branding"`
	ProductID    uint16 `json:"productId,omitempty"`

	Appearance  *Appearance  `json:"appearance,omitempty"`
	FIDOVersion *FIDOVersion `json:"fidoVersion,omitempty"`

	InterfaceStateKnown  bool `json:"interfaceStateKnown"`
	FIDOEnabled          bool `json:"fidoEnabled"`
	HOTPKeystrokeEnabled bool `json:"hotpKeystrokeEnabled"`
	CCIDEnabled          bool `json:"ccidEnabled"`

	CapabilitiesKnown               bool `json:"capabilitiesKnown"`
	FIDOPINSet                      bool `json:"fidoPINSet"`
	FIDOPINLocked                   bool `json:"fidoPINLocked"`
	SupportsHOTP                    bool `json:"supportsHOTP"`
	SupportsTOTP                    bool `json:"supportsTOTP"`
	SupportsNFC                     bool `json:"supportsNFC"`
	SupportsCCID                    bool `json:"supportsCCID"`
	SupportsFIDO21                  bool `json:"supportsFIDO21"`
	HasFingerprintSensor            bool `json:"hasFingerprintSensor"`
	SupportsFingerprintRegistration bool `json:"supportsFingerprintRegistration"`
	SupportsMandatoryFingerprint    bool `json:"supportsMandatoryFingerprint"`
	OTPRequiresFingerprint          bool `json:"otpRequiresFingerprint"`
	SupportsButtonHOTP              bool `json:"supportsButtonHOTP"`
	ButtonHOTPConfigured            bool `json:"buttonHOTPConfigured"`
	ButtonHOTPSendsEnter            bool `json:"buttonHOTPSendsEnter"`
	ButtonHOTPRequiresLongPress     bool `json:"buttonHOTPRequiresLongPress"`
	ButtonHOTPUsesNumericKeypad     bool `json:"buttonHOTPUsesNumericKeypad"`
}

DeviceInfo contains normalized, transport-neutral information about a Token2 device. Interface state and capability fields are meaningful when their corresponding Known field is true.

func Identify

func Identify(serialNumber string) (DeviceInfo, bool)

Identify returns device information derived from a full Token2 serial number. The boolean reports whether the model is in the built-in catalog.

func (DeviceInfo) ModelName

func (info DeviceInfo) ModelName(fallback string) string

ModelName returns the canonical model name derived from the serial number. fallback is returned when the model is not in the built-in catalog.

type FIDOVersion

type FIDOVersion struct {
	Major byte `json:"major"`
	Minor byte `json:"minor"`
	Patch byte `json:"patch"`
}

FIDOVersion is the three-component FIDO version reported by a Token2 device.

Directories

Path Synopsis
cmd
internal
protocol
Package protocol defines the Token2 commands shared by transport adapters.
Package protocol defines the Token2 commands shared by transport adapters.
Package resolver correlates one FIDO attachment with Token2's auxiliary interfaces and returns transport-neutral device information.
Package resolver correlates one FIDO attachment with Token2's auxiliary interfaces and returns transport-neutral device information.
transport
ctaphid
Package ctaphid accesses Token2 vendor commands over the CTAPHID protocol.
Package ctaphid accesses Token2 vendor commands over the CTAPHID protocol.
hid
Package hid accesses Token2 devices through USB HID feature reports.
Package hid accesses Token2 devices through USB HID feature reports.
pcsc
Package pcsc provides access to Token2 devices over PC/SC.
Package pcsc provides access to Token2 devices over PC/SC.

Jump to

Keyboard shortcuts

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