18
18
//! Encryption implementation specific to Parquet, as described
19
19
//! in the [spec](https://github.com/apache/parquet-format/blob/master/Encryption.md).
20
20
21
+ use std:: sync:: Arc ;
21
22
use ring:: aead:: { Aad , LessSafeKey , NonceSequence , UnboundKey , AES_128_GCM } ;
22
23
use ring:: rand:: { SecureRandom , SystemRandom } ;
23
24
use crate :: errors:: { ParquetError , Result } ;
@@ -172,8 +173,12 @@ pub fn create_footer_aad(file_aad: &[u8]) -> Result<Vec<u8>> {
172
173
create_module_aad ( file_aad, ModuleType :: Footer , -1 , -1 , -1 )
173
174
}
174
175
175
- fn create_module_aad ( file_aad : & [ u8 ] , module_type : ModuleType , row_group_ordinal : i32 ,
176
- column_ordinal : i32 , page_ordinal : i32 ) -> Result < Vec < u8 > > {
176
+ pub fn create_page_aad ( file_aad : & [ u8 ] , module_type : ModuleType , row_group_ordinal : i16 , column_ordinal : i16 , page_ordinal : i32 ) -> Result < Vec < u8 > > {
177
+ create_module_aad ( file_aad, module_type, row_group_ordinal, column_ordinal, page_ordinal)
178
+ }
179
+
180
+ fn create_module_aad ( file_aad : & [ u8 ] , module_type : ModuleType , row_group_ordinal : i16 ,
181
+ column_ordinal : i16 , page_ordinal : i32 ) -> Result < Vec < u8 > > {
177
182
178
183
let module_buf = [ module_type as u8 ] ;
179
184
@@ -187,15 +192,15 @@ fn create_module_aad(file_aad: &[u8], module_type: ModuleType, row_group_ordinal
187
192
if row_group_ordinal < 0 {
188
193
return Err ( general_err ! ( "Wrong row group ordinal: {}" , row_group_ordinal) ) ;
189
194
}
190
- if row_group_ordinal > u16 :: MAX as i32 {
195
+ if row_group_ordinal > i16 :: MAX {
191
196
return Err ( general_err ! ( "Encrypted parquet files can't have more than {} row groups: {}" ,
192
197
u16 :: MAX , row_group_ordinal) ) ;
193
198
}
194
199
195
200
if column_ordinal < 0 {
196
201
return Err ( general_err ! ( "Wrong column ordinal: {}" , column_ordinal) ) ;
197
202
}
198
- if column_ordinal > u16 :: MAX as i32 {
203
+ if column_ordinal > i16 :: MAX {
199
204
return Err ( general_err ! ( "Encrypted parquet files can't have more than {} columns: {}" ,
200
205
u16 :: MAX , column_ordinal) ) ;
201
206
}
@@ -205,25 +210,25 @@ fn create_module_aad(file_aad: &[u8], module_type: ModuleType, row_group_ordinal
205
210
let mut aad = Vec :: with_capacity ( file_aad. len ( ) + 5 ) ;
206
211
aad. extend_from_slice ( file_aad) ;
207
212
aad. extend_from_slice ( module_buf. as_ref ( ) ) ;
208
- aad. extend_from_slice ( ( row_group_ordinal as u16 ) . to_le_bytes ( ) . as_ref ( ) ) ;
209
- aad. extend_from_slice ( ( column_ordinal as u16 ) . to_le_bytes ( ) . as_ref ( ) ) ;
213
+ aad. extend_from_slice ( ( row_group_ordinal as i16 ) . to_le_bytes ( ) . as_ref ( ) ) ;
214
+ aad. extend_from_slice ( ( column_ordinal as i16 ) . to_le_bytes ( ) . as_ref ( ) ) ;
210
215
return Ok ( aad)
211
216
}
212
217
213
218
if page_ordinal < 0 {
214
- return Err ( general_err ! ( "Wrong column ordinal: {}" , page_ordinal) ) ;
219
+ return Err ( general_err ! ( "Wrong page ordinal: {}" , page_ordinal) ) ;
215
220
}
216
- if page_ordinal > u16 :: MAX as i32 {
221
+ if page_ordinal > i32 :: MAX {
217
222
return Err ( general_err ! ( "Encrypted parquet files can't have more than {} pages in a chunk: {}" ,
218
223
u16 :: MAX , page_ordinal) ) ;
219
224
}
220
225
221
226
let mut aad = Vec :: with_capacity ( file_aad. len ( ) + 7 ) ;
222
227
aad. extend_from_slice ( file_aad) ;
223
228
aad. extend_from_slice ( module_buf. as_ref ( ) ) ;
224
- aad. extend_from_slice ( ( row_group_ordinal as u16 ) . to_le_bytes ( ) . as_ref ( ) ) ;
225
- aad. extend_from_slice ( ( column_ordinal as u16 ) . to_le_bytes ( ) . as_ref ( ) ) ;
226
- aad. extend_from_slice ( ( page_ordinal as u16 ) . to_le_bytes ( ) . as_ref ( ) ) ;
229
+ aad. extend_from_slice ( row_group_ordinal. to_le_bytes ( ) . as_ref ( ) ) ;
230
+ aad. extend_from_slice ( column_ordinal. to_le_bytes ( ) . as_ref ( ) ) ;
231
+ aad. extend_from_slice ( page_ordinal. to_le_bytes ( ) . as_ref ( ) ) ;
227
232
Ok ( aad)
228
233
}
229
234
@@ -266,7 +271,9 @@ impl DecryptionPropertiesBuilder {
266
271
pub struct FileDecryptor {
267
272
decryption_properties : FileDecryptionProperties ,
268
273
// todo decr: change to BlockDecryptor
269
- footer_decryptor : RingGcmBlockDecryptor
274
+ footer_decryptor : RingGcmBlockDecryptor ,
275
+ aad_file_unique : Vec < u8 > ,
276
+ aad_prefix : Vec < u8 > ,
270
277
}
271
278
272
279
impl PartialEq for FileDecryptor {
@@ -276,30 +283,63 @@ impl PartialEq for FileDecryptor {
276
283
}
277
284
278
285
impl FileDecryptor {
279
- pub ( crate ) fn new ( decryption_properties : & FileDecryptionProperties ) -> Self {
286
+ pub ( crate ) fn new ( decryption_properties : & FileDecryptionProperties , aad_file_unique : Vec < u8 > , aad_prefix : Vec < u8 > ) -> Self {
280
287
Self {
281
288
// todo decr: if no key available yet (not set in properties, will be retrieved from metadata)
282
289
footer_decryptor : RingGcmBlockDecryptor :: new ( decryption_properties. footer_key . clone ( ) . unwrap ( ) . as_ref ( ) ) ,
283
- decryption_properties : decryption_properties. clone ( )
290
+ decryption_properties : decryption_properties. clone ( ) ,
291
+ aad_file_unique,
292
+ aad_prefix,
284
293
}
285
294
}
286
295
287
296
// todo decr: change to BlockDecryptor
288
297
pub ( crate ) fn get_footer_decryptor ( self ) -> RingGcmBlockDecryptor {
289
298
self . footer_decryptor
290
299
}
300
+
301
+ pub ( crate ) fn decryption_properties ( & self ) -> & FileDecryptionProperties {
302
+ & self . decryption_properties
303
+ }
304
+
305
+ pub ( crate ) fn footer_decryptor ( & self ) -> RingGcmBlockDecryptor {
306
+ self . footer_decryptor . clone ( )
307
+ }
308
+
309
+ pub ( crate ) fn aad_file_unique ( & self ) -> & Vec < u8 > {
310
+ & self . aad_file_unique
311
+ }
312
+
313
+ pub ( crate ) fn aad_prefix ( & self ) -> & Vec < u8 > {
314
+ & self . aad_prefix
315
+ }
291
316
}
292
317
318
+ #[ derive( Debug , Clone ) ]
293
319
pub struct CryptoContext {
294
- row_group_ordinal : i32 ,
295
- column_ordinal : i32 ,
296
- metadata_decryptor : FileDecryptor ,
297
- data_decryptor : FileDecryptor ,
298
- file_decryption_properties : FileDecryptionProperties ,
299
- aad : Vec < u8 > ,
320
+ pub ( crate ) start_decrypt_with_dictionary_page : bool ,
321
+ pub ( crate ) row_group_ordinal : i16 ,
322
+ pub ( crate ) column_ordinal : i16 ,
323
+ pub ( crate ) data_decryptor : Arc < FileDecryptor > ,
324
+ pub ( crate ) metadata_decryptor : Arc < FileDecryptor > ,
325
+
300
326
}
301
327
302
328
impl CryptoContext {
303
- pub fn data_decryptor ( self ) -> FileDecryptor { self . data_decryptor }
304
- pub fn file_decryption_properties ( & self ) -> & FileDecryptionProperties { & self . file_decryption_properties }
329
+ pub fn new ( start_decrypt_with_dictionary_page : bool , row_group_ordinal : i16 ,
330
+ column_ordinal : i16 , data_decryptor : Arc < FileDecryptor > ,
331
+ metadata_decryptor : Arc < FileDecryptor > ) -> Self {
332
+ Self {
333
+ start_decrypt_with_dictionary_page,
334
+ row_group_ordinal,
335
+ column_ordinal,
336
+ data_decryptor,
337
+ metadata_decryptor,
338
+ }
339
+ }
340
+ pub fn start_decrypt_with_dictionary_page ( & self ) -> & bool { & self . start_decrypt_with_dictionary_page }
341
+ pub fn row_group_ordinal ( & self ) -> & i16 { & self . row_group_ordinal }
342
+ pub fn column_ordinal ( & self ) -> & i16 { & self . column_ordinal }
343
+ pub fn data_decryptor ( & self ) -> Arc < FileDecryptor > { self . data_decryptor . clone ( ) }
344
+ pub fn metadata_decryptor ( & self ) -> Arc < FileDecryptor > { self . metadata_decryptor . clone ( ) }
305
345
}
0 commit comments