@@ -10,6 +10,7 @@ use eyre::{eyre, OptionExt};
10
10
use frost_core:: { Ciphersuite , Identifier } ;
11
11
use frostd:: PublicKey ;
12
12
use serde:: { Deserialize , Serialize } ;
13
+ use zeroize:: { Zeroize , ZeroizeOnDrop , Zeroizing } ;
13
14
14
15
use crate :: { ciphersuite_helper:: ciphersuite_helper, contact:: Contact , write_atomic} ;
15
16
@@ -30,6 +31,14 @@ pub struct Config {
30
31
pub group : BTreeMap < String , Group > ,
31
32
}
32
33
34
+ impl Zeroize for Config {
35
+ fn zeroize ( & mut self ) {
36
+ self . group . iter_mut ( ) . for_each ( |( _, g) | g. zeroize ( ) ) ;
37
+ }
38
+ }
39
+
40
+ impl ZeroizeOnDrop for Config { }
41
+
33
42
impl Config {
34
43
pub fn contact_by_pubkey ( & self , pubkey : & PublicKey ) -> Result < Contact , Box < dyn Error > > {
35
44
if Some ( pubkey) == self . communication_key . as_ref ( ) . map ( |c| & c. pubkey ) {
@@ -49,7 +58,7 @@ impl Config {
49
58
}
50
59
51
60
/// The communication key pair for the user.
52
- #[ derive( Clone , Debug , Serialize , Deserialize ) ]
61
+ #[ derive( Clone , Debug , Serialize , Deserialize , ZeroizeOnDrop ) ]
53
62
pub struct CommunicationKey {
54
63
/// The private key.
55
64
#[ serde(
@@ -62,7 +71,7 @@ pub struct CommunicationKey {
62
71
}
63
72
64
73
/// A FROST group the user belongs to.
65
- #[ derive( Clone , Debug , Serialize , Deserialize ) ]
74
+ #[ derive( Clone , Debug , Serialize , Deserialize , Zeroize ) ]
66
75
pub struct Group {
67
76
/// A human-readable description of the group to make it easier to select
68
77
/// groups
@@ -84,9 +93,12 @@ pub struct Group {
84
93
/// The default server the participants are using, if any.
85
94
pub server_url : Option < String > ,
86
95
/// The group participants, keyed by hex-encoded identifier
96
+ #[ zeroize( skip) ]
87
97
pub participant : BTreeMap < String , Participant > ,
88
98
}
89
99
100
+ impl ZeroizeOnDrop for Group { }
101
+
90
102
impl Group {
91
103
/// Returns a human-readable summary of the contact; used when it is
92
104
/// printed to the terminal.
@@ -169,7 +181,7 @@ impl Config {
169
181
..Default :: default ( )
170
182
} ) ;
171
183
}
172
- let bytes = std:: fs:: read ( & path) ?;
184
+ let bytes = Zeroizing :: new ( std:: fs:: read ( & path) ?) ;
173
185
let s = str:: from_utf8 ( & bytes) ?;
174
186
let mut config: Config = toml:: from_str ( s) ?;
175
187
config. path = Some ( path) ;
@@ -178,7 +190,7 @@ impl Config {
178
190
179
191
/// Write the config to path it was loaded from.
180
192
pub fn write ( & self ) -> Result < ( ) , Box < dyn Error > > {
181
- let s = toml:: to_string_pretty ( self ) ?;
193
+ let s = Zeroizing :: new ( toml:: to_string_pretty ( self ) ?) ;
182
194
let bytes = s. as_bytes ( ) ;
183
195
Ok ( write_atomic:: write_file (
184
196
self . path
0 commit comments