Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting the secrets manager secret for encryption #10

Merged
merged 1 commit into from
Nov 17, 2024
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
41 changes: 35 additions & 6 deletions src/core/functions/scalar/encrypt_to_etype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#include "simple_encryption/core/functions/function_data/encrypt_function_data.hpp"
#include "duckdb/planner/expression/bound_function_expression.hpp"
#include "simple_encryption/core/types.hpp"
#include "simple_encryption/core/functions/secrets.hpp"
#include "duckdb/common/vector_operations/generic_executor.hpp"
#include "duckdb/main/secret/secret_manager.hpp"

namespace simple_encryption {

Expand Down Expand Up @@ -99,17 +101,38 @@ ProcessAndCastDecrypt(shared_ptr<EncryptionState> encryption_state,
return decrypted_data;
}

EncryptFunctionData &GetEncryptionBindInfo(ExpressionState &state) {
auto &func_expr = (BoundFunctionExpression &)state.expr;
return (EncryptFunctionData &)*func_expr.bind_info;;
}

shared_ptr<SimpleEncryptionState>
GetSimpleEncryptionState(ExpressionState &state) {

auto &func_expr = (BoundFunctionExpression &)state.expr;
auto &info = (EncryptFunctionData &)*func_expr.bind_info;
auto &info = GetEncryptionBindInfo(state);

return info.context.registered_state->Get<SimpleEncryptionState>(
"simple_encryption");
}

unique_ptr<SecretEntry> GetSecretEntry(ExpressionState &state) {

auto simple_encryption_state =
info.context.registered_state->Get<SimpleEncryptionState>(
"simple_encryption");
auto &info = GetEncryptionBindInfo(state);
auto &secret_manager = SecretManager::Get(info.context);
auto transaction = CatalogTransaction::GetSystemCatalogTransaction(info.context);

return simple_encryption_state;
return secret_manager.GetSecretByName(transaction, "internal");
}

void GetKeyFromSecret(shared_ptr<SimpleEncryptionState> simple_encryption_state,
ExpressionState &state) {

auto secret_entry = GetSecretEntry(state);
auto &secret = secret_entry->secret;
auto encryption_secret = KeyValueSecret(*secret);

// do some stuffffff
auto x = encryption_secret.redact_keys;
}

bool HasSpace(shared_ptr<SimpleEncryptionState> simple_encryption_state,
Expand Down Expand Up @@ -169,8 +192,13 @@ void EncryptToEtype(LogicalType result_struct, Vector &input_vector,
using ENCRYPTED_TYPE = StructTypeTernary<uint64_t, uint64_t, T>;
using PLAINTEXT_TYPE = PrimitiveType<T>;

encryption_state->InitializeEncryption(
reinterpret_cast<const_data_ptr_t>(simple_encryption_state->iv), 16,
reinterpret_cast<const string *>(&key_t));

GenericExecutor::ExecuteUnary<PLAINTEXT_TYPE, ENCRYPTED_TYPE>(
input_vector, result, size, [&](PLAINTEXT_TYPE input) {

// increment the low part of the nonce
simple_encryption_state->iv[1]++;
simple_encryption_state->counter++;
Expand Down Expand Up @@ -364,6 +392,7 @@ ScalarFunctionSet GetDecryptionStructFunction() {
// set.AddFunction(ScalarFunction({EncryptionTypes::E_INTEGER(),
// LogicalType::VARCHAR}, LogicalTypeId::INTEGER, DecryptDataFromEtype,
// EncryptFunctionData::EncryptBind));

}

return set;
Expand Down
36 changes: 21 additions & 15 deletions src/core/functions/secrets/authentication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ namespace core {
return key_string;
}

bool CheckKeySize(const uint32_t size){

switch(size){
case 16:
case 24:
case 32:
return true;
default:
throw InvalidInputException("Invalid size for data encryption key: '%d', expected: 16, 24, or 32", size);
}
}

string_t GetDataEncryptionKey(const uint32_t size){

switch(size){
Expand All @@ -42,9 +54,8 @@ string_t GetDataEncryptionKey(const uint32_t size){
}

// This code partly copied / inspired by the gsheets extension for duckdb
static void CopySecret(const std::string &key, const CreateSecretInput &input,
static void AddSecretParameter(const std::string &key, const CreateSecretInput &input,
KeyValueSecret &result) {

// this method checks whether a secret_param is present in the secret_map
auto val = input.options.find(key);
// does this also take a key, value or list struct?
Expand All @@ -54,10 +65,8 @@ static void CopySecret(const std::string &key, const CreateSecretInput &input,
}

static void RegisterCommonSecretParameters(CreateSecretFunction &function) {
// Register named parameters for encryption of columns
// key encryption key (kek) (keks encrypt/decrypt data encryption keys (deks))
function.named_parameters["kek"] = LogicalType::VARCHAR;
function.named_parameters["column"] = LogicalType::VARCHAR;
function.named_parameters["client"] = LogicalType::VARCHAR;
function.named_parameters["master"] = LogicalType::VARCHAR;
function.named_parameters["key_id"] = LogicalType::VARCHAR;
}

Expand All @@ -68,18 +77,18 @@ static void InsertColumnKeys(KeyValueSecret &result, string column_key_name) {
static unique_ptr<BaseSecret>
CreateKeyEncryptionKey(ClientContext &context, CreateSecretInput &input) {

// leave this for now
auto scope = input.scope;

// create new KV secret
auto result =
make_uniq<KeyValueSecret>(scope, input.type, input.provider, input.name);

// Manage specific secret option
CopySecret("column", input, *result);
CopySecret("key_id", input, *result);

// Redact sensible keys
// RedactCommonKeys(*result);
// Manage specific secret options
// can be called if a data encryption key (DEK) needs to be stored
AddSecretParameter("column_encryption_key", input, *result);

// Hide (redact) sensitive information
result->redact_keys.insert("column");

return std::move(result);
Expand All @@ -98,11 +107,8 @@ void CoreSecretFunctions::RegisterStoreEncryptSecretFunction(DatabaseInstance &d

// Register the key_encryption_key secret provider
CreateSecretFunction key_encryption_key = {type, "client", CreateKeyEncryptionKey};

key_encryption_key.named_parameters["client"] = LogicalType::VARCHAR;
RegisterCommonSecretParameters(key_encryption_key);
ExtensionUtil::RegisterFunction(db, key_encryption_key);

}

}
Expand Down
3 changes: 2 additions & 1 deletion src/include/simple_encryption_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ class SimpleEncryptionState : public ClientContextState {
shared_ptr<EncryptionState> encryption_state;

// nonce metadata
uint64_t iv[2];
uint32_t counter = 0;
bool is_initialized = false;
uint64_t iv[2];

// encryption buffer
uint8_t *buffer_p;
Expand Down
1 change: 1 addition & 0 deletions src/simple_encryption_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ SimpleEncryptionState::SimpleEncryptionState(shared_ptr<ClientContext> context)
encryption_state = GetEncryptionUtil(*new_conn)->CreateEncryptionState();

// allocate encryption buffer
// maybe do this in a better way (i.e. use buffer manager?)
uint8_t encryption_buffer[MAX_BUFFER_SIZE];
buffer_p = encryption_buffer;

Expand Down
12 changes: 6 additions & 6 deletions test/sql/encryption/simple_struct_encryption.test
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ Catalog Error: Scalar Function with name simple_encryption does not exist!
require simple_encryption

statement ok
SELECT encrypt_etypes(11, '0123456789112345');
SELECT encrypt(11, '0123456789112345');

query I
SELECT decrypt_etypes({'nonce_hi': 11752579000357969348, 'nonce_lo': 2472254480, 'value': 1288890}, '0123456789112345');
SELECT decrypt({'nonce_hi': 11752579000357969348, 'nonce_lo': 2472254480, 'value': 1288890}, '0123456789112345');
----
194072790

Expand Down Expand Up @@ -52,13 +52,13 @@ SELECT decrypted_values FROM test_1;
1

statement ok
SELECT encrypt_etypes('testtest', '0123456789112345');
SELECT encrypt('testtest', '0123456789112345');

statement ok
CREATE TABLE test_varchar AS SELECT CAST('hello' AS VARCHAR) AS value FROM range(10);

statement ok
SELECT encrypt_etypes(value, '0123456789112345') AS encrypted_value FROM test_varchar;
SELECT encrypt(value, '0123456789112345') AS encrypted_value FROM test_varchar;

statement ok
ALTER TABLE test_varchar ADD COLUMN encrypted_values STRUCT(nonce_hi UBIGINT, nonce_lo UBIGINT, value VARCHAR);
Expand All @@ -67,10 +67,10 @@ statement ok
ALTER TABLE test_varchar ADD COLUMN decrypted_values VARCHAR;

statement ok
UPDATE test_varchar SET encrypted_values = encrypt_etypes(value, '0123456789112345');
UPDATE test_varchar SET encrypted_values = encrypt(value, '0123456789112345');

statement ok
UPDATE test_varchar SET decrypted_values = decrypt_etypes(encrypted_values, '0123456789112345');
UPDATE test_varchar SET decrypted_values = decrypt(encrypted_values, '0123456789112345');

query I
SELECT decrypted_values FROM test_varchar;
Expand Down
4 changes: 2 additions & 2 deletions test/sql/secrets/simple_secrets_test.test
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ set allow_persistent_secrets=false;
statement ok
CREATE SECRET (
TYPE INTERNAL,
KEY_ID 'key_id',
COLUMN 'column'
KEY_ID 'key_1',
MASTER '0123456789112345'
);
Loading