@@ -19,6 +19,7 @@ use crate::encryption::ciphers::{BlockDecryptor, RingGcmBlockDecryptor};
19
19
use crate :: encryption:: modules:: { create_module_aad, ModuleType } ;
20
20
use crate :: errors:: { ParquetError , Result } ;
21
21
use crate :: file:: column_crypto_metadata:: ColumnCryptoMetaData ;
22
+ use std:: borrow:: Cow ;
22
23
use std:: collections:: HashMap ;
23
24
use std:: fmt:: Formatter ;
24
25
use std:: io:: Read ;
@@ -204,6 +205,39 @@ impl FileDecryptionProperties {
204
205
pub fn with_key_retriever ( key_retriever : Arc < dyn KeyRetriever > ) -> DecryptionPropertiesBuilder {
205
206
DecryptionPropertiesBuilder :: new_with_key_retriever ( key_retriever)
206
207
}
208
+
209
+ /// Get the encryption key for decrypting a file's footer,
210
+ /// and also column data if uniform encryption is used.
211
+ pub ( crate ) fn footer_key ( & self , key_metadata : Option < & [ u8 ] > ) -> Result < Cow < Vec < u8 > > > {
212
+ match & self . keys {
213
+ DecryptionKeys :: Explicit ( keys) => Ok ( Cow :: Borrowed ( & keys. footer_key ) ) ,
214
+ DecryptionKeys :: ViaRetriever ( retriever) => {
215
+ let key = retriever. retrieve_key ( key_metadata. unwrap_or_default ( ) ) ?;
216
+ Ok ( Cow :: Owned ( key) )
217
+ }
218
+ }
219
+ }
220
+
221
+ /// Get the column-specific encryption key for decrypting column data and metadata within a file
222
+ pub ( crate ) fn column_key (
223
+ & self ,
224
+ column_name : & str ,
225
+ key_metadata : Option < & [ u8 ] > ,
226
+ ) -> Result < Cow < Vec < u8 > > > {
227
+ match & self . keys {
228
+ DecryptionKeys :: Explicit ( keys) => match keys. column_keys . get ( column_name) {
229
+ None => Err ( general_err ! (
230
+ "No column decryption key set for column '{}'" ,
231
+ column_name
232
+ ) ) ,
233
+ Some ( key) => Ok ( Cow :: Borrowed ( key) ) ,
234
+ } ,
235
+ DecryptionKeys :: ViaRetriever ( retriever) => {
236
+ let key = retriever. retrieve_key ( key_metadata. unwrap_or_default ( ) ) ?;
237
+ Ok ( Cow :: Owned ( key) )
238
+ }
239
+ }
240
+ }
207
241
}
208
242
209
243
impl std:: fmt:: Debug for FileDecryptionProperties {
@@ -307,14 +341,8 @@ impl FileDecryptor {
307
341
aad_prefix : Vec < u8 > ,
308
342
) -> Result < Self > {
309
343
let file_aad = [ aad_prefix. as_slice ( ) , aad_file_unique. as_slice ( ) ] . concat ( ) ;
310
- let footer_decryptor = match & decryption_properties. keys {
311
- DecryptionKeys :: Explicit ( keys) => RingGcmBlockDecryptor :: new ( & keys. footer_key ) ,
312
- DecryptionKeys :: ViaRetriever ( retriever) => {
313
- let footer_key = retriever. retrieve_key ( footer_key_metadata. unwrap_or_default ( ) ) ?;
314
- RingGcmBlockDecryptor :: new ( & footer_key)
315
- }
316
- } ;
317
- let footer_decryptor = footer_decryptor. map_err ( |e| {
344
+ let footer_key = decryption_properties. footer_key ( footer_key_metadata) ?;
345
+ let footer_decryptor = RingGcmBlockDecryptor :: new ( & footer_key) . map_err ( |e| {
318
346
general_err ! (
319
347
"Invalid footer key. {}" ,
320
348
e. to_string( ) . replace( "Parquet error: " , "" )
@@ -337,16 +365,10 @@ impl FileDecryptor {
337
365
column_name : & str ,
338
366
key_metadata : Option < & [ u8 ] > ,
339
367
) -> Result < Arc < dyn BlockDecryptor > > {
340
- match & self . decryption_properties . keys {
341
- DecryptionKeys :: Explicit ( keys) => match keys. column_keys . get ( column_name) {
342
- Some ( column_key) => Ok ( Arc :: new ( RingGcmBlockDecryptor :: new ( column_key) ?) ) ,
343
- None => self . get_footer_decryptor ( ) ,
344
- } ,
345
- DecryptionKeys :: ViaRetriever ( retriever) => {
346
- let key = retriever. retrieve_key ( key_metadata. unwrap_or_default ( ) ) ?;
347
- Ok ( Arc :: new ( RingGcmBlockDecryptor :: new ( & key) ?) )
348
- }
349
- }
368
+ let column_key = self
369
+ . decryption_properties
370
+ . column_key ( column_name, key_metadata) ?;
371
+ Ok ( Arc :: new ( RingGcmBlockDecryptor :: new ( & column_key) ?) )
350
372
}
351
373
352
374
pub ( crate ) fn get_column_metadata_decryptor (
0 commit comments