diff --git a/src-tauri/src/sync/pairing.rs b/src-tauri/src/sync/pairing.rs index 4ccd070..7979396 100644 --- a/src-tauri/src/sync/pairing.rs +++ b/src-tauri/src/sync/pairing.rs @@ -1,10 +1,10 @@ -use aes_gcm::{ Aes256Gcm, KeyInit }; use aes_gcm::aead::Aead; -use base64::{ engine::general_purpose::STANDARD, Engine }; -use rand::thread_rng; -use rand::Rng; +use aes_gcm::{Aes256Gcm, KeyInit}; +use base64::{engine::general_purpose::STANDARD, Engine}; +use rand::rng; use rand::seq::SliceRandom; -use serde::{ Deserialize, Serialize }; +use rand::Rng; +use serde::{Deserialize, Serialize}; use tauri::State; use uuid::Uuid; @@ -25,10 +25,10 @@ pub struct PairingManager { impl PairingManager { pub fn new() -> Self { - let mut rng = thread_rng(); + let mut rng = rng(); let pairing_key = Self::generate_emoji_sequence(&mut rng); - let encryption_key = rng.gen::<[u8; 32]>(); - let nonce = rng.gen::<[u8; 12]>(); + let encryption_key = rng.random::<[u8; 32]>(); + let nonce = rng.random::<[u8; 12]>(); PairingManager { pairing_key, encryption_key, @@ -39,7 +39,12 @@ impl PairingManager { pub fn generate_emoji_sequence(rng: &mut R) -> String { let mut emojis = EMOJI_POOL.to_vec(); emojis.shuffle(rng); - emojis.iter().take(PAIRING_KEY_LENGTH).cloned().collect::>().join(" ") + emojis + .iter() + .take(PAIRING_KEY_LENGTH) + .cloned() + .collect::>() + .join(" ") } pub fn validate_pairing(&self, input_key: &str) -> bool { @@ -53,52 +58,70 @@ impl PairingManager { pub fn get_nonce(&self) -> &[u8; 12] { &self.nonce } +} - pub fn generate_invitation_code(&self) -> String { - Uuid::new_v4().to_string() - } +#[tauri::command] +pub fn generate_invitation_code(_pairing_manager: State<'_, PairingManager>) -> String { + Uuid::new_v4().to_string() +} - pub fn encrypt_key(&self, key: &[u8; 32]) -> Result { - let cipher = Aes256Gcm::new(&self.encryption_key.into()); - let ciphertext = cipher - .encrypt(&self.nonce.into(), key.as_ref()) - .map_err(|e| e.to_string())?; - Ok(STANDARD.encode(ciphertext)) - } +#[tauri::command] +pub fn encrypt_key( + pairing_manager: State<'_, PairingManager>, + key: Vec, +) -> Result { + let key_array: [u8; 32] = key + .try_into() + .map_err(|_| "Invalid key length".to_string())?; + let cipher = Aes256Gcm::new(&pairing_manager.encryption_key.into()); + let ciphertext = cipher + .encrypt(&pairing_manager.nonce.into(), key_array.as_ref()) + .map_err(|e| e.to_string())?; + Ok(STANDARD.encode(ciphertext)) +} - pub fn decrypt_key(&self, encrypted_key: &str) -> Result<[u8; 32], String> { - let ciphertext = STANDARD.decode(encrypted_key).map_err(|e| e.to_string())?; - let cipher = Aes256Gcm::new(&self.encryption_key.into()); - let plaintext = cipher - .decrypt(&self.nonce.into(), ciphertext.as_ref()) - .map_err(|e| e.to_string())?; - let mut key = [0u8; 32]; - key.copy_from_slice(&plaintext); - Ok(key) - } +#[tauri::command] +pub fn decrypt_key( + pairing_manager: State<'_, PairingManager>, + encrypted_key: String, +) -> Result, String> { + let ciphertext = STANDARD.decode(&encrypted_key).map_err(|e| e.to_string())?; + let cipher = Aes256Gcm::new(&pairing_manager.encryption_key.into()); + let plaintext = cipher + .decrypt(&pairing_manager.nonce.into(), ciphertext.as_ref()) + .map_err(|e| e.to_string())?; + Ok(plaintext) +} - pub fn create_pairing_request(&self, inviter_id: String) -> PairingRequest { - PairingRequest { - inviter_id, - invitation_code: self.generate_invitation_code(), - } - } - - pub fn handle_pairing_response(&self, response: PairingRequest) -> bool { - self.validate_pairing(&response.invitation_code) +#[tauri::command] +pub fn create_pairing_request( + pairing_manager: State<'_, PairingManager>, + inviter_id: String, +) -> PairingRequest { + PairingRequest { + inviter_id, + invitation_code: generate_invitation_code(pairing_manager), } } +#[tauri::command] +pub fn handle_pairing_response( + pairing_manager: State<'_, PairingManager>, + response: PairingRequest, +) -> bool { + pairing_manager.validate_pairing(&response.invitation_code) +} + #[tauri::command] pub fn initiate_pairing(_pairing_manager: State<'_, PairingManager>) -> String { - let mut rng = thread_rng(); + let mut rng = rng(); PairingManager::generate_emoji_sequence(&mut rng) } #[tauri::command] pub fn complete_pairing( input_key: String, - pairing_manager: State<'_, PairingManager> + pairing_manager: State<'_, PairingManager>, ) -> Result { if pairing_manager.validate_pairing(&input_key) { let _shared_key = pairing_manager.encryption_key.to_vec(); @@ -110,6 +133,5 @@ pub fn complete_pairing( #[tauri::command] pub fn generate_invitation(pairing_manager: State<'_, PairingManager>) -> String { - pairing_manager.generate_invitation_code() + generate_invitation_code(pairing_manager) } -