Files
AuraVPN/crates/aura-pki/src/lib.rs
T
xah30 b8ce58ddf0 feat(crypto,pki): implement Wave 1 — hybrid KEM + PKI
aura-crypto: X25519 + ML-KEM-768 (FIPS 203) hybrid KEM, HKDF-SHA256 session
key derivation, ChaCha20-Poly1305 AeadSession with counter nonces; genuine
NIST ACVP ML-KEM-768 KAT (decapsulation vector). 16 tests green, clippy clean.

aura-pki: self-signed CA, server/client cert issuance (rcgen 0.14), mutual
X.509 chain verification via rustls-webpki, CRL revocation. 8 tests green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:55:06 +03:00

54 lines
1.9 KiB
Rust

//! aura-pki — mutual X.509 authentication for the Aura VPN.
//!
//! A self-signed Aura CA ([`AuraCa`]) issues a server certificate (carrying a
//! DNS SAN) and per-client certificates (`CN = client_id`). The server verifies
//! client certificates against the CA and the client verifies the server
//! certificate against the CA via [`AuraCertVerifier`]. v1 revocation is a
//! simple CRL: a set of revoked certificate serials or client ids, see
//! [`AuraCertVerifier::set_revoked`] and [`CrlStore`].
//!
//! Certificates use ECDSA P-256 / SHA-256 keys (rcgen's default), and chain
//! verification is performed with `rustls-webpki` against the CA trust anchor.
mod ca;
mod cert;
mod store;
pub use ca::{AuraCa, IssuedCert};
pub use cert::AuraCertVerifier;
pub use store::CrlStore;
/// Errors produced by the Aura PKI.
#[derive(Debug, thiserror::Error)]
pub enum PkiError {
/// A PEM/DER blob could not be parsed into a certificate.
#[error("failed to parse certificate: {0}")]
CertParse(String),
/// The supplied certificate chain was empty.
#[error("empty certificate chain")]
EmptyChain,
/// The trust anchor (CA certificate) could not be constructed.
#[error("invalid trust anchor: {0}")]
TrustAnchor(String),
/// Chain verification against the CA failed (bad signature, expired,
/// untrusted issuer, wrong key usage, ...).
#[error("certificate chain verification failed: {0}")]
Verification(String),
/// The server certificate is not valid for the requested name.
#[error("certificate is not valid for name '{0}'")]
NameMismatch(String),
/// The end-entity certificate did not contain the expected identity, e.g. a
/// client certificate without a Common Name.
#[error("missing identity in certificate: {0}")]
MissingIdentity(String),
/// The certificate was found in the revocation list.
#[error("certificate is revoked: {0}")]
Revoked(String),
}