Skip to content

Commit

Permalink
Merge pull request #10 from ccfelius/secrets
Browse files Browse the repository at this point in the history
Getting the secrets manager secret for encryption
  • Loading branch information
ccfelius authored Nov 17, 2024
2 parents c369283 + 7b9feda commit 4baa3ee
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 30 deletions.
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'
);

0 comments on commit 4baa3ee

Please sign in to comment.