Skip to content

Commit

Permalink
PG-857: use common JSON API for keyring (#252)
Browse files Browse the repository at this point in the history
This commit replaces dependency of the keyring code on JSON backend
functions with common JSON API.

Usage of the backend JSON funcs prevents the code to be used by
frontend tools like pg_waldump. Besides it requiers extra conversions
to Datums and DirectFunctionCall-s.

For: https://perconadev.atlassian.net/browse/PG-857
  • Loading branch information
dAdAbird authored Aug 21, 2024
1 parent 4fb220c commit 8996c03
Show file tree
Hide file tree
Showing 11 changed files with 848 additions and 206 deletions.
1 change: 1 addition & 0 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ src/keyring/keyring_vault.o \
src/keyring/keyring_api.o \
src/catalog/tde_global_space.o \
src/catalog/tde_keyring.o \
src/catalog/tde_keyring_parse_opts.o \
src/catalog/tde_principal_key.o \
src/common/pg_tde_shmem.o \
src/common/pg_tde_utils.o \
Expand Down
5 changes: 4 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pg_tde_sources = files(

'src/catalog/tde_global_space.c',
'src/catalog/tde_keyring.c',
'src/catalog/tde_keyring_parse_opts.c',
'src/catalog/tde_principal_key.c',
'src/common/pg_tde_shmem.c',
'src/common/pg_tde_utils.c',
Expand Down Expand Up @@ -109,7 +110,9 @@ tests += {
't/001_basic.pl',
't/002_rotate_key.pl',
't/003_remote_config.pl',
't/004_file_config.pl'
't/004_file_config.pl',
't/005_multiple_extensions.pl',
't/006_remote_vault_config.pl'
],
},
}
36 changes: 36 additions & 0 deletions pg_tde--1.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,23 @@ AS $$
'caPath' VALUE COALESCE(vault_ca_path,'')));
$$
LANGUAGE SQL;
CREATE OR REPLACE FUNCTION pg_tde_add_key_provider_vault_v2(provider_name VARCHAR(128),
vault_token JSON,
vault_url JSON,
vault_mount_path JSON,
vault_ca_path JSON)
RETURNS INT
AS $$
-- JSON keys in the options must be matched to the keys in
-- load_vaultV2_keyring_provider_options function.
SELECT pg_tde_add_key_provider('vault-v2', provider_name,
json_object('type' VALUE 'vault-v2',
'url' VALUE vault_url,
'token' VALUE vault_token,
'mountPath' VALUE vault_mount_path,
'caPath' VALUE vault_ca_path));
$$
LANGUAGE SQL;

CREATE FUNCTION pg_tde_list_all_key_providers
(OUT id INT,
Expand Down Expand Up @@ -116,6 +133,25 @@ AS $$
$$
LANGUAGE SQL;

CREATE OR REPLACE FUNCTION pg_tde_add_key_provider_vault_v2(PG_TDE_GLOBAL,
provider_name VARCHAR(128),
vault_token JSON,
vault_url JSON,
vault_mount_path JSON,
vault_ca_path JSON)
RETURNS INT
AS $$
-- JSON keys in the options must be matched to the keys in
-- load_vaultV2_keyring_provider_options function.
SELECT pg_tde_add_key_provider('PG_TDE_GLOBAL', 'vault-v2', provider_name,
json_object('type' VALUE 'vault-v2',
'url' VALUE vault_url,
'token' VALUE vault_token,
'mountPath' VALUE vault_mount_path,
'caPath' VALUE vault_ca_path));
$$
LANGUAGE SQL;

-- Table access method
CREATE FUNCTION pg_tdeam_basic_handler(internal)
RETURNS table_am_handler
Expand Down
81 changes: 37 additions & 44 deletions src/catalog/tde_keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,6 @@ PG_FUNCTION_INFO_V1(pg_tde_list_all_key_providers);
Datum pg_tde_list_all_key_providers(PG_FUNCTION_ARGS);

#define PG_TDE_KEYRING_FILENAME "pg_tde_keyrings"
/*
* These token must be exactly same as defined in
* pg_tde_add_key_provider_vault_v2 SQL interface
*/
#define VAULTV2_KEYRING_TOKEN_KEY "token"
#define VAULTV2_KEYRING_URL_KEY "url"
#define VAULTV2_KEYRING_MOUNT_PATH_KEY "mountPath"
#define VAULTV2_KEYRING_CA_PATH_KEY "caPath"

/*
* These token must be exactly same as defined in
* pg_tde_add_key_provider_file SQL interface
*/
#define FILE_KEYRING_PATH_KEY "path"
#define FILE_KEYRING_TYPE_KEY "type"
#define PG_TDE_LIST_PROVIDERS_COLS 4

typedef enum ProviderScanType
Expand All @@ -67,9 +52,9 @@ typedef enum ProviderScanType

static List *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid);

static FileKeyring *load_file_keyring_provider_options(Datum keyring_options);
static GenericKeyring *load_keyring_provider_options(ProviderType provider_type, Datum keyring_options);
static VaultV2Keyring *load_vaultV2_keyring_provider_options(Datum keyring_options);
static FileKeyring *load_file_keyring_provider_options(char *keyring_options);
static GenericKeyring *load_keyring_provider_options(ProviderType provider_type, char *keyring_options);
static VaultV2Keyring *load_vaultV2_keyring_provider_options(char *keyring_options);
static void debug_print_kerying(GenericKeyring *keyring);
static char *get_keyring_infofile_path(char *resPath, Oid dbOid, Oid spcOid);
static void key_provider_startup_cleanup(int tde_tbl_count, XLogExtensionInstall *ext_info, bool redo, void *arg);
Expand Down Expand Up @@ -165,12 +150,9 @@ get_keyring_provider_typename(ProviderType p_type)

static GenericKeyring *load_keyring_provider_from_record(KeyringProvideRecord *provider)
{
Datum option_datum;
GenericKeyring *keyring = NULL;

option_datum = CStringGetTextDatum(provider->options);

keyring = load_keyring_provider_options(provider->provider_type, option_datum);
keyring = load_keyring_provider_options(provider->provider_type, provider->options);
if (keyring)
{
keyring->key_id = provider->provider_id;
Expand Down Expand Up @@ -222,7 +204,7 @@ GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid)
}

static GenericKeyring *
load_keyring_provider_options(ProviderType provider_type, Datum keyring_options)
load_keyring_provider_options(ProviderType provider_type, char *keyring_options)
{
switch (provider_type)
{
Expand All @@ -239,44 +221,55 @@ load_keyring_provider_options(ProviderType provider_type, Datum keyring_options)
}

static FileKeyring *
load_file_keyring_provider_options(Datum keyring_options)
load_file_keyring_provider_options(char *keyring_options)
{
const char* file_path = extract_json_option_value(keyring_options, FILE_KEYRING_PATH_KEY);
FileKeyring *file_keyring = palloc0(sizeof(FileKeyring));

if(file_path == NULL)
FileKeyring *file_keyring = palloc0(sizeof(FileKeyring));

file_keyring->keyring.type = FILE_KEY_PROVIDER;

if (!ParseKeyringJSONOptions(FILE_KEY_PROVIDER, file_keyring,
keyring_options, strlen(keyring_options)))
{
ereport(DEBUG2,
return NULL;
}

if(strlen(file_keyring->file_name) == 0)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("file path is missing in the keyring options")));
return NULL;
}

file_keyring->keyring.type = FILE_KEY_PROVIDER;
strncpy(file_keyring->file_name, file_path, sizeof(file_keyring->file_name));
return file_keyring;
}

static VaultV2Keyring *
load_vaultV2_keyring_provider_options(Datum keyring_options)
load_vaultV2_keyring_provider_options(char *keyring_options)
{
VaultV2Keyring *vaultV2_keyring = palloc0(sizeof(VaultV2Keyring));
const char* token = extract_json_option_value(keyring_options, VAULTV2_KEYRING_TOKEN_KEY);
const char* url = extract_json_option_value(keyring_options, VAULTV2_KEYRING_URL_KEY);
const char* mount_path = extract_json_option_value(keyring_options, VAULTV2_KEYRING_MOUNT_PATH_KEY);
const char* ca_path = extract_json_option_value(keyring_options, VAULTV2_KEYRING_CA_PATH_KEY);
VaultV2Keyring *vaultV2_keyring = palloc0(sizeof(VaultV2Keyring));

if(token == NULL || url == NULL || mount_path == NULL)
vaultV2_keyring->keyring.type = VAULT_V2_KEY_PROVIDER;

if (!ParseKeyringJSONOptions(VAULT_V2_KEY_PROVIDER, vaultV2_keyring,
keyring_options, strlen(keyring_options)))
{
/* TODO: report error */
return NULL;
}

if(strlen(vaultV2_keyring->vault_token) == 0 ||
strlen(vaultV2_keyring->vault_url) == 0 ||
strlen(vaultV2_keyring->vault_mount_path) == 0)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("missing in the keyring options:%s%s%s",
!vaultV2_keyring->vault_token ? " token" : "",
!vaultV2_keyring->vault_url ? " url" : "",
!vaultV2_keyring->vault_mount_path ? " mountPath" : "")));
return NULL;
}

vaultV2_keyring->keyring.type = VAULT_V2_KEY_PROVIDER;
strncpy(vaultV2_keyring->vault_token, token, sizeof(vaultV2_keyring->vault_token));
strncpy(vaultV2_keyring->vault_url, url, sizeof(vaultV2_keyring->vault_url));
strncpy(vaultV2_keyring->vault_mount_path, mount_path, sizeof(vaultV2_keyring->vault_mount_path));
strncpy(vaultV2_keyring->vault_ca_path, ca_path ? ca_path : "", sizeof(vaultV2_keyring->vault_ca_path));
return vaultV2_keyring;
}

Expand Down
Loading

0 comments on commit 8996c03

Please sign in to comment.