app_utils/
lib.rs

1//! # app-utils
2//!
3//! Utility modules for policy parsing and timestamps.
4//!
5//! This crate provides non-core features:
6//! - YAML policy parsing
7//! - Trusted timestamp management
8//!
9//! Shared utilities for policy parsing (YAML) and trusted timestamp validation.
10
11#![forbid(unsafe_code)]
12
13pub mod error;
14
15pub mod yaml {
16    //! YAML policy document parsing and serialization
17    use core_policy::{Policy, PolicyError};
18    use serde::{Deserialize, Serialize};
19
20    /// Trait for policy parsers (OCP - extensible to JSON, TOML, etc.)
21    pub trait PolicyParser {
22        /// Parse a policy from a string
23        fn parse(&self, input: &str) -> Result<Policy, PolicyError>;
24    }
25
26    /// YAML parser implementation
27    pub struct YamlParser;
28
29    impl PolicyParser for YamlParser {
30        fn parse(&self, input: &str) -> Result<Policy, PolicyError> {
31            let policy: Policy = serde_yaml::from_str(input)
32                .map_err(|e| PolicyError::SerializationError(format!("YAML parse error: {}", e)))?;
33            policy.validate()?;
34            Ok(policy)
35        }
36    }
37
38    /// Serialize a value to YAML
39    pub fn to_yaml<T: Serialize>(value: &T) -> Result<String, String> {
40        serde_yaml::to_string(value).map_err(|e| format!("YAML serialization error: {}", e))
41    }
42
43    /// Deserialize from YAML
44    pub fn from_yaml<'a, T: Deserialize<'a>>(input: &'a str) -> Result<T, String> {
45        serde_yaml::from_str(input).map_err(|e| format!("YAML deserialization error: {}", e))
46    }
47}
48
49pub mod timestamp {
50    //! Trusted timestamp authority integration
51
52    use super::error::Result;
53    use serde::{Deserialize, Serialize};
54    use std::time::{SystemTime, UNIX_EPOCH};
55
56    /// Trusted timestamp from a timestamp authority
57    #[derive(Debug, Clone, Serialize, Deserialize)]
58    pub struct TrustedTimestamp {
59        /// Unix timestamp in seconds
60        pub timestamp: u64,
61
62        /// Timestamp authority identifier
63        pub authority: String,
64
65        /// Signature over the timestamp
66        pub signature: Vec<u8>,
67    }
68
69    impl TrustedTimestamp {
70        /// Create a new timestamp (unsigned - for testing)
71        pub fn new(authority: String) -> Result<Self> {
72            let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
73
74            Ok(Self {
75                timestamp,
76                authority,
77                signature: Vec::new(),
78            })
79        }
80
81        /// Get the timestamp as SystemTime
82        pub fn as_system_time(&self) -> SystemTime {
83            UNIX_EPOCH + std::time::Duration::from_secs(self.timestamp)
84        }
85
86        /// Check if timestamp is within a certain age
87        pub fn is_fresh(&self, max_age_secs: u64) -> Result<bool> {
88            let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
89
90            Ok(now.saturating_sub(self.timestamp) <= max_age_secs)
91        }
92    }
93
94    /// Simple timestamp provider (system time)
95    #[derive(Debug, Default)]
96    pub struct SystemTimestampProvider {
97        authority_id: String,
98    }
99
100    impl SystemTimestampProvider {
101        /// Create a new provider
102        pub fn new(authority_id: String) -> Self {
103            Self { authority_id }
104        }
105
106        /// Get current timestamp
107        pub fn now(&self) -> Result<TrustedTimestamp> {
108            TrustedTimestamp::new(self.authority_id.clone())
109        }
110    }
111}
112
113/// Re-export `hex` crate for encoding/decoding utilities.
114pub use hex;
115
116/// Re-export commonly used types
117pub use error::{Error, Result};
118pub use yaml::{PolicyParser, YamlParser};