Skip to content

Commit

Permalink
sqlcipher check
Browse files Browse the repository at this point in the history
  • Loading branch information
insipx committed Nov 27, 2024
1 parent 41204ab commit a7d56af
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
8 changes: 8 additions & 0 deletions xmtp_mls/src/storage/encrypted_store/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ impl StorageOption {
Ephemeral => SqliteConnection::establish(":memory:"),
}
}

pub(super) fn path(&self) -> Option<&String> {
use StorageOption::*;
match self {
Persistent(path) => Some(path),
_ => None,
}
}
}

#[derive(Clone, Debug)]
Expand Down
39 changes: 37 additions & 2 deletions xmtp_mls/src/storage/encrypted_store/sqlcipher_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ impl EncryptedConnection {
/// Creates a file for the salt and stores it
pub fn new(key: EncryptionKey, opts: &StorageOption) -> Result<Self, StorageError> {
use super::StorageOption::*;
Self::check_for_sqlcipher(opts)?;

let salt = match opts {
Ephemeral => None,
Persistent(ref db_path) => {
Expand All @@ -56,25 +58,45 @@ impl EncryptedConnection {
match (salt_path.try_exists()?, db_pathbuf.try_exists()?) {
// db and salt exist
(true, true) => {
tracing::debug!(
salt = %salt_path.display(),
db = %db_pathbuf.display(),
"salt and database exist, db=[{}], salt=[{}]",
db_pathbuf.display(),
salt_path.display(),
);
let file = File::open(salt_path)?;
salt = <Salt as hex::FromHex>::from_hex(
file.bytes().take(32).collect::<Result<Vec<u8>, _>>()?,
)?;
}
// the db exists and needs to be migrated
(false, true) => {
tracing::debug!("migrating sqlcipher db to plaintext header.");
tracing::debug!(
"migrating sqlcipher db=[{}] to plaintext header with salt=[{}]",
db_pathbuf.display(),
salt_path.display()
);
Self::migrate(db_path, key, &mut salt)?;
}
// the db doesn't exist yet and needs to be created
(false, false) => {
tracing::debug!("creating new sqlcipher db");
tracing::debug!(
"creating new sqlcipher db=[{}] with salt=[{}]",
db_pathbuf.display(),
salt_path.display()
);
Self::create(db_path, key, &mut salt)?;
}
// the db doesn't exist but the salt does
// This generally doesn't make sense & shouldn't happen.
// Create a new database and delete the salt file.
(true, false) => {
tracing::debug!(
"database [{}] does not exist, but the salt [{}] does, re-creating",
db_pathbuf.display(),
salt_path.display(),
);
std::fs::remove_file(salt_path)?;
Self::create(db_path, key, &mut salt)?;
}
Expand Down Expand Up @@ -199,6 +221,19 @@ impl EncryptedConnection {
)
}
}

fn check_for_sqlcipher(opts: &StorageOption) -> Result<(), StorageError> {
if let Some(path) = opts.path() {
let exists = std::path::Path::new(path).exists();
tracing::debug!("db @ [{}] exists? [{}]", path, exists);
}
let conn = &mut opts.conn()?;
let cipher_version = sql_query("PRAGMA cipher_version").load::<CipherVersion>(conn)?;
if cipher_version.is_empty() {
return Err(StorageError::SqlCipherNotLoaded);
}
Ok(())
}
}

impl super::native::ValidatedConnection for EncryptedConnection {
Expand Down

0 comments on commit a7d56af

Please sign in to comment.