Skip to content
Merged
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion cpp/src/parquet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,11 @@ endif()
if(PARQUET_REQUIRE_ENCRYPTION)
list(APPEND PARQUET_SHARED_PRIVATE_LINK_LIBS ${ARROW_OPENSSL_LIBS})
set(PARQUET_SRCS ${PARQUET_SRCS} encryption/aes_encryption.cc
encryption/openssl_internal.cc
encryption/encryption_utils.cc
encryption/external_dbpa_encryption.cc
encryption/openssl_internal.cc
encryption/external/dbpa_library_wrapper.cc
encryption/external/dbpa_utils.cc
encryption/external/loadable_encryptor_utils.cc
)
# Encryption key management
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/parquet/encryption/external/dbpa_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include <stdexcept>

#include "parquet/encryption/external/borrowed/dbpa_interface.h"
#include "parquet/encryption/external/third_party/dbpa_interface.h"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We missed this in an earlier PR. Because the code was not being used at the time, there were no compilation errors.

#include "parquet/types.h"
#include "arrow/type_fwd.h" // For arrow::Compression

Expand Down
268 changes: 213 additions & 55 deletions cpp/src/parquet/encryption/external_dbpa_encryption.cc

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions cpp/src/parquet/encryption/external_dbpa_encryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <map>
#include <vector>

#include "parquet/encryption/external/third_party/dbpa_interface.h"

#include "parquet/encryption/encryptor_interface.h"
#include "parquet/encryption/decryptor_interface.h"
#include "parquet/metadata.h"
Expand Down Expand Up @@ -46,7 +48,7 @@ class ExternalDBPAEncryptorAdapter : public EncryptorInterface {
::arrow::util::span<uint8_t> encrypted_footer) override;

private:
int32_t CallExternalDBPA(
int32_t InvokeExternalEncrypt(

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this name change so source files are easier to navigate. Sharing the same name among encryptor and decryptor was confusing.

::arrow::util::span<const uint8_t> plaintext, ::arrow::util::span<uint8_t> ciphertext);

ParquetCipher::type algorithm_;
Expand All @@ -57,6 +59,9 @@ class ExternalDBPAEncryptorAdapter : public EncryptorInterface {
Encoding::type encoding_type_;
std::string app_context_;
std::map<std::string, std::string> connection_config_;

std::unique_ptr<dbps::external::DataBatchProtectionAgentInterface> agent_instance_;
bool agent_initialized_ = false;
};

/// Factory for ExternalDBPAEncryptorAdapter instances. The cache exists while the write
Expand Down Expand Up @@ -104,7 +109,7 @@ class ExternalDBPADecryptorAdapter : public DecryptorInterface {
::arrow::util::span<uint8_t> plaintext) override;

private:
int32_t CallExternalDBPA(
int32_t InvokeExternalDecrypt(
::arrow::util::span<const uint8_t> ciphertext, ::arrow::util::span<uint8_t> plaintext);

ParquetCipher::type algorithm_;
Expand All @@ -116,6 +121,9 @@ class ExternalDBPADecryptorAdapter : public DecryptorInterface {
std::vector<Encoding::type> encoding_types_;
std::string app_context_;
std::map<std::string, std::string> connection_config_;

std::unique_ptr<dbps::external::DataBatchProtectionAgentInterface> agent_instance_;
bool agent_initialized_ = false;
};

/// Factory for ExternalDBPADecryptorAdapter instances. No cache exists for decryptors.
Expand Down
25 changes: 20 additions & 5 deletions cpp/src/parquet/encryption/external_dbpa_encryption_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ class ExternalDBPAEncryptorAdapterTest : public ::testing::Test {
"{\"user_id\": \"abc123\", \"location\": {\"lat\": 9.7489, \"lon\": -83.7534}}";
connection_config_ = {
{"lib_name", "dbpa_lib.so"},
{"config_path", "path/to/file"}
{"config_path", "path/to/file"},
{"agent_library_path", "libDBPATestAgent.so"}
};
}

void RoundtripEncryption(
ParquetCipher::type algorithm, std::string column_name, std::string key_id,
Type::type data_type, Compression::type compression_type, Encoding::type encoding_type,
std::string plaintext) {
ExternalDBPAEncryptorAdapter encryptor(
algorithm, column_name, key_id, data_type, compression_type, encoding_type,
app_context_, connection_config_);
ExternalDBPAEncryptorAdapter encryptor(algorithm, column_name, key_id, data_type,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just formatting, so that the encryptor and decryptor construction are similar in the code (no functional changes)

compression_type, encoding_type, app_context_,
connection_config_);

int32_t expected_ciphertext_length = plaintext.size();
int32_t actual_ciphertext_length = encryptor.CiphertextLength(plaintext.size());
Expand All @@ -39,7 +40,19 @@ class ExternalDBPAEncryptorAdapterTest : public ::testing::Test {
ASSERT_EQ(expected_ciphertext_length, encryption_length);

std::string ciphertext_str(ciphertext_buffer.begin(), ciphertext_buffer.end());
ASSERT_EQ(plaintext, ciphertext_str);

// We know this uses XOR encryption. Therefore, the ciphertext is the same as the plaintext.
// XOR encrytion encrypts each byte of the plaintext with 0xAA.
// See external/dbpa_test_agent.cc for the implementation.

// Assert that plaintext and ciphertext have the same length
ASSERT_EQ(plaintext.size(), ciphertext_str.size());

// Assert that ciphertext is plaintext XOR'd with 0xAA
for (size_t i = 0; i < plaintext.size(); i++) {
ASSERT_EQ(static_cast<uint8_t>(ciphertext_str[i]),
static_cast<uint8_t>(plaintext[i]) ^ 0xAA);
}

ExternalDBPADecryptorAdapter decryptor(algorithm, column_name, key_id, data_type,
compression_type, {encoding_type}, app_context_,
Expand All @@ -55,6 +68,8 @@ class ExternalDBPAEncryptorAdapterTest : public ::testing::Test {
ASSERT_EQ(expected_plaintext_length, decryption_length);

std::string plaintext_str(plaintext_buffer.begin(), plaintext_buffer.end());

// Assert that the decrypted plaintext matches the original plaintext
ASSERT_EQ(plaintext, plaintext_str);
}

Expand Down
1 change: 1 addition & 0 deletions cpp/src/parquet/encryption/read_configurations_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class TestDecryptionConfiguration
file_decryption_builder_5.key_retriever(kr5);
file_decryption_builder_5.connection_config({
{parquet::ParquetCipher::EXTERNAL_DBPA_V1, {
{"agent_library_path", "libDBPATestAgent.so"},
{"file_path", "/tmp/test"},
{"other_config", "value"}
}}
Expand Down
1 change: 1 addition & 0 deletions cpp/src/parquet/encryption/write_configurations_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ TEST_F(TestEncryptionConfiguration, EncryptWithPerColumnEncryption) {
->algorithm(parquet::ParquetCipher::AES_GCM_V1)
->connection_config({
{parquet::ParquetCipher::EXTERNAL_DBPA_V1, {
{"agent_library_path", "libDBPATestAgent.so"},
{"file_path", "/tmp/test"},
{"other_config", "value"}
}}
Expand Down
Loading