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
116 changes: 97 additions & 19 deletions cpp/src/parquet/encryption/external/dbpa_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,109 @@

#pragma once

#include <cstdint>
#include <cstddef>
#include <map>
#include <memory>
#include "parquet/platform.h"
#include "arrow/util/span.h"
#include <string>
#include <utility>
#include "span.hpp"
#include "enums.h"

using ::arrow::util::span;
#ifndef DBPS_EXPORT
#define DBPS_EXPORT
#endif

namespace parquet::encryption::external {
// TODO: this file was copied from
// https://github.com/protegrity/DataBatchProtectionService
// we need to find a better way to share it between repos.

//TODO: this will change once we have a solid defition of interfaces
namespace dbps::external {

class EncryptionResult {
};
using tcb::span;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

👍


class DecryptionResult {
};
/*
* DataBatchProtectionAgentInterface, EncryptionResult and DecryptionResult implementation contracts:
* - While handle to EncryptionResult/DecryptionResult exists, ciphertext()/plaintext() is guaranteed to return valid data
* - Read operations are not destructive. Multiple calls return the same data
* - Destructor must dispose of internal memory (either by delegation or cleanup)
* - No throwing exceptions. Errors reported via success() flag and error methods.
* - Library users must check size() to ensure the actual size of the returned payload.
*/

class PARQUET_EXPORT DataBatchProtectionAgentInterface {
public:
virtual std::unique_ptr<EncryptionResult> Encrypt(
span<const uint8_t> plaintext,
span<uint8_t> ciphertext) = 0;
class DBPS_EXPORT EncryptionResult {
public:
virtual span<const uint8_t> ciphertext() const = 0;

virtual std::unique_ptr<DecryptionResult> Decrypt(
span<const uint8_t> ciphertext) = 0;
// Allows a larger backing buffer than the exact ciphertext size.
// Library users must check size() to ensure the actual size of the returned payload.
virtual std::size_t size() const = 0;

virtual ~DataBatchProtectionAgentInterface() = default;
};
}
// Success flag; false indicates an error.
virtual bool success() const = 0;

// Error details (valid when success() == false).
virtual const std::string& error_message() const = 0;
virtual const std::map<std::string, std::string>& error_fields() const = 0;

virtual ~EncryptionResult() = default;
};

class DBPS_EXPORT DecryptionResult {
public:
virtual span<const uint8_t> plaintext() const = 0;

// Allows a larger backing buffer than the exact plaintext size.
// Library users must check size() to ensure the actual size of the returned payload.
virtual std::size_t size() const = 0;

// Success flag; false indicates an error.
virtual bool success() const = 0;

// Error details (valid when success() == false).
virtual const std::string& error_message() const = 0;
virtual const std::map<std::string, std::string>& error_fields() const = 0;

virtual ~DecryptionResult() = default;
};

class DBPS_EXPORT DataBatchProtectionAgentInterface {
public:
DataBatchProtectionAgentInterface() = default;

// user_id is not stored as a member; it is expected to be embedded into app_context
// (e.g., as a serialized map/JSON field).
virtual void init(
std::string column_name,
std::map<std::string, std::string> connection_config,
std::string app_context,
std::string column_key_id,
Type::type data_type,
CompressionCodec::type compression_type)
{
column_name_ = std::move(column_name);
connection_config_ = std::move(connection_config);
app_context_ = std::move(app_context);
column_key_id_ = std::move(column_key_id);
data_type_ = data_type;
compression_type_ = compression_type;
}

virtual std::unique_ptr<EncryptionResult> Encrypt(
span<const uint8_t> plaintext) = 0;

virtual std::unique_ptr<DecryptionResult> Decrypt(
span<const uint8_t> ciphertext) = 0;

virtual ~DataBatchProtectionAgentInterface() = default;

private:
std::string column_name_;
std::map<std::string, std::string> connection_config_;
std::string app_context_; // includes user_id

std::string column_key_id_;
Type::type data_type_;
CompressionCodec::type compression_type_;
};
}
25 changes: 3 additions & 22 deletions cpp/src/parquet/encryption/external/dbpa_library_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@

#include "parquet/encryption/external/dbpa_library_wrapper.h"
#include "parquet/encryption/external/dbpa_interface.h"
#include "arrow/util/span.h"
#include <dlfcn.h>

#include <stdexcept>
#include <functional>

#include <iostream>

#include "arrow/util/io_util.h"

using ::arrow::util::span;

namespace parquet::encryption::external {

// Default implementation for handle closing function
Expand Down Expand Up @@ -60,21 +57,5 @@ DBPALibraryWrapper::~DBPALibraryWrapper() {
// Now we can close the shared library using the provided function
handle_closing_fn_(library_handle_);
library_handle_ = nullptr;
}

// Decorator implementation of Encrypt method
std::unique_ptr<EncryptionResult> DBPALibraryWrapper::Encrypt(
span<const uint8_t> plaintext,
span<uint8_t> ciphertext) {

return wrapped_agent_->Encrypt(plaintext, ciphertext);
}

// Decorator implementation of Decrypt method
std::unique_ptr<DecryptionResult> DBPALibraryWrapper::Decrypt(
span<const uint8_t> ciphertext) {

return wrapped_agent_->Decrypt(ciphertext);
}

} // namespace parquet::encryption::external
} //DBPALibraryWrapper::~DBPALibraryWrapper()
} // namespace parquet::encryption::external
46 changes: 34 additions & 12 deletions cpp/src/parquet/encryption/external/dbpa_library_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@
#include <functional>

#include "parquet/encryption/external/dbpa_interface.h"
#include "arrow/util/span.h"
#include "span.hpp"

using ::arrow::util::span;
using tcb::span;

namespace parquet::encryption::external {

using dbps::external::DataBatchProtectionAgentInterface;
using dbps::external::EncryptionResult;
using dbps::external::DecryptionResult;
using dbps::external::Type;
using dbps::external::CompressionCodec;

// Default implementation for shared library closing function
// This is passed into the constructor of DBPALibraryWrapper,
// and is used as the default function to close the shared library.
void DefaultSharedLibraryClosingFn(void* library_handle);

// Decorator/Wrapper class for the DataBatchProtectionAgentInterface
// Its main purpose is to close the shared library when Arrow is about to destroy
// an intance of an DPBAgent
// an instance of an DBPAgent
//
// In the constructor we allow to pass a function that will be used to close the shared library.
// This simplifies testing, as we can use a mock function to avoid actually closing the shared library.
Expand All @@ -44,16 +50,32 @@ class DBPALibraryWrapper : public DataBatchProtectionAgentInterface {
// Doing it in a different order, may cause issues, as by unloading the library may cause the class
// definition to be unloaded before the destructor completes, and that is likely to cause issues
// (such as a segfault).
~DBPALibraryWrapper() override;
~DBPALibraryWrapper();

// Decorator implementation of init method
inline void init(
std::string column_name,
std::map<std::string, std::string> connection_config,
std::string app_context,
std::string column_key_id,
Type::type data_type,
CompressionCodec::type compression_type) override {
wrapped_agent_->init(std::move(column_name), std::move(connection_config),
std::move(app_context), std::move(column_key_id),
data_type, compression_type);
}

// Decorator implementation of Encrypt method
std::unique_ptr<EncryptionResult> Encrypt(
span<const uint8_t> plaintext,
span<uint8_t> ciphertext) override;
// Decorator implementation of Encrypt method - inlined for performance
inline std::unique_ptr<EncryptionResult> Encrypt(
span<const uint8_t> plaintext) override {
return wrapped_agent_->Encrypt(plaintext);
}

// Decorator implementation of Decrypt method
std::unique_ptr<DecryptionResult> Decrypt(
span<const uint8_t> ciphertext) override;
// Decorator implementation of Decrypt method - inlined for performance
inline std::unique_ptr<DecryptionResult> Decrypt(
span<const uint8_t> ciphertext) override {
return wrapped_agent_->Decrypt(ciphertext);
}
};

} // namespace parquet::encryption::external
} // namespace parquet::encryption::external
Loading
Loading