mirror of https://github.com/dswd/zvault
Refactor crypto
This commit is contained in:
parent
ca1916145f
commit
048a48873a
|
@ -187,7 +187,7 @@ pub fn run(
|
|||
println!();
|
||||
|
||||
let (public, secret) = Crypto::gen_keypair();
|
||||
let mut crypto = Crypto::dummy();
|
||||
let crypto = Crypto::dummy();
|
||||
crypto.add_secret_key(public, secret);
|
||||
let encryption = (EncryptionMethod::Sodium, public[..].to_vec().into());
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ pub enum DiffType {
|
|||
impl Repository {
|
||||
pub fn get_all_backups(&self) -> Result<HashMap<String, Backup>, RepositoryError> {
|
||||
Ok(try!(Backup::get_all_from(
|
||||
&self.crypto.lock().unwrap(),
|
||||
&self.crypto,
|
||||
self.layout.backups_path()
|
||||
)))
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ impl Repository {
|
|||
path: P,
|
||||
) -> Result<HashMap<String, Backup>, RepositoryError> {
|
||||
Ok(try!(Backup::get_all_from(
|
||||
&self.crypto.lock().unwrap(),
|
||||
&self.crypto,
|
||||
self.layout.backups_path().join(path)
|
||||
)))
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ impl Repository {
|
|||
|
||||
pub fn get_backup(&self, name: &str) -> Result<Backup, RepositoryError> {
|
||||
Ok(try!(Backup::read_from(
|
||||
&self.crypto.lock().unwrap(),
|
||||
&self.crypto,
|
||||
self.layout.backup_path(name)
|
||||
)))
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ impl Repository {
|
|||
let path = self.layout.backup_path(name);
|
||||
try!(fs::create_dir_all(path.parent().unwrap()));
|
||||
try!(backup.save_to(
|
||||
&self.crypto.lock().unwrap(),
|
||||
&self.crypto,
|
||||
self.config.encryption.clone(),
|
||||
path
|
||||
));
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::*;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::cmp::min;
|
||||
|
@ -62,7 +62,7 @@ fn load_bundles(
|
|||
path: &Path,
|
||||
base: &Path,
|
||||
bundles: &mut HashMap<BundleId, StoredBundle>,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
) -> Result<(Vec<StoredBundle>, Vec<StoredBundle>), BundleDbError> {
|
||||
let mut paths = vec![path.to_path_buf()];
|
||||
let mut bundle_paths = HashSet::new();
|
||||
|
@ -119,7 +119,7 @@ fn load_bundles(
|
|||
pub struct BundleDb {
|
||||
pub layout: Arc<ChunkRepositoryLayout>,
|
||||
uploader: Option<Arc<BundleUploader>>,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
local_bundles: HashMap<BundleId, StoredBundle>,
|
||||
remote_bundles: HashMap<BundleId, StoredBundle>,
|
||||
bundle_cache: LruCache<BundleId, (BundleReader, Vec<u8>)>
|
||||
|
@ -127,7 +127,7 @@ pub struct BundleDb {
|
|||
|
||||
|
||||
impl BundleDb {
|
||||
fn new(layout: Arc<ChunkRepositoryLayout>, crypto: Arc<Mutex<Crypto>>) -> Self {
|
||||
fn new(layout: Arc<ChunkRepositoryLayout>, crypto: Arc<Crypto>) -> Self {
|
||||
BundleDb {
|
||||
layout,
|
||||
crypto,
|
||||
|
@ -240,7 +240,7 @@ impl BundleDb {
|
|||
|
||||
pub fn open(
|
||||
layout: Arc<ChunkRepositoryLayout>,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
online: bool
|
||||
) -> Result<(Self, Vec<BundleInfo>, Vec<BundleInfo>), BundleDbError> {
|
||||
let mut self_ = Self::new(layout, crypto);
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::fs::{self, File};
|
|||
use std::io::{self, Read, Seek, SeekFrom, BufReader};
|
||||
use std::cmp::max;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
||||
quick_error!{
|
||||
|
@ -60,7 +60,7 @@ pub struct BundleReader {
|
|||
pub info: BundleInfo,
|
||||
pub version: u8,
|
||||
pub path: PathBuf,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
pub content_start: usize,
|
||||
pub chunks: Option<ChunkList>,
|
||||
pub chunk_positions: Option<Vec<usize>>
|
||||
|
@ -71,7 +71,7 @@ impl BundleReader {
|
|||
path: PathBuf,
|
||||
version: u8,
|
||||
content_start: usize,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
info: BundleInfo,
|
||||
) -> Self {
|
||||
BundleReader {
|
||||
|
@ -93,7 +93,7 @@ impl BundleReader {
|
|||
#[allow(needless_pass_by_value)]
|
||||
fn load_header<P: AsRef<Path>>(
|
||||
path: P,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
) -> Result<(BundleInfo, u8, usize), BundleReaderError> {
|
||||
let path = path.as_ref();
|
||||
let mut file = BufReader::new(try!(File::open(path).context(path)));
|
||||
|
@ -116,8 +116,6 @@ impl BundleReader {
|
|||
if let Some(ref encryption) = header.encryption {
|
||||
info_data = try!(
|
||||
crypto
|
||||
.lock()
|
||||
.unwrap()
|
||||
.decrypt(encryption, &info_data)
|
||||
.context(path)
|
||||
);
|
||||
|
@ -133,13 +131,13 @@ impl BundleReader {
|
|||
#[inline]
|
||||
pub fn load_info<P: AsRef<Path>>(
|
||||
path: P,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
) -> Result<BundleInfo, BundleReaderError> {
|
||||
Self::load_header(path, crypto).map(|b| b.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn load(path: PathBuf, crypto: Arc<Mutex<Crypto>>) -> Result<Self, BundleReaderError> {
|
||||
pub fn load(path: PathBuf, crypto: Arc<Crypto>) -> Result<Self, BundleReaderError> {
|
||||
let (header, version, content_start) = try!(Self::load_header(&path, crypto.clone()));
|
||||
Ok(BundleReader::new(
|
||||
path,
|
||||
|
@ -170,8 +168,6 @@ impl BundleReader {
|
|||
if let Some(ref encryption) = self.info.encryption {
|
||||
chunk_data = try!(
|
||||
self.crypto
|
||||
.lock()
|
||||
.unwrap()
|
||||
.decrypt(encryption, &chunk_data)
|
||||
.context(&self.path as &Path)
|
||||
);
|
||||
|
@ -212,8 +208,6 @@ impl BundleReader {
|
|||
if let Some(ref encryption) = self.info.encryption {
|
||||
data = try!(
|
||||
self.crypto
|
||||
.lock()
|
||||
.unwrap()
|
||||
.decrypt(encryption, &data)
|
||||
.context(&self.path as &Path)
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::*;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write, BufWriter};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::prelude::*;
|
||||
|
||||
|
@ -51,7 +51,7 @@ pub struct BundleWriter {
|
|||
compression: Option<Compression>,
|
||||
compression_stream: Option<CompressionStream>,
|
||||
encryption: Option<Encryption>,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
raw_size: usize,
|
||||
chunk_count: usize,
|
||||
chunks: ChunkList
|
||||
|
@ -63,7 +63,7 @@ impl BundleWriter {
|
|||
hash_method: HashMethod,
|
||||
compression: Option<Compression>,
|
||||
encryption: Option<Encryption>,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
) -> Result<Self, BundleWriterError> {
|
||||
let compression_stream = match compression {
|
||||
Some(ref compression) => Some(try!(compression.compress_stream().map_err(
|
||||
|
@ -106,14 +106,14 @@ impl BundleWriter {
|
|||
))
|
||||
}
|
||||
if let Some(ref encryption) = self.encryption {
|
||||
self.data = try!(self.crypto.lock().unwrap().encrypt(encryption, &self.data));
|
||||
self.data = try!(self.crypto.encrypt(encryption, &self.data));
|
||||
}
|
||||
let encoded_size = self.data.len();
|
||||
let mut chunk_data = Vec::with_capacity(self.chunks.encoded_size());
|
||||
self.chunks.write_to(&mut chunk_data).unwrap();
|
||||
let id = BundleId(self.hash_method.hash(&chunk_data));
|
||||
if let Some(ref encryption) = self.encryption {
|
||||
chunk_data = try!(self.crypto.lock().unwrap().encrypt(encryption, &chunk_data));
|
||||
chunk_data = try!(self.crypto.encrypt(encryption, &chunk_data));
|
||||
}
|
||||
let mut path = db.layout.temp_bundle_path();
|
||||
let mut file = BufWriter::new(try!(File::create(&path).context(&path as &Path)));
|
||||
|
@ -133,7 +133,7 @@ impl BundleWriter {
|
|||
};
|
||||
let mut info_data = try!(msgpack::encode(&info).context(&path as &Path));
|
||||
if let Some(ref encryption) = self.encryption {
|
||||
info_data = try!(self.crypto.lock().unwrap().encrypt(encryption, &info_data));
|
||||
info_data = try!(self.crypto.encrypt(encryption, &info_data));
|
||||
}
|
||||
let header = BundleHeader {
|
||||
encryption: self.encryption,
|
||||
|
|
|
@ -20,7 +20,7 @@ use std::mem;
|
|||
use std::cmp::max;
|
||||
use std::path::Path;
|
||||
use std::fs::{self, File};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use std::os::unix::fs::symlink;
|
||||
use std::io::Write;
|
||||
|
||||
|
@ -74,10 +74,10 @@ impl index::Key for Hash {
|
|||
}
|
||||
|
||||
pub struct Repository {
|
||||
pub layout: Arc<ChunkRepositoryLayout>,
|
||||
layout: Arc<ChunkRepositoryLayout>,
|
||||
pub config: Config,
|
||||
index: Index<Hash, Location>,
|
||||
crypto: Arc<Mutex<Crypto>>,
|
||||
crypto: Arc<Crypto>,
|
||||
bundle_map: BundleMap,
|
||||
next_data_bundle: u32,
|
||||
next_meta_bundle: u32,
|
||||
|
@ -133,7 +133,7 @@ impl Repository {
|
|||
try!(fs::create_dir_all(layout.local_locks_path())); // Added after v0.1.0
|
||||
let local_locks = LockFolder::new(layout.local_locks_path());
|
||||
let lock = try!(local_locks.lock(false));
|
||||
let crypto = Arc::new(Mutex::new(try!(Crypto::open(layout.keys_path()))));
|
||||
let crypto = Arc::new(try!(Crypto::open(layout.keys_path())));
|
||||
let (bundles, new, gone) = try!(BundleDb::open(layout.clone(), crypto.clone(), online));
|
||||
let (index, mut rebuild_index) =
|
||||
match unsafe { Index::open(layout.index_path(), &INDEX_MAGIC, INDEX_VERSION) } {
|
||||
|
@ -225,7 +225,7 @@ impl Repository {
|
|||
) -> Result<Self, RepositoryError> {
|
||||
let mut repo = try!(Repository::create(layout.clone(), &Config::default(), remote));
|
||||
for file in key_files {
|
||||
try!(repo.crypto.lock().unwrap().register_keyfile(file));
|
||||
try!(repo.crypto.register_keyfile(file));
|
||||
}
|
||||
repo = try!(Repository::open(layout, true));
|
||||
let mut backups: Vec<(String, Backup)> = try!(repo.get_all_backups()).into_iter().collect();
|
||||
|
@ -249,7 +249,7 @@ impl Repository {
|
|||
secret: SecretKey,
|
||||
) -> Result<(), RepositoryError> {
|
||||
try!(self.write_mode());
|
||||
try!(self.crypto.lock().unwrap().register_secret_key(
|
||||
try!(self.crypto.register_secret_key(
|
||||
public,
|
||||
secret
|
||||
));
|
||||
|
@ -266,7 +266,7 @@ impl Repository {
|
|||
#[inline]
|
||||
pub fn set_encryption(&mut self, public: Option<&PublicKey>) {
|
||||
if let Some(key) = public {
|
||||
if !self.crypto.lock().unwrap().contains_secret_key(key) {
|
||||
if !self.crypto.contains_secret_key(key) {
|
||||
tr_warn!("The secret key for that public key is not stored in the repository.")
|
||||
}
|
||||
let mut key_bytes = Vec::new();
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::io;
|
||||
use std::fs::{self, File};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use std::sync::{RwLock, Once, ONCE_INIT};
|
||||
|
||||
use serde_yaml;
|
||||
use serde_bytes::ByteBuf;
|
||||
|
@ -116,7 +116,7 @@ impl KeyfileYaml {
|
|||
|
||||
pub struct Crypto {
|
||||
path: Option<PathBuf>,
|
||||
keys: HashMap<PublicKey, SecretKey>
|
||||
keys: RwLock<HashMap<PublicKey, SecretKey>>
|
||||
}
|
||||
|
||||
impl Crypto {
|
||||
|
@ -125,7 +125,7 @@ impl Crypto {
|
|||
sodium_init();
|
||||
Crypto {
|
||||
path: None,
|
||||
keys: HashMap::new()
|
||||
keys: RwLock::new(HashMap::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,17 +152,17 @@ impl Crypto {
|
|||
}
|
||||
Ok(Crypto {
|
||||
path: Some(path),
|
||||
keys
|
||||
keys: RwLock::new(keys)
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_secret_key(&mut self, public: PublicKey, secret: SecretKey) {
|
||||
self.keys.insert(public, secret);
|
||||
pub fn add_secret_key(&self, public: PublicKey, secret: SecretKey) {
|
||||
self.keys.write().expect("Lock poisoned").insert(public, secret);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn register_keyfile<P: AsRef<Path>>(&mut self, path: P) -> Result<(), EncryptionError> {
|
||||
pub fn register_keyfile<P: AsRef<Path>>(&self, path: P) -> Result<(), EncryptionError> {
|
||||
let (public, secret) = try!(Self::load_keypair_from_file(path));
|
||||
self.register_secret_key(public, secret)
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ impl Crypto {
|
|||
|
||||
#[inline]
|
||||
pub fn register_secret_key(
|
||||
&mut self,
|
||||
&self,
|
||||
public: PublicKey,
|
||||
secret: SecretKey,
|
||||
) -> Result<(), EncryptionError> {
|
||||
|
@ -219,17 +219,17 @@ impl Crypto {
|
|||
let path = path.join(to_hex(&public[..]) + ".yaml");
|
||||
try!(Self::save_keypair_to_file(&public, &secret, path));
|
||||
}
|
||||
self.keys.insert(public, secret);
|
||||
self.keys.write().expect("Lock poisoned").insert(public, secret);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn contains_secret_key(&mut self, public: &PublicKey) -> bool {
|
||||
self.keys.contains_key(public)
|
||||
pub fn contains_secret_key(&self, public: &PublicKey) -> bool {
|
||||
self.keys.read().expect("Lock poisoned").contains_key(public)
|
||||
}
|
||||
|
||||
fn get_secret_key(&self, public: &PublicKey) -> Result<&SecretKey, EncryptionError> {
|
||||
self.keys.get(public).ok_or_else(
|
||||
fn get_secret_key(&self, public: &PublicKey) -> Result<SecretKey, EncryptionError> {
|
||||
self.keys.read().expect("Lock poisoned").get(public).cloned().ok_or_else(
|
||||
|| EncryptionError::MissingKey(*public)
|
||||
)
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ impl Crypto {
|
|||
let secret = try!(self.get_secret_key(&public));
|
||||
match *method {
|
||||
EncryptionMethod::Sodium => {
|
||||
sealedbox::open(data, &public, secret).map_err(|_| {
|
||||
sealedbox::open(data, &public, &secret).map_err(|_| {
|
||||
EncryptionError::Operation(tr!("Decryption failed"))
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue