fido
v0.1.1
A FIDO security key over hidraw: /sys/class/hidraw enumeration, the uevent file parsed by hand, and the usage page 0xF1D0 read through HIDIOCGRDESC. No libudev, and therefore no cgo.
LICENSE=BSD-3-ClauseCGO_ENABLED=0Linux system interfaces in pure Go โ reached through
/sys, ioctl and ordinary file descriptors, with
no libudev, no hidapi and no cgo.
$ go get github.com/go-gnulinux/fido@latest $ go get github.com/go-gnulinux/factors@latest
libudev is a C library, and it is avoidable. The reference
implementation enumerates HID devices through it, which would cost cgo — but udev is used
only to list the hidraw nodes, and /sys/class/hidraw already lists them.
Everything else libfido2 wants, it parses by hand out of the sysfs uevent file. So
that is what happens here, and the result is pure Go on eleven architectures.
The obstacle on Linux is a permission, not an API.
/dev/hidraw* belongs to root on a stock system. A package that reported that as
“no key found” would send a person to check a cable when the answer is a udev rule,
so the two are separate errors and the one that matters names the rule. The same
distinction runs all the way up: a factor that could not be asked has not failed, and
the policy counts it separately.
The ioctl number is not the same on every architecture, and that
is not a detail this org inherited — it is one it nearly got wrong.
asm-generic/ioctl.h wraps _IOC_SIZEBITS in an #ifndef, and
powerpc and mips override it: thirteen bits instead of fourteen, which moves the direction field
down one and changes every request number. A wrong request earns ENOTTY, which
would have been reported as not a security key — a real key found, filtered out,
never mentioned. Cross-compiling all eleven architectures does not catch it:
the arithmetic compiles perfectly and produces the wrong number. Reading the architecture's own
header does.
fido
v0.1.1
A FIDO security key over hidraw: /sys/class/hidraw enumeration, the uevent file parsed by hand, and the usage page 0xF1D0 read through HIDIOCGRDESC. No libudev, and therefore no cgo.
factors
v0.1.0
The security key as an mfa.Factor. Almost nothing is here on purpose โ asking a key is the same everywhere CTAP is. What stays is what only Linux knows: where a key is, and that one you may not open is not one that refused.
Pure Go with CGO_ENABLED=0, cross-built on the eleven
architectures Linux runs on, and held at 100% coverage over everything that needs no hardware.
The protocol above these is portable and lives in
go-authn/fido; the siblings are
go-macos and
go-mswin.
What has not been done is said plainly: the hidraw half has never run against
a key, because the machine this was written on is a Mac. The report-descriptor parser is checked
against seventeen real descriptors with IOKit's own verdict as the judge, and none of them is a
security key — which is the negative control.