@@ -29,13 +29,14 @@ use sha2::digest::Digest;
2929use chacha20:: ChaCha8Rng ;
3030use rand_core:: RngCore ;
3131
32- #[ derive( Copy , Clone ) ]
32+ #[ derive( Clone ) ]
3333pub struct RawStore < S >
3434where
3535 S : Store ,
3636{
3737 mode : RawStoreMode ,
38- symmetric_key : Option < [ u8 ; 32 ] > ,
38+ pin : Option < ShortData > ,
39+ key_filename : PathBuf ,
3940 store : S ,
4041}
4142
@@ -46,21 +47,17 @@ impl<S: Store> RawStore<S> {
4647 pin : Option < ShortData > ,
4748 rng : Option < ChaCha8Rng > ,
4849 ) -> Self {
49- let mut symmetric_key = [ 0u8 ; 32 ] ;
50-
50+ let key_filename = PathBuf :: from ( "encryption-key" ) ;
5151 if mode == RawStoreMode :: Encrypted {
52- let key_filename = PathBuf :: from ( "encryption-key" ) ;
5352 let res: Result < Bytes < 128 > , Error > =
5453 store:: read ( store, Location :: Internal , & key_filename) ;
55- debug_now ! ( "pin: {:?}" , pin) ;
56- let pin_key = Self :: get_pin_key ( pin. unwrap ( ) ) . into_vec ( ) ;
54+ let pin_key = Self :: get_pin_key ( pin. clone ( ) . unwrap ( ) ) . into_vec ( ) ;
5755 match res {
5856 // 'key_filename' not found, generate new key and save (encrypted) to 'key_filename'
5957 Err ( e) => {
6058 let mut new_key = [ 0u8 ; 32 ] ;
6159 rng. unwrap ( ) . fill_bytes ( & mut new_key) ;
6260
63- symmetric_key. copy_from_slice ( & new_key) ;
6461 let content =
6562 Self :: encrypt_content ( mode, & key_filename, pin_key. as_slice ( ) , & new_key) ;
6663 store:: write (
@@ -70,21 +67,17 @@ impl<S: Store> RawStore<S> {
7067 content. into_vec ( ) . as_slice ( ) ,
7168 ) ;
7269 }
73- // 'key_filename' found, extract symmetric key and use it
70+ // 'key_filename' found
7471 Ok ( data) => {
75- symmetric_key. copy_from_slice ( & Self :: decrypt_content (
76- mode,
77- & key_filename,
78- pin_key. as_slice ( ) ,
79- data,
80- ) ) ;
72+ // do nothing, read key on-demand
8173 }
8274 }
8375 }
8476
8577 Self {
8678 mode,
87- symmetric_key : Some ( symmetric_key) ,
79+ pin : pin. clone ( ) ,
80+ key_filename,
8881 store,
8982 }
9083 }
@@ -93,10 +86,8 @@ impl<S: Store> RawStore<S> {
9386 match mode {
9487 RawStoreMode :: Unencrypted => Message :: from_slice ( contents) . unwrap ( ) ,
9588 RawStoreMode :: Encrypted => {
96- let zero_iv = Self :: get_iv ( path) ;
97- debug_now ! ( "iv: {:?}" , zero_iv) ;
98- debug_now ! ( "key: {:?}" , key) ;
99- let cipher = Aes256Cbc :: new_from_slices ( key, & zero_iv) . unwrap ( ) ;
89+ let iv = Self :: get_iv ( path) ;
90+ let cipher = Aes256Cbc :: new_from_slices ( key, & iv) . unwrap ( ) ;
10091 let mut buffer = Message :: from_slice ( contents) . unwrap ( ) ;
10192 let l = contents. len ( ) ;
10293 buffer. resize_default ( l + ( 32 - l % 32 ) ) ;
@@ -113,42 +104,18 @@ impl<S: Store> RawStore<S> {
113104 contents : Bytes < N > ,
114105 ) -> Bytes < N > {
115106 match mode {
116- RawStoreMode :: Unencrypted => {
117- //debug_now!("READ DATA LEN - N:{:?} len:{:?} data: {:?}", N, contents.len(), &contents[..10]);
118- contents
119- }
107+ RawStoreMode :: Unencrypted => contents,
120108 RawStoreMode :: Encrypted => {
121- let zero_iv = Self :: get_iv ( path) ;
122- let cipher = Aes256Cbc :: new_from_slices ( key, & zero_iv ) . unwrap ( ) ;
109+ let iv = Self :: get_iv ( path) ;
110+ let cipher = Aes256Cbc :: new_from_slices ( key, & iv ) . unwrap ( ) ;
123111 let mut buffer = contents. clone ( ) ;
124112 let plaintext = cipher. decrypt ( & mut buffer) . unwrap ( ) ;
125113 let out = Bytes :: < N > :: from_slice ( plaintext) . unwrap ( ) ;
126- //debug_now!("READ DATA LEN - N:{:?} len:{:?} data: {:?}", N, out.len(), &out[..10]);
127114 out
128115 }
129116 }
130117 }
131118
132- pub fn change_pin ( & self , new_pin : ShortData ) -> Result < ( ) , Error > {
133- let key_filename = PathBuf :: from ( "encryption-key" ) ;
134- let pin_key = Self :: get_pin_key ( new_pin) . into_vec ( ) ;
135-
136- // write key with new pin
137- let content = Self :: encrypt_content (
138- RawStoreMode :: Encrypted ,
139- & key_filename,
140- pin_key. as_slice ( ) ,
141- & self . symmetric_key . unwrap ( ) ,
142- ) ;
143- store:: write (
144- self . store ,
145- Location :: Internal ,
146- & key_filename,
147- content. into_vec ( ) . as_slice ( ) ,
148- ) ;
149- Ok ( ( ) )
150- }
151-
152119 pub fn get_pin_key ( pin : ShortData ) -> Bytes < 32 > {
153120 let mut hash = sha2:: Sha256 :: new ( ) ;
154121 hash. update ( pin) ;
@@ -169,12 +136,55 @@ impl<S: Store> RawStore<S> {
169136 Bytes :: < 16 > :: from_slice ( & hashed. into_vec ( ) . as_slice ( ) [ ..16 ] ) . unwrap ( )
170137 }
171138
172- pub fn create_directories < ' s , X : LfsStorage > (
173- & self ,
174- fs : & Filesystem < ' s , X > ,
175- path : & Path ,
176- ) -> Result < ( ) , Error > {
177- store:: create_directories ( fs, path)
139+ fn read_symmetric_key ( & self ) -> Result < [ u8 ; 32 ] , Error > {
140+ if self . mode == RawStoreMode :: Unencrypted {
141+ return Ok ( [ 0u8 ; 32 ] ) ;
142+ }
143+
144+ let pin_key = Self :: get_pin_key ( self . pin . clone ( ) . unwrap ( ) ) . into_vec ( ) ;
145+ let res: Result < Bytes < 128 > , Error > =
146+ store:: read ( self . store , Location :: Internal , & self . key_filename ) ;
147+ let data = res. unwrap ( ) ;
148+
149+ let mut symmetric_key = [ 0u8 ; 32 ] ;
150+
151+ /*symmetric_key.copy_from_slice(&Self::decrypt_content(
152+ self.mode,
153+ &self.key_filename,
154+ pin_key.as_slice(),
155+ data,
156+ ));*/
157+ // instead explicitly decrypt "by-hand" to catch (and propagate) a wrong pin
158+ let iv = Self :: get_iv ( & self . key_filename ) ;
159+ let cipher = Aes256Cbc :: new_from_slices ( pin_key. as_slice ( ) , & iv) . unwrap ( ) ;
160+ let mut buffer = data. clone ( ) ;
161+ match cipher. decrypt ( & mut buffer) {
162+ Err ( e) => return Err ( Error :: FilesystemEncryptionError ) ,
163+ Ok ( plaintext) => symmetric_key. copy_from_slice ( plaintext)
164+ } ;
165+
166+ //let out = Bytes::<N>::from_slice(plaintext).unwrap();
167+
168+ Ok ( symmetric_key)
169+ }
170+
171+ pub fn change_pin ( & self , new_pin : ShortData ) -> Result < ( ) , Error > {
172+ let pin_key = Self :: get_pin_key ( new_pin) . into_vec ( ) ;
173+ // write key with new pin
174+ let key = self . read_symmetric_key ( ) ?;
175+ let content = Self :: encrypt_content (
176+ RawStoreMode :: Encrypted ,
177+ & self . key_filename ,
178+ pin_key. as_slice ( ) ,
179+ & key,
180+ ) ;
181+ store:: write (
182+ self . store ,
183+ Location :: Internal ,
184+ & self . key_filename ,
185+ content. into_vec ( ) . as_slice ( ) ,
186+ ) ;
187+ Ok ( ( ) )
178188 }
179189
180190 pub fn read < const N : usize > (
@@ -183,9 +193,10 @@ impl<S: Store> RawStore<S> {
183193 location : Location ,
184194 path : & Path ,
185195 ) -> Result < Bytes < N > , Error > {
186- debug_now ! ( "READ: {:?} {:?}" , N , path) ;
196+ //debug_now!("READ: {:?} {:?}", N, path);
197+ let key = self . read_symmetric_key ( ) ?;
187198 store:: read ( store, location, path)
188- . map ( |val| Self :: decrypt_content ( self . mode , path, & self . symmetric_key . unwrap ( ) , val) )
199+ . map ( |val| Self :: decrypt_content ( self . mode , path, & key , val) )
189200 }
190201
191202 pub fn write (
@@ -195,13 +206,9 @@ impl<S: Store> RawStore<S> {
195206 path : & Path ,
196207 contents : & [ u8 ] ,
197208 ) -> Result < ( ) , Error > {
198- debug_now ! ( "WRITE: {:?} data: {:?}" , path, & contents[ ..10 ] ) ;
199- let data = Self :: encrypt_content (
200- self . mode ,
201- path,
202- & self . symmetric_key . unwrap ( ) ,
203- & contents. clone ( ) ,
204- ) ;
209+ // debug_now!("WRITE: {:?} data: {:?}", path, &contents[..10]);
210+ let key = self . read_symmetric_key ( ) ?;
211+ let data = Self :: encrypt_content ( self . mode , path, & key, & contents. clone ( ) ) ;
205212 store:: write ( store, location, path, data. into_vec ( ) . as_slice ( ) )
206213 }
207214
@@ -212,15 +219,20 @@ impl<S: Store> RawStore<S> {
212219 path : & Path ,
213220 contents : & [ u8 ] ,
214221 ) -> Result < ( ) , Error > {
215- debug_now ! ( "STORE: {:?} data: {:?}" , path, & contents[ ..10 ] ) ;
216- let data = Self :: encrypt_content (
217- self . mode ,
218- path,
219- & self . symmetric_key . unwrap ( ) ,
220- & contents. clone ( ) ,
221- ) ;
222+ //debug_now!("STORE: {:?} data: {:?}", path, &contents[..10]);
223+ let key = self . read_symmetric_key ( ) ?;
224+ let data = Self :: encrypt_content ( self . mode , path, & key, & contents. clone ( ) ) ;
222225 store:: store ( store, location, path, data. into_vec ( ) . as_slice ( ) )
223226 }
227+
228+ pub fn create_directories < ' s , X : LfsStorage > (
229+ & self ,
230+ fs : & Filesystem < ' s , X > ,
231+ path : & Path ,
232+ ) -> Result < ( ) , Error > {
233+ store:: create_directories ( fs, path)
234+ }
235+
224236 pub fn delete ( & self , store : impl Store , location : Location , path : & Path ) -> bool {
225237 store:: delete ( store, location, path)
226238 }
0 commit comments