From 31bd1185f28fc44c8c674982f915d735380a2e8f Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Tue, 20 Aug 2024 00:45:08 +0800 Subject: [PATCH] feat: updates --- src-tauri/Cargo.lock | 143 ++++++++++++++++++++++++++++++++++++++++++ src-tauri/Cargo.toml | 3 + src-tauri/src/main.rs | 74 +++++++++++++++++++++- 3 files changed, 218 insertions(+), 2 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 762cafc..0899fbc 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -17,6 +17,30 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "aes-gcm-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163d1209787b2226543db17d317f5e9f5f54fd0d0f20834318f92013ebd78f37" +dependencies = [ + "aes", + "cipher", + "ghash", + "zeroize", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -305,6 +329,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "cocoa" version = "0.24.1" @@ -947,6 +981,16 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gimli" version = "0.29.0" @@ -1291,6 +1335,15 @@ dependencies = [ "cfb", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -1646,6 +1699,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "open" version = "3.2.0" @@ -1900,6 +1959,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -2139,6 +2210,18 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rust_util" +version = "0.6.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bca5d3493eb29d08dc76ee784a78723fe366fec5dfe67ab37da9d50fb868f7c" +dependencies = [ + "lazy_static", + "libc", + "term", + "term_size", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2204,6 +2287,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" name = "secure-editor-rs" version = "0.1.0" dependencies = [ + "aes-gcm-stream", + "hex", + "rust_util", "serde", "serde_json", "tauri", @@ -2482,6 +2568,12 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -2818,6 +2910,27 @@ dependencies = [ "utf-8", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "term_size" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "thin-slice" version = "0.1.1" @@ -3073,6 +3186,16 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "url" version = "2.5.2" @@ -3763,3 +3886,23 @@ dependencies = [ "quote", "syn 2.0.75", ] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.75", +] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 0fe7e5b..511ec40 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -14,6 +14,9 @@ tauri-build = { version = "1", features = [] } tauri = { version = "1", features = ["shell-open"] } serde = { version = "1", features = ["derive"] } serde_json = "1" +aes-gcm-stream = "0.2.3" +rust_util = "0.6.47" +hex = "0.4.3" [features] # This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!! diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index c883ecd..478a3d5 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,6 +1,76 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +use aes_gcm_stream::{Aes256GcmStreamDecryptor, Aes256GcmStreamEncryptor}; +use rust_util::{opt_result, simple_error, XResult}; +use std::fs; + +const ALGORITHM_AES_256_GCM: &str = "aes-256-gcm"; + +struct EncryptArgs { + file_name: String, + key: [u8; 32], + nonce: Vec, +} + +impl EncryptArgs { + fn new() -> XResult { + let args: Vec = std::env::args().collect(); + if args.len() != 5 { + return simple_error!("Bad encrypt args: {:?}", args); + } + let file_name = args[1].clone(); + let algorithm = args[2].clone(); + if algorithm.as_str() != ALGORITHM_AES_256_GCM { + return simple_error!("Bad algorithm: {}", algorithm); + } + let key_bytes = opt_result!(hex::decode(&args[3]), "Bad key: {} failed: {}", &args[3]); + if key_bytes.len() != 32 { + return simple_error!("Bad key length: {}", key_bytes.len()); + } + let nonce = opt_result!(hex::decode(&args[4]), "Bad nonce: {} failed: {}", &args[4]); + if nonce.len() != 12 { + return simple_error!("Bad nonce length: {}", nonce.len()); + } + let mut key = [0_u8; 32]; + for i in 0..32 { + key[i] = key_bytes[i]; + } + + Ok(EncryptArgs { + file_name, + key, + nonce, + }) + } + + fn read_to_string(&self) -> XResult { + Ok(opt_result!(String::from_utf8(self.read()?), "Read from file: {} failed: {} (not UTF-8)", &self.file_name)) + } + + fn read(&self) -> XResult> { + let file_content = opt_result!(fs::read(&self.file_name), "Read from file: {} failed: {}", &self.file_name); + let mut decryptor = Aes256GcmStreamDecryptor::new(self.key.clone(), &self.nonce); + decryptor.update(&file_content); + let plaintext = opt_result!(decryptor.finalize(), "Decrypt input file failed: {}"); + + Ok(plaintext) + } + + fn write_string(&self, content: &str) -> XResult<()> { + self.write(content.as_bytes()) + } + + fn write(&self, content: &[u8]) -> XResult<()> { + let mut encryptor = Aes256GcmStreamEncryptor::new(self.key.clone(), &self.nonce); + encryptor.update(content); + let (mut ciphertext, tag) = encryptor.finalize(); + ciphertext.extend_from_slice(&tag); + opt_result!(fs::write(&self.file_name, &ciphertext), "Write to file: {} failed: {}", &self.file_name); + Ok(()) + } +} + #[tauri::command] fn read_content() -> String { @@ -10,9 +80,9 @@ fn read_content() -> String { } #[tauri::command] -fn save_content(name: &str) -> String { +fn save_content(content: &str) -> String { // TOD save.... - format!("Hello, {}! You've been greeted from Rust!", name) + format!("Hello, {}! You've been greeted from Rust!", content) } fn main() {