Skip to main content

kipuka_otp/
lib.rs

1//! One-Time Password generation, validation, and lifecycle for EST enrollment.
2//!
3//! Provides OTP creation, cryptographic storage, and consumption for EST
4//! enrollment authentication per RHELBU-3536 R7-R12:
5//! - R7: Minimum 128-bit entropy for generated tokens
6//! - R8: Timing-safe comparison during validation
7//! - R9: Single-use and multi-use token support
8//! - R10: Configurable expiration and max-use limits
9//! - R11: Tokens stored as SHA-256 hashes (never plaintext)
10//! - R12: Periodic cleanup of expired tokens
11
12pub mod generate;
13pub mod store;
14pub mod validate;
15
16pub use generate::{OtpGenerator, OtpGeneratorConfig, OtpMetadata};
17pub use store::{DbOtpStore, InMemoryOtpStore, OtpRecord, OtpStore as OtpStoreTrait};
18pub use validate::{OtpValidator, ValidationResult};
19
20use std::sync::Arc;
21
22/// Errors produced by OTP operations.
23#[derive(Debug, thiserror::Error)]
24pub enum OtpError {
25    /// The supplied OTP token was not found in the store.
26    #[error("OTP token not found")]
27    NotFound,
28
29    /// The OTP has expired.
30    #[error("OTP has expired (expired at {expired_at})")]
31    Expired {
32        /// ISO-8601 expiration timestamp.
33        expired_at: String,
34    },
35
36    /// The OTP has exceeded its maximum usage count.
37    #[error("OTP usage limit exceeded ({max_uses} uses allowed)")]
38    UsageLimitExceeded {
39        /// Configured maximum uses.
40        max_uses: u32,
41    },
42
43    /// The OTP has been explicitly revoked by an administrator.
44    #[error("OTP has been revoked")]
45    Revoked,
46
47    /// Cryptographic or RNG error during token generation.
48    #[error("token generation failed: {0}")]
49    GenerationError(String),
50
51    /// Storage backend error.
52    #[error("storage error: {0}")]
53    StorageError(String),
54}
55
56/// Convenience alias for OTP operation results.
57pub type OtpResult<T> = Result<T, OtpError>;
58
59/// Placeholder OTP storage and validation engine.
60///
61/// Preserves backward compatibility with the main binary's initialization
62/// until the full OTP subsystem is wired in.
63pub struct OtpStore {
64    _private: (),
65}
66
67impl OtpStore {
68    /// Create a placeholder OTP store (backend integration pending).
69    pub fn placeholder() -> Arc<Self> {
70        Arc::new(Self { _private: () })
71    }
72}