Make related code compilable with frontend (#266)

* Make related code compilable with frontend

This commit makes the code around keyring, principal keys and WAL
encryption compilable with frontend tools. Namely:
- Hide everything that isn't compatible and of no use behind
  '#ifndef FRONTEND'
- Redefine code that is needed in both versions but should have
  different code. E.g. error handling, file descriptors and locks
- Make use of frontend lists instead of backend ones where needed.

For https://perconadev.atlassian.net/browse/PG-857
pull/209/head
Andrew Pogrebnoi 1 year ago committed by GitHub
parent 19f722e403
commit bf4725fc46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      Makefile.in
  2. 2
      meson.build
  3. 1011
      src/access/pg_tde_tdemap.c
  4. 287
      src/access/pg_tde_xlog.c
  5. 314
      src/access/pg_tde_xlog_encrypt.c
  6. 67
      src/catalog/tde_global_space.c
  7. 550
      src/catalog/tde_keyring.c
  8. 5
      src/catalog/tde_keyring_parse_opts.c
  9. 262
      src/catalog/tde_principal_key.c
  10. 23
      src/common/pg_tde_utils.c
  11. 17
      src/encryption/enc_tde.c
  12. 1
      src/include/access/pg_tde_tdemap.h
  13. 30
      src/include/access/pg_tde_xlog.h
  14. 35
      src/include/access/pg_tde_xlog_encrypt.h
  15. 29
      src/include/access/pg_tde_xlog_encrypt_fe.h
  16. 3
      src/include/catalog/tde_global_space.h
  17. 8
      src/include/catalog/tde_principal_key.h
  18. 4
      src/include/common/pg_tde_utils.h
  19. 4
      src/include/keyring/keyring.h
  20. 18
      src/include/keyring/keyring_config.h
  21. 86
      src/include/pg_tde_fe.h
  22. 10
      src/keyring/keyring.c
  23. 37
      src/keyring/keyring_api.c
  24. 17
      src/keyring/keyring_config.c
  25. 3
      src/keyring/keyring_curl.c
  26. 8
      src/keyring/keyring_file.c
  27. 5
      src/keyring/keyring_vault.c
  28. 5
      src/pg_tde.c

@ -36,8 +36,8 @@ src$(MAJORVERSION)/access/pg_tde_rewrite.o \
src$(MAJORVERSION)/access/pg_tdeam_handler.o \
src/access/pg_tde_ddl.o \
src/access/pg_tde_xlog.o \
src/access/pg_tde_xlog_encrypt.o \
src/transam/pg_tde_xact_handler.o \
src/keyring/keyring_config.o \
src/keyring/keyring_curl.o \
src/keyring/keyring_file.o \
src/keyring/keyring_vault.o \

@ -32,11 +32,11 @@ pg_tde_sources = files(
src_version / 'access/pg_tde_visibilitymap.c',
'src/access/pg_tde_ddl.c',
'src/access/pg_tde_xlog.c',
'src/access/pg_tde_xlog_encrypt.c',
'src/encryption/enc_tde.c',
'src/encryption/enc_aes.c',
'src/keyring/keyring_config.c',
'src/keyring/keyring_curl.c',
'src/keyring/keyring_file.c',
'src/keyring/keyring_vault.c',

File diff suppressed because it is too large Load Diff

@ -24,24 +24,8 @@
#include "utils/guc.h"
#include "utils/memutils.h"
#include "access/pg_tde_tdemap.h"
#include "access/pg_tde_xlog.h"
#include "encryption/enc_tde.h"
#ifdef PERCONA_EXT
#include "catalog/tde_global_space.h"
static char *TDEXLogEncryptBuf = NULL;
/* GUC */
static bool EncryptXLog = false;
static XLogPageHeaderData EncryptCurrentPageHrd;
static XLogPageHeaderData DecryptCurrentPageHrd;
static ssize_t TDEXLogWriteEncryptedPages(int fd, const void *buf, size_t count, off_t offset);
static void SetXLogPageIVPrefix(TimeLineID tli, XLogRecPtr lsn, char* iv_prefix);
static int XLOGChooseNumBuffers(void);
#endif
/*
* TDE fork XLog
@ -139,274 +123,3 @@ tdeheap_rmgr_identify(uint8 info)
return NULL;
}
#ifdef PERCONA_EXT
/*
* -------------------------
* XLog Storage Manager
*/
void
XLogInitGUC(void)
{
DefineCustomBoolVariable("pg_tde.wal_encrypt", /* name */
"Enable/Disable encryption of WAL.", /* short_desc */
NULL, /* long_desc */
&EncryptXLog, /* value address */
false, /* boot value */
PGC_POSTMASTER, /* context */
0, /* flags */
NULL, /* check_hook */
NULL, /* assign_hook */
NULL /* show_hook */
);
}
static int
XLOGChooseNumBuffers(void)
{
int xbuffers;
xbuffers = NBuffers / 32;
if (xbuffers > (wal_segment_size / XLOG_BLCKSZ))
xbuffers = (wal_segment_size / XLOG_BLCKSZ);
if (xbuffers < 8)
xbuffers = 8;
return xbuffers;
}
/*
* Defines the size of the XLog encryption buffer
*/
Size
TDEXLogEncryptBuffSize(void)
{
int xbuffers;
xbuffers = (XLOGbuffers == -1) ? XLOGChooseNumBuffers() : XLOGbuffers;
return (Size) XLOG_BLCKSZ * xbuffers;
}
/*
* Alloc memory for the encryption buffer.
*
* It should fit XLog buffers (XLOG_BLCKSZ * wal_buffers). We can't
* (re)alloc this buf in tdeheap_xlog_seg_write() based on the write size as
* it's called in the CRIT section, hence no allocations are allowed.
*
* Access to this buffer happens during XLogWrite() call which should
* be called with WALWriteLock held, hence no need in extra locks.
*/
void
TDEXLogShmemInit(void)
{
bool foundBuf;
if (EncryptXLog)
{
TDEXLogEncryptBuf = (char *)
TYPEALIGN(PG_IO_ALIGN_SIZE,
ShmemInitStruct("TDE XLog Encryption Buffer",
XLOG_TDE_ENC_BUFF_ALIGNED_SIZE,
&foundBuf));
elog(DEBUG1, "pg_tde: initialized encryption buffer %lu bytes", XLOG_TDE_ENC_BUFF_ALIGNED_SIZE);
}
}
void
TDEXLogSmgrInit(void)
{
SetXLogSmgr(&tde_xlog_smgr);
}
ssize_t
tdeheap_xlog_seg_write(int fd, const void *buf, size_t count, off_t offset)
{
if (EncryptXLog)
return TDEXLogWriteEncryptedPages(fd, buf, count, offset);
else
return pg_pwrite(fd, buf, count, offset);
}
/*
* Encrypt XLog page(s) from the buf and write to the segment file.
*/
static ssize_t
TDEXLogWriteEncryptedPages(int fd, const void *buf, size_t count, off_t offset)
{
char iv_prefix[16] = {0,};
size_t data_size = 0;
XLogPageHeader curr_page_hdr = &EncryptCurrentPageHrd;
XLogPageHeader enc_buf_page;
RelKeyData *key = GetRelationKey(GLOBAL_SPACE_RLOCATOR(XLOG_TDE_OID));
off_t enc_off;
size_t page_size = XLOG_BLCKSZ - offset % XLOG_BLCKSZ;
uint32 iv_ctr = 0;
#ifdef TDE_XLOG_DEBUG
elog(DEBUG1, "write encrypted WAL, pages amount: %d, size: %lu offset: %ld", count / (Size) XLOG_BLCKSZ, count, offset);
#endif
/*
* Go through the buf page-by-page and encrypt them.
* We may start or finish writing from/in the middle of the page
* (walsender or `full_page_writes = off`). So preserve a page header
* for the IV init data.
*
* TODO: check if walsender restarts form the beggining of the page
* in case of the crash.
*/
for (enc_off = 0; enc_off < count;)
{
data_size = Min(page_size, count);
if (page_size == XLOG_BLCKSZ)
{
memcpy((char *) curr_page_hdr, (char *) buf + enc_off, SizeOfXLogShortPHD);
/*
* Need to use a separate buf for the encryption so the page remains non-crypted
* in the XLog buf (XLogInsert has to have access to records' lsn).
*/
enc_buf_page = (XLogPageHeader) (TDEXLogEncryptBuf + enc_off);
memcpy((char *) enc_buf_page, (char *) buf + enc_off, (Size) XLogPageHeaderSize(curr_page_hdr));
enc_buf_page->xlp_info |= XLP_ENCRYPTED;
enc_off += XLogPageHeaderSize(curr_page_hdr);
data_size -= XLogPageHeaderSize(curr_page_hdr);
/* it's a beginning of the page */
iv_ctr = 0;
}
else
{
/* we're in the middle of the page */
iv_ctr = (offset % XLOG_BLCKSZ) - XLogPageHeaderSize(curr_page_hdr);
}
if (data_size + enc_off > count)
{
data_size = count - enc_off;
}
/*
* The page is zeroed (no data), no sense to enctypt.
* This may happen when base_backup or other requests XLOG SWITCH and
* some pages in XLog buffer still not used.
*/
if (curr_page_hdr->xlp_magic == 0)
{
/* ensure all the page is {0} */
Assert((*((char *) buf + enc_off) == 0) &&
memcmp((char *) buf + enc_off, (char *) buf + enc_off + 1, data_size - 1) == 0);
memcpy((char *) enc_buf_page, (char *) buf + enc_off, data_size);
}
else
{
SetXLogPageIVPrefix(curr_page_hdr->xlp_tli, curr_page_hdr->xlp_pageaddr, iv_prefix);
PG_TDE_ENCRYPT_DATA(iv_prefix, iv_ctr, (char *) buf + enc_off, data_size,
TDEXLogEncryptBuf + enc_off, key);
}
page_size = XLOG_BLCKSZ;
enc_off += data_size;
}
return pg_pwrite(fd, TDEXLogEncryptBuf, count, offset);
}
/*
* Read the XLog pages from the segment file and dectypt if need.
*/
ssize_t
tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset)
{
ssize_t readsz;
char iv_prefix[16] = {0,};
size_t data_size = 0;
XLogPageHeader curr_page_hdr = &DecryptCurrentPageHrd;
RelKeyData *key = GetRelationKey(GLOBAL_SPACE_RLOCATOR(XLOG_TDE_OID));
size_t page_size = XLOG_BLCKSZ - offset % XLOG_BLCKSZ;
off_t dec_off;
uint32 iv_ctr = 0;
#ifdef TDE_XLOG_DEBUG
elog(DEBUG1, "read from a WAL segment, pages amount: %d, size: %lu offset: %ld", count / (Size) XLOG_BLCKSZ, count, offset);
#endif
readsz = pg_pread(fd, buf, count, offset);
/*
* Read the buf page by page and decypt ecnrypted pages.
* We may start or fihish reading from/in the middle of the page (walreceiver)
* in such a case we should preserve the last read page header for
* the IV data and the encryption state.
*
* TODO: check if walsender/receiver restarts form the beggining of the page
* in case of the crash.
*/
for (dec_off = 0; dec_off < readsz;)
{
data_size = Min(page_size, readsz);
if (page_size == XLOG_BLCKSZ)
{
memcpy((char *) curr_page_hdr, (char *) buf + dec_off, SizeOfXLogShortPHD);
/* set the flag to "not encrypted" for the walreceiver */
((XLogPageHeader) ((char *) buf + dec_off))->xlp_info &= ~XLP_ENCRYPTED;
Assert(curr_page_hdr->xlp_magic == XLOG_PAGE_MAGIC || curr_page_hdr->xlp_magic == 0);
dec_off += XLogPageHeaderSize(curr_page_hdr);
data_size -= XLogPageHeaderSize(curr_page_hdr);
/* it's a beginning of the page */
iv_ctr = 0;
}
else
{
/* we're in the middle of the page */
iv_ctr = (offset % XLOG_BLCKSZ) - XLogPageHeaderSize(curr_page_hdr);
}
if ((data_size + dec_off) > readsz)
{
data_size = readsz - dec_off;
}
if (curr_page_hdr->xlp_info & XLP_ENCRYPTED)
{
SetXLogPageIVPrefix(curr_page_hdr->xlp_tli, curr_page_hdr->xlp_pageaddr, iv_prefix);
PG_TDE_DECRYPT_DATA(
iv_prefix, iv_ctr,
(char *) buf + dec_off, data_size, (char *) buf + dec_off, key);
}
page_size = XLOG_BLCKSZ;
dec_off += data_size;
}
return readsz;
}
/* IV: TLI(uint32) + XLogRecPtr(uint64)*/
static void
SetXLogPageIVPrefix(TimeLineID tli, XLogRecPtr lsn, char* iv_prefix)
{
iv_prefix[0] = (tli >> 24);
iv_prefix[1] = ((tli >> 16) & 0xFF);
iv_prefix[2] = ((tli >> 8) & 0xFF);
iv_prefix[3] = (tli & 0xFF);
iv_prefix[4] = (lsn >> 56);
iv_prefix[5] = ((lsn >> 48) & 0xFF);
iv_prefix[6] = ((lsn >> 40) & 0xFF);
iv_prefix[7] = ((lsn >> 32) & 0xFF);
iv_prefix[8] = ((lsn >> 24) & 0xFF);
iv_prefix[9] = ((lsn >> 16) & 0xFF);
iv_prefix[10] = ((lsn >> 8) & 0xFF);
iv_prefix[11] = (lsn & 0xFF);
}
#endif

@ -0,0 +1,314 @@
/*-------------------------------------------------------------------------
*
* pg_tde_xlog_encrypt.c
* Encrypted XLog storage manager
*
*
* IDENTIFICATION
* src/access/pg_tde_xlog_encrypt.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#ifdef PERCONA_EXT
#include "pg_tde.h"
#include "pg_tde_defines.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "catalog/pg_tablespace_d.h"
#include "storage/bufmgr.h"
#include "storage/shmem.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "access/pg_tde_xlog_encrypt.h"
#include "catalog/tde_global_space.h"
#include "encryption/enc_tde.h"
#ifdef FRONTEND
#include "pg_tde_fe.h"
#endif
static XLogPageHeaderData DecryptCurrentPageHrd;
static void SetXLogPageIVPrefix(TimeLineID tli, XLogRecPtr lsn, char* iv_prefix);
#ifndef FRONTEND
/* GUC */
static bool EncryptXLog = false;
static XLogPageHeaderData EncryptCurrentPageHrd;
static ssize_t TDEXLogWriteEncryptedPages(int fd, const void *buf, size_t count, off_t offset);
static char *TDEXLogEncryptBuf = NULL;
static int XLOGChooseNumBuffers(void);
void
XLogInitGUC(void)
{
DefineCustomBoolVariable("pg_tde.wal_encrypt", /* name */
"Enable/Disable encryption of WAL.", /* short_desc */
NULL, /* long_desc */
&EncryptXLog, /* value address */
false, /* boot value */
PGC_POSTMASTER, /* context */
0, /* flags */
NULL, /* check_hook */
NULL, /* assign_hook */
NULL /* show_hook */
);
}
static int
XLOGChooseNumBuffers(void)
{
int xbuffers;
xbuffers = NBuffers / 32;
if (xbuffers > (wal_segment_size / XLOG_BLCKSZ))
xbuffers = (wal_segment_size / XLOG_BLCKSZ);
if (xbuffers < 8)
xbuffers = 8;
return xbuffers;
}
/*
* Defines the size of the XLog encryption buffer
*/
Size
TDEXLogEncryptBuffSize(void)
{
int xbuffers;
xbuffers = (XLOGbuffers == -1) ? XLOGChooseNumBuffers() : XLOGbuffers;
return (Size) XLOG_BLCKSZ * xbuffers;
}
/*
* Alloc memory for the encryption buffer.
*
* It should fit XLog buffers (XLOG_BLCKSZ * wal_buffers). We can't
* (re)alloc this buf in tdeheap_xlog_seg_write() based on the write size as
* it's called in the CRIT section, hence no allocations are allowed.
*
* Access to this buffer happens during XLogWrite() call which should
* be called with WALWriteLock held, hence no need in extra locks.
*/
void
TDEXLogShmemInit(void)
{
bool foundBuf;
if (EncryptXLog)
{
TDEXLogEncryptBuf = (char *)
TYPEALIGN(PG_IO_ALIGN_SIZE,
ShmemInitStruct("TDE XLog Encryption Buffer",
XLOG_TDE_ENC_BUFF_ALIGNED_SIZE,
&foundBuf));
elog(DEBUG1, "pg_tde: initialized encryption buffer %lu bytes", XLOG_TDE_ENC_BUFF_ALIGNED_SIZE);
}
}
/*
* Encrypt XLog page(s) from the buf and write to the segment file.
*/
static ssize_t
TDEXLogWriteEncryptedPages(int fd, const void *buf, size_t count, off_t offset)
{
char iv_prefix[16] = {0,};
size_t data_size = 0;
XLogPageHeader curr_page_hdr = &EncryptCurrentPageHrd;
XLogPageHeader enc_buf_page;
RelKeyData *key = GetRelationKey(GLOBAL_SPACE_RLOCATOR(XLOG_TDE_OID));
off_t enc_off;
size_t page_size = XLOG_BLCKSZ - offset % XLOG_BLCKSZ;
uint32 iv_ctr = 0;
#ifdef TDE_XLOG_DEBUG
elog(DEBUG1, "write encrypted WAL, pages amount: %d, size: %lu offset: %ld", count / (Size) XLOG_BLCKSZ, count, offset);
#endif
/*
* Go through the buf page-by-page and encrypt them.
* We may start or finish writing from/in the middle of the page
* (walsender or `full_page_writes = off`). So preserve a page header
* for the IV init data.
*
* TODO: check if walsender restarts form the beggining of the page
* in case of the crash.
*/
for (enc_off = 0; enc_off < count;)
{
data_size = Min(page_size, count);
if (page_size == XLOG_BLCKSZ)
{
memcpy((char *) curr_page_hdr, (char *) buf + enc_off, SizeOfXLogShortPHD);
/*
* Need to use a separate buf for the encryption so the page remains non-crypted
* in the XLog buf (XLogInsert has to have access to records' lsn).
*/
enc_buf_page = (XLogPageHeader) (TDEXLogEncryptBuf + enc_off);
memcpy((char *) enc_buf_page, (char *) buf + enc_off, (Size) XLogPageHeaderSize(curr_page_hdr));
enc_buf_page->xlp_info |= XLP_ENCRYPTED;
enc_off += XLogPageHeaderSize(curr_page_hdr);
data_size -= XLogPageHeaderSize(curr_page_hdr);
/* it's a beginning of the page */
iv_ctr = 0;
}
else
{
/* we're in the middle of the page */
iv_ctr = (offset % XLOG_BLCKSZ) - XLogPageHeaderSize(curr_page_hdr);
}
if (data_size + enc_off > count)
{
data_size = count - enc_off;
}
/*
* The page is zeroed (no data), no sense to enctypt.
* This may happen when base_backup or other requests XLOG SWITCH and
* some pages in XLog buffer still not used.
*/
if (curr_page_hdr->xlp_magic == 0)
{
/* ensure all the page is {0} */
Assert((*((char *) buf + enc_off) == 0) &&
memcmp((char *) buf + enc_off, (char *) buf + enc_off + 1, data_size - 1) == 0);
memcpy((char *) enc_buf_page, (char *) buf + enc_off, data_size);
}
else
{
SetXLogPageIVPrefix(curr_page_hdr->xlp_tli, curr_page_hdr->xlp_pageaddr, iv_prefix);
PG_TDE_ENCRYPT_DATA(iv_prefix, iv_ctr, (char *) buf + enc_off, data_size,
TDEXLogEncryptBuf + enc_off, key);
}
page_size = XLOG_BLCKSZ;
enc_off += data_size;
}
return pg_pwrite(fd, TDEXLogEncryptBuf, count, offset);
}
#endif /* !FRONTEND */
void
TDEXLogSmgrInit(void)
{
SetXLogSmgr(&tde_xlog_smgr);
}
ssize_t
tdeheap_xlog_seg_write(int fd, const void *buf, size_t count, off_t offset)
{
#ifndef FRONTEND
if (EncryptXLog)
return TDEXLogWriteEncryptedPages(fd, buf, count, offset);
else
#endif
return pg_pwrite(fd, buf, count, offset);
}
/*
* Read the XLog pages from the segment file and dectypt if need.
*/
ssize_t
tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset)
{
ssize_t readsz;
char iv_prefix[16] = {0,};
size_t data_size = 0;
XLogPageHeader curr_page_hdr = &DecryptCurrentPageHrd;
RelKeyData *key = GetRelationKey(GLOBAL_SPACE_RLOCATOR(XLOG_TDE_OID));
size_t page_size = XLOG_BLCKSZ - offset % XLOG_BLCKSZ;
off_t dec_off;
uint32 iv_ctr = 0;
#ifdef TDE_XLOG_DEBUG
elog(DEBUG1, "read from a WAL segment, pages amount: %d, size: %lu offset: %ld", count / (Size) XLOG_BLCKSZ, count, offset);
#endif
readsz = pg_pread(fd, buf, count, offset);
/*
* Read the buf page by page and decypt ecnrypted pages.
* We may start or fihish reading from/in the middle of the page (walreceiver)
* in such a case we should preserve the last read page header for
* the IV data and the encryption state.
*
* TODO: check if walsender/receiver restarts form the beggining of the page
* in case of the crash.
*/
for (dec_off = 0; dec_off < readsz;)
{
data_size = Min(page_size, readsz);
if (page_size == XLOG_BLCKSZ)
{
memcpy((char *) curr_page_hdr, (char *) buf + dec_off, SizeOfXLogShortPHD);
/* set the flag to "not encrypted" for the walreceiver */
((XLogPageHeader) ((char *) buf + dec_off))->xlp_info &= ~XLP_ENCRYPTED;
Assert(curr_page_hdr->xlp_magic == XLOG_PAGE_MAGIC || curr_page_hdr->xlp_magic == 0);
dec_off += XLogPageHeaderSize(curr_page_hdr);
data_size -= XLogPageHeaderSize(curr_page_hdr);
/* it's a beginning of the page */
iv_ctr = 0;
}
else
{
/* we're in the middle of the page */
iv_ctr = (offset % XLOG_BLCKSZ) - XLogPageHeaderSize(curr_page_hdr);
}
if ((data_size + dec_off) > readsz)
{
data_size = readsz - dec_off;
}
if (curr_page_hdr->xlp_info & XLP_ENCRYPTED)
{
SetXLogPageIVPrefix(curr_page_hdr->xlp_tli, curr_page_hdr->xlp_pageaddr, iv_prefix);
PG_TDE_DECRYPT_DATA(
iv_prefix, iv_ctr,
(char *) buf + dec_off, data_size, (char *) buf + dec_off, key);
}
page_size = XLOG_BLCKSZ;
dec_off += data_size;
}
return readsz;
}
/* IV: TLI(uint32) + XLogRecPtr(uint64)*/
static void
SetXLogPageIVPrefix(TimeLineID tli, XLogRecPtr lsn, char* iv_prefix)
{
iv_prefix[0] = (tli >> 24);
iv_prefix[1] = ((tli >> 16) & 0xFF);
iv_prefix[2] = ((tli >> 8) & 0xFF);
iv_prefix[3] = (tli & 0xFF);
iv_prefix[4] = (lsn >> 56);
iv_prefix[5] = ((lsn >> 48) & 0xFF);
iv_prefix[6] = ((lsn >> 40) & 0xFF);
iv_prefix[7] = ((lsn >> 32) & 0xFF);
iv_prefix[8] = ((lsn >> 24) & 0xFF);
iv_prefix[9] = ((lsn >> 16) & 0xFF);
iv_prefix[10] = ((lsn >> 8) & 0xFF);
iv_prefix[11] = (lsn & 0xFF);
}
#endif /* PERCONA_EXT */

@ -15,15 +15,16 @@
#ifdef PERCONA_EXT
#include "catalog/pg_tablespace_d.h"
#include "nodes/pg_list.h"
#include "storage/shmem.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "access/pg_tde_tdemap.h"
#include "catalog/tde_global_space.h"
#include "catalog/tde_keyring.h"
#include "catalog/tde_principal_key.h"
#include "common/pg_tde_utils.h"
#ifdef FRONTEND
#include "pg_tde_fe.h"
#endif
#include <openssl/rand.h>
#include <openssl/err.h>
@ -31,19 +32,24 @@
#define PRINCIPAL_KEY_DEFAULT_NAME "tde-global-catalog-key"
#define KEYRING_DEFAULT_NAME "default_global_tablespace_keyring"
#define KEYRING_DEFAULT_FILE_NAME "pg_tde_default_keyring_CHANGE_AND_REMOVE_IT"
#define DefaultKeyProvider GetKeyProviderByName(KEYRING_DEFAULT_NAME, \
GLOBAL_DATA_TDE_OID, GLOBALTABLESPACE_OID)
#ifndef FRONTEND
static void init_keys(void);
static void init_default_keyring(void);
static TDEPrincipalKey * create_principal_key(const char *key_name,
GenericKeyring * keyring, Oid dbOid,
Oid spcOid);
#endif /* !FRONTEND */
void
TDEInitGlobalKeys(void)
TDEInitGlobalKeys(const char *dir)
{
#ifndef FRONTEND
char db_map_path[MAXPGPATH] = {0};
pg_tde_set_db_file_paths(&GLOBAL_SPACE_RLOCATOR(XLOG_TDE_OID),
@ -54,40 +60,55 @@ TDEInitGlobalKeys(void)
init_keys();
}
else
#endif /* !FRONTEND */
{
RelKeyData *ikey;
if (dir != NULL)
pg_tde_set_globalspace_dir(dir);
ikey = pg_tde_get_key_from_file(&GLOBAL_SPACE_RLOCATOR(XLOG_TDE_OID));
/*
* Internal Key should be in the TopMemmoryContext because of SSL contexts. This
* context is being initialized by OpenSSL with the pointer to the encryption
* context which is valid only for the current backend. So new backends have to
* inherit a cached key with NULL SSL connext and any changes to it have to remain
* local ot the backend.
* (see https://github.com/Percona-Lab/pg_tde/pull/214#discussion_r1648998317)
*/
* Internal Key should be in the TopMemmoryContext because of SSL
* contexts. This context is being initialized by OpenSSL with the
* pointer to the encryption context which is valid only for the
* current backend. So new backends have to inherit a cached key with
* NULL SSL connext and any changes to it have to remain local ot the
* backend. (see
* https://github.com/Percona-Lab/pg_tde/pull/214#discussion_r1648998317)
*/
pg_tde_put_key_into_map(XLOG_TDE_OID, ikey);
}
}
#ifndef FRONTEND
static void
init_default_keyring(void)
{
if (GetAllKeyringProviders(GLOBAL_DATA_TDE_OID, GLOBALTABLESPACE_OID) == NIL)
{
char path[MAXPGPATH] = {0};
static KeyringProvideRecord provider =
{
.provider_name = KEYRING_DEFAULT_NAME,
.provider_type = FILE_KEY_PROVIDER,
.options =
"{"
"\"type\": \"file\","
" \"path\": \"pg_tde_default_keyring_CHANGE_AND_REMOVE_IT\"" /* TODO: not sure about
* the location */
"}"
};
if (getcwd(path, sizeof(path)) == NULL)
elog(WARNING, "unable to get current working dir");
/* TODO: not sure about the location. Currently it's in $PGDATA */
join_path_components(path, path, KEYRING_DEFAULT_FILE_NAME);
snprintf(provider.options, MAX_KEYRING_OPTION_LEN,
"{"
"\"type\": \"file\","
"\"path\": \"%s\""
"}", path
);
/*
* TODO: should we remove it automaticaly on
* pg_tde_rotate_principal_key() ?
@ -103,11 +124,11 @@ init_default_keyring(void)
/*
* Create and store global space keys (principal and internal) and cache the
* internal key.
*
* Since we always keep an Internal key in the memory for the global tablespace
*
* Since we always keep an Internal key in the memory for the global tablespace
* and read it from disk once, only during the server start, we need no cache for
* the principal key.
*
*
* This function has to be run during the cluster start only, so no locks needed.
*/
static void
@ -165,7 +186,7 @@ create_principal_key(const char *key_name, GenericKeyring * keyring,
principalKey->keyInfo.keyringId = keyring->key_id;
strncpy(principalKey->keyInfo.keyId.name, key_name, TDE_KEY_NAME_LEN);
snprintf(principalKey->keyInfo.keyId.versioned_name, TDE_KEY_NAME_LEN,
"%s_%d", principalKey->keyInfo.keyId.name, principalKey->keyInfo.keyId.version);
"%s_%d", principalKey->keyInfo.keyId.name, principalKey->keyInfo.keyId.version);
gettimeofday(&principalKey->keyInfo.creationTime, NULL);
keyInfo = KeyringGenerateNewKeyAndStore(keyring, principalKey->keyInfo.keyId.versioned_name, INTERNAL_KEY_LEN, false);
@ -181,4 +202,6 @@ create_principal_key(const char *key_name, GenericKeyring * keyring,
return principalKey;
}
#endif /* FRONTEND */
#endif /* PERCONA_EXT */

@ -10,7 +10,6 @@
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "funcapi.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/pg_tde_xlog.h"
@ -18,29 +17,27 @@
#include "catalog/tde_keyring.h"
#include "catalog/tde_principal_key.h"
#include "access/skey.h"
#include "access/relscan.h"
#include "access/relation.h"
#include "catalog/namespace.h"
#include "utils/lsyscache.h"
#include "access/heapam.h"
#include "utils/snapmgr.h"
#include "utils/fmgroids.h"
#include "common/pg_tde_utils.h"
#include "common/pg_tde_shmem.h"
#include "executor/spi.h"
#include "miscadmin.h"
#include "unistd.h"
#include "utils/builtins.h"
#include "pg_tde.h"
PG_FUNCTION_INFO_V1(pg_tde_add_key_provider_internal);
Datum pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS);
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"
#define PG_TDE_LIST_PROVIDERS_COLS 4
#ifndef FRONTEND
#include "access/heapam.h"
#include "common/pg_tde_shmem.h"
#include "funcapi.h"
#include "access/relscan.h"
#include "access/relation.h"
#include "catalog/namespace.h"
#include "executor/spi.h"
#else
#include "fe_utils/simple_list.h"
#include "pg_tde_fe.h"
#endif /* !FRONTEND */
typedef enum ProviderScanType
{
@ -50,13 +47,33 @@ typedef enum ProviderScanType
PROVIDER_SCAN_ALL
} ProviderScanType;
static List *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid);
#define PG_TDE_KEYRING_FILENAME "pg_tde_keyrings"
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 GenericKeyring *load_keyring_provider_from_record(KeyringProvideRecord *provider);
static char *get_keyring_infofile_path(char *resPath, Oid dbOid, Oid spcOid);
static bool fetch_next_key_provider(int fd, off_t* curr_pos, KeyringProvideRecord *provider);
#ifdef FRONTEND
static SimplePtrList *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid);
static void simple_list_free(SimplePtrList *list);
#else
static List *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid);
PG_FUNCTION_INFO_V1(pg_tde_add_key_provider_internal);
Datum pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(pg_tde_list_all_key_providers);
Datum pg_tde_list_all_key_providers(PG_FUNCTION_ARGS);
#define PG_TDE_LIST_PROVIDERS_COLS 4
static void key_provider_startup_cleanup(int tde_tbl_count, XLogExtensionInstall *ext_info, bool redo, void *arg);
static const char *get_keyring_provider_typename(ProviderType p_type);
static uint32 write_key_provider_info(KeyringProvideRecord *provider,
@ -148,22 +165,6 @@ get_keyring_provider_typename(ProviderType p_type)
return NULL;
}
static GenericKeyring *load_keyring_provider_from_record(KeyringProvideRecord *provider)
{
GenericKeyring *keyring = NULL;
keyring = load_keyring_provider_options(provider->provider_type, provider->options);
if (keyring)
{
keyring->key_id = provider->provider_id;
strncpy(keyring->provider_name, provider->provider_name, sizeof(keyring->provider_name));
keyring->type = provider->provider_type;
strncpy(keyring->options, provider->options, sizeof(keyring->options));
debug_print_kerying(keyring);
}
return keyring;
}
List *
GetAllKeyringProviders(Oid dbOid, Oid spcOid)
{
@ -190,140 +191,6 @@ GetKeyProviderByName(const char *provider_name, Oid dbOid, Oid spcOid)
return keyring;
}
GenericKeyring *
GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid)
{
GenericKeyring *keyring = NULL;
List *providers = scan_key_provider_file(PROVIDER_SCAN_BY_ID, &provider_id, dbOid, spcOid);
if (providers != NIL)
{
keyring = (GenericKeyring *)linitial(providers);
list_free(providers);
}
return keyring;
}
static GenericKeyring *
load_keyring_provider_options(ProviderType provider_type, char *keyring_options)
{
switch (provider_type)
{
case FILE_KEY_PROVIDER:
return (GenericKeyring *)load_file_keyring_provider_options(keyring_options);
break;
case VAULT_V2_KEY_PROVIDER:
return (GenericKeyring *)load_vaultV2_keyring_provider_options(keyring_options);
break;
default:
break;
}
return NULL;
}
static FileKeyring *
load_file_keyring_provider_options(char *keyring_options)
{
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)))
{
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;
}
return file_keyring;
}
static VaultV2Keyring *
load_vaultV2_keyring_provider_options(char *keyring_options)
{
VaultV2Keyring *vaultV2_keyring = palloc0(sizeof(VaultV2Keyring));
vaultV2_keyring->keyring.type = VAULT_V2_KEY_PROVIDER;
if (!ParseKeyringJSONOptions(VAULT_V2_KEY_PROVIDER, vaultV2_keyring,
keyring_options, strlen(keyring_options)))
{
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;
}
return vaultV2_keyring;
}
static void
debug_print_kerying(GenericKeyring *keyring)
{
int debug_level = DEBUG2;
elog(debug_level, "Keyring type: %d", keyring->type);
elog(debug_level, "Keyring name: %s", keyring->provider_name);
elog(debug_level, "Keyring id: %d", keyring->key_id);
switch (keyring->type)
{
case FILE_KEY_PROVIDER:
elog(debug_level, "File Keyring Path: %s", ((FileKeyring *)keyring)->file_name);
break;
case VAULT_V2_KEY_PROVIDER:
elog(debug_level, "Vault Keyring Token: %s", ((VaultV2Keyring *)keyring)->vault_token);
elog(debug_level, "Vault Keyring URL: %s", ((VaultV2Keyring *)keyring)->vault_url);
elog(debug_level, "Vault Keyring Mount Path: %s", ((VaultV2Keyring *)keyring)->vault_mount_path);
elog(debug_level, "Vault Keyring CA Path: %s", ((VaultV2Keyring *)keyring)->vault_ca_path);
break;
case UNKNOWN_KEY_PROVIDER:
elog(debug_level, "Unknown Keyring ");
break;
}
}
/*
* Fetch the next key provider from the file and update the curr_pos
*/
static bool
fetch_next_key_provider(int fd, off_t* curr_pos, KeyringProvideRecord *provider)
{
off_t bytes_read = 0;
Assert(provider != NULL);
Assert(fd >= 0);
bytes_read = pg_pread(fd, provider, sizeof(KeyringProvideRecord), *curr_pos);
*curr_pos += bytes_read;
if (bytes_read == 0)
return false;
if (bytes_read != sizeof(KeyringProvideRecord))
{
close(fd);
/* Corrupt file */
ereport(ERROR,
(errcode_for_file_access(),
errmsg("key provider info file is corrupted: %m"),
errdetail("invalid key provider record size %lld expected %lu", bytes_read, sizeof(KeyringProvideRecord) )));
}
return true;
}
static uint32
write_key_provider_info(KeyringProvideRecord *provider, Oid database_id,
@ -436,71 +303,6 @@ redo_key_provider_info(KeyringProviderXLRecord* xlrec)
return write_key_provider_info(&xlrec->provider, xlrec->database_id, xlrec->tablespace_id, xlrec->offset_in_file, true, false);
}
/*
* Scan the key provider info file and can also apply filter based on scanType
*/
static List *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid)
{
off_t curr_pos = 0;
int fd;
char kp_info_path[MAXPGPATH] = {0};
KeyringProvideRecord provider;
List *providers_list = NIL;
if (scanType != PROVIDER_SCAN_ALL)
Assert(scanKey != NULL);
get_keyring_infofile_path(kp_info_path, dbOid, spcOid);
LWLockAcquire(tde_provider_info_lock(), LW_SHARED);
fd = BasicOpenFile(kp_info_path, PG_BINARY);
if (fd < 0)
{
LWLockRelease(tde_provider_info_lock());
ereport(DEBUG2,
(errcode_for_file_access(),
errmsg("could not open tde file \"%s\": %m", kp_info_path)));
return NIL;
}
while (fetch_next_key_provider(fd, &curr_pos, &provider))
{
bool match = false;
ereport(DEBUG2,
(errmsg("read key provider ID=%d %s", provider.provider_id, provider.provider_name)));
if (scanType == PROVIDER_SCAN_BY_NAME)
{
if (strcasecmp(provider.provider_name, (char*)scanKey) == 0)
match = true;
}
else if (scanType == PROVIDER_SCAN_BY_ID)
{
if (provider.provider_id == *(int *)scanKey)
match = true;
}
else if (scanType == PROVIDER_SCAN_BY_TYPE)
{
if (provider.provider_type == *(ProviderType*)scanKey)
match = true;
}
else if (scanType == PROVIDER_SCAN_ALL)
match = true;
if (match)
{
GenericKeyring *keyring = load_keyring_provider_from_record(&provider);
if (keyring)
{
providers_list = lappend(providers_list, keyring);
}
}
}
close(fd);
LWLockRelease(tde_provider_info_lock());
return providers_list;
}
void
cleanup_key_provider_info(Oid databaseId, Oid tablespaceId)
{
@ -511,16 +313,6 @@ cleanup_key_provider_info(Oid databaseId, Oid tablespaceId)
PathNameDeleteTemporaryFile(kp_info_path, false);
}
static char*
get_keyring_infofile_path(char* resPath, Oid dbOid, Oid spcOid)
{
char *db_path = pg_tde_get_tde_file_dir(dbOid, spcOid);
Assert(db_path != NULL);
join_path_components(resPath, db_path, PG_TDE_KEYRING_FILENAME);
pfree(db_path);
return resPath;
}
Datum
pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS)
{
@ -599,3 +391,279 @@ pg_tde_list_all_key_providers(PG_FUNCTION_ARGS)
list_free_deep(all_providers);
return (Datum)0;
}
GenericKeyring *
GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid)
{
GenericKeyring *keyring = NULL;
List *providers = scan_key_provider_file(PROVIDER_SCAN_BY_ID, &provider_id, dbOid, spcOid);
if (providers != NIL)
{
keyring = (GenericKeyring *)linitial(providers);
list_free(providers);
}
return keyring;
}
#endif /* !FRONTEND */
#ifdef FRONTEND
GenericKeyring *
GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid)
{
GenericKeyring *keyring = NULL;
SimplePtrList *providers = scan_key_provider_file(PROVIDER_SCAN_BY_ID, &provider_id, dbOid, spcOid);
if (providers != NULL)
{
keyring = (GenericKeyring *) providers->head->ptr;
simple_list_free(providers);
}
return keyring;
}
static void
simple_list_free(SimplePtrList *list)
{
SimplePtrListCell *cell;
cell = list->head;
while (cell != NULL)
{
SimplePtrListCell *next;
next = cell->next;
pfree(cell);
cell = next;
}
}
#endif /* FRONTEND */
/*
* Scan the key provider info file and can also apply filter based on scanType
*/
#ifndef FRONTEND
static List *
#else
static SimplePtrList *
#endif
scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid)
{
off_t curr_pos = 0;
int fd;
char kp_info_path[MAXPGPATH] = {0};
KeyringProvideRecord provider;
#ifndef FRONTEND
List *providers_list = NIL;
#else
SimplePtrList *providers_list = NULL;
#endif
if (scanType != PROVIDER_SCAN_ALL)
Assert(scanKey != NULL);
get_keyring_infofile_path(kp_info_path, dbOid, spcOid);
LWLockAcquire(tde_provider_info_lock(), LW_SHARED);
fd = BasicOpenFile(kp_info_path, PG_BINARY);
if (fd < 0)
{
LWLockRelease(tde_provider_info_lock());
ereport(DEBUG2,
(errcode_for_file_access(),
errmsg("could not open tde file \"%s\": %m", kp_info_path)));
return providers_list;
}
while (fetch_next_key_provider(fd, &curr_pos, &provider))
{
bool match = false;
ereport(DEBUG2,
(errmsg("read key provider ID=%d %s", provider.provider_id, provider.provider_name)));
if (scanType == PROVIDER_SCAN_BY_NAME)
{
if (strcasecmp(provider.provider_name, (char*)scanKey) == 0)
match = true;
}
else if (scanType == PROVIDER_SCAN_BY_ID)
{
if (provider.provider_id == *(int *)scanKey)
match = true;
}
else if (scanType == PROVIDER_SCAN_BY_TYPE)
{
if (provider.provider_type == *(ProviderType*)scanKey)
match = true;
}
else if (scanType == PROVIDER_SCAN_ALL)
match = true;
if (match)
{
GenericKeyring *keyring = load_keyring_provider_from_record(&provider);
if (keyring)
{
#ifndef FRONTEND
providers_list = lappend(providers_list, keyring);
#else
if (providers_list == NULL)
providers_list = palloc(sizeof(providers_list));
simple_ptr_list_append(providers_list, keyring);
#endif
}
}
}
close(fd);
LWLockRelease(tde_provider_info_lock());
return providers_list;
}
static GenericKeyring *
load_keyring_provider_from_record(KeyringProvideRecord *provider)
{
GenericKeyring *keyring = NULL;
keyring = load_keyring_provider_options(provider->provider_type, provider->options);
if (keyring)
{
keyring->key_id = provider->provider_id;
strncpy(keyring->provider_name, provider->provider_name, sizeof(keyring->provider_name));
keyring->type = provider->provider_type;
strncpy(keyring->options, provider->options, sizeof(keyring->options));
debug_print_kerying(keyring);
}
return keyring;
}
static GenericKeyring *
load_keyring_provider_options(ProviderType provider_type, char *keyring_options)
{
switch (provider_type)
{
case FILE_KEY_PROVIDER:
return (GenericKeyring *)load_file_keyring_provider_options(keyring_options);
break;
case VAULT_V2_KEY_PROVIDER:
return (GenericKeyring *)load_vaultV2_keyring_provider_options(keyring_options);
break;
default:
break;
}
return NULL;
}
static FileKeyring *
load_file_keyring_provider_options(char *keyring_options)
{
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)))
{
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;
}
return file_keyring;
}
static VaultV2Keyring *
load_vaultV2_keyring_provider_options(char *keyring_options)
{
VaultV2Keyring *vaultV2_keyring = palloc0(sizeof(VaultV2Keyring));
vaultV2_keyring->keyring.type = VAULT_V2_KEY_PROVIDER;
if (!ParseKeyringJSONOptions(VAULT_V2_KEY_PROVIDER, vaultV2_keyring,
keyring_options, strlen(keyring_options)))
{
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;
}
return vaultV2_keyring;
}
static void
debug_print_kerying(GenericKeyring *keyring)
{
int debug_level = DEBUG2;
elog(debug_level, "Keyring type: %d", keyring->type);
elog(debug_level, "Keyring name: %s", keyring->provider_name);
elog(debug_level, "Keyring id: %d", keyring->key_id);
switch (keyring->type)
{
case FILE_KEY_PROVIDER:
elog(debug_level, "File Keyring Path: %s", ((FileKeyring *)keyring)->file_name);
break;
case VAULT_V2_KEY_PROVIDER:
elog(debug_level, "Vault Keyring Token: %s", ((VaultV2Keyring *)keyring)->vault_token);
elog(debug_level, "Vault Keyring URL: %s", ((VaultV2Keyring *)keyring)->vault_url);
elog(debug_level, "Vault Keyring Mount Path: %s", ((VaultV2Keyring *)keyring)->vault_mount_path);
elog(debug_level, "Vault Keyring CA Path: %s", ((VaultV2Keyring *)keyring)->vault_ca_path);
break;
case UNKNOWN_KEY_PROVIDER:
elog(debug_level, "Unknown Keyring ");
break;
}
}
static char*
get_keyring_infofile_path(char* resPath, Oid dbOid, Oid spcOid)
{
char *db_path = pg_tde_get_tde_file_dir(dbOid, spcOid);
Assert(db_path != NULL);
join_path_components(resPath, db_path, PG_TDE_KEYRING_FILENAME);
pfree(db_path);
return resPath;
}
/*
* Fetch the next key provider from the file and update the curr_pos
*/
static bool
fetch_next_key_provider(int fd, off_t* curr_pos, KeyringProvideRecord *provider)
{
off_t bytes_read = 0;
Assert(provider != NULL);
Assert(fd >= 0);
bytes_read = pg_pread(fd, provider, sizeof(KeyringProvideRecord), *curr_pos);
*curr_pos += bytes_read;
if (bytes_read == 0)
return false;
if (bytes_read != sizeof(KeyringProvideRecord))
{
close(fd);
/* Corrupt file */
ereport(ERROR,
(errcode_for_file_access(),
errmsg("key provider info file is corrupted: %m"),
errdetail("invalid key provider record size %ld expected %lu", bytes_read, sizeof(KeyringProvideRecord) )));
}
return true;
}

@ -23,6 +23,7 @@
*/
#include "postgres.h"
#include "common/file_perm.h"
#include "common/jsonapi.h"
#include "mb/pg_wchar.h"
#include "storage/fd.h"
@ -30,6 +31,10 @@
#include "catalog/tde_keyring.h"
#include "keyring/keyring_curl.h"
#ifdef FRONTEND
#include "pg_tde_fe.h"
#endif
#include <unistd.h>
#define MAX_CONFIG_FILE_DATA_LENGTH 1024

@ -13,8 +13,6 @@
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "catalog/tde_principal_key.h"
#include "common/pg_tde_shmem.h"
#include "storage/lwlock.h"
#include "storage/fd.h"
#include "utils/palloc.h"
#include "utils/memutils.h"
@ -22,14 +20,22 @@
#include "utils/timestamp.h"
#include "common/relpath.h"
#include "miscadmin.h"
#include "funcapi.h"
#include "utils/builtins.h"
#include "pg_tde.h"
#include "access/pg_tde_xlog.h"
#include <sys/time.h>
#include "access/pg_tde_tdemap.h"
#include "catalog/tde_global_space.h"
#ifndef FRONTEND
#include "common/pg_tde_shmem.h"
#include "funcapi.h"
#include "storage/lwlock.h"
#else
#include "pg_tde_fe.h"
#endif
#include <sys/time.h>
#ifndef FRONTEND
typedef struct TdePrincipalKeySharedState
{
@ -206,125 +212,6 @@ save_principal_key_info(TDEPrincipalKeyInfo *principal_key_info)
return pg_tde_save_principal_key(principal_key_info);
}
/*
* Public interface to get the principal key for the current database
* If the principal key is not present in the cache, it is loaded from
* the keyring and stored in the cache.
* When the principal key is not set for the database. The function returns
* throws an error.
*/
TDEPrincipalKey *
GetPrincipalKey(Oid dbOid, Oid spcOid)
{
GenericKeyring *keyring;
TDEPrincipalKey *principalKey = NULL;
TDEPrincipalKeyInfo *principalKeyInfo = NULL;
const keyInfo *keyInfo = NULL;
KeyringReturnCodes keyring_ret;
LWLock *lock_files = tde_lwlock_mk_files();
LWLock *lock_cache = tde_lwlock_mk_cache();
// TODO: This recursion counter is a dirty hack until the metadata is in the catalog
// As otherwise we would call GetPrincipalKey recursively and deadlock
static int recursion = 0;
if(recursion > 0)
{
return NULL;
}
recursion++;
/* We don't store global space key in cache */
if (spcOid != GLOBALTABLESPACE_OID)
{
LWLockAcquire(lock_cache, LW_SHARED);
principalKey = get_principal_key_from_cache(dbOid);
LWLockRelease(lock_cache);
}
if (principalKey)
{
recursion--;
return principalKey;
}
/*
* We should hold an exclusive lock here to ensure that a valid principal key, if found, is added
* to the cache without any interference.
*/
LWLockAcquire(lock_files, LW_SHARED);
LWLockAcquire(lock_cache, LW_EXCLUSIVE);
/* We don't store global space key in cache */
if (spcOid != GLOBALTABLESPACE_OID)
{
principalKey = get_principal_key_from_cache(dbOid);
}
if (principalKey)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return principalKey;
}
/* Principal key not present in cache. Load from the keyring */
principalKeyInfo = pg_tde_get_principal_key(dbOid, spcOid);
if (principalKeyInfo == NULL)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return NULL;
}
keyring = GetKeyProviderByID(principalKeyInfo->keyringId, dbOid, spcOid);
if (keyring == NULL)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return NULL;
}
keyInfo = KeyringGetKey(keyring, principalKeyInfo->keyId.versioned_name, false, &keyring_ret);
if (keyInfo == NULL)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return NULL;
}
principalKey = palloc(sizeof(TDEPrincipalKey));
memcpy(&principalKey->keyInfo, principalKeyInfo, sizeof(principalKey->keyInfo));
memcpy(principalKey->keyData, keyInfo->data.data, keyInfo->data.len);
principalKey->keyLength = keyInfo->data.len;
Assert(dbOid == principalKey->keyInfo.databaseId);
/* We don't store global space key in cache */
if (spcOid != GLOBALTABLESPACE_OID)
{
push_principal_key_to_cache(principalKey);
}
/* Release the exclusive locks here */
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
if (principalKeyInfo)
pfree(principalKeyInfo);
recursion--;
return principalKey;
}
/*
* SetPrincipalkey:
* We need to ensure that only one principal key is set for a database.
@ -855,3 +742,130 @@ pg_tde_get_key_info(PG_FUNCTION_ARGS, Oid dbOid, Oid spcOid)
PG_RETURN_DATUM(result);
}
#endif /* FRONTEND */
/*
* Public interface to get the principal key for the current database
* If the principal key is not present in the cache, it is loaded from
* the keyring and stored in the cache.
* When the principal key is not set for the database. The function returns
* throws an error.
*/
TDEPrincipalKey *
GetPrincipalKey(Oid dbOid, Oid spcOid)
{
GenericKeyring *keyring;
TDEPrincipalKey *principalKey = NULL;
TDEPrincipalKeyInfo *principalKeyInfo = NULL;
const keyInfo *keyInfo = NULL;
KeyringReturnCodes keyring_ret;
LWLock *lock_files = tde_lwlock_mk_files();
LWLock *lock_cache = tde_lwlock_mk_cache();
// TODO: This recursion counter is a dirty hack until the metadata is in the catalog
// As otherwise we would call GetPrincipalKey recursively and deadlock
static int recursion = 0;
if(recursion > 0)
{
return NULL;
}
recursion++;
#ifndef FRONTEND
/* We don't store global space key in cache */
if (spcOid != GLOBALTABLESPACE_OID)
{
LWLockAcquire(lock_cache, LW_SHARED);
principalKey = get_principal_key_from_cache(dbOid);
LWLockRelease(lock_cache);
}
if (principalKey)
{
recursion--;
return principalKey;
}
#endif
/*
* We should hold an exclusive lock here to ensure that a valid principal key, if found, is added
* to the cache without any interference.
*/
LWLockAcquire(lock_files, LW_SHARED);
LWLockAcquire(lock_cache, LW_EXCLUSIVE);
#ifndef FRONTEND
/* We don't store global space key in cache */
if (spcOid != GLOBALTABLESPACE_OID)
{
principalKey = get_principal_key_from_cache(dbOid);
}
if (principalKey)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return principalKey;
}
#endif
/* Principal key not present in cache. Load from the keyring */
principalKeyInfo = pg_tde_get_principal_key(dbOid, spcOid);
if (principalKeyInfo == NULL)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return NULL;
}
keyring = GetKeyProviderByID(principalKeyInfo->keyringId, dbOid, spcOid);
if (keyring == NULL)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return NULL;
}
keyInfo = KeyringGetKey(keyring, principalKeyInfo->keyId.versioned_name, false, &keyring_ret);
if (keyInfo == NULL)
{
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
recursion--;
return NULL;
}
principalKey = palloc(sizeof(TDEPrincipalKey));
memcpy(&principalKey->keyInfo, principalKeyInfo, sizeof(principalKey->keyInfo));
memcpy(principalKey->keyData, keyInfo->data.data, keyInfo->data.len);
principalKey->keyLength = keyInfo->data.len;
Assert(dbOid == principalKey->keyInfo.databaseId);
#ifndef FRONTEND
/* We don't store global space key in cache */
if (spcOid != GLOBALTABLESPACE_OID)
{
push_principal_key_to_cache(principalKey);
}
#endif
/* Release the exclusive locks here */
LWLockRelease(lock_cache);
LWLockRelease(lock_files);
if (principalKeyInfo)
pfree(principalKeyInfo);
recursion--;
return principalKey;
}

@ -10,13 +10,16 @@
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/pg_tablespace_d.h"
#include "utils/snapmgr.h"
#include "commands/defrem.h"
#include "common/pg_tde_utils.h"
#ifndef FRONTEND
#include "access/genam.h"
#include "access/heapam.h"
Oid
get_tde_basic_table_am_oid(void)
{
@ -79,6 +82,17 @@ get_tde_tables_count(void)
return count;
}
#endif /* !FRONTEND */
static char globalspace_dir[MAXPGPATH] = {0};
void
pg_tde_set_globalspace_dir(const char *dir)
{
Assert(dir != NULL);
strncpy(globalspace_dir, dir, sizeof(globalspace_dir));
}
/* returns the palloc'd string */
char *
pg_tde_get_tde_file_dir(Oid dbOid, Oid spcOid)
@ -87,6 +101,11 @@ pg_tde_get_tde_file_dir(Oid dbOid, Oid spcOid)
* expects it (`dbOid`) to be `0` if this is a global space.
*/
if (spcOid == GLOBALTABLESPACE_OID)
{
if (strlen(globalspace_dir) > 0)
return pstrdup(globalspace_dir);
return pstrdup("global");
}
return GetDatabasePath(dbOid, spcOid);
}

@ -163,6 +163,7 @@ pg_tde_crypt(const char* iv_prefix, uint32 start_offset, const char* data, uint3
}
}
#ifndef FRONTEND
/*
* pg_tde_crypt_tuple:
* Does the encryption/decryption of tuple data in place
@ -247,6 +248,8 @@ AesEncryptKey(const TDEPrincipalKey *principal_key, const RelFileLocator *rlocat
AesEncrypt(principal_key->keyData, iv, ((unsigned char*)&rel_key_data->internal_key), INTERNAL_KEY_LEN, ((unsigned char *)&(*p_enc_rel_key_data)->internal_key), (int *)enc_key_bytes);
}
#endif /* FRONTEND */
/*
* Provide a simple interface to decrypt a given key.
*
@ -264,11 +267,21 @@ void AesDecryptKey(const TDEPrincipalKey *principal_key, const RelFileLocator *r
memcpy(iv, &rlocator->spcOid, sizeof(Oid));
memcpy(iv + sizeof(Oid), &rlocator->dbOid, sizeof(Oid));
*p_rel_key_data = (RelKeyData *) MemoryContextAlloc(TopMemoryContext, sizeof(RelKeyData));
#ifndef FRONTEND
MemoryContext oldcontext;
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
#endif
*p_rel_key_data = (RelKeyData *) palloc(sizeof(RelKeyData));
#ifndef FRONTEND
MemoryContextSwitchTo(oldcontext);
#endif
/* Fill in the structure */
memcpy(*p_rel_key_data, enc_rel_key_data, sizeof(RelKeyData));
(*p_rel_key_data)->internal_key.ctx = NULL;
AesDecrypt(principal_key->keyData, iv, ((unsigned char*) &enc_rel_key_data->internal_key), INTERNAL_KEY_LEN, ((unsigned char *)&(*p_rel_key_data)->internal_key) , (int *)key_bytes);
}
}

@ -12,7 +12,6 @@
#include "access/xlog_internal.h"
#include "catalog/pg_tablespace_d.h"
#include "catalog/tde_principal_key.h"
#include "storage/fd.h"
#include "storage/relfilelocator.h"
typedef struct InternalKey

@ -9,12 +9,11 @@
#ifndef PG_TDE_XLOG_H
#define PG_TDE_XLOG_H
#ifndef FRONTEND
#include "postgres.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#ifdef PERCONA_EXT
#include "access/xlog_smgr.h"
#endif
/* TDE XLOG resource manager */
#define XLOG_TDE_ADD_RELATION_KEY 0x00
@ -38,28 +37,5 @@ static const RmgrData tdeheap_rmgr = {
.rm_identify = tdeheap_rmgr_identify
};
#ifdef PERCONA_EXT
/* XLog encryption staff */
extern Size TDEXLogEncryptBuffSize(void);
#define XLOG_TDE_ENC_BUFF_ALIGNED_SIZE add_size(TDEXLogEncryptBuffSize(), PG_IO_ALIGN_SIZE)
extern void TDEXLogShmemInit(void);
extern ssize_t tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset);
extern ssize_t tdeheap_xlog_seg_write(int fd, const void *buf, size_t count, off_t offset);
static const XLogSmgr tde_xlog_smgr = {
.seg_read = tdeheap_xlog_seg_read,
.seg_write = tdeheap_xlog_seg_write,
};
extern void TDEXLogSmgrInit(void);
extern void XLogInitGUC(void);
#endif
#endif /* !FRONTEND */
#endif /* PG_TDE_XLOG_H */

@ -0,0 +1,35 @@
/*-------------------------------------------------------------------------
*
* pg_tde_xlog_encrypt.h
* Encrypted XLog storage manager
*
*-------------------------------------------------------------------------
*/
#ifndef PG_TDE_XLOGENCRYPT_H
#define PG_TDE_XLOGENCRYPT_H
#include "postgres.h"
#ifdef PERCONA_EXT
#include "access/xlog_smgr.h"
extern Size TDEXLogEncryptBuffSize(void);
#define XLOG_TDE_ENC_BUFF_ALIGNED_SIZE add_size(TDEXLogEncryptBuffSize(), PG_IO_ALIGN_SIZE)
extern void TDEXLogShmemInit(void);
extern ssize_t tdeheap_xlog_seg_read(int fd, void *buf, size_t count, off_t offset);
extern ssize_t tdeheap_xlog_seg_write(int fd, const void *buf, size_t count, off_t offset);
static const XLogSmgr tde_xlog_smgr = {
.seg_read = tdeheap_xlog_seg_read,
.seg_write = tdeheap_xlog_seg_write,
};
extern void TDEXLogSmgrInit(void);
extern void XLogInitGUC(void);
#endif /* PERCONA_EXT */
#endif /* PG_TDE_XLOGENCRYPT_H */

@ -0,0 +1,29 @@
/*-------------------------------------------------------------------------
*
* pg_tde_xlog_encrypt_fe.h
* Frontened definitions for encrypted XLog storage manager
*
*-------------------------------------------------------------------------
*/
#ifndef PG_TDE_XLOGENCRYPT_FE_H
#define PG_TDE_XLOGENCRYPT_FE_H
#ifdef PERCONA_EXT
#include "access/pg_tde_xlog_encrypt.h"
#include "catalog/tde_global_space.h"
#include "encryption/enc_aes.h"
#include "keyring/keyring_file.h"
#include "keyring/keyring_vault.h"
/* Frontend has to call it needs to read an encrypted XLog */
#define TDE_XLOG_INIT(kring_dir) \
AesInit(); \
InstallFileKeyring(); \
InstallVaultV2Keyring(); \
TDEInitGlobalKeys(kring_dir); \
TDEXLogSmgrInit()
#endif /* PERCONA_EXT */
#endif /* PG_TDE_XLOGENCRYPT_FE_H */

@ -21,6 +21,7 @@
* We take Oids of the sql operators, so there is no overlap with the "real"
* catalog objects possible.
*/
#define GLOBAL_DATA_TDE_OID InvalidOid
#define XLOG_TDE_OID 608
#define GLOBAL_DATA_TDE_OID InvalidOid
@ -31,6 +32,6 @@
_obj_oid \
}
extern void TDEInitGlobalKeys(void);
extern void TDEInitGlobalKeys(const char *dir);
#endif /* TDE_GLOBAL_CATALOG_H */

@ -15,7 +15,9 @@
#include "catalog/tde_keyring.h"
#include "keyring/keyring_api.h"
#include "nodes/pg_list.h"
#ifndef FRONTEND
#include "storage/lwlock.h"
#endif
#define DEFAULT_PRINCIPAL_KEY_VERSION 1
#define PRINCIPAL_KEY_NAME_LEN TDE_KEY_NAME_LEN
@ -57,8 +59,14 @@ typedef struct XLogPrincipalKeyRotate
extern void InitializePrincipalKeyInfo(void);
extern void cleanup_principal_key_info(Oid databaseId, Oid tablespaceId);
#ifndef FRONTEND
extern LWLock *tde_lwlock_mk_files(void);
extern LWLock *tde_lwlock_mk_cache(void);
#else
#define tde_lwlock_mk_files() NULL
#define tde_lwlock_mk_cache() NULL
#endif
extern bool save_principal_key_info(TDEPrincipalKeyInfo *principalKeyInfo);

@ -9,12 +9,16 @@
#define PG_TDE_UTILS_H
#include "postgres.h"
#ifndef FRONTEND
#include "nodes/pg_list.h"
extern Oid get_tde_basic_table_am_oid(void);
extern Oid get_tde_table_am_oid(void);
extern List *get_all_tde_tables(void);
extern int get_tde_tables_count(void);
#endif /* !FRONTEND */
extern char *pg_tde_get_tde_file_dir(Oid dbOid, Oid spcOid);
extern void pg_tde_set_globalspace_dir(const char *dir);
#endif /*PG_TDE_UTILS_H*/

@ -1,4 +0,0 @@
#pragma once
void keyringInitialize(void);

@ -1,18 +0,0 @@
#ifndef KEYRING_CONFIG_H
#define KEYRING_CONFIG_H
#include "postgres.h"
enum KeyringProvider
{
PROVIDER_UNKNOWN,
PROVIDER_FILE,
PROVIDER_VAULT_V2,
} ;
extern enum KeyringProvider keyringProvider;
void keyringRegisterVariables(void);
#endif // KEYRING_CONFIG_H

@ -0,0 +1,86 @@
/*-------------------------------------------------------------------------
*
* pg_tde_fe.h
* TDE redefinitions for frontend included code
*
* src/include/pg_tde_fe.h
*
*-------------------------------------------------------------------------
*/
#ifndef PG_TDE_EREPORT_H
#define PG_TDE_EREPORT_H
#ifdef FRONTEND
#include "postgres_fe.h"
#include "utils/elog.h"
#include "common/logging.h"
#include "common/file_perm.h"
#pragma GCC diagnostic ignored "-Wunused-macros"
#pragma GCC diagnostic ignored "-Wunused-value"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wextra"
/*
* Errors handling
* ----------------------------------------
*/
#define tde_fe_errlog(_type, ...) \
({ \
if (tde_fe_error_level >= ERROR) \
pg_log_error##_type(__VA_ARGS__); \
else if (tde_fe_error_level >= WARNING) \
pg_log_warning##_type(__VA_ARGS__); \
else if (tde_fe_error_level >= LOG) \
pg_log_info##_type(__VA_ARGS__); \
else \
pg_log_debug##_type(__VA_ARGS__); \
})
#define errmsg(...) tde_fe_errlog(, __VA_ARGS__)
#define errhint(...) tde_fe_errlog(_hint, __VA_ARGS__)
#define errdetail(...) tde_fe_errlog(_detail, __VA_ARGS__)
#define errcode_for_file_access() NULL
#define errcode(e) NULL
#define tde_error_handle_exit(elevel) \
do { \
if (elevel >= PANIC) \
pg_unreachable(); \
else if (elevel >= ERROR) \
exit(1); \
} while(0)
#define elog(elevel, fmt, ...) \
do { \
tde_fe_error_level = elevel; \
errmsg(fmt, ##__VA_ARGS__); \
tde_error_handle_exit(elevel); \
} while(0)
#define ereport(elevel,...) \
do { \
tde_fe_error_level = elevel; \
__VA_ARGS__; \
tde_error_handle_exit(elevel); \
} while(0)
static int tde_fe_error_level = 0;
/*
* -------------
*/
#define LWLockAcquire(lock, mode) NULL
#define LWLockRelease(lock_files) NULL
#define LWLock void
#define BasicOpenFile(fileName, fileFlags) open(fileName, fileFlags, PG_FILE_MODE_OWNER)
#define pg_fsync(fd) fsync(fd)
#endif /* FRONTEND */
#endif /* PG_TDE_EREPORT_H */

@ -1,10 +0,0 @@
#include "keyring/keyring.h"
#include "keyring/keyring_config.h"
#include "keyring/keyring_api.h"
void keyringInitialize(void)
{
keyringRegisterVariables();
keyringInitializeCache();
}

@ -2,13 +2,16 @@
#include "keyring/keyring_api.h"
#include "keyring/keyring_file.h"
#include "keyring/keyring_vault.h"
#include "keyring/keyring_config.h"
#include "postgres.h"
#include "access/xlog.h"
#include "storage/shmem.h"
#include "nodes/pg_list.h"
#include "utils/memutils.h"
#ifdef FRONTEND
#include "fe_utils/simple_list.h"
#include "pg_tde_fe.h"
#endif
#include <assert.h>
#include <openssl/rand.h>
@ -19,9 +22,14 @@ typedef struct KeyProviders
ProviderType type;
} KeyProviders;
#ifndef FRONTEND
List *registeredKeyProviders = NIL;
#else
SimplePtrList registeredKeyProviders = {NULL, NULL};
#endif
static KeyProviders *find_key_provider(ProviderType type);
#ifndef FRONTEND
static KeyProviders *
find_key_provider(ProviderType type)
{
@ -36,9 +44,25 @@ find_key_provider(ProviderType type)
}
return NULL;
}
#else
static KeyProviders *
find_key_provider(ProviderType type)
{
SimplePtrListCell *lc;
for (lc = registeredKeyProviders.head; lc; lc = lc->next)
{
KeyProviders *kp = (KeyProviders *) lc->ptr;
if (kp->type == type)
{
return kp;
}
}
return NULL;
}
#endif /* !FRONTEND */
bool RegisterKeyProvider(const TDEKeyringRoutine *routine, ProviderType type)
{
MemoryContext oldcontext;
KeyProviders *kp;
Assert(routine != NULL);
@ -52,12 +76,21 @@ bool RegisterKeyProvider(const TDEKeyringRoutine *routine, ProviderType type)
(errmsg("Key provider of type %d already registered", type)));
return false;
}
#ifndef FRONTEND
MemoryContext oldcontext;
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
#endif
kp = palloc(sizeof(KeyProviders));
kp->routine = (TDEKeyringRoutine *)routine;
kp->type = type;
#ifndef FRONTEND
registeredKeyProviders = lappend(registeredKeyProviders, kp);
MemoryContextSwitchTo(oldcontext);
#else
simple_ptr_list_append(&registeredKeyProviders, kp);
#endif
return true;
}

@ -1,17 +0,0 @@
#include "keyring/keyring_config.h"
#include "keyring/keyring_file.h"
#include "keyring/keyring_vault.h"
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include "utils/guc.h"
enum KeyringProvider keyringProvider = PROVIDER_UNKNOWN;
void keyringRegisterVariables(void)
{
// nop for now
}

@ -9,8 +9,9 @@
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "keyring/keyring_curl.h"
#include "keyring/keyring_config.h"
#include "pg_tde_defines.h"
CURL* keyringCurl = NULL;

@ -13,11 +13,16 @@
#include "postgres.h"
#include "keyring/keyring_file.h"
#include "keyring/keyring_config.h"
#include "catalog/tde_keyring.h"
#include "common/file_perm.h"
#include "keyring/keyring_api.h"
#include "storage/fd.h"
#include "utils/wait_event.h"
#ifdef FRONTEND
#include "pg_tde_fe.h"
#endif
#include <stdio.h>
#include <unistd.h>
@ -131,6 +136,7 @@ set_key_by_name(GenericKeyring* keyring, keyInfo *key, bool throw_error)
file_keyring->file_name)));
return KEYRING_CODE_RESOURCE_NOT_ACCESSABLE;
}
if (pg_fsync(fd) != 0)
{
close(fd);

@ -12,7 +12,6 @@
#include "postgres.h"
#include "keyring/keyring_vault.h"
#include "keyring/keyring_config.h"
#include "keyring/keyring_curl.h"
#include "keyring/keyring_api.h"
#include "pg_tde_defines.h"
@ -26,6 +25,10 @@
#include "common/base64.h"
#ifdef FRONTEND
#include "pg_tde_fe.h"
#endif
/*
* JSON parser state
*/

@ -20,11 +20,11 @@
#include "storage/shmem.h"
#include "access/pg_tde_ddl.h"
#include "access/pg_tde_xlog.h"
#include "access/pg_tde_xlog_encrypt.h"
#include "encryption/enc_aes.h"
#include "access/pg_tde_tdemap.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "keyring/keyring_config.h"
#include "keyring/keyring_api.h"
#include "common/pg_tde_shmem.h"
#include "common/pg_tde_utils.h"
@ -87,7 +87,7 @@ tde_shmem_startup(void)
AesInit();
#ifdef PERCONA_EXT
TDEInitGlobalKeys();
TDEInitGlobalKeys(NULL);
TDEXLogShmemInit();
TDEXLogSmgrInit();
@ -102,7 +102,6 @@ _PG_init(void)
elog(WARNING, "pg_tde can only be loaded at server startup. Restart required.");
}
keyringRegisterVariables();
InitializePrincipalKeyInfo();
InitializeKeyProviderInfo();
#ifdef PERCONA_EXT

Loading…
Cancel
Save