Punk-Passkey
============

WebAuthn passkeys for Punk applications - the fourth authentication
factor beside passwords, TOTP and OAuth2.

This is a separate distribution rather than part of Punk because it
brings libcrypto, through Crypt::JWS and its C ABI - the same route
Punk::OAuth2 takes.


THIS RELEASE

The parsing layer, and nothing above it. The two ceremonies, the
credential schema and the `passkey` keyword follow.

That order is deliberate. What ships here is the code that reads
attacker-supplied bytes before anything has been authenticated: a CBOR
decoder cut down to the subset WebAuthn actually emits, the conversion
from a COSE public key to something Crypt::JWS can import, and the
conversion from an authenticator's ASN.1 signature to the form JOSE
verifies. Everything built on top of it is assembly on parts that
already exist and are already tested; this part was new, so it was
built first, alone, and tested hardest.


WHAT IT REFUSES

The decoder accepts definite-length maps, arrays and strings, integers
that fit in an IV, and true/false/null. It refuses indefinite lengths,
every tag, floats, other simple values, nesting past eight, any length
that reads past the end of the input, repeated map keys, and trailing
bytes after a complete document.

The refusals are the design rather than a list of things not yet
reached: no authenticator emits any of them, so nothing legitimate is
lost, and each one is a class of parser bug that cannot happen. See
the module documentation for the reasoning on the three that are worth
arguing about.


HOW IT IS TESTED

Against published reference data and real captured documents, never
against vectors written by hand.

  - the RFC 8949 Appendix A test vectors, verbatim, in both
    directions: every vector the decoder accepts must produce the
    published value, and every vector it refuses must be one the
    documented subset excludes;

  - registration responses captured from a YubiKey, a Windows Hello
    platform authenticator and a `none`-attestation platform key,
    whose key material was confirmed genuine with openssl before it
    was checked in;

  - the key encoder compared byte for byte against the
    SubjectPublicKeyInfo openssl writes for the same key, EC and RSA;

  - forty real ECDSA signatures made by openssl, converted here and
    verified through libcrypto, which is the only check that a
    conversion is right rather than merely self-consistent.

t/fixtures/README names the source of every byte.


INSTALLATION

	perl Makefile.PL
	make
	make test
	make install

Needs a C compiler, Crypt::JWS 0.05 and File::Raw::JSON 0.07, and perl
5.10 or newer.


SUPPORT

	perldoc Punk::Passkey


LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION <email@lnation.org>.

This is free software, licensed under the Artistic License 2.0
(GPL Compatible).
