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

Adding SECRET syntax #9

Merged
merged 1 commit into from
Nov 16, 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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
src/core/functions/function_data/encrypt_function_data.cpp
src/core/functions/cast/varchar_cast.cpp
src/core/functions/table/encrypt_table.cpp
src/core/functions/secrets/authentication.cpp
src/core/utils/simple_encryption_utils.cpp
src/core/crypto/crypto_primitives.cpp)

Expand Down
24 changes: 0 additions & 24 deletions src/core/crypto/crypto_primitives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,6 @@

namespace duckdb {

void sha256(const char *in, size_t in_len, hash_bytes &out) {
duckdb_mbedtls::MbedTlsWrapper::ComputeSha256Hash(in, in_len, (char *)out);
}

void hmac256(const std::string &message, const char *secret, size_t secret_len,
hash_bytes &out) {
duckdb_mbedtls::MbedTlsWrapper::Hmac256(secret, secret_len, message.data(),
message.size(), (char *)out);
}

void hmac256(std::string message, hash_bytes secret, hash_bytes &out) {
hmac256(message, (char *)secret, sizeof(hash_bytes), out);
}

void hex256(hash_bytes &in, hash_str &out) {
const char *hex = "0123456789abcdef";
unsigned char *pin = in;
unsigned char *pout = out;
for (; pin < in + sizeof(in); pout += 2, pin++) {
pout[0] = hex[(*pin >> 4) & 0xF];
pout[1] = hex[*pin & 0xF];
}
}

const EVP_CIPHER *GetCipher(const string &key,
AESStateSSL::Algorithm algorithm) {

Expand Down Expand Up @@ -75,7 +51,7 @@
throw InternalException("Invalid AES key length");
}
}
}

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::GetCipher': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Check warning on line 54 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

AESStateSSL::AESStateSSL() : context(EVP_CIPHER_CTX_new()) {
if (!(context)) {
Expand Down Expand Up @@ -204,7 +180,7 @@
throw InvalidInputException("Computed AES tag differs from read AES tag, "
"are you using the right key?");
}
}

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64, x64-windows-static-md)

'duckdb::AESStateSSL::Finalize': not all control paths return a value [D:\a\simple-encryption\simple-encryption\build\release\extension\simple_encryption\simple_encryption_loadable_extension.vcxproj]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

Check warning on line 183 in src/core/crypto/crypto_primitives.cpp

View workflow job for this annotation

GitHub Actions / Build extension binaries / Windows (windows_amd64_rtools, x64-mingw-static)

control reaches end of non-void function [-Wreturn-type]

} // namespace duckdb

Expand Down
6 changes: 1 addition & 5 deletions src/core/functions/scalar/encrypt_to_etype.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#define DUCKDB_EXTENSION_MAIN

// what is the maximum size of biggest type in duckdb
#define MAX_BUFFER_SIZE 1024

#include "duckdb.hpp"
#include "duckdb/common/exception.hpp"
#include "duckdb/common/types.hpp"
Expand All @@ -22,8 +19,6 @@
#include "simple_encryption/core/types.hpp"
#include "duckdb/common/vector_operations/generic_executor.hpp"

// temporary

namespace simple_encryption {

namespace core {
Expand Down Expand Up @@ -79,6 +74,7 @@ ProcessAndCastDecrypt(shared_ptr<EncryptionState> encryption_state,
size_t decrypted_size = encrypted_size;
Blob::FromBase64(base64_data, reinterpret_cast<data_ptr_t>(buffer_p),
encrypted_size);

D_ASSERT(encrypted_size <= base64_data.GetSize());

string_t decrypted_data =
Expand Down
109 changes: 109 additions & 0 deletions src/core/functions/secrets/authentication.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "simple_encryption/core/functions/secrets.hpp"
#include "simple_encryption/common.hpp"
#include "simple_encryption/core/utils/simple_encryption_utils.hpp"
#include "simple_encryption/core/crypto/crypto_primitives.hpp"
#include "simple_encryption/core/functions/scalar.hpp"
#include "duckdb/common/exception.hpp"
#include "duckdb/main/secret/secret.hpp"
#include "duckdb/main/extension_util.hpp"
#include "openssl/rand.h"
#include <fstream>
#include <cstdlib>

namespace simple_encryption {

namespace core {

string_t GenerateDataEncryptionKey(const uint32_t size){

unsigned char* key = new unsigned char[size];

// generate random bytes with OpenSSL function
RAND_bytes(key, size);

// cast back to string ('normal' string, not duckdb string)
std::string key_string(reinterpret_cast<char*>(key), size);

return key_string;
}

string_t GetDataEncryptionKey(const uint32_t size){

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

// This code partly copied / inspired by the gsheets extension for duckdb
static void CopySecret(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?
if (val != input.options.end()) {
result.secret_map[key] = val->second;
}
}

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["key_id"] = LogicalType::VARCHAR;
}

static void InsertColumnKeys(KeyValueSecret &result, string column_key_name) {
result.redact_keys.insert(column_key_name);
}

static unique_ptr<BaseSecret>
CreateKeyEncryptionKey(ClientContext &context, CreateSecretInput &input) {

auto scope = input.scope;

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);

result->redact_keys.insert("column");

return std::move(result);
}

void CoreSecretFunctions::RegisterStoreEncryptSecretFunction(DatabaseInstance &db) {

string type = "internal";

// Register the new secret type
SecretType secret_type;
secret_type.name = type;
secret_type.deserializer = KeyValueSecret::Deserialize<KeyValueSecret>;
secret_type.default_provider = "client";
ExtensionUtil::RegisterSecretType(db, secret_type);

// 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);

}

}
}
2 changes: 2 additions & 0 deletions src/core/module.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include "simple_encryption/core/module.hpp"
#include "simple_encryption/common.hpp"
#include "simple_encryption/core/functions/scalar.hpp"
#include "simple_encryption/core/functions/secrets.hpp"

namespace simple_encryption {
namespace core {

void CoreModule::Register(DatabaseInstance &db) {
CoreScalarFunctions::Register(db);
CoreSecretFunctions::Register(db);
}
} // namespace core
} // namespace simple_encryption
12 changes: 0 additions & 12 deletions src/include/simple_encryption/core/crypto/crypto_primitives.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@ typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;

namespace duckdb {

typedef unsigned char hash_bytes[32];
typedef unsigned char hash_str[64];

void sha256(const char *in, size_t in_len, hash_bytes &out);

void hmac256(const std::string &message, const char *secret, size_t secret_len,
hash_bytes &out);

void hmac256(std::string message, hash_bytes secret, hash_bytes &out);

void hex256(hash_bytes &in, hash_str &out);

class DUCKDB_EXTENSION_API AESStateSSL : public duckdb::EncryptionState {

public:
Expand Down
3 changes: 1 addition & 2 deletions src/include/simple_encryption/core/functions/scalar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ struct CoreScalarFunctions {

private:
static void RegisterEncryptDataScalarFunction(duckdb::DatabaseInstance &db);
static void
RegisterEncryptDataStructScalarFunction(duckdb::DatabaseInstance &db);
static void RegisterEncryptDataStructScalarFunction(duckdb::DatabaseInstance &db);
};

} // namespace core
Expand Down
29 changes: 29 additions & 0 deletions src/include/simple_encryption/core/functions/secrets.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <string>
#include "duckdb/main/database.hpp"

namespace simple_encryption {

namespace core {

std::string read_token_from_file(const std::string &file_path);
duckdb::string_t GenerateDataEncryptionKey();

struct CoreSecretFunctions {
public:
//! Register all CreateSecretFunctions
static void Register(duckdb::DatabaseInstance &db){
RegisterStoreEncryptSecretFunction(db);
// RegisterGetEncryptSecretStructFunction(db);
// RegisterDeleteEncryptSecretStructFunction(db);
}

private:
static void RegisterStoreEncryptSecretFunction(duckdb::DatabaseInstance &db);
// static void RegisterGetEncryptSecretStructFunction(duckdb::DatabaseInstance &db);
// static void RegisterDeleteEncryptSecretStructFunction(duckdb::DatabaseInstance &db);
};

}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions test/sql/secrets/simple_secrets_test.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# name: test/sql/secrets/simple_secrets_test.test
# description: Test secret creation for internal encryption
# group: [simple-encryption/secrets]

statement ok
PRAGMA enable_verification;

require simple_encryption

# Ensure any currently stored secrets don't interfere with the test
statement ok
set allow_persistent_secrets=false;

# Create an internal secret (for internal encryption of columns)
statement ok
CREATE SECRET (
TYPE INTERNAL,
KEY_ID 'key_id',
COLUMN 'column'
);
Loading