lockbook_shared/
access_info.rs

1use crate::account::Account;
2use crate::crypto::{AESEncrypted, AESKey};
3use crate::{pubkey, symkey, SharedResult};
4use libsecp256k1::PublicKey;
5use serde::{Deserialize, Serialize};
6
7pub type EncryptedUserAccessKey = AESEncrypted<AESKey>;
8pub type EncryptedFolderAccessKey = AESEncrypted<AESKey>;
9
10#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
11pub enum UserAccessMode {
12    Read,
13    Write,
14    Owner, // todo: remove
15}
16
17#[derive(Serialize, Deserialize, Debug, Clone)]
18pub struct UserAccessInfo {
19    pub mode: UserAccessMode,
20    pub encrypted_by: PublicKey,
21    pub encrypted_for: PublicKey,
22    pub access_key: EncryptedUserAccessKey,
23    pub deleted: bool,
24}
25
26impl PartialEq for UserAccessInfo {
27    fn eq(&self, other: &Self) -> bool {
28        self.mode == other.mode
29            && self.encrypted_for == other.encrypted_for
30            && self.encrypted_by == other.encrypted_by
31            && self.deleted == other.deleted
32    }
33}
34
35impl UserAccessInfo {
36    pub fn encrypt(
37        account: &Account, encrypted_by: &PublicKey, encrypted_for: &PublicKey, key: &AESKey,
38        mode: UserAccessMode,
39    ) -> SharedResult<Self> {
40        let private_key = account.private_key;
41        let user_key = pubkey::get_aes_key(&private_key, encrypted_for)?;
42        let encrypted_file_key = symkey::encrypt(&user_key, key)?;
43        Ok(UserAccessInfo {
44            mode,
45            encrypted_by: *encrypted_by,
46            encrypted_for: *encrypted_for,
47            access_key: encrypted_file_key,
48            deleted: false,
49        })
50    }
51
52    pub fn decrypt(&self, account: &Account) -> SharedResult<AESKey> {
53        let shared_secret = pubkey::get_aes_key(&account.private_key, &self.encrypted_by)?;
54        let encrypted = &self.access_key;
55        let decrypted = symkey::decrypt(&shared_secret, encrypted)?;
56        Ok(decrypted)
57    }
58}
59
60#[cfg(test)]
61mod unit_tests {
62    use crate::access_info::{UserAccessInfo, UserAccessMode};
63    use crate::account::Account;
64    use crate::symkey;
65
66    #[test]
67    fn encrypt_decrypt_1() {
68        let account = Account::new("test1".to_string(), "test2".to_string());
69        let key = symkey::generate_key();
70        let encrypted = UserAccessInfo::encrypt(
71            &account,
72            &account.public_key(),
73            &account.public_key(),
74            &key,
75            UserAccessMode::Write,
76        )
77        .unwrap();
78        let decrypted = encrypted.decrypt(&account).unwrap();
79        assert_eq!(key, decrypted);
80    }
81
82    #[test]
83    fn encrypt_decrypt_2() {
84        let account1 = Account::new("test1".to_string(), "test2".to_string());
85        let account2 = Account::new("test2".to_string(), "test2".to_string());
86        let key = symkey::generate_key();
87        let encrypted = UserAccessInfo::encrypt(
88            &account1,
89            &account1.public_key(),
90            &account2.public_key(),
91            &key,
92            UserAccessMode::Write,
93        )
94        .unwrap();
95        let decrypted = encrypted.decrypt(&account2).unwrap();
96        assert_eq!(key, decrypted);
97    }
98}