dig-stun 0.2.0

RFC 5389 STUN codec, client, address-scope table, peer observation and agreement — how a DIG node learns and believes its public address.
Documentation
//! The signed-Binding credential (`SPEC.md` §14) — how a DIG-operated UDP STUN server tells a DIG
//! node's ask from anyone else's.
//!
//! A **signed Binding** is an RFC 5389 Binding request that carries the requester's TLS-leaf
//! `SubjectPublicKeyInfo` and an ECDSA-P256 signature, by that leaf's private key, over a
//! server-issued nonce. It proves three things and only three: (1) the sender **holds the private
//! key** of the SPKI it carries — the same key whose SHA-256 is its `peer_id` on every mTLS peer
//! session; (2) the sender **received the server's challenge** at the source address it is sending
//! from (return-routability); (3) the request is **fresh** (≤ 120 s) and **bound to this server**.
//!
//! **It proves nothing about network membership.** Any party can mint a P-256 key in microseconds
//! and complete the exchange (§14.10). What it buys is attributability (every answer is tied to a
//! `peer_id`), an accident/scanner filter, a cost floor (one signature per ask, ~200 µs of CPU), and
//! a pre-crypto gate (no signature is verified for a source that has not completed a round trip). A
//! caller MUST NOT describe a verified credential as access control or as proof the sender is a
//! member of the DIG network.
//!
//! Internally split by concern — wire plumbing, the nonce, the signature, the request shape, the
//! error-response shape, the decision table, and the signed client — but every public item is
//! re-exported flat at this module's own path (`SPEC.md` §8.1), matching how this crate's own
//! (private) `codec` and `client` modules are flattened to the crate root.

mod decide;
mod nonce;
mod request;
mod response;
mod signature;
mod signed_client;
mod wire;

pub use decide::{decide, CredentialMode, ServerDecision};
pub use nonce::{NonceCheck, NonceIssuer, NONCE_BUCKET_SECS, NONCE_LEN};
pub use request::{classify_request, encode_identity_request, encode_signed_request, RequestKind};
pub use response::{encode_challenge, parse_challenge, Challenge};
pub use signature::{
    signing_message, verify_signed_request, StunSigner, VerifiedIdentity, SIG_DOMAIN_TAG,
};
pub use signed_client::{query_reflexive_address_signed, SignedQueryError};
pub use wire::{
    CredentialError, ATTR_DIG_IDENTITY, ATTR_DIG_SIGNATURE, ATTR_ERROR_CODE, ATTR_NONCE,
    ATTR_REALM, BINDING_ERROR, CREDENTIAL_VERSION, ERR_BAD_REQUEST, ERR_STALE_NONCE,
    ERR_UNAUTHENTICATED, MAX_SIGNATURE_LEN, P256_SPKI_LEN, P256_SPKI_PREFIX, REALM,
};