Skip to content

Commit 1fcca9c

Browse files
committed
Add TestReader::new, less pub functions, add test_non_uniform_encryption_diabled_aad_storage
1 parent 751b54e commit 1fcca9c

File tree

6 files changed

+97
-51
lines changed

6 files changed

+97
-51
lines changed

parquet/src/arrow/arrow_reader/mod.rs

+58
Original file line numberDiff line numberDiff line change
@@ -1881,6 +1881,64 @@ mod tests {
18811881
verify_encryption_test_file_read(file, decryption_properties);
18821882
}
18831883

1884+
#[test]
1885+
#[cfg(feature = "encryption")]
1886+
fn test_non_uniform_encryption_diabled_aad_storage() {
1887+
let testdata = arrow::util::test_util::parquet_test_data();
1888+
let path =
1889+
format!("{testdata}/encrypt_columns_and_footer_disable_aad_storage.parquet.encrypted");
1890+
let file = File::open(path.clone()).unwrap();
1891+
1892+
let footer_key = "0123456789012345".as_bytes(); // 128bit/16
1893+
let column_1_key = "1234567890123450".as_bytes();
1894+
let column_2_key = "1234567890123451".as_bytes();
1895+
1896+
// Provided AAD prefix overrides the one stored in the file
1897+
let decryption_properties = FileDecryptionProperties::builder(footer_key.to_vec())
1898+
.with_column_key("double_field", column_1_key.to_vec())
1899+
.with_column_key("float_field", column_2_key.to_vec())
1900+
.with_aad_prefix("tester")
1901+
.build()
1902+
.unwrap();
1903+
1904+
verify_encryption_test_file_read(file, decryption_properties);
1905+
1906+
// Using wrong AAD prefix should fail
1907+
let decryption_properties = FileDecryptionProperties::builder(footer_key.to_vec())
1908+
.with_column_key("double_field", column_1_key.to_vec())
1909+
.with_column_key("float_field", column_2_key.to_vec())
1910+
.with_aad_prefix("wrong_aad_prefix")
1911+
.build()
1912+
.unwrap();
1913+
1914+
let file = File::open(path.clone()).unwrap();
1915+
let options = ArrowReaderOptions::default()
1916+
.with_file_decryption_properties(decryption_properties.clone());
1917+
let result = ArrowReaderMetadata::load(&file, options.clone());
1918+
assert!(result.is_err());
1919+
assert_eq!(
1920+
result.unwrap_err().to_string(),
1921+
"Parquet error: Provided footer key and AAD were unable to decrypt parquet footer"
1922+
);
1923+
1924+
// Using wrong AAD prefix stored in the file should fail
1925+
let decryption_properties = FileDecryptionProperties::builder(footer_key.to_vec())
1926+
.with_column_key("double_field", column_1_key.to_vec())
1927+
.with_column_key("float_field", column_2_key.to_vec())
1928+
.build()
1929+
.unwrap();
1930+
1931+
let file = File::open(path).unwrap();
1932+
let options = ArrowReaderOptions::default()
1933+
.with_file_decryption_properties(decryption_properties.clone());
1934+
let result = ArrowReaderMetadata::load(&file, options.clone());
1935+
assert!(result.is_err());
1936+
assert_eq!(
1937+
result.unwrap_err().to_string(),
1938+
"Parquet error: Provided footer key and AAD were unable to decrypt parquet footer"
1939+
);
1940+
}
1941+
18841942
#[test]
18851943
fn test_non_uniform_encryption_plaintext_footer_without_decryption() {
18861944
let testdata = arrow::util::test_util::parquet_test_data();

parquet/src/arrow/async_reader/mod.rs

+20-35
Original file line numberDiff line numberDiff line change
@@ -1198,8 +1198,21 @@ mod tests {
11981198
data: Bytes,
11991199
metadata: Arc<ParquetMetaData>,
12001200
requests: Arc<Mutex<Vec<Range<usize>>>>,
1201-
#[cfg(feature = "encryption")]
1202-
file_decryption_properties: Option<FileDecryptionProperties>,
1201+
}
1202+
1203+
#[cfg(feature = "encryption")]
1204+
impl TestReader {
1205+
async fn new(
1206+
data: Bytes,
1207+
metadata: Arc<ParquetMetaData>,
1208+
requests: Arc<Mutex<Vec<Range<usize>>>>,
1209+
) -> Self {
1210+
Self {
1211+
data,
1212+
metadata,
1213+
requests,
1214+
}
1215+
}
12031216
}
12041217

12051218
impl AsyncFileReader for TestReader {
@@ -1238,8 +1251,6 @@ mod tests {
12381251
data: data.clone(),
12391252
metadata: metadata.clone(),
12401253
requests: Default::default(),
1241-
#[cfg(feature = "encryption")]
1242-
file_decryption_properties: None,
12431254
};
12441255

12451256
let requests = async_reader.requests.clone();
@@ -1297,8 +1308,6 @@ mod tests {
12971308
data: data.clone(),
12981309
metadata: metadata.clone(),
12991310
requests: Default::default(),
1300-
#[cfg(feature = "encryption")]
1301-
file_decryption_properties: None,
13021311
};
13031312

13041313
let requests = async_reader.requests.clone();
@@ -1364,8 +1373,6 @@ mod tests {
13641373
data: data.clone(),
13651374
metadata: metadata.clone(),
13661375
requests: Default::default(),
1367-
#[cfg(feature = "encryption")]
1368-
file_decryption_properties: None,
13691376
};
13701377

13711378
let options = ArrowReaderOptions::new().with_page_index(true);
@@ -1434,8 +1441,6 @@ mod tests {
14341441
data: data.clone(),
14351442
metadata: metadata.clone(),
14361443
requests: Default::default(),
1437-
#[cfg(feature = "encryption")]
1438-
file_decryption_properties: None,
14391444
};
14401445

14411446
let builder = ParquetRecordBatchStreamBuilder::new(async_reader)
@@ -1482,8 +1487,6 @@ mod tests {
14821487
data: data.clone(),
14831488
metadata: metadata.clone(),
14841489
requests: Default::default(),
1485-
#[cfg(feature = "encryption")]
1486-
file_decryption_properties: None,
14871490
};
14881491

14891492
let options = ArrowReaderOptions::new().with_page_index(true);
@@ -1567,8 +1570,6 @@ mod tests {
15671570
data: data.clone(),
15681571
metadata: metadata.clone(),
15691572
requests: Default::default(),
1570-
#[cfg(feature = "encryption")]
1571-
file_decryption_properties: None,
15721573
};
15731574

15741575
let options = ArrowReaderOptions::new().with_page_index(true);
@@ -1640,8 +1641,6 @@ mod tests {
16401641
data: data.clone(),
16411642
metadata: metadata.clone(),
16421643
requests: Default::default(),
1643-
#[cfg(feature = "encryption")]
1644-
file_decryption_properties: None,
16451644
};
16461645

16471646
let options = ArrowReaderOptions::new().with_page_index(true);
@@ -1692,8 +1691,6 @@ mod tests {
16921691
data,
16931692
metadata: Arc::new(metadata),
16941693
requests: Default::default(),
1695-
#[cfg(feature = "encryption")]
1696-
file_decryption_properties: None,
16971694
};
16981695
let requests = test.requests.clone();
16991696

@@ -1771,8 +1768,6 @@ mod tests {
17711768
data,
17721769
metadata: Arc::new(metadata),
17731770
requests: Default::default(),
1774-
#[cfg(feature = "encryption")]
1775-
file_decryption_properties: None,
17761771
};
17771772

17781773
let stream = ParquetRecordBatchStreamBuilder::new(test.clone())
@@ -1865,8 +1860,6 @@ mod tests {
18651860
data: data.clone(),
18661861
metadata: metadata.clone(),
18671862
requests: Default::default(),
1868-
#[cfg(feature = "encryption")]
1869-
file_decryption_properties: None,
18701863
};
18711864

18721865
let a_filter =
@@ -1935,8 +1928,6 @@ mod tests {
19351928
data: data.clone(),
19361929
metadata: metadata.clone(),
19371930
requests: Default::default(),
1938-
#[cfg(feature = "encryption")]
1939-
file_decryption_properties: None,
19401931
};
19411932

19421933
let requests = async_reader.requests.clone();
@@ -2013,8 +2004,6 @@ mod tests {
20132004
data: data.clone(),
20142005
metadata: metadata.clone(),
20152006
requests: Default::default(),
2016-
#[cfg(feature = "encryption")]
2017-
file_decryption_properties: None,
20182007
};
20192008

20202009
let builder = ParquetRecordBatchStreamBuilder::new(async_reader)
@@ -2160,8 +2149,6 @@ mod tests {
21602149
data: data.clone(),
21612150
metadata: metadata.clone(),
21622151
requests: Default::default(),
2163-
#[cfg(feature = "encryption")]
2164-
file_decryption_properties: None,
21652152
};
21662153
let builder = ParquetRecordBatchStreamBuilder::new(async_reader)
21672154
.await
@@ -2199,8 +2186,6 @@ mod tests {
21992186
data: data.clone(),
22002187
metadata: metadata.clone(),
22012188
requests: Default::default(),
2202-
#[cfg(feature = "encryption")]
2203-
file_decryption_properties: None,
22042189
};
22052190

22062191
let mut builder = ParquetRecordBatchStreamBuilder::new(async_reader)
@@ -2338,8 +2323,6 @@ mod tests {
23382323
data,
23392324
metadata: Arc::new(metadata),
23402325
requests: Default::default(),
2341-
#[cfg(feature = "encryption")]
2342-
file_decryption_properties: None,
23432326
};
23442327
let requests = test.requests.clone();
23452328

@@ -2514,7 +2497,9 @@ mod tests {
25142497
.build()
25152498
.unwrap();
25162499

2517-
verify_encryption_test_file_read_async(&mut file, decryption_properties).await.unwrap();
2500+
verify_encryption_test_file_read_async(&mut file, decryption_properties)
2501+
.await
2502+
.unwrap();
25182503
}
25192504

25202505
#[tokio::test]
@@ -2687,7 +2672,7 @@ mod tests {
26872672
.build()
26882673
.unwrap();
26892674

2690-
let _ = verify_encryption_test_file_read_async(&mut file, decryption_properties).await;
2675+
verify_encryption_test_file_read_async(&mut file, decryption_properties).await;
26912676
}
26922677

26932678
#[tokio::test]
@@ -2702,7 +2687,7 @@ mod tests {
27022687
.build()
27032688
.unwrap();
27042689

2705-
let _ = verify_encryption_test_file_read_async(&mut file, decryption_properties).await;
2690+
verify_encryption_test_file_read_async(&mut file, decryption_properties).await;
27062691
}
27072692

27082693
#[tokio::test]

parquet/src/arrow/async_reader/store.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,9 @@ impl AsyncFileReader for ParquetObjectReader {
175175
let metadata = ParquetMetaDataReader::new()
176176
.with_column_indexes(self.preload_column_index)
177177
.with_offset_indexes(self.preload_offset_index)
178-
.with_prefetch_hint(self.metadata_size_hint);
179-
#[cfg(feature = "encryption")]
180-
let metadata = metadata
181-
.with_decryption_properties(self.file_decryption_properties.clone().as_ref());
182-
183-
let metadata = metadata.load_and_finish(self, file_size).await?;
178+
.with_prefetch_hint(self.metadata_size_hint)
179+
.load_and_finish(self, file_size)
180+
.await?;
184181
Ok(Arc::new(metadata))
185182
})
186183
}

parquet/src/encryption/decryption.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn read_and_decrypt<T: Read>(
3939
// CryptoContext is a data structure that holds the context required to
4040
// decrypt parquet modules (data pages, dictionary pages, etc.).
4141
#[derive(Debug, Clone)]
42-
pub struct CryptoContext {
42+
pub(crate) struct CryptoContext {
4343
pub(crate) row_group_ordinal: usize,
4444
pub(crate) column_ordinal: usize,
4545
pub(crate) page_ordinal: Option<usize>,
@@ -145,7 +145,7 @@ impl CryptoContext {
145145
pub struct FileDecryptionProperties {
146146
footer_key: Vec<u8>,
147147
column_keys: HashMap<String, Vec<u8>>,
148-
aad_prefix: Option<Vec<u8>>,
148+
pub(crate) aad_prefix: Option<Vec<u8>>,
149149
}
150150

151151
impl FileDecryptionProperties {
@@ -178,8 +178,8 @@ impl DecryptionPropertiesBuilder {
178178
})
179179
}
180180

181-
pub fn with_aad_prefix(mut self, value: Vec<u8>) -> Self {
182-
self.aad_prefix = Some(value);
181+
pub fn with_aad_prefix(mut self, value: &str) -> Self {
182+
self.aad_prefix = Some(value.as_bytes().to_vec());
183183
self
184184
}
185185

@@ -191,7 +191,7 @@ impl DecryptionPropertiesBuilder {
191191
}
192192

193193
#[derive(Clone, Debug)]
194-
pub struct FileDecryptor {
194+
pub(crate) struct FileDecryptor {
195195
decryption_properties: FileDecryptionProperties,
196196
footer_decryptor: Option<Arc<dyn BlockDecryptor>>,
197197
file_aad: Vec<u8>,

parquet/src/encryption/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@
1818
//! Encryption implementation specific to Parquet, as described
1919
//! in the [spec](https://github.com/apache/parquet-format/blob/master/Encryption.md).
2020
21-
pub mod ciphers;
22-
pub mod decryption;
23-
pub mod modules;
21+
mod ciphers;
22+
pub(crate) mod decryption;
23+
pub(crate) mod modules;

parquet/src/file/metadata/reader.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,9 @@ impl ParquetMetaDataReader {
721721
decrypted_fmd_buf = footer_decryptor?
722722
.decrypt(prot.as_slice().as_ref(), aad_footer.as_ref())
723723
.map_err(|_| {
724-
general_err!("Provided footer key was unable to decrypt parquet footer")
724+
general_err!(
725+
"Provided footer key and AAD were unable to decrypt parquet footer"
726+
)
725727
})?;
726728
prot = TCompactSliceInputProtocol::new(decrypted_fmd_buf.as_ref());
727729

@@ -847,7 +849,11 @@ fn get_file_decryptor(
847849
let aad_file_unique = algo
848850
.aad_file_unique
849851
.ok_or_else(|| general_err!("AAD unique file identifier is not set"))?;
850-
let aad_prefix: Vec<u8> = algo.aad_prefix.unwrap_or_default();
852+
let aad_prefix = if file_decryption_properties.aad_prefix.is_some() {
853+
file_decryption_properties.aad_prefix.clone().unwrap()
854+
} else {
855+
algo.aad_prefix.unwrap_or_default()
856+
};
851857

852858
FileDecryptor::new(file_decryption_properties, aad_file_unique, aad_prefix)
853859
}

0 commit comments

Comments
 (0)