diff options
author | Conrad Ludgate <conradludgate@gmail.com> | 2023-04-17 21:12:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-17 21:12:02 +0100 |
commit | c7d89c1703c6dc580b2ef2cbb66b0df0b1e72b50 (patch) | |
tree | b9d7a653f3460a9f9d3a96106c273b9cbd382710 /atuin-client/src/encryption.rs | |
parent | 678323b54393777eac7e84ff3f6b1f8921083f56 (diff) |
chore: uuhhhhhh crypto lol (#805)
* chore: uuhhhhhh crypto lol
* remove dead code
* fix key decoding
* use inplace encryption
Diffstat (limited to 'atuin-client/src/encryption.rs')
-rw-r--r-- | atuin-client/src/encryption.rs | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/atuin-client/src/encryption.rs b/atuin-client/src/encryption.rs index fe19ce9b9..9145a11df 100644 --- a/atuin-client/src/encryption.rs +++ b/atuin-client/src/encryption.rs @@ -14,7 +14,11 @@ use base64::prelude::{Engine, BASE64_STANDARD}; use eyre::{eyre, Context, Result}; use fs_err as fs; use serde::{Deserialize, Serialize}; -use sodiumoxide::crypto::secretbox; +pub use xsalsa20poly1305::Key; +use xsalsa20poly1305::{ + aead::{Nonce, OsRng}, + AeadInPlace, KeyInit, XSalsa20Poly1305, +}; use crate::{ history::{History, HistoryWithoutDelete}, @@ -24,14 +28,14 @@ use crate::{ #[derive(Debug, Serialize, Deserialize)] pub struct EncryptedHistory { pub ciphertext: Vec<u8>, - pub nonce: secretbox::Nonce, + pub nonce: Nonce<XSalsa20Poly1305>, } -pub fn new_key(settings: &Settings) -> Result<secretbox::Key> { +pub fn new_key(settings: &Settings) -> Result<Key> { let path = settings.key_path.as_str(); - let key = secretbox::gen_key(); - let encoded = encode_key(key.clone())?; + let key = XSalsa20Poly1305::generate_key(&mut OsRng); + let encoded = encode_key(&key)?; let mut file = fs::File::create(path)?; file.write_all(encoded.as_bytes())?; @@ -40,7 +44,7 @@ pub fn new_key(settings: &Settings) -> Result<secretbox::Key> { } // Loads the secret key, will create + save if it doesn't exist -pub fn load_key(settings: &Settings) -> Result<secretbox::Key> { +pub fn load_key(settings: &Settings) -> Result<Key> { let path = settings.key_path.as_str(); let key = if PathBuf::from(path).exists() { @@ -60,8 +64,8 @@ pub fn load_encoded_key(settings: &Settings) -> Result<String> { let key = fs::read_to_string(path)?; Ok(key) } else { - let key = secretbox::gen_key(); - let encoded = encode_key(key)?; + let key = XSalsa20Poly1305::generate_key(&mut OsRng); + let encoded = encode_key(&key)?; let mut file = fs::File::create(path)?; file.write_all(encoded.as_bytes())?; @@ -70,38 +74,47 @@ pub fn load_encoded_key(settings: &Settings) -> Result<String> { } } -pub type Key = secretbox::Key; -pub fn encode_key(key: secretbox::Key) -> Result<String> { - let buf = rmp_serde::to_vec(&key).wrap_err("could not encode key to message pack")?; +pub fn encode_key(key: &Key) -> Result<String> { + let buf = rmp_serde::to_vec(key.as_slice()).wrap_err("could not encode key to message pack")?; let buf = BASE64_STANDARD.encode(buf); Ok(buf) } -pub fn decode_key(key: String) -> Result<secretbox::Key> { +pub fn decode_key(key: String) -> Result<Key> { let buf = BASE64_STANDARD .decode(key.trim_end()) .wrap_err("encryption key is not a valid base64 encoding")?; - let buf: secretbox::Key = rmp_serde::from_slice(&buf) + let buf: &[u8] = rmp_serde::from_slice(&buf) .wrap_err("encryption key is not a valid message pack encoding")?; - Ok(buf) + Ok(*Key::from_slice(buf)) } -pub fn encrypt(history: &History, key: &secretbox::Key) -> Result<EncryptedHistory> { +pub fn encrypt(history: &History, key: &Key) -> Result<EncryptedHistory> { // serialize with msgpack - let buf = rmp_serde::to_vec(history)?; - - let nonce = secretbox::gen_nonce(); + let mut buf = rmp_serde::to_vec(history)?; - let ciphertext = secretbox::seal(&buf, &nonce, key); + let nonce = XSalsa20Poly1305::generate_nonce(&mut OsRng); + XSalsa20Poly1305::new(key) + .encrypt_in_place(&nonce, &[], &mut buf) + .map_err(|_| eyre!("could not encrypt"))?; - Ok(EncryptedHistory { ciphertext, nonce }) + Ok(EncryptedHistory { + ciphertext: buf, + nonce, + }) } -pub fn decrypt(encrypted_history: &EncryptedHistory, key: &secretbox::Key) -> Result<History> { - let plaintext = secretbox::open(&encrypted_history.ciphertext, &encrypted_history.nonce, key) - .map_err(|_| eyre!("failed to open secretbox - invalid key?"))?; +pub fn decrypt(mut encrypted_history: EncryptedHistory, key: &Key) -> Result<History> { + XSalsa20Poly1305::new(key) + .decrypt_in_place( + &encrypted_history.nonce, + &[], + &mut encrypted_history.ciphertext, + ) + .map_err(|_| eyre!("could not encrypt"))?; + let plaintext = encrypted_history.ciphertext; let history = rmp_serde::from_slice(&plaintext); @@ -126,7 +139,7 @@ pub fn decrypt(encrypted_history: &EncryptedHistory, key: &secretbox::Key) -> Re #[cfg(test)] mod test { - use sodiumoxide::crypto::secretbox; + use xsalsa20poly1305::{aead::OsRng, KeyInit, XSalsa20Poly1305}; use crate::history::History; @@ -134,8 +147,8 @@ mod test { #[test] fn test_encrypt_decrypt() { - let key1 = secretbox::gen_key(); - let key2 = secretbox::gen_key(); + let key1 = XSalsa20Poly1305::generate_key(&mut OsRng); + let key2 = XSalsa20Poly1305::generate_key(&mut OsRng); let history = History::new( chrono::Utc::now(), @@ -156,12 +169,12 @@ mod test { // test decryption works // this should pass - match decrypt(&e1, &key1) { + match decrypt(e1, &key1) { Err(e) => panic!("failed to decrypt, got {}", e), Ok(h) => assert_eq!(h, history), }; // this should err - let _ = decrypt(&e2, &key1).expect_err("expected an error decrypting with invalid key"); + let _ = decrypt(e2, &key1).expect_err("expected an error decrypting with invalid key"); } } |