Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.apache.parquet.hadoop.ParquetFileWriter.Mode.OVERWRITE;
import static org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.BOOLEAN;
import static org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -102,6 +103,8 @@
* identity storage in file metadata.
* ENCRYPT_COLUMNS_AND_FOOTER_CTR: Encrypt six columns and the footer, with different
* keys. Use the alternative (AES_GCM_CTR_V1) algorithm.
* ENCRYPT_COLUMNS_PLAINTEXT_FOOTER_CTR: Encrypt six columns with different keys and
* a plaintext footer, using AES_GCM_CTR_V1.
* NO_ENCRYPTION: Do not encrypt anything
*
*
Expand All @@ -126,6 +129,7 @@ public class TestEncryptionOptions {
private ErrorCollector errorCollector = new ErrorCollector();
private InterOpTester interop = new InterOpTester();
private static final String CHANGESET = "40379b3";
private static final String PLAINTEXT_FOOTER_CTR_CHANGESET = "eedfad3f086678d282a00d8ff3cf8932d5d29af5";

private static final byte[] FOOTER_ENCRYPTION_KEY = "0123456789012345".getBytes();
private static final byte[][] COLUMN_ENCRYPTION_KEYS = {
Expand All @@ -145,7 +149,8 @@ public class TestEncryptionOptions {

private static final int ROW_COUNT = 10000;
private static final List<SingleRow> DATA = Collections.unmodifiableList(SingleRow.generateRandomData(ROW_COUNT));
private static final List<SingleRow> LINEAR_DATA = Collections.unmodifiableList(SingleRow.generateLinearData(250));
// The C++-generated interoperability fixtures contain one row group of 50 rows.
private static final List<SingleRow> LINEAR_DATA = Collections.unmodifiableList(SingleRow.generateLinearData(50));

private static final MessageType SCHEMA = SingleRow.getSchema();

Expand Down Expand Up @@ -239,6 +244,20 @@ public FileEncryptionProperties getEncryptionProperties() {
.build();
}
},
ENCRYPT_COLUMNS_PLAINTEXT_FOOTER_CTR {
/**
* Encryption configuration 9: Encrypt six columns with different keys and a plaintext footer.
* Use AES_GCM_CTR_V1.
*/
public FileEncryptionProperties getEncryptionProperties() {
return FileEncryptionProperties.builder(FOOTER_ENCRYPTION_KEY)
.withFooterKeyMetadata(footerKeyMetadata)
.withEncryptedColumns(getColumnEncryptionPropertiesMap())
.withAlgorithm(ParquetCipher.AES_GCM_CTR_V1)
.withPlaintextFooter()
.build();
}
},
UNIFORM_ENCRYPTION_PLAINTEXT_FOOTER {
/**
* Encryption configuration 7: Encrypt all columns with the same key.
Expand Down Expand Up @@ -408,7 +427,9 @@ private void testReadEncryptedParquetFiles(Path root, List<SingleRow> data) {

// Read only the non-encrypted columns
if ((decryptionConfiguration == DecryptionConfiguration.NO_DECRYPTION)
&& (encryptionConfiguration == EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER)) {
&& (encryptionConfiguration == EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER
|| encryptionConfiguration
== EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER_CTR)) {
conf.set(
"parquet.read.schema",
Types.buildMessage()
Expand Down Expand Up @@ -480,6 +501,7 @@ private void testReadEncryptedParquetFiles(Path root, List<SingleRow> data) {
}
}
}
assertThat(rowNum).isEqualTo(data.size());
} catch (ParquetCryptoRuntimeException e) {
checkResult(file.getName(), decryptionConfiguration, e);
} catch (Exception e) {
Expand Down Expand Up @@ -510,15 +532,20 @@ private void testInteropReadEncryptedParquetFiles(boolean readOnlyEncrypted, Lis
if (EncryptionConfiguration.ENCRYPT_COLUMNS_PLAIN_FOOTER_COMPLETE == encryptionConfiguration) {
continue;
}
Path file = interop.GetInterOpFile(getFileName(encryptionConfiguration), CHANGESET);
boolean plaintextFooterCtr =
encryptionConfiguration == EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER_CTR;
String changeset = plaintextFooterCtr ? PLAINTEXT_FOOTER_CTR_CHANGESET : CHANGESET;
Path file = interop.GetInterOpFile(getFileName(encryptionConfiguration), changeset);
LOG.info("==> Decryption configuration {}", decryptionConfiguration);
FileDecryptionProperties fileDecryptionProperties = decryptionConfiguration.getDecryptionProperties();

LOG.info("--> Read file {} {}", file.toString(), encryptionConfiguration);

// Read only the non-encrypted columns
if ((decryptionConfiguration == DecryptionConfiguration.NO_DECRYPTION)
&& (encryptionConfiguration == EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER)) {
&& (encryptionConfiguration == EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER
|| encryptionConfiguration
== EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER_CTR)) {
conf.set(
"parquet.read.schema",
Types.buildMessage()
Expand Down Expand Up @@ -558,6 +585,7 @@ private void testInteropReadEncryptedParquetFiles(boolean readOnlyEncrypted, Lis
}
}
}
assertThat(rowNum).isEqualTo(data.size());
} catch (ParquetCryptoRuntimeException e) {
checkResult(file.getName(), decryptionConfiguration, e);
} catch (Exception e) {
Expand Down Expand Up @@ -640,7 +668,8 @@ private void checkResult(
// be thrown if the file is encrypted.
if (decryptionConfiguration == DecryptionConfiguration.NO_DECRYPTION) {
if ((encryptionConfiguration != EncryptionConfiguration.NO_ENCRYPTION
&& encryptionConfiguration != EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER)) {
&& encryptionConfiguration != EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER
&& encryptionConfiguration != EncryptionConfiguration.ENCRYPT_COLUMNS_PLAINTEXT_FOOTER_CTR)) {
if (!exceptionMsg.endsWith("No keys available")
&& !exceptionMsg.endsWith("Null File Decryptor")
&& !exceptionMsg.endsWith("Footer key unavailable")) {
Expand Down
Loading