coven_crypto/custody/
key_session.rs1use super::{Custody, KeyError, KeyMaterial};
4use coven_foundation::locks::lock_unpoisoned;
5use std::sync::{Arc, Mutex};
6
7pub struct KeySession<T: KeyMaterial> {
11 held: Mutex<Option<Held<T>>>,
12}
13
14struct Held<T: KeyMaterial> {
15 keys: Option<T>,
16 custody: Arc<dyn Custody<T>>,
17}
18
19impl<T: KeyMaterial> KeySession<T> {
20 pub fn open(custody: Arc<dyn Custody<T>>) -> Result<Self, KeyError> {
22 let mut held = Held { keys: None, custody };
24 held.keys = held.custody.unlock()?;
25 Ok(Self { held: Mutex::new(Some(held)) })
26 }
27
28 pub fn read(&self) -> Result<Option<T>, KeyError> {
30 let held = lock_unpoisoned(&self.held);
31 Ok(held.as_ref().ok_or(KeyError::StoreClosed)?.keys.clone())
32 }
33
34 pub fn persist(&self, keys: &T) -> Result<(), KeyError> {
37 let mut held = lock_unpoisoned(&self.held);
38 let held = held.as_mut().ok_or(KeyError::StoreClosed)?;
39 held.custody.persist(keys)?;
40 held.keys = Some(keys.clone());
41 Ok(())
42 }
43
44 pub fn forget(&self) -> Result<(), KeyError> {
48 let mut held = lock_unpoisoned(&self.held);
49 let held = held.as_mut().ok_or(KeyError::StoreClosed)?;
50 held.custody.forget()?;
51 held.keys = None;
52 Ok(())
53 }
54
55 pub fn close(&self) {
58 lock_unpoisoned(&self.held).take();
59 }
60}
61
62impl<T: KeyMaterial> Drop for Held<T> {
63 fn drop(&mut self) {
64 self.keys.take();
65 self.custody.close();
66 }
67}
68
69impl<T: KeyMaterial> std::fmt::Debug for KeySession<T> {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 f.write_str("KeySession([REDACTED])")
72 }
73}
74
75#[cfg(test)]
76#[path = "key_session_tests.rs"]
77mod tests;