fido2

package
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package fido2 provides FIDO2 hmac-secret support for deriving age keys.

Index

Constants

View Source
const (
	// FIDO2RecipientHRP is the human-readable part for FIDO2 recipients
	FIDO2RecipientHRP = "age1fido2"

	// MinCredentialIDSize is the minimum size of a credential ID
	MinCredentialIDSize = 16

	// MaxCredentialIDSize is the maximum size of a credential ID
	MaxCredentialIDSize = 256
)
View Source
const (
	// SaltSize is the size of the salt for hmac-secret in bytes
	SaltSize = 32

	// DefaultRPID is the default relying party ID
	DefaultRPID = "confcrypt"
)
View Source
const AAGUIDSize = 16

AAGUIDSize is the size of the AAGUID in bytes

Variables

View Source
var (
	// ErrInvalidFIDO2Recipient is returned when parsing an invalid FIDO2 recipient
	ErrInvalidFIDO2Recipient = errors.New("invalid FIDO2 recipient")

	// ErrInvalidChecksum is returned when bech32 checksum validation fails
	ErrInvalidChecksum = errors.New("invalid bech32 checksum")
)
View Source
var (
	// ErrNoDevice is returned when no FIDO2 device is detected
	ErrNoDevice = errors.New("no FIDO2 device detected")

	// ErrHMACSecretNotSupported is returned when the device doesn't support hmac-secret
	ErrHMACSecretNotSupported = errors.New("device does not support hmac-secret extension")

	// ErrDeviceNotFound is returned when a specific device is not found
	ErrDeviceNotFound = errors.New("FIDO2 device not found")

	// ErrCredentialNotFound is returned when credential assertion fails
	ErrCredentialNotFound = errors.New("credential not found on device")
)

Functions

func DeriveAgeKeyPair

func DeriveAgeKeyPair(secret, salt []byte) (privateKey, publicKey []byte, err error)

DeriveAgeKeyPair derives an X25519 key pair from a FIDO2 hmac-secret

func DeriveSecret

func DeriveSecret(devicePath string, id *Identity, pin string) ([]byte, error)

DeriveSecret derives the hmac-secret from a FIDO2 device using stored identity

func DeviceRequiresPIN

func DeviceRequiresPIN(devicePath string) bool

DeviceRequiresPIN checks if the device requires a PIN for operations

func EncodeRecipient

func EncodeRecipient(id *Identity) (string, error)

EncodeRecipient encodes a FIDO2 identity to a bech32 recipient string Format: credIDLen(2) + credID(variable) + rpIDLen(1) + rpID(variable) + aaguid(16) + salt(32) + pubkey(32)

func GenerateSalt

func GenerateSalt() ([]byte, error)

GenerateSalt generates a random salt for hmac-secret

func IsFIDO2Recipient

func IsFIDO2Recipient(s string) bool

IsFIDO2Recipient checks if a string is a FIDO2 recipient

func SupportsHMACSecret

func SupportsHMACSecret(devicePath string) (bool, error)

SupportsHMACSecret checks if the device supports the hmac-secret extension

Types

type Device

type Device struct {
	Path         string
	ProductInfo  string
	Manufacturer string
	Product      string
	VendorID     int16
	ProductID    int16
}

Device represents a connected FIDO2 device

func DetectDevices

func DetectDevices() ([]Device, error)

DetectDevices returns a list of connected FIDO2 devices

func FindDeviceByAAGUID

func FindDeviceByAAGUID(aaguid []byte) (*Device, error)

FindDeviceByAAGUID finds a connected FIDO2 device by its AAGUID

func GetFirstDevice

func GetFirstDevice() (*Device, error)

GetFirstDevice returns the first connected FIDO2 device

type DeviceInfo

type DeviceInfo struct {
	Path         string
	ProductInfo  string
	Serial       string
	SupportsHMAC bool
	RequiresPIN  bool
}

DeviceInfo contains cached device information

func GetDeviceInfo

func GetDeviceInfo(devicePath string) (*DeviceInfo, error)

GetDeviceInfo gets all device info in a single call to avoid multiple touches

type Identity

type Identity struct {
	CredentialID []byte // Variable length credential ID
	Salt         []byte // 32 bytes
	RPID         string // Relying party ID
	RPIDHash     []byte // 32 bytes SHA256 hash of RPID
	AAGUID       []byte // 16 bytes - device identifier for pre-touch matching
	PubKey       []byte // 32 bytes (X25519 public key)
}

Identity holds the data needed to derive an age key from a FIDO2 device

func CreateCredential

func CreateCredential(devicePath, rpID, pin string) (*Identity, error)

CreateCredential creates a new FIDO2 credential with hmac-secret extension (two touches)

func CreateCredentialStep2

func CreateCredentialStep2(devicePath string, partial *PartialIdentity, pin string) (*Identity, error)

CreateCredentialStep2 derives the key from the credential (requires touch)

func DecodeRecipient

func DecodeRecipient(recipient string) (*Identity, error)

DecodeRecipient decodes a bech32 FIDO2 recipient string to an Identity

func GenerateIdentity

func GenerateIdentity(devicePath, rpID, pin string) (*Identity, error)

GenerateIdentity generates a new FIDO2-derived age identity

func (*Identity) DerivePrivateKey

func (id *Identity) DerivePrivateKey(devicePath, pin string) ([]byte, error)

DerivePrivateKey derives the age private key from a FIDO2 identity

func (*Identity) ToAgeIdentity

func (id *Identity) ToAgeIdentity(devicePath, pin string) (age.Identity, error)

ToAgeIdentity converts the FIDO2 identity to an age.Identity

func (*Identity) ToAgeRecipient

func (id *Identity) ToAgeRecipient() age.Recipient

ToAgeRecipient returns the age.Recipient for this identity

type PartialIdentity

type PartialIdentity struct {
	CredentialID []byte
	Salt         []byte
	RPID         string
	AAGUID       []byte // 16 bytes - captured from device during credential creation
}

PartialIdentity holds credential data before key derivation

func CreateCredentialStep1

func CreateCredentialStep1(devicePath, rpID, pin string) (*PartialIdentity, error)

CreateCredentialStep1 creates a FIDO2 credential (requires touch) Returns a partial identity that needs Step2 to derive the key

Jump to

Keyboard shortcuts

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