Skip to content

Commit

Permalink
Don't panic if we're trying to dehydrate an Account libolm has created
Browse files Browse the repository at this point in the history
  • Loading branch information
poljar committed Jan 17, 2025
1 parent c0d22ed commit 62d871e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ pub enum DehydratedDeviceError {
/// There was an error with the libolm pickle format
#[error(transparent)]
LibolmPickle(#[from] LibolmPickleError),
/// The current account was created by libolm and can't be converted into a
/// dehydrated device.
#[error("The Account can't be turned into a dehydrated device since it was created by libolm")]
InvalidAccocunt,
}

/// Error type describing the different ways message decoding can fail.
Expand Down
20 changes: 13 additions & 7 deletions src/olm/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,15 +479,18 @@ impl Account {
use self::dehydrated_device::Pickle;
use crate::{utilities::base64_encode, DehydratedDeviceError, LibolmPickleError};

let pickle: Pickle = self.into();
let pickle: Pickle = self.try_into()?;
let mut encoded = pickle
.encode_to_vec()
.map_err(|e| DehydratedDeviceError::LibolmPickle(LibolmPickleError::Encode(e)))?;

let cipher = ChaCha20Poly1305::new(key.into());
let rng = thread_rng();
let nonce = ChaCha20Poly1305::generate_nonce(rng);
let ciphertext = cipher.encrypt(&nonce, encoded.as_slice());

encoded.zeroize();

let ciphertext = ciphertext?;

Ok(DehydratedDeviceResult {
Expand Down Expand Up @@ -883,8 +886,10 @@ mod dehydrated_device {

pub(super) const PICKLE_VERSION: u32 = 1;

impl From<&Account> for Pickle {
fn from(account: &Account) -> Self {
impl TryFrom<&Account> for Pickle {
type Error = DehydratedDeviceError;

fn try_from(account: &Account) -> Result<Self, Self::Error> {
let one_time_keys: Vec<_> = account
.one_time_keys
.secret_keys()
Expand All @@ -895,16 +900,16 @@ mod dehydrated_device {
let fallback_key =
account.fallback_keys.fallback_key.as_ref().and_then(|f| f.try_into().ok());

Self {
Ok(Self {
version: PICKLE_VERSION,
private_curve25519_key: account.diffie_hellman_key.secret_key().to_bytes(),
private_ed25519_key: account
.signing_key
.unexpanded_secret_key()
.expect("Cannot dehydrate an account created from a libolm pickle"),
.ok_or_else(|| DehydratedDeviceError::InvalidAccocunt)?,
one_time_keys,
opt_fallback_key: OptFallbackKey { fallback_key },
}
})
}
}

Expand Down Expand Up @@ -1591,7 +1596,8 @@ mod test {
let alice = Account::new();

let mut encoded = Vec::<u8>::new();
let pickle = Pickle::from(&alice);
let pickle = Pickle::try_from(&alice)
.expect("We should be able to create a dehydrated device from the account");
let size = pickle.encode(&mut encoded).expect("Should dehydrate");
assert_eq!(size, encoded.len());

Expand Down

0 comments on commit 62d871e

Please sign in to comment.