SEEDing WEbAuthN CrEDentials (weeds out implementation bugs)
Spec: https://github.com/dicekeys/seeding-webauthn.
Contains:
keypair_from_seed_mac
specifying how to generate the P256 keypairscredential_id_from_seed_nonce_rpidhash
, specifying how to serialize credentialsvalidate_credential_id
specifying how to verify a received credential ID is validnonce_extstate_mac_from_credential_id
, specifying how to deserialize credential IDs- test vectors (can easily adapt, uses independent seeded DRBG)
Does not contain:
- construction of nonce / unique ID from
(seed, rp_id, user_id, entropy)
quadruples; this is left to the authenticator implementation by the specification.
The signatures are over b"seedweed"
.
Calling seedweed.load_test_vectors(shortlist=True)
in the following should
be sufficient to hit all the known tricky corner cases.
For all test vectors v
in seedweed.load_test_vectors()
:
- set
v["seed"]
- call authenticator MC with
v["rp_id"]
(freely chooseuser_id
and other parameters) - extract generated
credential_id
,public_key
, and pass toseedweed.conformance.verify_make_credential
together with the attested data that was signed
This test verifies that credential IDs generated by the authenticator can be used by spec-compliant implementations.
For all test vectors v
in seedweed.load_test_vectors()
:
- set
v["seed"]
- call authenticator GA with
v["credential_id"]
,v["rp_id"]
(freely chooseuser_id
and other parameters) - pass generated signature with data that was signed to
seedweed.conformance.verify_get_assertion
This test verifies that the authenticator can use credential IDs generated by a spec-compliant implementations.
The authenticator has leeway on:
- how to generate a nonce ("uniqueId") for its credentials
- whether to include "extState" in its (generated) credential IDs
- whether to follow RFC 6979, i.e., deterministic signatures
However:
- given (seed, credentialID), the P256 keypair is determined, and
- additionally given rpIdHash, appropriate credential binding can be verified
P256 public keys are serialized here as (X, Y) coordinates, each as zero-padded 32 byte big-endian.
To install, need Python >=3.6, then: pip install seedweed
Once done, there should be a command generate-seedweed-test-vectors
you can run that
recreates the test vectors. Modifying the Parameters allows generating
more test vectors, as needed.
Many ways, one is to make setup
and then source venv/bin/activate
.
Uses flit
for packaging as it seems least-effort (flit build
, flit install
).
Please save files with UNIX-style line endings, and run make check
to enforce
basic consistency (make fix
can automatically fix most issues).