crypto: Use an atomic int for the key count.
parent
350578739c
commit
cf9ecbd0e8
|
@ -18,6 +18,7 @@ use std::mem;
|
||||||
#[cfg(feature = "sqlite-cryptostore")]
|
#[cfg(feature = "sqlite-cryptostore")]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::error::{OlmError, Result, SignatureError, VerificationResult};
|
use super::error::{OlmError, Result, SignatureError, VerificationResult};
|
||||||
|
@ -70,7 +71,7 @@ pub struct OlmMachine {
|
||||||
/// this is None, no action will be taken. After a sync request the client
|
/// this is None, no action will be taken. After a sync request the client
|
||||||
/// needs to set this for us, depending on the count we will suggest the
|
/// needs to set this for us, depending on the count we will suggest the
|
||||||
/// client to upload new keys.
|
/// client to upload new keys.
|
||||||
uploaded_signed_key_count: Option<u64>,
|
uploaded_signed_key_count: Option<AtomicU64>,
|
||||||
/// Store for the encryption keys.
|
/// Store for the encryption keys.
|
||||||
/// Persists all the encrytpion keys so a client can resume the session
|
/// Persists all the encrytpion keys so a client can resume the session
|
||||||
/// without the need to create new keys.
|
/// without the need to create new keys.
|
||||||
|
@ -170,16 +171,23 @@ impl OlmMachine {
|
||||||
|
|
||||||
// If we have a known key count, check that we have more than
|
// If we have a known key count, check that we have more than
|
||||||
// max_one_time_Keys() / 2, otherwise tell the client to upload more.
|
// max_one_time_Keys() / 2, otherwise tell the client to upload more.
|
||||||
match self.uploaded_signed_key_count {
|
match &self.uploaded_signed_key_count {
|
||||||
Some(count) => {
|
Some(count) => {
|
||||||
let max_keys = self.account.max_one_time_keys().await as u64;
|
let max_keys = self.account.max_one_time_keys().await as u64;
|
||||||
let key_count = (max_keys / 2) - count;
|
let key_count = (max_keys / 2) - count.load(Ordering::Relaxed);
|
||||||
key_count > 0
|
key_count > 0
|
||||||
}
|
}
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_key_count(&mut self, count: u64) {
|
||||||
|
match &self.uploaded_signed_key_count {
|
||||||
|
Some(c) => c.store(count, Ordering::Relaxed),
|
||||||
|
None => self.uploaded_signed_key_count = Some(AtomicU64::new(count)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Receive a successful keys upload response.
|
/// Receive a successful keys upload response.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -203,10 +211,12 @@ impl OlmMachine {
|
||||||
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
|
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
|
||||||
debug!(
|
debug!(
|
||||||
"Updated uploaded one-time key count {} -> {}, marking keys as published",
|
"Updated uploaded one-time key count {} -> {}, marking keys as published",
|
||||||
self.uploaded_signed_key_count.as_ref().map_or(0, |c| *c),
|
self.uploaded_signed_key_count
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |c| c.load(Ordering::Relaxed)),
|
||||||
count
|
count
|
||||||
);
|
);
|
||||||
self.uploaded_signed_key_count = Some(count);
|
self.update_key_count(count);
|
||||||
|
|
||||||
self.account.mark_keys_as_published().await;
|
self.account.mark_keys_as_published().await;
|
||||||
self.store.save_account(self.account.clone()).await?;
|
self.store.save_account(self.account.clone()).await?;
|
||||||
|
@ -470,8 +480,9 @@ impl OlmMachine {
|
||||||
/// Returns the number of newly generated one-time keys. If no keys can be
|
/// Returns the number of newly generated one-time keys. If no keys can be
|
||||||
/// generated returns an empty error.
|
/// generated returns an empty error.
|
||||||
async fn generate_one_time_keys(&self) -> StdResult<u64, ()> {
|
async fn generate_one_time_keys(&self) -> StdResult<u64, ()> {
|
||||||
match self.uploaded_signed_key_count {
|
match &self.uploaded_signed_key_count {
|
||||||
Some(count) => {
|
Some(count) => {
|
||||||
|
let count = count.load(Ordering::Relaxed);
|
||||||
let max_keys = self.account.max_one_time_keys().await as u64;
|
let max_keys = self.account.max_one_time_keys().await as u64;
|
||||||
let max_on_server = max_keys / 2;
|
let max_on_server = max_keys / 2;
|
||||||
|
|
||||||
|
@ -1244,7 +1255,7 @@ impl OlmMachine {
|
||||||
.get(&keys::KeyAlgorithm::SignedCurve25519);
|
.get(&keys::KeyAlgorithm::SignedCurve25519);
|
||||||
|
|
||||||
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
|
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
|
||||||
self.uploaded_signed_key_count = Some(count);
|
self.update_key_count(count);
|
||||||
|
|
||||||
for event_result in &mut response.to_device.events {
|
for event_result in &mut response.to_device.events {
|
||||||
let event = if let Ok(e) = event_result.deserialize() {
|
let event = if let Ok(e) = event_result.deserialize() {
|
||||||
|
@ -1389,6 +1400,7 @@ mod test {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
use std::sync::atomic::AtomicU64;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
@ -1463,7 +1475,7 @@ mod test {
|
||||||
|
|
||||||
async fn get_prepared_machine() -> (OlmMachine, OneTimeKeys) {
|
async fn get_prepared_machine() -> (OlmMachine, OneTimeKeys) {
|
||||||
let mut machine = OlmMachine::new(&user_id(), DEVICE_ID).unwrap();
|
let mut machine = OlmMachine::new(&user_id(), DEVICE_ID).unwrap();
|
||||||
machine.uploaded_signed_key_count = Some(0);
|
machine.uploaded_signed_key_count = Some(AtomicU64::new(0));
|
||||||
let (_, otk) = machine
|
let (_, otk) = machine
|
||||||
.keys_for_upload()
|
.keys_for_upload()
|
||||||
.await
|
.await
|
||||||
|
@ -1666,7 +1678,7 @@ mod test {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_one_time_key_signing() {
|
async fn test_one_time_key_signing() {
|
||||||
let mut machine = OlmMachine::new(&user_id(), DEVICE_ID).unwrap();
|
let mut machine = OlmMachine::new(&user_id(), DEVICE_ID).unwrap();
|
||||||
machine.uploaded_signed_key_count = Some(49);
|
machine.uploaded_signed_key_count = Some(AtomicU64::new(49));
|
||||||
|
|
||||||
let mut one_time_keys = machine.signed_one_time_keys().await.unwrap();
|
let mut one_time_keys = machine.signed_one_time_keys().await.unwrap();
|
||||||
let identity_keys = machine.account.identity_keys();
|
let identity_keys = machine.account.identity_keys();
|
||||||
|
@ -1686,7 +1698,7 @@ mod test {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_keys_for_upload() {
|
async fn test_keys_for_upload() {
|
||||||
let mut machine = OlmMachine::new(&user_id(), DEVICE_ID).unwrap();
|
let mut machine = OlmMachine::new(&user_id(), DEVICE_ID).unwrap();
|
||||||
machine.uploaded_signed_key_count = Some(0);
|
machine.uploaded_signed_key_count = Some(AtomicU64::default());
|
||||||
|
|
||||||
let identity_keys = machine.account.identity_keys();
|
let identity_keys = machine.account.identity_keys();
|
||||||
let ed25519_key = identity_keys.ed25519();
|
let ed25519_key = identity_keys.ed25519();
|
||||||
|
|
Loading…
Reference in New Issue