reachable_secrets/
server.rs1use std::path::{Path, PathBuf};
6use std::sync::Arc;
7
8use redb::Database;
9use tokio::sync::RwLock;
10
11use reach_core::{
12 communication::secrets::*,
13 memory::{ImmutableCell, Key, macros::immutable_cell},
14 wire::{AttestantVerifyingKeys, ReachableVerifyingKeys, Salts},
15};
16use reach_proc_macros::request_handler_macro;
17use reach_signatures::Digestible;
18use reach_websocket::{LocalServerContext, WebSocketServer, macros::*, start as core_start};
19
20use crate::error::Error;
21use crate::memory::ReachableSigningKeys;
22
23pub struct SecretsGlobalContext {
24 data_path: PathBuf,
25 pub db: Database,
26}
27
28impl SecretsGlobalContext {
29 pub fn new(data_path: PathBuf) -> Self {
30 let db = Database::create(data_path.join("database.redb"))
31 .expect("Database path should be writeable.");
32
33 Self { data_path, db }
34 }
35
36 pub fn data_path<P: AsRef<Path>>(&self, path: P) -> PathBuf {
37 self.data_path.join(path)
38 }
39}
40
41pub struct SecretsSessionContext {
42 unlocked_key: ImmutableCell<Key>,
43 attestant_verifying_keys: ImmutableCell<AttestantVerifyingKeys>,
44 salts: ImmutableCell<Salts>,
45 signing_keys: ImmutableCell<ReachableSigningKeys>,
46 pub all_verifying_keys: Option<Vec<ReachableVerifyingKeys>>,
47 pub verifying_keys: Option<usize>,
48}
49
50impl From<SecretsSessionContext> for () {
51 fn from(_: SecretsSessionContext) {}
52}
53
54#[derive(Clone)]
55pub struct SecretsSessionContextInit {}
56
57impl From<SecretsSessionContextInit> for Arc<RwLock<SecretsSessionContext>> {
58 fn from(_: SecretsSessionContextInit) -> Self {
59 Arc::new(RwLock::new(SecretsSessionContext {
60 unlocked_key: ImmutableCell::new(),
61 attestant_verifying_keys: ImmutableCell::new(),
62 salts: ImmutableCell::new(),
63 signing_keys: ImmutableCell::new(),
64 verifying_keys: None,
65 all_verifying_keys: None,
66 }))
67 }
68}
69
70impl SecretsSessionContext {
71 pub fn verifying_keys(&self) -> Result<&ReachableVerifyingKeys, Error> {
72 let all_verifying_keys = self
73 .all_verifying_keys
74 .as_ref()
75 .ok_or(Error::MissingVerifyingKeys)?;
76 let idx = self.verifying_keys.ok_or(Error::MissingVerifyingKeys)?;
77
78 all_verifying_keys
79 .get(idx)
80 .ok_or(Error::MissingVerifyingKeys)
81 }
82
83 immutable_cell!(or: unlocked_key, Key, Error::Internal);
84 immutable_cell!(or: salts, Salts, Error::Internal);
85 immutable_cell!(or: attestant_verifying_keys, AttestantVerifyingKeys, Error::Internal);
86 immutable_cell!(or_init: signing_keys, ReachableSigningKeys, Error);
87}
88
89pub type SecretsConnectionContext = LocalServerContext<Request, Response>;
90pub type SecretsConnection = WebSocketServer<SecretsConnectionContext>;
91
92request_wrapper!(SecretsRequest, Request);
93
94request_delegator!(
95 SecretsDelegator,
96 SecretsCommunication,
97 SecretsGlobalContext,
98 SecretsSessionContext,
99 SecretsRequest,
100 (
101 Hello,
102 Initialize,
103 UnlockKey,
104 GetReachablePublicKeys,
105 AllReachableVerifyingKeys,
106 ),
107);
108
109request_handler_macro!(
110 request_handler,
111 SecretsCommunication,
112 SecretsRequest,
113 SecretsGlobalContext,
114 SecretsSessionContext,
115);
116
117pub async fn start<const B: usize>(
118 socket_path: impl AsRef<Path>,
119 global_context: SecretsGlobalContext,
120 session_context_init: SecretsSessionContextInit,
121) -> std::io::Result<()> {
122 core_start::<B, (), SecretsDelegator, SecretsCommunication, SecretsConnectionContext>(
123 socket_path,
124 (),
125 global_context,
126 session_context_init,
127 )
128 .await
129}
130
131pub(crate) fn populate_verifying_keys(
132 ctx: &mut SecretsSessionContext,
133 all_reachable_verifying_keys: &[ReachableVerifyingKeys],
134 verifying_keys_index: usize,
135) {
136 ctx.all_verifying_keys
137 .replace(all_reachable_verifying_keys.to_vec());
138 ctx.verifying_keys.replace(verifying_keys_index);
139}
140
141pub(crate) fn verifying_keys_index(
142 signing_keys: &ReachableSigningKeys,
143 reachable_verifying_keys: &[ReachableVerifyingKeys],
144) -> Result<usize, Error> {
145 let verifying_keys_digest = signing_keys.unsigned_verifying_keys().finalized_digest();
146
147 reachable_verifying_keys
148 .iter()
149 .enumerate()
150 .fold(None, |acc, (i, vk)| match acc {
151 Some(_) => acc,
152 None => (vk.finalized_digest() == verifying_keys_digest).then_some(i),
153 })
154 .ok_or(Error::MissingVerifyingKeys)
155}