From 15ab9fa8a39b2487f5edec66b113e4750d344cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85strand?= Date: Mon, 19 May 2025 18:06:02 +0200 Subject: [PATCH] Verify provider have in-use keys before change Prevent the change if they do not. In the future we might want to add a "force" parameter, but for now the command line utility can be used while the cluster is offline if that is necessary. --- contrib/pg_tde/expected/create_database.out | 2 +- .../pg_tde/expected/default_principal_key.out | 22 +-- contrib/pg_tde/expected/key_provider.out | 77 +++++++--- contrib/pg_tde/sql/key_provider.sql | 30 +++- contrib/pg_tde/src/catalog/tde_keyring.c | 12 ++ .../pg_tde/src/catalog/tde_principal_key.c | 84 +++++++++++ .../src/include/catalog/tde_principal_key.h | 1 + contrib/pg_tde/t/010_change_key_provider.pl | 76 ---------- .../t/expected/010_change_key_provider.out | 139 ------------------ 9 files changed, 195 insertions(+), 248 deletions(-) diff --git a/contrib/pg_tde/expected/create_database.out b/contrib/pg_tde/expected/create_database.out index 6e3eaa5cf21..d3b0e602259 100644 --- a/contrib/pg_tde/expected/create_database.out +++ b/contrib/pg_tde/expected/create_database.out @@ -26,7 +26,7 @@ INSERT INTO test_plain (x) VALUES (30), (40); SELECT pg_tde_add_global_key_provider_file('global-file-vault','/tmp/template_provider_global.per'); pg_tde_add_global_key_provider_file ------------------------------------- - -4 + -6 (1 row) SELECT pg_tde_set_default_key_using_global_key_provider('default-key', 'global-file-vault'); diff --git a/contrib/pg_tde/expected/default_principal_key.out b/contrib/pg_tde/expected/default_principal_key.out index 00ccd625194..c3236e55f68 100644 --- a/contrib/pg_tde/expected/default_principal_key.out +++ b/contrib/pg_tde/expected/default_principal_key.out @@ -3,7 +3,7 @@ CREATE EXTENSION IF NOT EXISTS pg_buffercache; SELECT pg_tde_add_global_key_provider_file('file-provider','/tmp/pg_tde_regression_default_key.per'); pg_tde_add_global_key_provider_file ------------------------------------- - -3 + -5 (1 row) -- Should fail: no default principal key for the server yet @@ -30,18 +30,20 @@ SELECT key_provider_id, key_provider_name, key_name FROM pg_tde_default_key_info(); key_provider_id | key_provider_name | key_name -----------------+-------------------+------------- - -3 | file-provider | default-key + -5 | file-provider | default-key (1 row) -- fails SELECT pg_tde_delete_global_key_provider('file-provider'); ERROR: Can't delete a provider which is currently in use SELECT id, provider_name FROM pg_tde_list_all_global_key_providers(); - id | provider_name -----+--------------- + id | provider_name +----+------------------ -1 | file-keyring - -3 | file-provider -(2 rows) + -3 | global-provider + -4 | global-provider2 + -5 | file-provider +(4 rows) -- Should fail: no principal key for the database yet SELECT key_provider_id, key_provider_name, key_name @@ -60,7 +62,7 @@ SELECT key_provider_id, key_provider_name, key_name FROM pg_tde_key_info(); key_provider_id | key_provider_name | key_name -----------------+-------------------+------------- - -3 | file-provider | default-key + -5 | file-provider | default-key (1 row) SELECT current_database() AS regress_database @@ -86,7 +88,7 @@ SELECT key_provider_id, key_provider_name, key_name FROM pg_tde_key_info(); key_provider_id | key_provider_name | key_name -----------------+-------------------+------------- - -3 | file-provider | default-key + -5 | file-provider | default-key (1 row) \c :regress_database @@ -101,7 +103,7 @@ SELECT key_provider_id, key_provider_name, key_name FROM pg_tde_key_info(); key_provider_id | key_provider_name | key_name -----------------+-------------------+----------------- - -3 | file-provider | new-default-key + -5 | file-provider | new-default-key (1 row) \c regress_pg_tde_other @@ -109,7 +111,7 @@ SELECT key_provider_id, key_provider_name, key_name FROM pg_tde_key_info(); key_provider_id | key_provider_name | key_name -----------------+-------------------+----------------- - -3 | file-provider | new-default-key + -5 | file-provider | new-default-key (1 row) SELECT pg_buffercache_evict(bufferid) FROM pg_buffercache WHERE relfilenode = (SELECT relfilenode FROM pg_class WHERE oid = 'test_enc'::regclass); diff --git a/contrib/pg_tde/expected/key_provider.out b/contrib/pg_tde/expected/key_provider.out index c57a555cc79..1829c099725 100644 --- a/contrib/pg_tde/expected/key_provider.out +++ b/contrib/pg_tde/expected/key_provider.out @@ -57,27 +57,12 @@ SELECT * FROM pg_tde_list_all_database_key_providers(); 2 | file-provider2 | file | {"path" : "/tmp/pg_tde_test_keyring2.per"} (2 rows) -SELECT pg_tde_change_database_key_provider_file('file-provider','/tmp/pg_tde_test_keyring_other.per'); - pg_tde_change_database_key_provider_file ------------------------------------------- - 1 -(1 row) - -SELECT * FROM pg_tde_list_all_database_key_providers(); - id | provider_name | provider_type | options -----+----------------+---------------+------------------------------------------------- - 1 | file-provider | file | {"path" : "/tmp/pg_tde_test_keyring_other.per"} - 2 | file-provider2 | file | {"path" : "/tmp/pg_tde_test_keyring2.per"} -(2 rows) - -SELECT pg_tde_verify_key(); -ERROR: failed to retrieve principal key test-db-key from keyring with ID 1 SELECT pg_tde_change_database_key_provider_file('file-provider', json_object('foo' VALUE '/tmp/pg_tde_test_keyring.per')); ERROR: unexpected field "foo" for external value "path" SELECT * FROM pg_tde_list_all_database_key_providers(); - id | provider_name | provider_type | options -----+----------------+---------------+------------------------------------------------- - 1 | file-provider | file | {"path" : "/tmp/pg_tde_test_keyring_other.per"} + id | provider_name | provider_type | options +----+----------------+---------------+-------------------------------------------- + 1 | file-provider | file | {"path" : "/tmp/pg_tde_test_keyring.per"} 2 | file-provider2 | file | {"path" : "/tmp/pg_tde_test_keyring2.per"} (2 rows) @@ -282,6 +267,62 @@ SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {" ERROR: unexpected boolean in field "path" SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": true}}'); ERROR: unexpected boolean in field "path" +-- Modifying key providers fails if new settings can't fetch existing server key +SELECT pg_tde_add_global_key_provider_file('global-provider', '/tmp/global-provider-file-1'); + pg_tde_add_global_key_provider_file +------------------------------------- + -3 +(1 row) + +SELECT pg_tde_set_server_key_using_global_key_provider('server-key', 'global-provider'); + pg_tde_set_server_key_using_global_key_provider +------------------------------------------------- + +(1 row) + +SELECT pg_tde_change_global_key_provider_file('global-provider','/tmp/global-provider-file-2'); +ERROR: could not fetch key "server-key" used as server key from modified key provider "global-provider": 0 +-- Modifying key providers fails if new settings can't fetch existing database key +SELECT pg_tde_add_global_key_provider_file('global-provider2', '/tmp/global-provider-file-1'); + pg_tde_add_global_key_provider_file +------------------------------------- + -4 +(1 row) + +SELECT current_database() AS regress_database +\gset +CREATE DATABASE db_using_global_provider; +\c db_using_global_provider; +CREATE EXTENSION pg_tde; +SELECT pg_tde_set_key_using_global_key_provider('database-key', 'global-provider2'); + pg_tde_set_key_using_global_key_provider +------------------------------------------ + +(1 row) + +\c :regress_database +SELECT pg_tde_change_global_key_provider_file('global-provider2', '/tmp/global-provider-file-2'); +ERROR: could not fetch key "database-key" used by database "db_using_global_provider" from modified key provider "global-provider2": 0 +DROP DATABASE db_using_global_provider; +CREATE DATABASE db_using_database_provider; +\c db_using_database_provider; +CREATE EXTENSION pg_tde; +SELECT pg_tde_add_database_key_provider_file('db-provider', '/tmp/db-provider-file'); + pg_tde_add_database_key_provider_file +--------------------------------------- + 1 +(1 row) + +SELECT pg_tde_set_key_using_database_key_provider('database-key', 'db-provider'); + pg_tde_set_key_using_database_key_provider +-------------------------------------------- + +(1 row) + +SELECT pg_tde_change_database_key_provider_file('db-provider', '/tmp/db-provider-file-2'); +ERROR: could not fetch key "database-key" used by database "db_using_database_provider" from modified key provider "db-provider": 0 +\c :regress_database +DROP DATABASE db_using_database_provider; -- Deleting key providers fails if key name is NULL SELECT pg_tde_delete_database_key_provider(NULL); ERROR: provider_name cannot be null diff --git a/contrib/pg_tde/sql/key_provider.sql b/contrib/pg_tde/sql/key_provider.sql index c777d8aaa26..665aa28049b 100644 --- a/contrib/pg_tde/sql/key_provider.sql +++ b/contrib/pg_tde/sql/key_provider.sql @@ -19,10 +19,6 @@ SELECT pg_tde_verify_key(); SELECT pg_tde_change_database_key_provider_file('not-existent-provider','/tmp/pg_tde_test_keyring.per'); SELECT * FROM pg_tde_list_all_database_key_providers(); -SELECT pg_tde_change_database_key_provider_file('file-provider','/tmp/pg_tde_test_keyring_other.per'); -SELECT * FROM pg_tde_list_all_database_key_providers(); -SELECT pg_tde_verify_key(); - SELECT pg_tde_change_database_key_provider_file('file-provider', json_object('foo' VALUE '/tmp/pg_tde_test_keyring.per')); SELECT * FROM pg_tde_list_all_database_key_providers(); @@ -135,6 +131,31 @@ SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": tr SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": true}}'); SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": true}}'); +-- Modifying key providers fails if new settings can't fetch existing server key +SELECT pg_tde_add_global_key_provider_file('global-provider', '/tmp/global-provider-file-1'); +SELECT pg_tde_set_server_key_using_global_key_provider('server-key', 'global-provider'); +SELECT pg_tde_change_global_key_provider_file('global-provider','/tmp/global-provider-file-2'); + +-- Modifying key providers fails if new settings can't fetch existing database key +SELECT pg_tde_add_global_key_provider_file('global-provider2', '/tmp/global-provider-file-1'); +SELECT current_database() AS regress_database +\gset +CREATE DATABASE db_using_global_provider; +\c db_using_global_provider; +CREATE EXTENSION pg_tde; +SELECT pg_tde_set_key_using_global_key_provider('database-key', 'global-provider2'); +\c :regress_database +SELECT pg_tde_change_global_key_provider_file('global-provider2', '/tmp/global-provider-file-2'); +DROP DATABASE db_using_global_provider; +CREATE DATABASE db_using_database_provider; +\c db_using_database_provider; +CREATE EXTENSION pg_tde; +SELECT pg_tde_add_database_key_provider_file('db-provider', '/tmp/db-provider-file'); +SELECT pg_tde_set_key_using_database_key_provider('database-key', 'db-provider'); +SELECT pg_tde_change_database_key_provider_file('db-provider', '/tmp/db-provider-file-2'); +\c :regress_database +DROP DATABASE db_using_database_provider; + -- Deleting key providers fails if key name is NULL SELECT pg_tde_delete_database_key_provider(NULL); SELECT pg_tde_delete_global_key_provider(NULL); @@ -157,4 +178,5 @@ SELECT pg_tde_set_key_using_database_key_provider(repeat('K', 256), 'file-provid SELECT pg_tde_set_key_using_global_key_provider(repeat('K', 256), 'file-keyring'); SELECT pg_tde_set_server_key_using_global_key_provider(repeat('K', 256), 'file-keyring'); + DROP EXTENSION pg_tde; diff --git a/contrib/pg_tde/src/catalog/tde_keyring.c b/contrib/pg_tde/src/catalog/tde_keyring.c index bc11c6240aa..afd4236eba7 100644 --- a/contrib/pg_tde/src/catalog/tde_keyring.c +++ b/contrib/pg_tde/src/catalog/tde_keyring.c @@ -511,6 +511,18 @@ check_provider_record(KeyringProviderRecord *provider_record) KeyringValidate(provider); +#ifndef FRONTEND /* We can't scan the pg_database catalog from + * frontend. */ + if (provider->keyring_id != 0) + { + /* + * If we are modifying an existing provider, verify that all of the + * keys already in use are the same. + */ + pg_tde_verify_provider_keys_in_use(provider); + } +#endif + pfree(provider); } diff --git a/contrib/pg_tde/src/catalog/tde_principal_key.c b/contrib/pg_tde/src/catalog/tde_principal_key.c index c86e2c930c5..d318aaaf6b5 100644 --- a/contrib/pg_tde/src/catalog/tde_principal_key.c +++ b/contrib/pg_tde/src/catalog/tde_principal_key.c @@ -942,6 +942,90 @@ pg_tde_is_provider_used(Oid databaseOid, Oid providerId) } } +/* + * Verifies that all keys that are currently in use matches the keys available + * at the provided key provider. This is meant to be used before modifying an + * existing provider to ensure the new settings will provide the same keys as + * those that are already in use. + */ +void +pg_tde_verify_provider_keys_in_use(GenericKeyring *modified_provider) +{ + TDEPrincipalKey *existing_principal_key; + HeapTuple tuple; + SysScanDesc scan; + Relation rel; + + Assert(modified_provider); + Assert(modified_provider->keyring_id); + + LWLockAcquire(tde_lwlock_enc_keys(), LW_EXCLUSIVE); + + /* Check the server key that is used for WAL encryption */ + existing_principal_key = GetPrincipalKeyNoDefault(GLOBAL_DATA_TDE_OID, LW_EXCLUSIVE); + if (existing_principal_key != NULL && + existing_principal_key->keyInfo.keyringId == modified_provider->keyring_id) + { + char *key_name = existing_principal_key->keyInfo.name; + KeyringReturnCodes return_code; + KeyInfo *proposed_key; + + proposed_key = KeyringGetKey(modified_provider, key_name, &return_code); + if (!proposed_key) + { + ereport(ERROR, + errmsg("could not fetch key \"%s\" used as server key from modified key provider \"%s\": %d", + key_name, modified_provider->provider_name, return_code)); + } + + if (proposed_key->data.len != existing_principal_key->keyLength || + memcmp(proposed_key->data.data, existing_principal_key->keyData, proposed_key->data.len) != 0) + { + ereport(ERROR, + errmsg("key \"%s\" from modified key provider \"%s\" does not match existing server key", + key_name, modified_provider->provider_name)); + } + } + + /* Check all databases for usage of keys from this key provider. */ + rel = table_open(DatabaseRelationId, AccessShareLock); + scan = systable_beginscan(rel, 0, false, NULL, 0, NULL); + + while (HeapTupleIsValid(tuple = systable_getnext(scan))) + { + Form_pg_database database = (Form_pg_database) GETSTRUCT(tuple); + + existing_principal_key = GetPrincipalKeyNoDefault(database->oid, LW_EXCLUSIVE); + if (existing_principal_key != NULL && + existing_principal_key->keyInfo.keyringId == modified_provider->keyring_id) + { + char *key_name = existing_principal_key->keyInfo.name; + KeyringReturnCodes return_code; + KeyInfo *proposed_key; + + proposed_key = KeyringGetKey(modified_provider, key_name, &return_code); + if (!proposed_key) + { + ereport(ERROR, + errmsg("could not fetch key \"%s\" used by database \"%s\" from modified key provider \"%s\": %d", + key_name, database->datname.data, modified_provider->provider_name, return_code)); + } + + if (proposed_key->data.len != existing_principal_key->keyLength || + memcmp(proposed_key->data.data, existing_principal_key->keyData, proposed_key->data.len) != 0) + { + ereport(ERROR, + errmsg("key \"%s\" from modified key provider \"%s\" does not match existing key used by database \"%s\"", + key_name, modified_provider->provider_name, database->datname.data)); + } + } + } + systable_endscan(scan); + table_close(rel, AccessShareLock); + + LWLockRelease(tde_lwlock_enc_keys()); +} + static bool pg_tde_is_same_principal_key(TDEPrincipalKey *a, TDEPrincipalKey *b) { diff --git a/contrib/pg_tde/src/include/catalog/tde_principal_key.h b/contrib/pg_tde/src/include/catalog/tde_principal_key.h index ee5870ccf7b..26dd6f22bef 100644 --- a/contrib/pg_tde/src/include/catalog/tde_principal_key.h +++ b/contrib/pg_tde/src/include/catalog/tde_principal_key.h @@ -55,5 +55,6 @@ extern TDEPrincipalKey *GetPrincipalKey(Oid dbOid, void *lockMode); extern void xl_tde_perform_rotate_key(XLogPrincipalKeyRotate *xlrec); extern bool pg_tde_is_provider_used(Oid databaseOid, Oid providerId); +extern void pg_tde_verify_provider_keys_in_use(GenericKeyring *proposed_provider); #endif /* PG_TDE_PRINCIPAL_KEY_H */ diff --git a/contrib/pg_tde/t/010_change_key_provider.pl b/contrib/pg_tde/t/010_change_key_provider.pl index 60b40243222..edf482c2ba7 100644 --- a/contrib/pg_tde/t/010_change_key_provider.pl +++ b/contrib/pg_tde/t/010_change_key_provider.pl @@ -62,82 +62,6 @@ PGTDE::psql($node, 'postgres', "SELECT pg_tde_verify_key();"); PGTDE::psql($node, 'postgres', "SELECT pg_tde_is_encrypted('test_enc');"); PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc ORDER BY id;'); -# Change provider and do not move file -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_change_database_key_provider_file('file-vault', '/tmp/change_key_provider_3.per');" -); -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_list_all_database_key_providers();"); - -PGTDE::psql($node, 'postgres', "SELECT pg_tde_verify_key();"); -PGTDE::psql($node, 'postgres', "SELECT pg_tde_is_encrypted('test_enc');"); -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc ORDER BY id;'); - -PGTDE::append_to_result_file("-- server restart"); -$node->restart; - -# Verify -PGTDE::psql($node, 'postgres', "SELECT pg_tde_verify_key();"); -PGTDE::psql($node, 'postgres', "SELECT pg_tde_is_encrypted('test_enc');"); -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc ORDER BY id;'); - -PGTDE::append_to_result_file( - "-- mv /tmp/change_key_provider_2.per /tmp/change_key_provider_3.per"); -move('/tmp/change_key_provider_2.per', '/tmp/change_key_provider_3.per'); - -PGTDE::append_to_result_file("-- server restart"); -$node->restart; - -# Verify -PGTDE::psql($node, 'postgres', "SELECT pg_tde_verify_key();"); -PGTDE::psql($node, 'postgres', "SELECT pg_tde_is_encrypted('test_enc');"); -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc ORDER BY id;'); - -PGTDE::psql($node, 'postgres', 'DROP EXTENSION pg_tde CASCADE;'); - -PGTDE::psql($node, 'postgres', 'CREATE EXTENSION IF NOT EXISTS pg_tde;'); - -# Change provider and generate a new principal key -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_add_database_key_provider_file('file-vault', '/tmp/change_key_provider_4.per');" -); -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_set_key_using_database_key_provider('test-key', 'file-vault');" -); - -PGTDE::psql($node, 'postgres', - 'CREATE TABLE test_enc (id serial, k integer, PRIMARY KEY (id)) USING tde_heap;' -); -PGTDE::psql($node, 'postgres', 'INSERT INTO test_enc (k) VALUES (5), (6);'); - -PGTDE::psql($node, 'postgres', "SELECT pg_tde_verify_key();"); -PGTDE::psql($node, 'postgres', "SELECT pg_tde_is_encrypted('test_enc');"); -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc ORDER BY id;'); - -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_change_database_key_provider_file('file-vault', '/tmp/change_key_provider_3.per');" -); - -PGTDE::append_to_result_file("-- server restart"); -$node->restart; - -# Verify -PGTDE::psql($node, 'postgres', "SELECT pg_tde_verify_key();"); -PGTDE::psql($node, 'postgres', "SELECT pg_tde_is_encrypted('test_enc');"); -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc ORDER BY id;'); -PGTDE::psql($node, 'postgres', - 'CREATE TABLE test_enc2 (id serial, k integer, PRIMARY KEY (id)) USING tde_heap;' -); - -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_change_database_key_provider_file('file-vault', '/tmp/change_key_provider_4.per');" -); - -# Verify -PGTDE::psql($node, 'postgres', "SELECT pg_tde_verify_key();"); -PGTDE::psql($node, 'postgres', "SELECT pg_tde_is_encrypted('test_enc');"); -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc ORDER BY id;'); - PGTDE::psql($node, 'postgres', 'DROP EXTENSION pg_tde CASCADE;'); $node->stop; diff --git a/contrib/pg_tde/t/expected/010_change_key_provider.out b/contrib/pg_tde/t/expected/010_change_key_provider.out index e7442031672..73c6b280d17 100644 --- a/contrib/pg_tde/t/expected/010_change_key_provider.out +++ b/contrib/pg_tde/t/expected/010_change_key_provider.out @@ -90,144 +90,5 @@ SELECT * FROM test_enc ORDER BY id; 2 | 6 (2 rows) -SELECT pg_tde_change_database_key_provider_file('file-vault', '/tmp/change_key_provider_3.per'); - pg_tde_change_database_key_provider_file ------------------------------------------- - 1 -(1 row) - -SELECT pg_tde_list_all_database_key_providers(); - pg_tde_list_all_database_key_providers ------------------------------------------------------------------------ - (1,file-vault,file,"{""path"" : ""/tmp/change_key_provider_3.per""}") -(1 row) - -SELECT pg_tde_verify_key(); -psql::1: ERROR: failed to retrieve principal key test-key from keyring with ID 1 -SELECT pg_tde_is_encrypted('test_enc'); - pg_tde_is_encrypted ---------------------- - t -(1 row) - -SELECT * FROM test_enc ORDER BY id; - id | k -----+--- - 1 | 5 - 2 | 6 -(2 rows) - --- server restart -SELECT pg_tde_verify_key(); -psql::1: ERROR: failed to retrieve principal key test-key from keyring with ID 1 -SELECT pg_tde_is_encrypted('test_enc'); - pg_tde_is_encrypted ---------------------- - t -(1 row) - -SELECT * FROM test_enc ORDER BY id; -psql::1: ERROR: failed to retrieve principal key test-key from keyring with ID 1 --- mv /tmp/change_key_provider_2.per /tmp/change_key_provider_3.per --- server restart -SELECT pg_tde_verify_key(); - pg_tde_verify_key -------------------- - -(1 row) - -SELECT pg_tde_is_encrypted('test_enc'); - pg_tde_is_encrypted ---------------------- - t -(1 row) - -SELECT * FROM test_enc ORDER BY id; - id | k -----+--- - 1 | 5 - 2 | 6 -(2 rows) - -DROP EXTENSION pg_tde CASCADE; -psql::1: NOTICE: drop cascades to table test_enc -CREATE EXTENSION IF NOT EXISTS pg_tde; -SELECT pg_tde_add_database_key_provider_file('file-vault', '/tmp/change_key_provider_4.per'); - pg_tde_add_database_key_provider_file ---------------------------------------- - 1 -(1 row) - -SELECT pg_tde_set_key_using_database_key_provider('test-key', 'file-vault'); - pg_tde_set_key_using_database_key_provider --------------------------------------------- - -(1 row) - -CREATE TABLE test_enc (id serial, k integer, PRIMARY KEY (id)) USING tde_heap; -INSERT INTO test_enc (k) VALUES (5), (6); -SELECT pg_tde_verify_key(); - pg_tde_verify_key -------------------- - -(1 row) - -SELECT pg_tde_is_encrypted('test_enc'); - pg_tde_is_encrypted ---------------------- - t -(1 row) - -SELECT * FROM test_enc ORDER BY id; - id | k -----+--- - 1 | 5 - 2 | 6 -(2 rows) - -SELECT pg_tde_change_database_key_provider_file('file-vault', '/tmp/change_key_provider_3.per'); - pg_tde_change_database_key_provider_file ------------------------------------------- - 1 -(1 row) - --- server restart -SELECT pg_tde_verify_key(); -psql::1: ERROR: Failed to verify principal key header for key test-key, incorrect principal key or corrupted key file -SELECT pg_tde_is_encrypted('test_enc'); - pg_tde_is_encrypted ---------------------- - t -(1 row) - -SELECT * FROM test_enc ORDER BY id; -psql::1: ERROR: Failed to verify principal key header for key test-key, incorrect principal key or corrupted key file -CREATE TABLE test_enc2 (id serial, k integer, PRIMARY KEY (id)) USING tde_heap; -psql::1: ERROR: Failed to verify principal key header for key test-key, incorrect principal key or corrupted key file -SELECT pg_tde_change_database_key_provider_file('file-vault', '/tmp/change_key_provider_4.per'); - pg_tde_change_database_key_provider_file ------------------------------------------- - 1 -(1 row) - -SELECT pg_tde_verify_key(); - pg_tde_verify_key -------------------- - -(1 row) - -SELECT pg_tde_is_encrypted('test_enc'); - pg_tde_is_encrypted ---------------------- - t -(1 row) - -SELECT * FROM test_enc ORDER BY id; - id | k -----+--- - 1 | 5 - 2 | 6 -(2 rows) - DROP EXTENSION pg_tde CASCADE; psql::1: NOTICE: drop cascades to table test_enc