crypto: Store the device signatures with the devices as well.
This commit is contained in:
parent
a9d645cbcd
commit
2481fbbd27
2 changed files with 91 additions and 5 deletions
|
@ -36,6 +36,7 @@ pub struct Device {
|
|||
device_id: Arc<Box<DeviceId>>,
|
||||
algorithms: Arc<Vec<Algorithm>>,
|
||||
keys: Arc<BTreeMap<AlgorithmAndDeviceId, String>>,
|
||||
signatures: Arc<BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>>>,
|
||||
display_name: Arc<Option<String>>,
|
||||
deleted: Arc<AtomicBool>,
|
||||
trust_state: Arc<Atomic<TrustState>>,
|
||||
|
@ -75,12 +76,14 @@ impl Device {
|
|||
trust_state: TrustState,
|
||||
algorithms: Vec<Algorithm>,
|
||||
keys: BTreeMap<AlgorithmAndDeviceId, String>,
|
||||
signatures: BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>>,
|
||||
) -> Self {
|
||||
Device {
|
||||
user_id: Arc::new(user_id),
|
||||
device_id: Arc::new(device_id),
|
||||
display_name: Arc::new(display_name),
|
||||
trust_state: Arc::new(Atomic::new(trust_state)),
|
||||
signatures: Arc::new(signatures),
|
||||
algorithms: Arc::new(algorithms),
|
||||
keys: Arc::new(keys),
|
||||
deleted: Arc::new(AtomicBool::new(false)),
|
||||
|
@ -115,6 +118,11 @@ impl Device {
|
|||
&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.
|
||||
pub fn trust_state(&self) -> TrustState {
|
||||
self.trust_state.load(Ordering::Relaxed)
|
||||
|
@ -144,6 +152,7 @@ impl Device {
|
|||
|
||||
self.algorithms = Arc::new(device_keys.algorithms.clone());
|
||||
self.keys = Arc::new(device_keys.keys.clone());
|
||||
self.signatures = Arc::new(device_keys.signatures.clone());
|
||||
self.display_name = display_name;
|
||||
|
||||
Ok(())
|
||||
|
@ -180,6 +189,8 @@ impl Device {
|
|||
#[cfg(test)]
|
||||
impl From<&OlmMachine> for Device {
|
||||
fn from(machine: &OlmMachine) -> Self {
|
||||
let signatures = BTreeMap::new();
|
||||
|
||||
Device {
|
||||
user_id: Arc::new(machine.user_id().clone()),
|
||||
device_id: Arc::new(machine.device_id().into()),
|
||||
|
@ -204,6 +215,7 @@ impl From<&OlmMachine> for Device {
|
|||
),
|
||||
display_name: Arc::new(None),
|
||||
deleted: Arc::new(AtomicBool::new(false)),
|
||||
signatures: Arc::new(signatures),
|
||||
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()),
|
||||
device_id: Arc::new(device_keys.device_id.clone()),
|
||||
algorithms: Arc::new(device_keys.algorithms.clone()),
|
||||
signatures: Arc::new(device_keys.signatures.clone()),
|
||||
keys: Arc::new(device_keys.keys.clone()),
|
||||
display_name: Arc::new(
|
||||
device_keys
|
||||
|
|
|
@ -272,6 +272,25 @@ impl SqliteStore {
|
|||
)
|
||||
.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(())
|
||||
}
|
||||
|
||||
|
@ -473,19 +492,55 @@ impl SqliteStore {
|
|||
.await?;
|
||||
|
||||
let keys: BTreeMap<AlgorithmAndDeviceId, String> = key_rows
|
||||
.iter()
|
||||
.into_iter()
|
||||
.filter_map(|row| {
|
||||
let algorithm: &str = &row.0;
|
||||
let algorithm = KeyAlgorithm::try_from(algorithm).ok()?;
|
||||
let key = &row.1;
|
||||
let algorithm = KeyAlgorithm::try_from(&*row.0).ok()?;
|
||||
let key = row.1;
|
||||
|
||||
Some((
|
||||
AlgorithmAndDeviceId(algorithm, device_id.as_str().into()),
|
||||
key.to_owned(),
|
||||
key,
|
||||
))
|
||||
})
|
||||
.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(
|
||||
user_id,
|
||||
device_id.as_str().into(),
|
||||
|
@ -493,6 +548,7 @@ impl SqliteStore {
|
|||
trust_state,
|
||||
algorithms,
|
||||
keys,
|
||||
signatures,
|
||||
);
|
||||
|
||||
store.add(device);
|
||||
|
@ -562,6 +618,23 @@ impl SqliteStore {
|
|||
.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(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue