Skip to content

PG-1658 Remove server key if it is the unused default key #484

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

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
40 changes: 40 additions & 0 deletions contrib/pg_tde/expected/delete_principal_key.out
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,46 @@ SELECT pg_tde_delete_key();

(1 row)

-- Delete default key even if it's configured for a database or server key, as
-- long as it's unused. Regardless how the key was set, we unset it if it's the
-- same key as is used as a default key. This is probably a bug.
SELECT pg_tde_set_default_key_using_global_key_provider('test-db-key','file-provider');
pg_tde_set_default_key_using_global_key_provider
--------------------------------------------------

(1 row)

SELECT pg_tde_set_key_using_global_key_provider('test-db-key','file-provider');
pg_tde_set_key_using_global_key_provider
------------------------------------------

(1 row)

SELECT pg_tde_set_server_key_using_global_key_provider('test-db-key','file-provider');
WARNING: The WAL encryption feature is currently in beta and may be unstable. Do not use it in production environments!
pg_tde_set_server_key_using_global_key_provider
-------------------------------------------------

(1 row)

SELECT pg_tde_delete_default_key();
pg_tde_delete_default_key
---------------------------

(1 row)

SELECT pg_tde_key_info(); -- No key configured
pg_tde_key_info
-----------------
(,,,)
(1 row)

SELECT pg_tde_server_key_info(); -- No key configured
pg_tde_server_key_info
------------------------
(,,,)
(1 row)

SELECT pg_tde_delete_global_key_provider('file-provider');
pg_tde_delete_global_key_provider
-----------------------------------
Expand Down
11 changes: 11 additions & 0 deletions contrib/pg_tde/sql/delete_principal_key.sql
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,16 @@ SELECT pg_tde_delete_default_key();

DROP TABLE test_table;
SELECT pg_tde_delete_key();

-- Delete default key even if it's configured for a database or server key, as
-- long as it's unused. Regardless how the key was set, we unset it if it's the
-- same key as is used as a default key. This is probably a bug.
SELECT pg_tde_set_default_key_using_global_key_provider('test-db-key','file-provider');
SELECT pg_tde_set_key_using_global_key_provider('test-db-key','file-provider');
SELECT pg_tde_set_server_key_using_global_key_provider('test-db-key','file-provider');
SELECT pg_tde_delete_default_key();
SELECT pg_tde_key_info(); -- No key configured
SELECT pg_tde_server_key_info(); -- No key configured

SELECT pg_tde_delete_global_key_provider('file-provider');
DROP EXTENSION pg_tde;
12 changes: 5 additions & 7 deletions contrib/pg_tde/src/access/pg_tde_tdemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ pg_tde_delete_principal_key(Oid dbOid)
char path[MAXPGPATH];

Assert(LWLockHeldByMeInMode(tde_lwlock_enc_keys(), LW_EXCLUSIVE));
Assert(pg_tde_count_relations(dbOid) == 0);
Assert(pg_tde_count_encryption_keys(dbOid) == 0);

pg_tde_set_db_file_path(dbOid, path);

Expand Down Expand Up @@ -672,17 +672,15 @@ pg_tde_find_map_entry(const RelFileLocator *rlocator, TDEMapEntryType key_type,
}

/*
* Counts number of encrypted objects in a database.
* Counts number of encryption keys in a key file.
*
* Does not check if objects actually exist but just that they have keys in
* the map file. For the only current caller, checking if we can use
* FILE_COPY, this is good enough but for other workloads where a false
* positive is more harmful this might not be.
* the key file.
*
* Works even if the database has no map file.
* Works even if the database has no key file.
*/
int
pg_tde_count_relations(Oid dbOid)
pg_tde_count_encryption_keys(Oid dbOid)
{
char db_map_path[MAXPGPATH];
File map_fd;
Expand Down
22 changes: 18 additions & 4 deletions contrib/pg_tde/src/catalog/tde_principal_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ pg_tde_delete_key(PG_FUNCTION_ARGS)
* If database has something encryted, we can try to fallback to the
* default principal key
*/
if (pg_tde_count_relations(MyDatabaseId) != 0)
if (pg_tde_count_encryption_keys(MyDatabaseId) != 0)
{
default_principal_key = GetPrincipalKeyNoDefault(DEFAULT_DATA_TDE_OID, LW_EXCLUSIVE);
if (default_principal_key == NULL)
Expand Down Expand Up @@ -785,7 +785,7 @@ pg_tde_delete_default_key(PG_FUNCTION_ARGS)
* delete default principal key if there are encrypted tables in
* the database.
*/
if (pg_tde_count_relations(dbOid) != 0)
if (pg_tde_count_encryption_keys(dbOid) != 0)
{
ereport(ERROR,
errmsg("cannot delete default principal key"),
Expand All @@ -798,8 +798,22 @@ pg_tde_delete_default_key(PG_FUNCTION_ARGS)
}

/*
* Remove empty key map files for databases that has no encrypted tables
* as we cannot leave reference to the default principal key.
* The default key may have been used as server key, check if there are
* any WAL encryption keys that uses it.
*/
principal_key = GetPrincipalKeyNoDefault(GLOBAL_DATA_TDE_OID, LW_EXCLUSIVE);
if (pg_tde_is_same_principal_key(default_principal_key, principal_key))
{
if (pg_tde_count_encryption_keys(GLOBAL_DATA_TDE_OID) != 0)
ereport(ERROR,
errmsg("cannot delete default principal key"),
errhint("There are WAL encryption keys."));
dbs = lappend_oid(dbs, GLOBAL_DATA_TDE_OID);
}

/*
* Remove empty key files for OIDs that have no encryption keys as we
* cannot leave references to the default principal key.
*/
foreach_oid(dbOid, dbs)
{
Expand Down
2 changes: 1 addition & 1 deletion contrib/pg_tde/src/include/access/pg_tde_tdemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ extern bool pg_tde_has_smgr_key(RelFileLocator rel);
extern InternalKey *pg_tde_get_smgr_key(RelFileLocator rel);
extern void pg_tde_free_key_map_entry(RelFileLocator rel);

extern int pg_tde_count_relations(Oid dbOid);
extern int pg_tde_count_encryption_keys(Oid dbOid);

extern void pg_tde_delete_tde_files(Oid dbOid);

Expand Down
2 changes: 1 addition & 1 deletion contrib/pg_tde/src/pg_tde_event_capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ pg_tde_proccess_utility(PlannedStmt *pstmt,
int count;

LWLockAcquire(tde_lwlock_enc_keys(), LW_SHARED);
count = pg_tde_count_relations(dbOid);
count = pg_tde_count_encryption_keys(dbOid);
LWLockRelease(tde_lwlock_enc_keys());

if (count > 0)
Expand Down
Loading