@@ -319,7 +319,8 @@ impl ProtocolWalletApi for BMPWallet<Connection> {
319319 }
320320}
321321pub trait WalletApi {
322- const DB_PATH : & str ;
322+ const DB_NAME : & str ;
323+ const ENC_DB_NAME : & str ;
323324 const SEEDS_TABLE_NAME : & ' static str ;
324325 const IMPORTED_KEYS_TABLE_NAME : & ' static str ;
325326
@@ -339,7 +340,7 @@ pub trait WalletApi {
339340 fn balance ( & self ) -> Amount ;
340341
341342 fn encrypt ( self , password : & str ) -> anyhow:: Result < BMPWallet < Connection > > ;
342- fn decrypt ( self , password : & str ) -> anyhow:: Result < BMPWallet < Connection > > ;
343+ fn decrypt ( & self , password : & str ) -> anyhow:: Result < ( ) > ;
343344
344345 fn persist ( & mut self ) -> anyhow:: Result < bool > ;
345346
@@ -369,7 +370,8 @@ pub trait WalletApi {
369370impl WalletApi for BMPWallet < Connection > {
370371 const SEEDS_TABLE_NAME : & ' static str = "bmp_seeds" ;
371372 const IMPORTED_KEYS_TABLE_NAME : & ' static str = "bmp_imported_keys" ;
372- const DB_PATH : & str = "bmp_bdk_wallet.db3" ;
373+ const DB_NAME : & str = "bmp_bdk_wallet.db3" ;
374+ const ENC_DB_NAME : & str = "bmp_bdk_encrypted.db3" ;
373375
374376 fn persist ( & mut self ) -> anyhow:: Result < bool > {
375377 // Persist imported keys and then persist staged changes from ChangeSet
@@ -606,7 +608,7 @@ impl WalletApi for BMPWallet<Connection> {
606608 . build ( network)
607609 . expect ( "Internal description generation should not fail" ) ;
608610
609- let mut db = Connection :: new ( Self :: DB_PATH ) ?;
611+ let mut db = Connection :: new ( Self :: DB_NAME ) ?;
610612
611613 let wallet = Wallet :: create ( descriptor, change_descriptor)
612614 . network ( network)
@@ -637,13 +639,13 @@ impl WalletApi for BMPWallet<Connection> {
637639 // This will also load the imported keys
638640 fn load_wallet ( network : Network , password : Option < & str > ) -> anyhow:: Result < Self > {
639641 let mut db = if let Some ( password) = password {
640- let salt = get_salt ( Self :: DB_PATH ) ?;
642+ let salt = get_salt ( Self :: DB_NAME ) ?;
641643 let decrypt_key = derive_key_from_password ( password, & salt) ?;
642- let conn = Connection :: open ( Self :: DB_PATH ) ?;
644+ let conn = Connection :: open ( Self :: ENC_DB_NAME ) ?;
643645 conn. pragma_update ( None , "key" , decrypt_key) ?;
644646 conn
645647 } else {
646- Connection :: open ( Self :: DB_PATH ) ?
648+ Connection :: open ( Self :: DB_NAME ) ?
647649 } ;
648650
649651 let wallet_opt = Wallet :: load ( ) . check_network ( network) . load_wallet ( & mut db) ?;
@@ -684,47 +686,39 @@ impl WalletApi for BMPWallet<Connection> {
684686 Connection :: get_seed_phrase ( & self . db , Self :: SEEDS_TABLE_NAME )
685687 }
686688
687- fn decrypt ( self , password : & str ) -> anyhow:: Result < BMPWallet < Connection > > {
688- let salt = get_salt ( Self :: DB_PATH ) ?;
689-
689+ /// The decryption is done on the active connection which holds the decryption key in memory.
690+ /// Without setting the right `pragma` value when connected to the database, an attacker
691+ /// will not be able to access the database. Even when the active connection has decrypted the
692+ /// file, on file system the database is still encrypted and can't be accessed.
693+ /// The decryption is done only to the active connection
694+ fn decrypt ( & self , password : & str ) -> anyhow:: Result < ( ) > {
695+ let salt = get_salt ( Self :: DB_NAME ) ?;
690696 let decrypt_key = derive_key_from_password ( password, & salt) ?;
691-
692- let encrypted_conn = Connection :: open ( Self :: DB_PATH ) ?;
693- encrypted_conn. pragma_update ( None , "key" , decrypt_key) ?;
694-
695- Ok ( Self {
696- wallet : self . wallet ,
697- imported_keys : self . imported_keys ,
698- imported_balance : self . imported_balance ,
699- signers_loaded : false ,
700- db : encrypted_conn,
701- } )
697+ self . db . pragma_update ( None , "key" , & decrypt_key) ?;
698+ Ok ( ( ) )
702699 }
703700
704701 fn encrypt ( self , password : & str ) -> anyhow:: Result < BMPWallet < Connection > > {
705702 // Derive encryption key from password
706- let salt_path = format ! ( "{}.salt" , Self :: DB_PATH ) ;
703+ let salt_path = format ! ( "{}.salt" , Self :: DB_NAME ) ;
707704
708705 let mut salt = [ 0u8 ; 16 ] ;
709706 rand:: rng ( ) . fill_bytes ( & mut salt) ;
710707
711708 fs:: write ( & salt_path, general_purpose:: STANDARD . encode ( salt) ) ?;
712709 let enc_key = derive_key_from_password ( password, & salt) ?;
713710
714- let encrypted_conn = Connection :: open ( "bmp_encrypted.db3" ) ?;
711+ let encrypted_conn = Connection :: open ( Self :: ENC_DB_NAME ) ?;
715712 encrypted_conn. pragma_update ( None , "key" , & enc_key) ?;
716713
717714 let mut sql = format ! (
718715 "ATTACH DATABASE '{}' AS encrypted_db KEY '{}';" ,
719- "bmp_encrypted.db3" , enc_key
716+ Self :: ENC_DB_NAME , enc_key
720717 ) ;
721718 sql += " SELECT sqlcipher_export('encrypted_db'); DETACH DATABASE encrypted_db;" ;
722719
723720 self . db . execute_batch ( & sql) ?;
724-
725- // Rename the bmp_encrypted.db3 to bmp_wallet.db3
726- fs:: remove_file ( Self :: DB_PATH ) ?;
727- fs:: rename ( "bmp_encrypted.db3" , Self :: DB_PATH ) ?;
721+ fs:: remove_file ( Self :: DB_NAME ) ?;
728722
729723 Ok ( Self {
730724 wallet : self . wallet ,
0 commit comments