crypto: Store the device signatures with the devices as well.
parent
a9d645cbcd
commit
2481fbbd27
|
@ -36,6 +36,7 @@ pub struct Device {
|
||||||
device_id: Arc<Box<DeviceId>>,
|
device_id: Arc<Box<DeviceId>>,
|
||||||
algorithms: Arc<Vec<Algorithm>>,
|
algorithms: Arc<Vec<Algorithm>>,
|
||||||
keys: Arc<BTreeMap<AlgorithmAndDeviceId, String>>,
|
keys: Arc<BTreeMap<AlgorithmAndDeviceId, String>>,
|
||||||
|
signatures: Arc<BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>>>,
|
||||||
display_name: Arc<Option<String>>,
|
display_name: Arc<Option<String>>,
|
||||||
deleted: Arc<AtomicBool>,
|
deleted: Arc<AtomicBool>,
|
||||||
trust_state: Arc<Atomic<TrustState>>,
|
trust_state: Arc<Atomic<TrustState>>,
|
||||||
|
@ -75,12 +76,14 @@ impl Device {
|
||||||
trust_state: TrustState,
|
trust_state: TrustState,
|
||||||
algorithms: Vec<Algorithm>,
|
algorithms: Vec<Algorithm>,
|
||||||
keys: BTreeMap<AlgorithmAndDeviceId, String>,
|
keys: BTreeMap<AlgorithmAndDeviceId, String>,
|
||||||
|
signatures: BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Device {
|
Device {
|
||||||
user_id: Arc::new(user_id),
|
user_id: Arc::new(user_id),
|
||||||
device_id: Arc::new(device_id),
|
device_id: Arc::new(device_id),
|
||||||
display_name: Arc::new(display_name),
|
display_name: Arc::new(display_name),
|
||||||
trust_state: Arc::new(Atomic::new(trust_state)),
|
trust_state: Arc::new(Atomic::new(trust_state)),
|
||||||
|
signatures: Arc::new(signatures),
|
||||||
algorithms: Arc::new(algorithms),
|
algorithms: Arc::new(algorithms),
|
||||||
keys: Arc::new(keys),
|
keys: Arc::new(keys),
|
||||||
deleted: Arc::new(AtomicBool::new(false)),
|
deleted: Arc::new(AtomicBool::new(false)),
|
||||||
|
@ -115,6 +118,11 @@ impl Device {
|
||||||
&self.keys
|
&self.keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a map containing all the device signatures.
|
||||||
|
pub fn signatures(&self) -> &BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>> {
|
||||||
|
&self.signatures
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the trust state of the device.
|
/// Get the trust state of the device.
|
||||||
pub fn trust_state(&self) -> TrustState {
|
pub fn trust_state(&self) -> TrustState {
|
||||||
self.trust_state.load(Ordering::Relaxed)
|
self.trust_state.load(Ordering::Relaxed)
|
||||||
|
@ -144,6 +152,7 @@ impl Device {
|
||||||
|
|
||||||
self.algorithms = Arc::new(device_keys.algorithms.clone());
|
self.algorithms = Arc::new(device_keys.algorithms.clone());
|
||||||
self.keys = Arc::new(device_keys.keys.clone());
|
self.keys = Arc::new(device_keys.keys.clone());
|
||||||
|
self.signatures = Arc::new(device_keys.signatures.clone());
|
||||||
self.display_name = display_name;
|
self.display_name = display_name;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -180,6 +189,8 @@ impl Device {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl From<&OlmMachine> for Device {
|
impl From<&OlmMachine> for Device {
|
||||||
fn from(machine: &OlmMachine) -> Self {
|
fn from(machine: &OlmMachine) -> Self {
|
||||||
|
let signatures = BTreeMap::new();
|
||||||
|
|
||||||
Device {
|
Device {
|
||||||
user_id: Arc::new(machine.user_id().clone()),
|
user_id: Arc::new(machine.user_id().clone()),
|
||||||
device_id: Arc::new(machine.device_id().into()),
|
device_id: Arc::new(machine.device_id().into()),
|
||||||
|
@ -204,6 +215,7 @@ impl From<&OlmMachine> for Device {
|
||||||
),
|
),
|
||||||
display_name: Arc::new(None),
|
display_name: Arc::new(None),
|
||||||
deleted: Arc::new(AtomicBool::new(false)),
|
deleted: Arc::new(AtomicBool::new(false)),
|
||||||
|
signatures: Arc::new(signatures),
|
||||||
trust_state: Arc::new(Atomic::new(TrustState::Unset)),
|
trust_state: Arc::new(Atomic::new(TrustState::Unset)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,6 +229,7 @@ impl TryFrom<&DeviceKeys> for Device {
|
||||||
user_id: Arc::new(device_keys.user_id.clone()),
|
user_id: Arc::new(device_keys.user_id.clone()),
|
||||||
device_id: Arc::new(device_keys.device_id.clone()),
|
device_id: Arc::new(device_keys.device_id.clone()),
|
||||||
algorithms: Arc::new(device_keys.algorithms.clone()),
|
algorithms: Arc::new(device_keys.algorithms.clone()),
|
||||||
|
signatures: Arc::new(device_keys.signatures.clone()),
|
||||||
keys: Arc::new(device_keys.keys.clone()),
|
keys: Arc::new(device_keys.keys.clone()),
|
||||||
display_name: Arc::new(
|
display_name: Arc::new(
|
||||||
device_keys
|
device_keys
|
||||||
|
|
|
@ -272,6 +272,25 @@ impl SqliteStore {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
connection
|
||||||
|
.execute(
|
||||||
|
r#"
|
||||||
|
CREATE TABLE IF NOT EXISTS device_signatures (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
"device_id" INTEGER NOT NULL,
|
||||||
|
"user_id" TEXT NOT NULL,
|
||||||
|
"key_algorithm" TEXT NOT NULL,
|
||||||
|
"signature" TEXT NOT NULL,
|
||||||
|
FOREIGN KEY ("device_id") REFERENCES "devices" ("id")
|
||||||
|
ON DELETE CASCADE
|
||||||
|
UNIQUE(device_id, user_id, key_algorithm)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS "device_keys_device_id" ON "device_keys" ("device_id");
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,19 +492,55 @@ impl SqliteStore {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let keys: BTreeMap<AlgorithmAndDeviceId, String> = key_rows
|
let keys: BTreeMap<AlgorithmAndDeviceId, String> = key_rows
|
||||||
.iter()
|
.into_iter()
|
||||||
.filter_map(|row| {
|
.filter_map(|row| {
|
||||||
let algorithm: &str = &row.0;
|
let algorithm = KeyAlgorithm::try_from(&*row.0).ok()?;
|
||||||
let algorithm = KeyAlgorithm::try_from(algorithm).ok()?;
|
let key = row.1;
|
||||||
let key = &row.1;
|
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
AlgorithmAndDeviceId(algorithm, device_id.as_str().into()),
|
AlgorithmAndDeviceId(algorithm, device_id.as_str().into()),
|
||||||
key.to_owned(),
|
key,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let signature_rows: Vec<(String, String, String)> = query_as(
|
||||||
|
"SELECT user_id, key_algorithm, signature
|
||||||
|
FROM device_signatures WHERE device_id = ?",
|
||||||
|
)
|
||||||
|
.bind(device_row_id)
|
||||||
|
.fetch_all(&mut *connection)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut signatures: BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>> =
|
||||||
|
BTreeMap::new();
|
||||||
|
|
||||||
|
for row in signature_rows {
|
||||||
|
let user_id = if let Ok(u) = UserId::try_from(&*row.0) {
|
||||||
|
u
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let key_algorithm = if let Ok(k) = KeyAlgorithm::try_from(&*row.1) {
|
||||||
|
k
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let signature = row.2;
|
||||||
|
|
||||||
|
if !signatures.contains_key(&user_id) {
|
||||||
|
let _ = signatures.insert(user_id.clone(), BTreeMap::new());
|
||||||
|
}
|
||||||
|
let user_map = signatures.get_mut(&user_id).unwrap();
|
||||||
|
|
||||||
|
user_map.insert(
|
||||||
|
AlgorithmAndDeviceId(key_algorithm, device_id.as_str().into()),
|
||||||
|
signature.to_owned(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let device = Device::new(
|
let device = Device::new(
|
||||||
user_id,
|
user_id,
|
||||||
device_id.as_str().into(),
|
device_id.as_str().into(),
|
||||||
|
@ -493,6 +548,7 @@ impl SqliteStore {
|
||||||
trust_state,
|
trust_state,
|
||||||
algorithms,
|
algorithms,
|
||||||
keys,
|
keys,
|
||||||
|
signatures,
|
||||||
);
|
);
|
||||||
|
|
||||||
store.add(device);
|
store.add(device);
|
||||||
|
@ -562,6 +618,23 @@ impl SqliteStore {
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (user_id, signature_map) in device.signatures() {
|
||||||
|
for (key_id, signature) in signature_map {
|
||||||
|
query(
|
||||||
|
"INSERT OR IGNORE INTO device_signatures (
|
||||||
|
device_id, user_id, key_algorithm, signature
|
||||||
|
) VALUES (?1, ?2, ?3, ?4)
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.bind(device_row_id)
|
||||||
|
.bind(user_id.as_str())
|
||||||
|
.bind(key_id.0.to_string())
|
||||||
|
.bind(signature)
|
||||||
|
.execute(&mut *connection)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue