use crate::db::types::Database;
use crate::{
DatabaseKey,
error::{DatabaseIntegrityError, DatabaseOpenError},
format::{
DatabaseVersion,
kdb::parse_kdb,
kdbx3::{decrypt_kdbx3, parse_kdbx3},
kdbx4::{decrypt_kdbx4, parse_kdbx4},
},
};
impl Database {
pub fn open(source: &mut dyn std::io::Read, key: DatabaseKey) -> Result<Database, DatabaseOpenError> {
let mut data = Vec::new();
source.read_to_end(&mut data)?;
Database::parse(data.as_ref(), key)
}
pub fn parse(data: &[u8], key: DatabaseKey) -> Result<Database, DatabaseOpenError> {
let database_version = DatabaseVersion::parse(data)?;
match database_version {
DatabaseVersion::KDB(_) => parse_kdb(data, &key),
DatabaseVersion::KDB2(_) => Err(DatabaseOpenError::UnsupportedVersion),
DatabaseVersion::KDB3(_) => parse_kdbx3(data, &key),
DatabaseVersion::KDB4(_) => parse_kdbx4(data, &key),
}
}
pub fn get_xml(source: &mut dyn std::io::Read, key: DatabaseKey) -> Result<Vec<u8>, DatabaseOpenError> {
let mut data = Vec::new();
source.read_to_end(&mut data)?;
let database_version = DatabaseVersion::parse(data.as_ref())?;
let data = match database_version {
DatabaseVersion::KDB(_) => return Err(DatabaseOpenError::UnsupportedVersion),
DatabaseVersion::KDB2(_) => return Err(DatabaseOpenError::UnsupportedVersion),
DatabaseVersion::KDB3(_) => decrypt_kdbx3(data.as_ref(), &key)?.2,
DatabaseVersion::KDB4(_) => decrypt_kdbx4(data.as_ref(), &key)?.3,
};
Ok(data)
}
pub fn get_version(source: &mut dyn std::io::Read) -> Result<DatabaseVersion, DatabaseIntegrityError> {
let mut data = vec![0; DatabaseVersion::get_version_header_size()];
_ = source.read(&mut data)?;
DatabaseVersion::parse(data.as_ref())
}
}