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

PG-1258: Implement pg_tde_verify_principal_key functions #43

Merged
merged 1 commit into from
Feb 7, 2025
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
12 changes: 9 additions & 3 deletions contrib/earthdistance/expected/earthdistance_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -1060,10 +1060,12 @@ drop extension cube;
public | pg_tde_set_principal_key | boolean | principal_key_name character varying, pg_tde_global, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_set_principal_key | boolean | principal_key_name character varying, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_set_server_principal_key | boolean | principal_key_name character varying, pg_tde_global, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_verify_global_principal_key | void | | func
public | pg_tde_verify_principal_key | void | | func
public | pg_tde_version | text | | func
public | pg_tdeam_basic_handler | table_am_handler | internal | func
public | pg_tdeam_handler | table_am_handler | internal | func
(56 rows)
(58 rows)

\do
List of operators
Expand Down Expand Up @@ -1138,10 +1140,12 @@ create extension cube with schema c;
public | pg_tde_set_principal_key | boolean | principal_key_name character varying, pg_tde_global, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_set_principal_key | boolean | principal_key_name character varying, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_set_server_principal_key | boolean | principal_key_name character varying, pg_tde_global, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_verify_global_principal_key | void | | func
public | pg_tde_verify_principal_key | void | | func
public | pg_tde_version | text | | func
public | pg_tdeam_basic_handler | table_am_handler | internal | func
public | pg_tdeam_handler | table_am_handler | internal | func
(56 rows)
(58 rows)

\do public.*
List of operators
Expand Down Expand Up @@ -1239,10 +1243,12 @@ NOTICE: drop cascades to column f1 of table foo
public | pg_tde_set_principal_key | boolean | principal_key_name character varying, pg_tde_global, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_set_principal_key | boolean | principal_key_name character varying, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_set_server_principal_key | boolean | principal_key_name character varying, pg_tde_global, provider_name character varying DEFAULT NULL::character varying, ensure_new_key boolean DEFAULT false | func
public | pg_tde_verify_global_principal_key | void | | func
public | pg_tde_verify_principal_key | void | | func
public | pg_tde_version | text | | func
public | pg_tdeam_basic_handler | table_am_handler | internal | func
public | pg_tdeam_handler | table_am_handler | internal | func
(56 rows)
(58 rows)

\do public.*
List of operators
Expand Down
8 changes: 8 additions & 0 deletions contrib/pg_tde/expected/key_provider.out
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ SELECT pg_tde_set_principal_key('test-db-principal-key','file-provider');
t
(1 row)

SELECT pg_tde_verify_principal_key();
pg_tde_verify_principal_key
-----------------------------

(1 row)

SELECT pg_tde_change_key_provider_file('not-existent-provider','/tmp/pg_tde_test_keyring.per');
ERROR: key provider "not-existent-provider" does not exists
HINT: Use pg_tde_add_key_provider interface to create the key provider
Expand All @@ -63,6 +69,8 @@ SELECT * FROM pg_tde_list_all_key_providers();
2 | file-provider2 | file | {"type" : "file", "path" : "/tmp/pg_tde_test_keyring2.per"}
(2 rows)

SELECT pg_tde_verify_principal_key();
ERROR: Failed to retrieve key from keyring
SELECT pg_tde_change_key_provider_file('file-provider', json_object('foo' VALUE '/tmp/pg_tde_test_keyring.per'));
ERROR: parse json keyring config: unexpected field foo
SELECT * FROM pg_tde_list_all_key_providers();
Expand Down
10 changes: 10 additions & 0 deletions contrib/pg_tde/pg_tde--1.0-beta2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,16 @@ RETURNS VOID
AS 'MODULE_PATHNAME'
LANGUAGE C;

CREATE FUNCTION pg_tde_verify_principal_key()
RETURNS VOID
AS 'MODULE_PATHNAME'
LANGUAGE C;

CREATE FUNCTION pg_tde_verify_global_principal_key()
RETURNS VOID
AS 'MODULE_PATHNAME'
LANGUAGE C;

CREATE FUNCTION pg_tde_principal_key_info()
RETURNS TABLE ( principal_key_name text,
key_provider_name text,
Expand Down
2 changes: 2 additions & 0 deletions contrib/pg_tde/sql/key_provider.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ SELECT pg_tde_add_key_provider_file('file-provider2','/tmp/pg_tde_test_keyring2.
SELECT * FROM pg_tde_list_all_key_providers();

SELECT pg_tde_set_principal_key('test-db-principal-key','file-provider');
SELECT pg_tde_verify_principal_key();

SELECT pg_tde_change_key_provider_file('not-existent-provider','/tmp/pg_tde_test_keyring.per');
SELECT * FROM pg_tde_list_all_key_providers();

SELECT pg_tde_change_key_provider_file('file-provider','/tmp/pg_tde_test_keyring_other.per');
SELECT * FROM pg_tde_list_all_key_providers();
SELECT pg_tde_verify_principal_key();

SELECT pg_tde_change_key_provider_file('file-provider', json_object('foo' VALUE '/tmp/pg_tde_test_keyring.per'));
SELECT * FROM pg_tde_list_all_key_providers();
Expand Down
52 changes: 48 additions & 4 deletions contrib/pg_tde/src/catalog/tde_principal_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
PG_FUNCTION_INFO_V1(pg_tde_delete_key_provider);
PG_FUNCTION_INFO_V1(pg_tde_delete_key_provider_global);

PG_FUNCTION_INFO_V1(pg_tde_verify_principal_key);
PG_FUNCTION_INFO_V1(pg_tde_verify_global_principal_key);

typedef struct TdePrincipalKeySharedState
{
LWLockPadded *Locks;
Expand Down Expand Up @@ -84,7 +87,7 @@ static void shared_memory_shutdown(int code, Datum arg);
static void principal_key_startup_cleanup(int tde_tbl_count, XLogExtensionInstall *ext_info, bool redo, void *arg);
static void clear_principal_key_cache(Oid databaseId);
static inline dshash_table *get_principal_key_Hash(void);
static TDEPrincipalKey *get_principal_key_from_keyring(Oid dbOid);
static TDEPrincipalKey *get_principal_key_from_keyring(Oid dbOid, bool pushToCache);
static TDEPrincipalKey *get_principal_key_from_cache(Oid dbOid);
static void push_principal_key_to_cache(TDEPrincipalKey *principalKey);
static Datum pg_tde_get_key_info(PG_FUNCTION_ARGS, Oid dbOid);
Expand All @@ -94,6 +97,7 @@ static bool set_principal_key_with_keyring(const char *key_name,
Oid dbOid,
bool ensure_new_key);
static bool pg_tde_is_provider_used(Oid databaseOid, Oid providerId);
static bool pg_tde_verify_principal_key_internal(Oid databaseOid);

static Datum pg_tde_delete_key_provider_internal(PG_FUNCTION_ARGS, int is_global);

Expand Down Expand Up @@ -617,6 +621,18 @@ pg_tde_principal_key_info_global(PG_FUNCTION_ARGS)
return pg_tde_get_key_info(fcinfo, GLOBAL_DATA_TDE_OID);
}

Datum
pg_tde_verify_principal_key(PG_FUNCTION_ARGS)
{
return pg_tde_verify_principal_key_internal(MyDatabaseId);
}

Datum
pg_tde_verify_global_principal_key(PG_FUNCTION_ARGS)
{
return pg_tde_verify_principal_key_internal(GLOBAL_DATA_TDE_OID);
}

static Datum
pg_tde_get_key_info(PG_FUNCTION_ARGS, Oid dbOid)
{
Expand Down Expand Up @@ -691,7 +707,7 @@ pg_tde_get_key_info(PG_FUNCTION_ARGS, Oid dbOid)
* Caller should hold an exclusive tde_lwlock_enc_keys lock
*/
static TDEPrincipalKey *
get_principal_key_from_keyring(Oid dbOid)
get_principal_key_from_keyring(Oid dbOid, bool pushToCache)
{
GenericKeyring *keyring;
TDEPrincipalKey *principalKey = NULL;
Expand Down Expand Up @@ -730,7 +746,7 @@ get_principal_key_from_keyring(Oid dbOid)

#ifndef FRONTEND
/* We don't store global space key in cache */
if (!TDEisInGlobalSpace(dbOid))
if (pushToCache && !TDEisInGlobalSpace(dbOid))
{
push_principal_key_to_cache(principalKey);

Expand Down Expand Up @@ -794,7 +810,7 @@ GetPrincipalKey(Oid dbOid, LWLockMode lockMode)
}
#endif

return get_principal_key_from_keyring(dbOid);
return get_principal_key_from_keyring(dbOid, true);
}

#ifndef FRONTEND
Expand Down Expand Up @@ -918,4 +934,32 @@ pg_tde_delete_key_provider_internal(PG_FUNCTION_ARGS, int is_global)
PG_RETURN_VOID();
}

static bool
pg_tde_verify_principal_key_internal(Oid databaseOid)
{
TDEPrincipalKey *fromKeyring;
TDEPrincipalKey *fromCache;

LWLockAcquire(tde_lwlock_enc_keys(), LW_EXCLUSIVE);

fromKeyring = get_principal_key_from_keyring(databaseOid, false);
fromCache = get_principal_key_from_cache(databaseOid);

LWLockRelease(tde_lwlock_enc_keys());

if (fromKeyring == NULL)
{
ereport(ERROR,
(errmsg("Failed to retrieve key from keyring")));
}

if (fromCache != NULL && (fromKeyring->keyLength != fromCache->keyLength || memcmp(fromKeyring->keyData, fromCache->keyData, fromCache->keyLength) != 0))
{
ereport(ERROR,
(errmsg("Key returned by keyring and cached in pg_tde is different")));
}

PG_RETURN_VOID();
}

#endif