1- use std:: { env , fmt, fs, path:: Path , str:: FromStr } ;
1+ use std:: { fmt, fs, path:: Path , str:: FromStr } ;
22
33use argon2:: { password_hash:: SaltString , Argon2 , Params , PasswordHasher } ;
44use base64:: Engine ;
@@ -73,19 +73,26 @@ impl AccountSecretKey {
7373 self . 0 . public . clone ( ) . into_compressed ( )
7474 }
7575
76- pub fn from_encrypted_file ( path : impl AsRef < Path > ) -> Result < Self , EncryptionError > {
76+ pub fn from_encrypted_file (
77+ path : impl AsRef < Path > ,
78+ password : & str ,
79+ ) -> Result < Self , EncryptionError > {
7780 let key_file = fs:: File :: open ( path) ?;
7881 let encrypted: EncryptedSecretKey = serde_json:: from_reader ( key_file) ?;
79- encrypted. try_decrypt ( )
82+ encrypted. try_decrypt ( password )
8083 }
8184
82- pub fn to_encrypted_file ( & self , path : impl AsRef < Path > ) -> Result < ( ) , EncryptionError > {
85+ pub fn to_encrypted_file (
86+ & self ,
87+ path : impl AsRef < Path > ,
88+ password : & str ,
89+ ) -> Result < ( ) , EncryptionError > {
8390 if path. as_ref ( ) . exists ( ) {
8491 panic ! ( "File {} already exists" , path. as_ref( ) . display( ) )
8592 }
8693
8794 let f = fs:: File :: create ( path) ?;
88- let encrypted = EncryptedSecretKey :: encrypt ( & self . to_bytes ( ) ) ?;
95+ let encrypted = EncryptedSecretKey :: encrypt ( & self . to_bytes ( ) , password ) ?;
8996
9097 serde_json:: to_writer ( f, & encrypted) ?;
9198 Ok ( ( ) )
@@ -188,8 +195,6 @@ pub enum EncryptionError {
188195 Io ( #[ from] std:: io:: Error ) ,
189196 #[ error( transparent) ]
190197 SerdeJson ( #[ from] serde_json:: Error ) ,
191- #[ error( "MINA_PRIVKEY_PASS environment variable must be set!" ) ]
192- PasswordEnvVarMissing ,
193198}
194199
195200#[ derive( Serialize , Deserialize , Debug ) ]
@@ -222,10 +227,8 @@ impl EncryptedSecretKey {
222227 ) )
223228 }
224229
225- pub fn try_decrypt ( & self ) -> Result < AccountSecretKey , EncryptionError > {
230+ pub fn try_decrypt ( & self , password : & str ) -> Result < AccountSecretKey , EncryptionError > {
226231 // prepare inputs to cipher
227- let password =
228- env:: var ( "MINA_PRIVKEY_PASS" ) . map_err ( |_| EncryptionError :: PasswordEnvVarMissing ) ?;
229232 let password = password. as_bytes ( ) ;
230233 let pwsalt = self . pwsalt . try_decode ( Self :: ENCRYPTION_DATA_VERSION_BYTE ) ?;
231234 let nonce = self . nonce . try_decode ( Self :: ENCRYPTION_DATA_VERSION_BYTE ) ?;
@@ -253,14 +256,12 @@ impl EncryptedSecretKey {
253256 Ok ( AccountSecretKey :: from_bytes ( & decrypted[ 1 ..] ) ?)
254257 }
255258
256- pub fn encrypt ( key : & [ u8 ] ) -> Result < Self , EncryptionError > {
259+ pub fn encrypt ( key : & [ u8 ] , password : & str ) -> Result < Self , EncryptionError > {
257260 let argon2 = Self :: setup_argon ( Self :: PW_DIFF ) ?;
258261
259262 // add the prefix byt to the key
260263 let mut key_prefixed = vec ! [ Self :: SECRET_KEY_PREFIX_BYTE ] ;
261264 key_prefixed. extend ( key) ;
262- let password =
263- env:: var ( "MINA_PRIVKEY_PASS" ) . map_err ( |_| EncryptionError :: PasswordEnvVarMissing ) ?;
264265
265266 let salt = SaltString :: generate ( & mut OsRng ) ;
266267 let password_hash = argon2
@@ -290,6 +291,8 @@ impl EncryptedSecretKey {
290291
291292#[ cfg( test) ]
292293mod tests {
294+ use std:: env;
295+
293296 use super :: * ;
294297
295298 #[ test]
@@ -316,18 +319,19 @@ mod tests {
316319
317320 #[ test]
318321 fn test_encrypt_decrypt ( ) {
319- env:: set_var ( "MINA_PRIVKEY_PASS" , "not-very-secure-pass" ) ;
322+ let password = "not-very-secure-pass" ;
323+
320324 let new_key = AccountSecretKey :: rand ( ) ;
321325 let tmp_dir = env:: temp_dir ( ) ;
322326 let tmp_path = format ! ( "{}/{}-key" , tmp_dir. display( ) , new_key. public_key( ) ) ;
323327
324328 // dump encrypted file
325329 new_key
326- . to_encrypted_file ( & tmp_path)
330+ . to_encrypted_file ( & tmp_path, password )
327331 . expect ( "Failed to encrypt secret key" ) ;
328332
329333 // load and decrypt
330- let decrypted = AccountSecretKey :: from_encrypted_file ( & tmp_path)
334+ let decrypted = AccountSecretKey :: from_encrypted_file ( & tmp_path, password )
331335 . expect ( "Failed to decrypt secret key file" ) ;
332336
333337 assert_eq ! (
@@ -339,10 +343,10 @@ mod tests {
339343
340344 #[ test]
341345 fn test_ocaml_key_decrypt ( ) {
342- env :: set_var ( "MINA_PRIVKEY_PASS" , "not-very-secure-pass" ) ;
346+ let password = "not-very-secure-pass" ;
343347 let key_path = "../tests/files/accounts/test-key-1" ;
344348 let expected_public_key = "B62qmg7n4XqU3SFwx9KD9B7gxsKwxJP5GmxtBpHp1uxyN3grujii9a1" ;
345- let decrypted = AccountSecretKey :: from_encrypted_file ( key_path)
349+ let decrypted = AccountSecretKey :: from_encrypted_file ( key_path, password )
346350 . expect ( "Failed to decrypt secret key file" ) ;
347351
348352 assert_eq ! (
0 commit comments