parent
da44f49c56
commit
f8ae7d4e0e
8 changed files with 106 additions and 117 deletions
67
Cargo.lock
generated
67
Cargo.lock
generated
|
@ -10,14 +10,13 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aes"
|
name = "aes"
|
||||||
version = "0.7.5"
|
version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
|
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cipher",
|
"cipher",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
"opaque-debug",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -122,21 +121,14 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "block-modes"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e"
|
|
||||||
dependencies = [
|
|
||||||
"block-padding",
|
|
||||||
"cipher",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-padding"
|
name = "block-padding"
|
||||||
version = "0.2.1"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
|
@ -162,6 +154,15 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cbc"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
|
||||||
|
dependencies = [
|
||||||
|
"cipher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.73"
|
version = "1.0.73"
|
||||||
|
@ -195,11 +196,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cipher"
|
name = "cipher"
|
||||||
version = "0.3.0"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
|
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"crypto-common",
|
||||||
|
"inout",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -366,6 +368,16 @@ dependencies = [
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.27.2"
|
version = "0.27.2"
|
||||||
|
@ -842,6 +854,16 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inout"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||||
|
dependencies = [
|
||||||
|
"block-padding",
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -1139,12 +1161,6 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2"
|
checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "opaque-debug"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "option-ext"
|
name = "option-ext"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -2214,7 +2230,7 @@ dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
"block-modes",
|
"cbc",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
"cookie 0.14.4",
|
"cookie 0.14.4",
|
||||||
|
@ -2222,6 +2238,7 @@ dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"gethostname",
|
"gethostname",
|
||||||
"hmac-sha1",
|
"hmac-sha1",
|
||||||
|
"inout",
|
||||||
"lazy_static 1.4.0",
|
"lazy_static 1.4.0",
|
||||||
"log",
|
"log",
|
||||||
"phonenumber",
|
"phonenumber",
|
||||||
|
|
|
@ -50,9 +50,8 @@ lazy_static = "1.4.0"
|
||||||
uuid = { version = "0.8", features = ["v4"] }
|
uuid = { version = "0.8", features = ["v4"] }
|
||||||
steamguard = { version = "^0.9.0", path = "./steamguard" }
|
steamguard = { version = "^0.9.0", path = "./steamguard" }
|
||||||
dirs = "3.0.2"
|
dirs = "3.0.2"
|
||||||
ring = "0.16.20"
|
ring = { version = "0.16.20", features = ["std"] }
|
||||||
aes = "0.7.4"
|
aes = "0.8.3"
|
||||||
block-modes = "0.8.1"
|
|
||||||
thiserror = "1.0.26"
|
thiserror = "1.0.26"
|
||||||
crossterm = { version = "0.23.2", features = ["event-stream"] }
|
crossterm = { version = "0.23.2", features = ["event-stream"] }
|
||||||
qrcode = { version = "0.12.0", optional = true }
|
qrcode = { version = "0.12.0", optional = true }
|
||||||
|
@ -62,6 +61,8 @@ zeroize = "^1.4.3"
|
||||||
serde_path_to_error = "0.1.11"
|
serde_path_to_error = "0.1.11"
|
||||||
update-informer = { version = "1.0.0", optional = true, default-features = false, features = ["github"] }
|
update-informer = { version = "1.0.0", optional = true, default-features = false, features = ["github"] }
|
||||||
phonenumber = "0.3"
|
phonenumber = "0.3"
|
||||||
|
cbc = { version = "0.1.2", features = ["std"] }
|
||||||
|
inout = { version = "0.1.3", features = ["std"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempdir = "0.3"
|
tempdir = "0.3"
|
||||||
|
|
|
@ -412,21 +412,11 @@ pub enum ManifestAccountLoadError {
|
||||||
Unknown(#[from] anyhow::Error),
|
Unknown(#[from] anyhow::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<block_modes::BlockModeError> for ManifestAccountLoadError {
|
|
||||||
fn from(error: block_modes::BlockModeError) -> Self {
|
|
||||||
Self::Unknown(anyhow::Error::from(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<base64::DecodeError> for ManifestAccountLoadError {
|
impl From<base64::DecodeError> for ManifestAccountLoadError {
|
||||||
fn from(error: base64::DecodeError) -> Self {
|
fn from(error: base64::DecodeError) -> Self {
|
||||||
Self::Unknown(anyhow::Error::from(error))
|
Self::Unknown(anyhow::Error::from(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<block_modes::InvalidKeyIvLength> for ManifestAccountLoadError {
|
|
||||||
fn from(error: block_modes::InvalidKeyIvLength) -> Self {
|
|
||||||
Self::Unknown(anyhow::Error::from(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<std::io::Error> for ManifestAccountLoadError {
|
impl From<std::io::Error> for ManifestAccountLoadError {
|
||||||
fn from(error: std::io::Error) -> Self {
|
fn from(error: std::io::Error) -> Self {
|
||||||
Self::Unknown(anyhow::Error::from(error))
|
Self::Unknown(anyhow::Error::from(error))
|
||||||
|
@ -639,11 +629,10 @@ mod tests {
|
||||||
manifest: "src/fixtures/maFiles/manifest-v1/1-account/manifest.json",
|
manifest: "src/fixtures/maFiles/manifest-v1/1-account/manifest.json",
|
||||||
passkey: None,
|
passkey: None,
|
||||||
},
|
},
|
||||||
// FIXME: disabled because of #233
|
Test {
|
||||||
// Test {
|
manifest: "src/fixtures/maFiles/manifest-v1/1-account-encrypted/manifest.json",
|
||||||
// manifest: "src/fixtures/maFiles/manifest-v1/1-account-encrypted/manifest.json",
|
passkey: Some(SecretString::new("password".into())),
|
||||||
// passkey: Some(SecretString::new("password".into())),
|
},
|
||||||
// },
|
|
||||||
Test {
|
Test {
|
||||||
manifest: "src/fixtures/maFiles/manifest-v1/2-account/manifest.json",
|
manifest: "src/fixtures/maFiles/manifest-v1/2-account/manifest.json",
|
||||||
passkey: None,
|
passkey: None,
|
||||||
|
|
|
@ -374,11 +374,10 @@ mod tests {
|
||||||
dir: "src/fixtures/maFiles/compat/1-account/",
|
dir: "src/fixtures/maFiles/compat/1-account/",
|
||||||
passkey: None,
|
passkey: None,
|
||||||
},
|
},
|
||||||
// FIXME: disabled because of #233
|
Test {
|
||||||
// Test {
|
dir: "src/fixtures/maFiles/compat/1-account-encrypted/",
|
||||||
// manifest: "src/fixtures/maFiles/compat/1-account-encrypted/",
|
passkey: Some(SecretString::new("password".into())),
|
||||||
// passkey: Some(SecretString::new("password".into())),
|
},
|
||||||
// },
|
|
||||||
Test {
|
Test {
|
||||||
dir: "src/fixtures/maFiles/compat/2-account/",
|
dir: "src/fixtures/maFiles/compat/2-account/",
|
||||||
passkey: None,
|
passkey: None,
|
||||||
|
@ -402,9 +401,7 @@ mod tests {
|
||||||
for file in std::fs::read_dir(case.dir)? {
|
for file in std::fs::read_dir(case.dir)? {
|
||||||
let file = file?;
|
let file = file?;
|
||||||
let path = file.path();
|
let path = file.path();
|
||||||
eprintln!("copying {:?}", path);
|
|
||||||
let dest = temp.path().join(path.file_name().unwrap());
|
let dest = temp.path().join(path.file_name().unwrap());
|
||||||
eprintln!("to {:?}", dest);
|
|
||||||
std::fs::copy(&path, dest)?;
|
std::fs::copy(&path, dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
use aes::cipher::block_padding::Pkcs7;
|
||||||
|
use aes::cipher::{BlockDecryptMut, BlockEncryptMut, InvalidLength, KeyIvInit};
|
||||||
use aes::Aes256;
|
use aes::Aes256;
|
||||||
use block_modes::block_padding::{NoPadding, Padding, Pkcs7};
|
|
||||||
use block_modes::{BlockMode, Cbc};
|
|
||||||
use ring::pbkdf2;
|
use ring::pbkdf2;
|
||||||
use ring::rand::SecureRandom;
|
use ring::rand::SecureRandom;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -78,38 +78,22 @@ impl LegacySdaCompatible {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Aes256Cbc = Cbc<Aes256, NoPadding>;
|
|
||||||
impl EntryEncryptor for LegacySdaCompatible {
|
impl EntryEncryptor for LegacySdaCompatible {
|
||||||
// ngl, this logic sucks ass. its kinda annoying that the logic is not completely symetric.
|
|
||||||
|
|
||||||
fn encrypt(
|
fn encrypt(
|
||||||
passkey: &str,
|
passkey: &str,
|
||||||
params: &EntryEncryptionParams,
|
params: &EntryEncryptionParams,
|
||||||
plaintext: Vec<u8>,
|
plaintext: Vec<u8>,
|
||||||
) -> anyhow::Result<Vec<u8>, EntryEncryptionError> {
|
) -> anyhow::Result<Vec<u8>, EntryEncryptionError> {
|
||||||
let key = Self::get_encryption_key(passkey, ¶ms.salt)?;
|
let key = Self::get_encryption_key(passkey, ¶ms.salt)?;
|
||||||
let iv = base64::decode(¶ms.iv)?;
|
let mut iv = [0u8; IV_LENGTH];
|
||||||
let cipher = Aes256Cbc::new_from_slices(&key, &iv)?;
|
base64::decode_config_slice(¶ms.iv, base64::STANDARD, &mut iv)?;
|
||||||
|
|
||||||
let origsize = plaintext.len();
|
let cipher = cbc::Encryptor::<Aes256>::new_from_slices(&key, &iv)?;
|
||||||
let buffersize: usize = (origsize / 16 + (if origsize % 16 == 0 { 0 } else { 1 })) * 16;
|
|
||||||
let mut buffer = vec![];
|
let ciphertext = cipher.encrypt_padded_vec_mut::<Pkcs7>(&plaintext);
|
||||||
for chunk in plaintext.as_slice().chunks(128) {
|
|
||||||
let chunksize = chunk.len();
|
let encoded = base64::encode(ciphertext);
|
||||||
let buffersize = (chunksize / 16 + (if chunksize % 16 == 0 { 0 } else { 1 })) * 16;
|
Ok(encoded.as_bytes().to_vec())
|
||||||
let mut chunkbuffer = vec![0xffu8; buffersize];
|
|
||||||
chunkbuffer[..chunksize].copy_from_slice(chunk);
|
|
||||||
if buffersize != chunksize {
|
|
||||||
// pad the last chunk
|
|
||||||
chunkbuffer = Pkcs7::pad(&mut chunkbuffer, chunksize, buffersize)
|
|
||||||
.unwrap()
|
|
||||||
.to_vec();
|
|
||||||
}
|
|
||||||
buffer.append(&mut chunkbuffer);
|
|
||||||
}
|
|
||||||
let ciphertext = cipher.encrypt(&mut buffer, buffersize)?;
|
|
||||||
let final_buffer = base64::encode(ciphertext);
|
|
||||||
return Ok(final_buffer.as_bytes().to_vec());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(
|
fn decrypt(
|
||||||
|
@ -118,46 +102,51 @@ impl EntryEncryptor for LegacySdaCompatible {
|
||||||
ciphertext: Vec<u8>,
|
ciphertext: Vec<u8>,
|
||||||
) -> anyhow::Result<Vec<u8>, EntryEncryptionError> {
|
) -> anyhow::Result<Vec<u8>, EntryEncryptionError> {
|
||||||
let key = Self::get_encryption_key(passkey, ¶ms.salt)?;
|
let key = Self::get_encryption_key(passkey, ¶ms.salt)?;
|
||||||
let iv = base64::decode(¶ms.iv)?;
|
let mut iv = [0u8; IV_LENGTH];
|
||||||
let cipher = Aes256Cbc::new_from_slices(&key, &iv)?;
|
base64::decode_config_slice(¶ms.iv, base64::STANDARD, &mut iv)?;
|
||||||
|
let cipher = cbc::Decryptor::<Aes256>::new_from_slices(&key, &iv)?;
|
||||||
let decoded = base64::decode(ciphertext)?;
|
let decoded = base64::decode(ciphertext)?;
|
||||||
let size: usize = decoded.len() / 16 + (if decoded.len() % 16 == 0 { 0 } else { 1 });
|
let size: usize = decoded.len() / 16 + (if decoded.len() % 16 == 0 { 0 } else { 1 });
|
||||||
let mut buffer = vec![0xffu8; 16 * size];
|
let mut buffer = vec![0xffu8; 16 * size];
|
||||||
buffer[..decoded.len()].copy_from_slice(&decoded);
|
buffer[..decoded.len()].copy_from_slice(&decoded);
|
||||||
let decrypted = cipher.decrypt(&mut buffer)?;
|
let decrypted = cipher.decrypt_padded_mut::<Pkcs7>(&mut buffer)?;
|
||||||
let unpadded = Pkcs7::unpad(decrypted)?;
|
Ok(decrypted.to_vec())
|
||||||
Ok(unpadded.to_vec())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum EntryEncryptionError {
|
pub enum EntryEncryptionError {
|
||||||
|
#[error("Invalid ciphertext length. The ciphertext must be a multiple of 16 bytes.")]
|
||||||
|
InvalidCipherTextLength,
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Unknown(#[from] anyhow::Error),
|
Unknown(#[from] anyhow::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For some reason, these errors do not get converted to `ManifestAccountLoadError`s, even though they get converted into `anyhow::Error` just fine. I am too lazy to figure out why right now.
|
/// For some reason, these errors do not get converted to `ManifestAccountLoadError`s, even though they get converted into `anyhow::Error` just fine. I am too lazy to figure out why right now.
|
||||||
impl From<block_modes::BlockModeError> for EntryEncryptionError {
|
impl From<InvalidLength> for EntryEncryptionError {
|
||||||
fn from(error: block_modes::BlockModeError) -> Self {
|
fn from(error: InvalidLength) -> Self {
|
||||||
Self::Unknown(anyhow::Error::from(error))
|
Self::Unknown(anyhow::Error::from(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<block_modes::InvalidKeyIvLength> for EntryEncryptionError {
|
|
||||||
fn from(error: block_modes::InvalidKeyIvLength) -> Self {
|
impl From<inout::NotEqualError> for EntryEncryptionError {
|
||||||
|
fn from(error: inout::NotEqualError) -> Self {
|
||||||
Self::Unknown(anyhow::Error::from(error))
|
Self::Unknown(anyhow::Error::from(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<block_modes::block_padding::PadError> for EntryEncryptionError {
|
|
||||||
fn from(_error: block_modes::block_padding::PadError) -> Self {
|
impl From<inout::PadError> for EntryEncryptionError {
|
||||||
Self::Unknown(anyhow!("PadError"))
|
fn from(error: inout::PadError) -> Self {
|
||||||
|
Self::Unknown(anyhow::Error::from(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<block_modes::block_padding::UnpadError> for EntryEncryptionError {
|
|
||||||
fn from(_error: block_modes::block_padding::UnpadError) -> Self {
|
impl From<inout::block_padding::UnpadError> for EntryEncryptionError {
|
||||||
Self::Unknown(anyhow!("UnpadError"))
|
fn from(error: inout::block_padding::UnpadError) -> Self {
|
||||||
|
Self::Unknown(anyhow::Error::from(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<base64::DecodeError> for EntryEncryptionError {
|
impl From<base64::DecodeError> for EntryEncryptionError {
|
||||||
fn from(error: base64::DecodeError) -> Self {
|
fn from(error: base64::DecodeError) -> Self {
|
||||||
Self::Unknown(anyhow::Error::from(error))
|
Self::Unknown(anyhow::Error::from(error))
|
||||||
|
@ -178,14 +167,18 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encryption_key() {
|
fn test_encryption_key() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
LegacySdaCompatible::get_encryption_key("password", "GMhL0N2hqXg=").unwrap(),
|
LegacySdaCompatible::get_encryption_key("password", "GMhL0N2hqXg=")
|
||||||
|
.unwrap()
|
||||||
|
.as_slice(),
|
||||||
base64::decode("KtiRa4/OxW83MlB6URf+Z8rAGj7CBY+pDlwD/NuVo6Y=")
|
base64::decode("KtiRa4/OxW83MlB6URf+Z8rAGj7CBY+pDlwD/NuVo6Y=")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_slice()
|
.as_slice()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
LegacySdaCompatible::get_encryption_key("password", "wTzTE9A6aN8=").unwrap(),
|
LegacySdaCompatible::get_encryption_key("password", "wTzTE9A6aN8=")
|
||||||
|
.unwrap()
|
||||||
|
.as_slice(),
|
||||||
base64::decode("Dqpej/3DqEat0roJaHmu3luYgDzRCUmzX94n4fqvWj8=")
|
base64::decode("Dqpej/3DqEat0roJaHmu3luYgDzRCUmzX94n4fqvWj8=")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_slice()
|
.as_slice()
|
||||||
|
@ -194,12 +187,22 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ensure_encryption_symmetric() -> anyhow::Result<()> {
|
fn test_ensure_encryption_symmetric() -> anyhow::Result<()> {
|
||||||
|
let cases = [
|
||||||
|
"foo",
|
||||||
|
"tactical glizzy",
|
||||||
|
"glizzy gladiator",
|
||||||
|
"shadow wizard money gang",
|
||||||
|
"shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells, shadow wizard money gang, we love casting spells",
|
||||||
|
];
|
||||||
let passkey = "password";
|
let passkey = "password";
|
||||||
let params = EntryEncryptionParams::generate();
|
let params = EntryEncryptionParams::generate();
|
||||||
let orig = "tactical glizzy".as_bytes().to_vec();
|
for case in cases {
|
||||||
let encrypted = LegacySdaCompatible::encrypt(passkey, ¶ms, orig.clone()).unwrap();
|
eprintln!("testing case: {} (len {})", case, case.len());
|
||||||
let result = LegacySdaCompatible::decrypt(passkey, ¶ms, encrypted).unwrap();
|
let orig = case.as_bytes().to_vec();
|
||||||
assert_eq!(orig, result.to_vec());
|
let encrypted = LegacySdaCompatible::encrypt(passkey, ¶ms, orig.clone()).unwrap();
|
||||||
|
let result = LegacySdaCompatible::decrypt(passkey, ¶ms, encrypted).unwrap();
|
||||||
|
assert_eq!(orig, result.to_vec());
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Z0HJDSN9EuFOpKEeBzftCWxTsh0sV6QQriLTVrn37FyGNaXhGgzeHlvPfHgkXKCYbALTgx/B2fLh1CEojKO1/eqEgN+982CadR3EXk+vH1k5AMuGhMXPpsEeIh27ltxrdAEzWdlPlAyentBgOKlTCoN6iF+EZVORvp2pPaMrebyHi8/5Y+XC3HrMgfgmP7lFGpUgZK8f0mKB/pGaW+0/3oVikggBK3MIWlh4s9bC9LlMy5H+oU0n/Iu3P9dpbko1bDMKIbUKEPzS3wHXyQRg32zPIfONR0bswb7QTfAhoKixZrAenQluX3lXRL0JFafNEPzUY4r/DJ1pIMLK9cEvbzqwsPth6jrIZRd+zvgnshfNnGLCblYkPo4fGwePuhX2W2w6qgFMpo69rkSp1Zz6JKC/gH9YyL4a8N768ml9H1so5XBm7eB+fMRIL7bHof+V1CxGXX3z1RvjGRHPwKcrKLvffxTTs/dBHb9UDFtTprk=
|
Z0HJDSN9EuFOpKEeBzftCWxTsh0sV6QQriLTVrn37FyGNaXhGgzeHlvPfHgkXKCYbALTgx/B2fLh1CEojKO1/eqEgN+982CadR3EXk+vH1k5AMuGhMXPpsEeIh27ltxrdAEzWdlPlAyentBgOKlTCoN6iF+EZVORvp2pPaMrebyHi8/5Y+XC3HrMgfgmP7lFGpUgZK8f0mKB/pGaW+0/3oVikggBK3MIWlh4s9bC9LlMy5H+oU0n/Iu3P9dpbko1bDMKIbUKEPzS3wHXyQRg32zPIfONR0bswb7QTfAhoKixZrAenQluX3lXRL0JFafNEPzUY4r/DJ1pIMLK9cEvbzqwsPth6jrIZRd+zvgnshfNnGLCblYkPo4fGwePuhX2W2w6qgFMpo69rkSp1Zz6JKC/gH9YyL4a8N768ml9H1so5XBm7eB+fMRIL7bHof+V1CxGXX3z1RvjGRHPwKcrKLvffxTTs/dBHb9UDFtTprlymLZf6C53c5vMBQ/hk4fm
|
|
@ -1 +0,0 @@
|
||||||
ZQqJk4KW7pb5bndkra244z3ttIks58UplODn5IgljrOK3bKORSwrnZYb9Iv6YsirmrT0hQ3tx381GhQu4Nyj/PFHHCfFTrduaCoMLRrHDsmsexOW93Yo02acHXNfPSvxtjGfZpsuIZVlhVy8JDH/ESXp88cKn2zqjXQWu6pLnah1YPlpZuTfArw69+Em7V1OH1CoKnsYuhCo/x4u7fXhMNgDlRBvDbO4enGzaixonPu9er5Zp6iNEeuAUqmD0DHASygNmzBhUBHv8Avng8YKbvu611yQVT2KybnIoL+Q11Y36GoFhWskmG3lLwh/1OlReGwJ1iX0lDDthoel/Ygj6EC2+wkR8V7eMQf48R15xdBILYTzcrjtiuLCr9MBc/HM/ToEa3QCGwGkXvshR/meJ1BiqaRARKfvJcj4eMSpiUvhDe1QFXXjfXRdetJcknyJ8Pv6v10G/OV3ELYwdx2dYL5C+Ao4qj9QCjoD8bb/juCjtZoSxMncbm4T7ORbXs/Ulx+TEuOUmRAjxr+zaWzzO7ZfYJMhIPz+LSixKpaVmxP89DEK5LJ1T6jA50QmPft6AbOMuoq99haWH9lMgqrIfBB+ZNNHSEE9PwMUxhX/TQP3oJgmrnZcMV4nBOcovbWM5s+odu2mvzoAcRMHVxEztASbMBwdJ7amJvoRRrXTtp642FQHAe8pFPlW14x1hShXAO4YfYkmmAhLqlujammuQ6bRg7XjBvh0zE88i5UBRiRsH+MV35u3c0ciugUmbrAZ0u9Yfv19MNSMVNMsREDuxQ==
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"encrypted": true,
|
|
||||||
"first_run": true,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"encryption_iv": "ifChnv66eA+/dYqGsQMIOA==",
|
|
||||||
"encryption_salt": "O2K8FAOWK9c=",
|
|
||||||
"filename": "1234.maFile",
|
|
||||||
"steamid": 1234
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"periodic_checking": false,
|
|
||||||
"periodic_checking_interval": 5,
|
|
||||||
"periodic_checking_checkall": false,
|
|
||||||
"auto_confirm_market_transactions": false,
|
|
||||||
"auto_confirm_trades": false
|
|
||||||
}
|
|
Loading…
Reference in a new issue