cinderella

[unmaintained] simple CI engine
Log | Files | Refs | README | LICENSE

commit 682b0f6a650151b18d0b86c656bde9f55da66f45
parent 38d6d6338c53f0bd4c9731158d3f97004760c6de
Author: Stefan Koch <programming@stefan-koch.name>
Date:   Sun, 24 Nov 2019 11:38:28 +0100

let user input password on encrypt and decrypt

Diffstat:
MCargo.lock | 11+++++++++++
MCargo.toml | 1+
Msrc/crypto.rs | 23+++++++++++++----------
Msrc/lib.rs | 12+++++++-----
Msrc/main.rs | 9+++++++--
5 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -88,6 +88,7 @@ dependencies = [ "lettre_email 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rmp-serde 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", "sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -726,6 +727,15 @@ dependencies = [ ] [[package]] +name = "rpassword" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "ryu" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1043,6 +1053,7 @@ dependencies = [ "checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" "checksum rmp 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f594cb7ff8f1c5a7907f6be91f15795c8301e0d5718eb007fb5832723dd716e" "checksum rmp-serde 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4a31c0798045f039ace94e0166f76478b3ba83116ec7c9d4bc934c5b13b8df21" +"checksum rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f072d931f11a96546efd97642e1e75e807345aced86b947f9239102f262d0fcd" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0" "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" diff --git a/Cargo.toml b/Cargo.toml @@ -15,6 +15,7 @@ evalexpr = "5" lettre = "0.9" lettre_email = "0.9" sodiumoxide = "0.2.5" +rpassword = "4.0" [dev-dependencies] tempfile = "3" diff --git a/src/crypto.rs b/src/crypto.rs @@ -7,20 +7,18 @@ use sodiumoxide::crypto::secretbox::{self, Key, Nonce}; use sodiumoxide::crypto::pwhash::{self, Salt}; #[derive(Serialize, Deserialize)] -pub struct CryptoFile { +struct CryptoFile { pwsalt: Salt, nonce: Nonce, content: Vec<u8>, } -pub struct SaltedKey { +struct SaltedKey { pwsalt: Salt, key: Key, } -pub fn gen_key_from_pw(password: &str) -> SaltedKey { - let salt = pwhash::gen_salt(); - +fn gen_salted_key(password: &str, salt: Salt) -> SaltedKey { // cf. https://docs.rs/sodiumoxide/0.2.5/sodiumoxide/crypto/pwhash/index.html#example-key-derivation let mut k = secretbox::Key([0; secretbox::KEYBYTES]); { @@ -36,8 +34,13 @@ pub fn gen_key_from_pw(password: &str) -> SaltedKey { } } +fn gen_salted_key_random_salt(password: &str) -> SaltedKey { + let salt = pwhash::gen_salt(); + gen_salted_key(password, salt) +} + pub fn encrypt_string(plaintext: &str, password: &str) -> Vec<u8> { - let salted_key = gen_key_from_pw(password); + let salted_key = gen_salted_key_random_salt(password); let nonce = secretbox::gen_nonce(); let ciphertext = secretbox::seal(plaintext.as_bytes(), &nonce, &salted_key.key); @@ -51,11 +54,11 @@ pub fn encrypt_string(plaintext: &str, password: &str) -> Vec<u8> { rmp_serde::to_vec(&f).unwrap() } -pub fn decrypt_file(filepath: &str) -> String { +pub fn decrypt_file(filepath: &str, password: &str) -> Result<String, ()> { let r = File::open(filepath).unwrap(); let f: CryptoFile = rmp_serde::from_read(r).unwrap(); - let key = secretbox::gen_key(); + let salted_key = gen_salted_key(password, f.pwsalt); - let bytes = secretbox::open(&f.content, &f.nonce, &key).unwrap(); - String::from_utf8(bytes).unwrap() + secretbox::open(&f.content, &f.nonce, &salted_key.key) + .map(|bytes| String::from_utf8(bytes).unwrap()) } diff --git a/src/lib.rs b/src/lib.rs @@ -127,14 +127,16 @@ pub fn run(exec_config: &ExecutionConfig) { } } -pub fn encrypt(filepath: String) { +pub fn encrypt(filepath: String, password: &str) { let plaintext = "some data"; - let cipher = crypto::encrypt_string(plaintext, "my-password"); + let cipher = crypto::encrypt_string(plaintext, password); fs::write(filepath, cipher).expect("Unable to write file"); } -pub fn decrypt(filepath: String) { - let plaintext = crypto::decrypt_file(&filepath); - println!("{}", plaintext); +pub fn decrypt(filepath: String, password: &str) { + match crypto::decrypt_file(&filepath, password) { + Ok(plaintext) => println!("{}", plaintext), + _ => println!("Cannot decrypt, probably wrong password"), + } } diff --git a/src/main.rs b/src/main.rs @@ -1,5 +1,6 @@ use std::env; +use rpassword; use getopts::Options; use cinderella::ExecutionConfig; @@ -29,7 +30,9 @@ fn encrypt(args: Vec<String>) { } else { let filepath = args[2].clone(); - cinderella::encrypt(filepath); + let pass = rpassword::read_password_from_tty(Some("Password: ")).unwrap(); + + cinderella::encrypt(filepath, &pass); } } @@ -39,7 +42,9 @@ fn decrypt(args: Vec<String>) { } else { let filepath = args[2].clone(); - cinderella::decrypt(filepath); + let pass = rpassword::read_password_from_tty(Some("Password: ")).unwrap(); + + cinderella::decrypt(filepath, &pass); } }