|
18 | 18 | use crate::errors::{ParquetError, Result};
|
19 | 19 | use ring::aead::{Aad, LessSafeKey, UnboundKey, AES_128_GCM};
|
20 | 20 | use std::collections::HashMap;
|
| 21 | +use std::io::Read; |
21 | 22 |
|
22 | 23 | const NONCE_LEN: usize = 12;
|
23 | 24 | const TAG_LEN: usize = 16;
|
24 | 25 | const SIZE_LEN: usize = 4;
|
25 | 26 |
|
26 | 27 | pub trait BlockDecryptor {
|
27 | 28 | fn decrypt(&self, length_and_ciphertext: &[u8], aad: &[u8]) -> Result<Vec<u8>>;
|
| 29 | + |
| 30 | + fn read_and_decrypt<T: Read>(&self, input: &mut T, aad: &[u8]) -> Result<Vec<u8>>; |
28 | 31 | }
|
29 | 32 |
|
30 | 33 | #[derive(Debug, Clone)]
|
@@ -59,6 +62,16 @@ impl BlockDecryptor for RingGcmBlockDecryptor {
|
59 | 62 | result.resize(result.len() - TAG_LEN, 0u8);
|
60 | 63 | Ok(result)
|
61 | 64 | }
|
| 65 | + |
| 66 | + fn read_and_decrypt<T: Read>(&self, input: &mut T, aad: &[u8]) -> Result<Vec<u8>> { |
| 67 | + let mut len_bytes = [0; 4]; |
| 68 | + input.read_exact(&mut len_bytes)?; |
| 69 | + let ciphertext_len = u32::from_le_bytes(len_bytes) as usize; |
| 70 | + let mut ciphertext = vec![0; 4 + ciphertext_len]; |
| 71 | + input.read_exact(&mut ciphertext[4..])?; |
| 72 | + |
| 73 | + self.decrypt(&ciphertext, aad.as_ref()) |
| 74 | + } |
62 | 75 | }
|
63 | 76 |
|
64 | 77 | #[derive(Debug, Clone, PartialEq)]
|
@@ -102,7 +115,9 @@ impl DecryptionPropertiesBuilder {
|
102 | 115 |
|
103 | 116 | pub fn build(self) -> Result<FileDecryptionProperties> {
|
104 | 117 | if self.footer_key.is_none() && self.column_keys.is_none() {
|
105 |
| - return Err(ParquetError::General("Footer or at least one column key is required".to_string())) |
| 118 | + return Err(ParquetError::General( |
| 119 | + "Footer or at least one column key is required".to_string(), |
| 120 | + )); |
106 | 121 | }
|
107 | 122 |
|
108 | 123 | Ok(FileDecryptionProperties {
|
|
0 commit comments