Reference implementation and test vectors for DiceKey's "Seeding WebAuthN" specification
SEEDing WEbAuthN CrEDentials (weeds out implementation bugs)
Spec: https://github.com/dicekeys/seeding-webauthn.
Contains:
keypair_from_seed_macspecifying how to generate the P256 keypairscredential_id_from_seed_nonce_rpidhash, specifying how to serialize credentialsvalidate_credential_idspecifying 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".
Conformance testing
Calling seedweed.load_test_vectors(shortlist=True) in the following should
be sufficient to hit all the known tricky corner cases.
1. MakeCredential
For all test vectors v in seedweed.load_test_vectors():
- set
v["seed"] - call authenticator MC with
v["rp_id"](freely chooseuser_idand other parameters) - extract generated
credential_id,public_key, and pass toseedweed.conformance.verify_make_credentialtogether with the attested data that was signed
This test verifies that credential IDs generated by the authenticator can be used by spec-compliant implementations.
2. GetAssertion
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_idand 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.
On test vectors
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.
Installation
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.
Development
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).
Contributing
Please save files with UNIX-style line endings, and run make check to enforce
basic consistency (make fix can automatically fix most issues).