Skip to main content

Crate webauthn_kit

Crate webauthn_kit 

Source
Expand description

§webauthn-kit

Standalone WebAuthn / FIDO2 passkey verification kit: real CTAP2/COSE cryptographic verification with zero framework coupling. This is not a wrapper around navigator.credentials server emulation — it implements the server side of the protocol directly on ring.

§What it does

  • Full CTAP2 authenticator data parsing (rpIdHash, flags, signCount, attested credential data incl. AAGUID) — protocol
  • verify_registration / verify_authentication ceremonies — protocol
  • Attestation statement verification for the none, packed (self- and x5c-based basic/AttCA), and fido-u2f formats, with X.509 chain verification against caller-configured trust anchors — attestation
  • COSE public key parsing and signature verification for ES256 (ECDSA P-256 + SHA-256), ES384 (ECDSA P-384 + SHA-384), EdDSA (Ed25519), and RS256 (RSA PKCS#1 v1.5 + SHA-256) via ring — crypto
  • Enforceable credential policies — user verification (UV), multi-device / backup eligibility (BE/BS), and registration algorithm allowlists — policy
  • Challenge generation from the OS CSPRNG, single-use consumption (replay protection), freshness/expiry enforcement, and the sign-count clone-detection state machine — challenge
  • Storage-free credential record + browser wire DTOs — credential

§Quick start

use webauthn_kit::{
    check_sign_count, verify_authentication, verify_registration, AttestationPolicy,
    AuthenticationParams, ChallengeStore, CredentialPolicy, UserVerificationPolicy,
    WebauthnConfig,
};

let config = WebauthnConfig {
    rp_id: "example.com".into(),
    rp_name: "Example".into(),
    rp_origins: vec!["https://example.com".into()],
    allowed_algorithms: vec![-7, -35, -257], // ES256, ES384, RS256
    challenge_timeout_secs: 300,
    attestation: AttestationPolicy::default(),
    // Server-side enforcement: UV required, synced passkeys rejected.
    credential_policy: CredentialPolicy {
        user_verification: UserVerificationPolicy::Required,
        ..CredentialPolicy::default()
    },
    resident_key: Default::default(),
    attestation_conveyance: Default::default(),
};

// 1. Issue a challenge (single-use; store the (id, bytes) pair).
let store = ChallengeStore::new();
let (challenge_b64, create_options) =
    store.generate_registration_challenge(&config, "alice", "Alice", &[]);
// ... send `create_options` to the browser, receive RegistrationResponse ...

// 2. Verify a registration response (see tests/vectors.rs for a full
//    roundtrip with a synthetic keypair).
// let result = verify_registration(&challenge, &client_data_json_b64,
//     &attestation_object_b64, "", &config.rp_id, &config.rp_origins,
//     &config.attestation)?;

// 3. Verify an assertion; persist result.new_sign_count afterwards.
// let result = verify_authentication(&AuthenticationParams { ... })?;

§Storage contract (what this crate does NOT do)

This crate is deliberately storage-free. The integrator owns:

§Security notes

  • #![forbid(unsafe_code)]; all cryptography via ring.
  • Every parser accepts hostile input and returns Err instead of panicking (property/fuzz-tested in tests/fuzz.rs).
  • Challenge bytes are 32 bytes from the OS CSPRNG; consumption is single-use and freshness-bounded.
  • Attestation is verified for none, packed, and fido-u2f; unknown formats are rejected unless the AttestationPolicy::allow_unknown_formats escape hatch is set (trust-weakening). Provenance claims are bounded by the configured trust anchors: with none configured, unanchored certificate chains are accepted but flagged (TrustLevel::BasicAtt + warning) and must be treated as self-attested. Only TrustLevel::AttCa attests device provenance. Other formats (android-key, tpm, …) are tranche-2 work — see attestation.
  • Supported algorithms: ES256 (COSE −7), ES384 (COSE −35), EdDSA (Ed25519, COSE −8), and RS256 (COSE −257). Curve/algorithm bindings are enforced at parse time (a P-256 key claiming ES384 is rejected); other algorithms are rejected with WebauthnError::UnsupportedAlgorithm.
  • Sign-count policy: a stored counter of 0 disables the check (authenticators without counters); otherwise a strictly decreasing counter is rejected. Equal counters are allowed by design.
  • User verification (policy::UserVerificationPolicy): Required is enforced server-side — ceremonies whose authenticator UV flag is clear fail with WebauthnError::UserVerificationRequired. The default (Preferred) reports the flag without rejecting, preserving per-caller policy decisions.
  • Multi-device credentials (policy::BackupPolicy): the BE/BS flags are parsed from signed authenticator data and reported on both ceremony results; BackupPolicy::RequireDeviceBound rejects syncable (BE=1) credentials. See the policy module docs for account-recovery implications before allowing synced passkeys on sensitive flows.

Re-exports§

pub use aaguid::known_aaguid;
pub use attestation::verify_attestation;
pub use attestation::AttestationFormat;
pub use attestation::AttestationPolicy;
pub use attestation::AttestationResult;
pub use attestation::TrustLevel;
pub use challenge::check_sign_count;
pub use challenge::ChallengeStore;
pub use config::WebauthnConfig;
pub use credential::AllowCredential;
pub use credential::AuthenticationOptions;
pub use credential::AuthenticationResponse;
pub use credential::AuthenticationResult;
pub use credential::AuthenticatorSelection;
pub use credential::ExcludeCredential;
pub use credential::PubKeyCredParam;
pub use credential::RegistrationOptions;
pub use credential::RegistrationResponse;
pub use credential::RegistrationResult;
pub use credential::RelyingParty;
pub use credential::WebauthnCredential;
pub use credential::WebauthnUser;
pub use crypto::alg_to_name;
pub use crypto::base64_decode_urlsafe;
pub use crypto::base64_encode_urlsafe;
pub use crypto::cbor_bytes;
pub use crypto::cbor_map_entries;
pub use crypto::generate_challenge_bytes;
pub use crypto::parse_cose_key;
pub use crypto::verify_cose_signature;
pub use crypto::CosePublicKey;
pub use crypto::COSE_ALG_EDDSA;
pub use crypto::COSE_ALG_ES256;
pub use crypto::COSE_ALG_ES384;
pub use crypto::COSE_ALG_RS256;
pub use crypto::COSE_CRV_ED25519;
pub use crypto::COSE_CRV_P384;
pub use crypto::COSE_KTY_EC2;
pub use crypto::COSE_KTY_OKP;
pub use crypto::COSE_KTY_RSA;
pub use error::WebauthnError;
pub use policy::AttestationConveyance;
pub use policy::BackupPolicy;
pub use policy::CredentialPolicy;
pub use policy::ResidentKeyPolicy;
pub use policy::UserVerificationPolicy;
pub use protocol::verify_authentication;
pub use protocol::verify_registration;
pub use protocol::AuthenticationParams;

Modules§

aaguid
Well-known authenticator AAGUIDs (informational registry).
attestation
Attestation statement parsing and verification (WebAuthn Level 2 §8).
challenge
Challenge generation, single-use consumption (replay protection), freshness/expiry enforcement, and the sign-count clone-detection state machine.
config
Relying-party configuration.
credential
WebAuthn credential descriptor and protocol DTOs (options, responses, results).
crypto
COSE key parsing and signature verification (ES256 / ES384 / RS256 / EdDSA) via ring, plus base64url helpers and CSPRNG challenge generation.
error
Error type for all webauthn-kit operations.
policy
Caller-enforceable credential policies for the registration and authentication ceremonies.
protocol
CTAP2 protocol parsing and ceremony verification.