diff options
Diffstat (limited to 'src/backend')
22 files changed, 8 insertions, 846 deletions
diff --git a/src/backend/Makefile b/src/backend/Makefile index 3a64affd508..9706a958488 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -21,7 +21,7 @@ SUBDIRS = access bootstrap catalog parser commands executor foreign lib libpq \ main nodes optimizer partitioning port postmaster \ regex replication rewrite \ statistics storage tcop tsearch utils $(top_builddir)/src/timezone \ - jit crypto + jit include $(srcdir)/common.mk @@ -212,12 +212,6 @@ endif $(INSTALL_DATA) $(srcdir)/libpq/pg_hba.conf.sample '$(DESTDIR)$(datadir)/pg_hba.conf.sample' $(INSTALL_DATA) $(srcdir)/libpq/pg_ident.conf.sample '$(DESTDIR)$(datadir)/pg_ident.conf.sample' $(INSTALL_DATA) $(srcdir)/utils/misc/postgresql.conf.sample '$(DESTDIR)$(datadir)/postgresql.conf.sample' - $(INSTALL_DATA) $(srcdir)/crypto/ckey_aws.sh.sample '$(DESTDIR)$(datadir)/auth_commands/ckey_aws.sh.sample' - $(INSTALL_DATA) $(srcdir)/crypto/ckey_direct.sh.sample '$(DESTDIR)$(datadir)/auth_commands/ckey_direct.sh.sample' - $(INSTALL_DATA) $(srcdir)/crypto/ckey_passphrase.sh.sample '$(DESTDIR)$(datadir)/auth_commands/ckey_passphrase.sh.sample' - $(INSTALL_DATA) $(srcdir)/crypto/ckey_piv_nopin.sh.sample '$(DESTDIR)$(datadir)/auth_commands/ckey_piv_nopin.sh.sample' - $(INSTALL_DATA) $(srcdir)/crypto/ckey_piv_pin.sh.sample '$(DESTDIR)$(datadir)/auth_commands/ckey_piv_pin.sh.sample' - $(INSTALL_DATA) $(srcdir)/crypto/ssl_passphrase.sh.sample '$(DESTDIR)$(datadir)/auth_commands/ssl_passphrase.sh.sample' ifeq ($(with_llvm), yes) install-bin: install-postgres-bitcode @@ -243,7 +237,6 @@ endif installdirs: $(MKDIR_P) '$(DESTDIR)$(bindir)' '$(DESTDIR)$(datadir)' - $(MKDIR_P) '$(DESTDIR)$(datadir)' '$(DESTDIR)$(datadir)/auth_commands' ifeq ($(PORTNAME), cygwin) ifeq ($(MAKE_DLL), true) $(MKDIR_P) '$(DESTDIR)$(libdir)' @@ -283,13 +276,7 @@ endif $(MAKE) -C utils uninstall-data rm -f '$(DESTDIR)$(datadir)/pg_hba.conf.sample' \ '$(DESTDIR)$(datadir)/pg_ident.conf.sample' \ - '$(DESTDIR)$(datadir)/postgresql.conf.sample' \ - '$(DESTDIR)$(datadir)/auth_commands/ckey_aws.sh.sample' \ - '$(DESTDIR)$(datadir)/auth_commands/ckey_direct.sh.sample' \ - '$(DESTDIR)$(datadir)/auth_commands/ckey_passphrase.sh.sample' \ - '$(DESTDIR)$(datadir)/auth_commands/ckey_piv_nopin.sh.sample' \ - '$(DESTDIR)$(datadir)/auth_commands/ckey_piv_pin.sh.sample' \ - '$(DESTDIR)$(datadir)/auth_commands/ssl_passphrase.sh.sample' + '$(DESTDIR)$(datadir)/postgresql.conf.sample' ifeq ($(with_llvm), yes) $(call uninstall_llvm_module,postgres) endif diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 48ca46a941c..9867e1b4039 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -44,13 +44,11 @@ #include "commands/tablespace.h" #include "common/controldata_utils.h" #include "executor/instrument.h" -#include "crypto/kmgr.h" #include "miscadmin.h" #include "pg_trace.h" #include "pgstat.h" #include "port/atomics.h" #include "postmaster/bgwriter.h" -#include "postmaster/postmaster.h" #include "postmaster/startup.h" #include "postmaster/walwriter.h" #include "replication/basebackup.h" @@ -83,7 +81,6 @@ #include "utils/timestamp.h" extern uint32 bootstrap_data_checksum_version; -extern int bootstrap_file_encryption_keylen; /* Unsupported old recovery command file names (relative to $PGDATA) */ #define RECOVERY_COMMAND_FILE "recovery.conf" @@ -4621,7 +4618,6 @@ InitControlFile(uint64 sysidentifier) ControlFile->wal_log_hints = wal_log_hints; ControlFile->track_commit_timestamp = track_commit_timestamp; ControlFile->data_checksum_version = bootstrap_data_checksum_version; - ControlFile->file_encryption_keylen = bootstrap_file_encryption_keylen; } static void @@ -4721,7 +4717,6 @@ ReadControlFile(void) pg_crc32c crc; int fd; static char wal_segsz_str[20]; - static char file_encryption_keylen_str[20]; int r; /* @@ -4910,12 +4905,6 @@ ReadControlFile(void) /* Make the initdb settings visible as GUC variables, too */ SetConfigOption("data_checksums", DataChecksumsEnabled() ? "yes" : "no", PGC_INTERNAL, PGC_S_OVERRIDE); - - Assert(ControlFile != NULL); - snprintf(file_encryption_keylen_str, sizeof(file_encryption_keylen_str), "%d", - ControlFile->file_encryption_keylen); - SetConfigOption("file_encryption_keylen", file_encryption_keylen_str, PGC_INTERNAL, - PGC_S_OVERRIDE); } /* @@ -5365,16 +5354,6 @@ BootStrapXLOG(void) /* some additional ControlFile fields are set in WriteControlFile() */ WriteControlFile(); - /* Enable file encryption if required */ - if (ControlFile->file_encryption_keylen > 0) - BootStrapKmgr(); - - if (terminal_fd != -1) - { - close(terminal_fd); - terminal_fd = -1; - } - /* Bootstrap the commit log, too */ BootStrapCLOG(); BootStrapCommitTs(); diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index bf93135a483..a7ed93fdc14 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -28,14 +28,12 @@ #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/link-canary.h" -#include "crypto/kmgr.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "pg_getopt.h" #include "pgstat.h" #include "postmaster/bgwriter.h" -#include "postmaster/postmaster.h" #include "postmaster/startup.h" #include "postmaster/walwriter.h" #include "replication/walreceiver.h" @@ -53,8 +51,6 @@ #include "utils/relmapper.h" uint32 bootstrap_data_checksum_version = 0; /* No checksum */ -int bootstrap_file_encryption_keylen = 0; /* disabled */ -char *bootstrap_old_key_datadir = NULL; /* disabled */ static void CheckerModeMain(void); @@ -228,7 +224,7 @@ AuxiliaryProcessMain(int argc, char *argv[]) /* If no -x argument, we are a CheckerProcess */ MyAuxProcType = CheckerProcess; - while ((flag = getopt(argc, argv, "B:c:d:D:FkK:r:R:u:x:X:-:")) != -1) + while ((flag = getopt(argc, argv, "B:c:d:D:Fkr:x:X:-:")) != -1) { switch (flag) { @@ -257,18 +253,9 @@ AuxiliaryProcessMain(int argc, char *argv[]) case 'k': bootstrap_data_checksum_version = PG_DATA_CHECKSUM_VERSION; break; - case 'K': - bootstrap_file_encryption_keylen = atoi(optarg); - break; - case 'u': - bootstrap_old_key_datadir = pstrdup(optarg); - break; case 'r': strlcpy(OutputFileName, optarg, MAXPGPATH); break; - case 'R': - terminal_fd = atoi(optarg); - break; case 'x': MyAuxProcType = atoi(optarg); break; @@ -325,12 +312,6 @@ AuxiliaryProcessMain(int argc, char *argv[]) proc_exit(1); } - if (bootstrap_file_encryption_keylen != 0 && - bootstrap_file_encryption_keylen != 128 && - bootstrap_file_encryption_keylen != 192 && - bootstrap_file_encryption_keylen != 256) - elog(PANIC, "unrecognized file encryption length: %d", bootstrap_file_encryption_keylen); - switch (MyAuxProcType) { case StartupProcess: diff --git a/src/backend/crypto/Makefile b/src/backend/crypto/Makefile deleted file mode 100644 index c27362029d8..00000000000 --- a/src/backend/crypto/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile -# Makefile for src/backend/crypto -# -# IDENTIFICATION -# src/backend/crypto/Makefile -# -#------------------------------------------------------------------------- - -subdir = src/backend/crypto -top_builddir = ../../.. -include $(top_builddir)/src/Makefile.global - -OBJS = \ - kmgr.o - -include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/crypto/ckey_aws.sh.sample b/src/backend/crypto/ckey_aws.sh.sample deleted file mode 100755 index 0341621c2e5..00000000000 --- a/src/backend/crypto/ckey_aws.sh.sample +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh - -# This uses the AWS Secrets Manager using the AWS CLI and OpenSSL. - -[ "$#" -ne 1 ] && echo "cluster_key_command usage: $0 \"%d\"" 1>&2 && exit 1 -# No need for %R or -R since we are not prompting - -DIR="$1" -[ ! -e "$DIR" ] && echo "$DIR does not exist" 1>&2 && exit 1 -[ ! -d "$DIR" ] && echo "$DIR is not a directory" 1>&2 && exit 1 - -# File containing the id of the AWS secret -AWS_ID_FILE="$DIR/aws-secret.id" - - -# ---------------------------------------------------------------------- - - -# Create an AWS Secrets Manager secret? -if [ ! -e "$AWS_ID_FILE" ] -then # The 'postgres' operating system user must have permission to - # access the AWS CLI - - # The epoch-time/directory/hostname combination is unique - HASH=$(echo -n "$(date '+%s')$DIR$(hostname)" | sha1sum | cut -d' ' -f1) - AWS_SECRET_ID="Postgres-cluster-key-$HASH" - - # Use stdin to avoid passing the secret on the command line - openssl rand -hex 32 | - aws secretsmanager create-secret \ - --name "$AWS_SECRET_ID" \ - --description 'Used for Postgres cluster file encryption' \ - --secret-string 'file:///dev/stdin' \ - --output text > /dev/null - if [ "$?" -ne 0 ] - then echo 'cluster key generation failed' 1>&2 - exit 1 - fi - - echo "$AWS_SECRET_ID" > "$AWS_ID_FILE" -fi - -if ! aws secretsmanager get-secret-value \ - --secret-id "$(cat "$AWS_ID_FILE")" \ - --output text -then echo 'cluster key retrieval failed' 1>&2 - exit 1 -fi | awk -F'\t' 'NR == 1 {print $4}' - -exit 0 diff --git a/src/backend/crypto/ckey_direct.sh.sample b/src/backend/crypto/ckey_direct.sh.sample deleted file mode 100755 index 1c41d53acc1..00000000000 --- a/src/backend/crypto/ckey_direct.sh.sample +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -# This uses a key supplied by the user -# If OpenSSL is installed, you can generate a pseudo-random key by running: -# openssl rand -hex 32 -# To get a true random key, run: -# wget -q -O - 'https://www.random.org/cgi-bin/randbyte?nbytes=32&format=h' | tr -d ' \n'; echo - -[ "$#" -lt 1 ] && echo "cluster_key_command usage: $0 %R [%p]" 1>&2 && exit 1 -# Supports environment variable PROMPT - -FD="$1" -[ ! -t "$FD" ] && echo "file descriptor $FD does not refer to a terminal" 1>&2 && exit 1 - -[ "$2" ] && PROMPT="$2" - - -# ---------------------------------------------------------------------- - -[ ! "$PROMPT" ] && PROMPT='Enter cluster key as 64 hexadecimal characters: ' - -stty -echo <&"$FD" - -echo 1>&"$FD" -echo -n "$PROMPT" 1>&"$FD" -read KEY <&"$FD" - -stty echo <&"$FD" - -if [ "$(expr "$KEY" : '[0-9a-fA-F]*$')" -ne 64 ] -then echo 'invalid; must be 64 hexadecimal characters' 1>&2 - exit 1 -fi - -echo "$KEY" - -exit 0 diff --git a/src/backend/crypto/ckey_passphrase.sh.sample b/src/backend/crypto/ckey_passphrase.sh.sample deleted file mode 100755 index 1098e99e549..00000000000 --- a/src/backend/crypto/ckey_passphrase.sh.sample +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -# This uses a passphrase supplied by the user. - -[ "$#" -lt 1 ] && echo "cluster_key_command usage: $0 %R [\"%p\"]" 1>&2 && exit 1 - -FD="$1" -[ ! -t "$FD" ] && echo "file descriptor $FD does not refer to a terminal" 1>&2 && exit 1 -# Supports environment variable PROMPT - -[ "$2" ] && PROMPT="$2" - - -# ---------------------------------------------------------------------- - -[ ! "$PROMPT" ] && PROMPT='Enter cluster passphrase: ' - -stty -echo <&"$FD" - -echo 1>&"$FD" -echo -n "$PROMPT" 1>&"$FD" -read PASS <&"$FD" - -stty echo <&"$FD" - -if [ ! "$PASS" ] -then echo 'invalid: empty passphrase' 1>&2 - exit 1 -fi - -echo "$PASS" | sha256sum | cut -d' ' -f1 - -exit 0 diff --git a/src/backend/crypto/ckey_piv_nopin.sh.sample b/src/backend/crypto/ckey_piv_nopin.sh.sample deleted file mode 100755 index ac7dc941ee6..00000000000 --- a/src/backend/crypto/ckey_piv_nopin.sh.sample +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh - -# This uses the public/private keys on a PIV device, like a CAC or Yubikey. -# It uses a PIN stored in a file. -# It uses OpenSSL with PKCS11 enabled via OpenSC. - -[ "$#" -ne 1 ] && echo "cluster_key_command usage: $0 \"%d\"" 1>&2 && exit 1 -# Supports environment variable PIV_PIN_FILE -# No need for %R or -R since we are not prompting for a PIN - -DIR="$1" -[ ! -e "$DIR" ] && echo "$DIR does not exist" 1>&2 && exit 1 -[ ! -d "$DIR" ] && echo "$DIR is not a directory" 1>&2 && exit 1 - -# Set these here or pass in as environment variables. -# File that stores the PIN to unlock the PIV -#PIV_PIN_FILE='' -# PIV slot 3 is the "Key Management" slot, so we use '0:3' -PIV_SLOT='0:3' - -# File containing the cluster key encrypted with the PIV_SLOT's public key -KEY_FILE="$DIR/pivpass.key" - - -# ---------------------------------------------------------------------- - -[ ! "$PIV_PIN_FILE" ] && echo 'PIV_PIN_FILE undefined' 1>&2 && exit 1 -[ ! -e "$PIV_PIN_FILE" ] && echo "$PIV_PIN_FILE does not exist" 1>&2 && exit 1 -[ -d "$PIV_PIN_FILE" ] && echo "$PIV_PIN_FILE is a directory" 1>&2 && exit 1 - -[ ! "$KEY_FILE" ] && echo 'KEY_FILE undefined' 1>&2 && exit 1 -[ -d "$KEY_FILE" ] && echo "$KEY_FILE is a directory" 1>&2 && exit 1 - -# Create a cluster key encrypted with the PIV_SLOT's public key? -if [ ! -e "$KEY_FILE" ] -then # The 'postgres' operating system user must have permission to - # access the PIV device. - - openssl rand -hex 32 | - if ! openssl rsautl -engine pkcs11 -keyform engine -encrypt \ - -inkey "$PIV_SLOT" -passin file:"$PIV_PIN_FILE" -out "$KEY_FILE" - then echo 'cluster key generation failed' 1>&2 - exit 1 - fi - - # Warn the user to save the cluster key in a safe place - cat 1>&2 <<END - -WARNING: The PIV device can be locked and require a reset if too many PIN -attempts fail. It is recommended to run this command manually and save -the cluster key in a secure location for possible recovery. -END - -fi - -# Decrypt the cluster key encrypted with the PIV_SLOT's public key -if ! openssl rsautl -engine pkcs11 -keyform engine -decrypt \ - -inkey "$PIV_SLOT" -passin file:"$PIV_PIN_FILE" -in "$KEY_FILE" -then echo 'cluster key decryption failed' 1>&2 - exit 1 -fi - -exit 0 diff --git a/src/backend/crypto/ckey_piv_pin.sh.sample b/src/backend/crypto/ckey_piv_pin.sh.sample deleted file mode 100755 index e6310087ffd..00000000000 --- a/src/backend/crypto/ckey_piv_pin.sh.sample +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh - -# This uses the public/private keys on a PIV device, like a CAC or Yubikey. -# It requires a user-entered PIN. -# It uses OpenSSL with PKCS11 enabled via OpenSC. - -[ "$#" -lt 2 ] && echo "cluster_key_command usage: $0 \"%d\" %R [\"%p\"]" 1>&2 && exit 1 -# Supports environment variable PROMPT - -DIR="$1" -[ ! -e "$DIR" ] && echo "$DIR does not exist" 1>&2 && exit 1 -[ ! -d "$DIR" ] && echo "$DIR is not a directory" 1>&2 && exit 1 - -FD="$2" -[ ! -t "$FD" ] && echo "file descriptor $FD does not refer to a terminal" 1>&2 && exit 1 - -[ "$3" ] && PROMPT="$3" - -# PIV slot 3 is the "Key Management" slot, so we use '0:3' -PIV_SLOT='0:3' - -# File containing the cluster key encrypted with the PIV_SLOT's public key -KEY_FILE="$DIR/pivpass.key" - - -# ---------------------------------------------------------------------- - -[ ! "$PROMPT" ] && PROMPT='Enter PIV PIN: ' - -stty -echo <&"$FD" - -# Create a cluster key encrypted with the PIV_SLOT's public key? -if [ ! -e "$KEY_FILE" ] -then echo 1>&"$FD" - echo -n "$PROMPT" 1>&"$FD" - - # The 'postgres' operating system user must have permission to - # access the PIV device. - - openssl rand -hex 32 | - # 'engine "pkcs11" set.' message confuses prompting - if ! openssl rsautl -engine pkcs11 -keyform engine -encrypt \ - -inkey "$PIV_SLOT" -passin fd:"$FD" -out "$KEY_FILE" 2>&1 - then stty echo <&"$FD" - echo 'cluster key generation failed' 1>&2 - exit 1 - fi | grep -v 'engine "pkcs11" set\.' - - echo 1>&"$FD" - - # Warn the user to save the cluster key in a safe place - cat 1>&"$FD" <<END - -WARNING: The PIV can be locked and require a reset if too many PIN -attempts fail. It is recommended to run this command manually and save -the cluster key in a secure location for possible recovery. -END - -fi - -echo 1>&"$FD" -echo -n "$PROMPT" 1>&"$FD" - -# Decrypt the cluster key encrypted with the PIV_SLOT's public key -if ! openssl rsautl -engine pkcs11 -keyform engine -decrypt \ - -inkey "$PIV_SLOT" -passin fd:"$FD" -in "$KEY_FILE" 2>&1 -then stty echo <&"$FD" - echo 'cluster key retrieval failed' 1>&2 - exit 1 -fi | grep -v 'engine "pkcs11" set\.' - -echo 1>&"$FD" - -stty echo <&"$FD" - -exit 0 diff --git a/src/backend/crypto/kmgr.c b/src/backend/crypto/kmgr.c deleted file mode 100644 index 4e701e02756..00000000000 --- a/src/backend/crypto/kmgr.c +++ /dev/null @@ -1,372 +0,0 @@ -/*------------------------------------------------------------------------- - * - * kmgr.c - * Cluster file encryption routines - * - * Cluster file encryption is enabled if user requests it during initdb. - * During bootstrap, we generate data encryption keys, wrap them with the - * cluster-level key, and store them into each file located at KMGR_DIR. - * Once generated, these are not changed. During startup, we decrypt all - * internal keys and load them to the shared memory space. Internal keys - * on the shared memory are read-only. All wrapping and unwrapping key - * routines require the OpenSSL library. - * - * Copyright (c) 2020, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/backend/crypto/kmgr.c - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include <sys/stat.h> -#include <unistd.h> - -#include "funcapi.h" -#include "miscadmin.h" -#include "pgstat.h" - -#include "common/file_perm.h" -#include "common/hex_decode.h" -#include "common/kmgr_utils.h" -#include "common/sha2.h" -#include "access/xlog.h" -#include "crypto/kmgr.h" -#include "storage/copydir.h" -#include "storage/fd.h" -#include "storage/ipc.h" -#include "storage/shmem.h" -#include "utils/builtins.h" -#include "utils/memutils.h" -/* Struct stores file encryption keys in plaintext format */ -typedef struct KmgrShmemData -{ - CryptoKey intlKeys[KMGR_MAX_INTERNAL_KEYS]; -} KmgrShmemData; -static KmgrShmemData *KmgrShmem; - -/* GUC variables */ -char *cluster_key_command = NULL; -int file_encryption_keylen = 0; - -CryptoKey bootstrap_keys[KMGR_MAX_INTERNAL_KEYS]; - -extern char *bootstrap_old_key_datadir; -extern int bootstrap_file_encryption_keylen; - -static void bzeroKmgrKeys(int status, Datum arg); -static void KmgrSaveCryptoKeys(const char *dir, CryptoKey *keys); -static CryptoKey *generate_crypto_key(int len); - -/* - * This function must be called ONCE during initdb. - */ -void -BootStrapKmgr(void) -{ - char live_path[MAXPGPATH]; - CryptoKey *keys_wrap; - int nkeys; - char cluster_key_hex[ALLOC_KMGR_CLUSTER_KEY_LEN]; - int cluster_key_hex_len; - unsigned char cluster_key[KMGR_CLUSTER_KEY_LEN]; - -#ifndef USE_OPENSSL - ereport(ERROR, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - (errmsg("cluster file encryption is not supported because OpenSSL is not supported by this build"), - errhint("Compile with --with-openssl to use this feature.")))); -#endif - - snprintf(live_path, sizeof(live_path), "%s/%s", DataDir, LIVE_KMGR_DIR); - - /* copy cluster file encryption keys from an old cluster? */ - if (bootstrap_old_key_datadir != NULL) - { - char old_key_dir[MAXPGPATH]; - - snprintf(old_key_dir, sizeof(old_key_dir), "%s/%s", - bootstrap_old_key_datadir, LIVE_KMGR_DIR); - copydir(old_key_dir, LIVE_KMGR_DIR, true); - } - /* create empty directory */ - else - { - if (mkdir(LIVE_KMGR_DIR, pg_dir_create_mode) < 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not create cluster file encryption directory \"%s\": %m", - LIVE_KMGR_DIR))); - } - - /* - * Get key encryption key from the cluster_key command. The cluster_key - * command might want to check for the existance of files in the - * live directory, so run this _after_ copying the directory in place. - */ - cluster_key_hex_len = kmgr_run_cluster_key_command(cluster_key_command, - cluster_key_hex, - ALLOC_KMGR_CLUSTER_KEY_LEN, - live_path); - - if (hex_decode(cluster_key_hex, cluster_key_hex_len, (char*) cluster_key) != - KMGR_CLUSTER_KEY_LEN) - ereport(ERROR, - (errmsg("cluster key must be %d hexadecimal characters", - KMGR_CLUSTER_KEY_LEN * 2))); - - /* generate new cluster file encryption keys */ - if (bootstrap_old_key_datadir == NULL) - { - CryptoKey bootstrap_keys_wrap[KMGR_MAX_INTERNAL_KEYS]; - PgCipherCtx *cluster_key_ctx; - - /* Create KEK encryption context */ - cluster_key_ctx = pg_cipher_ctx_create(PG_CIPHER_AES_GCM, cluster_key, - KMGR_CLUSTER_KEY_LEN, true); - if (!cluster_key_ctx) - elog(ERROR, "could not initialize encryption context"); - - /* Wrap all data encryption keys by key encryption key */ - for (int id = 0; id < KMGR_MAX_INTERNAL_KEYS; id++) - { - CryptoKey *key; - - /* generate a data encryption key */ - key = generate_crypto_key(bootstrap_file_encryption_keylen); - - /* Set this key's ID */ - key->pgkey_id = id; - - if (!kmgr_wrap_key(cluster_key_ctx, key, &(bootstrap_keys_wrap[id]))) - { - pg_cipher_ctx_free(cluster_key_ctx); - elog(ERROR, "failed to wrap data encryption key"); - } - - explicit_bzero(key, sizeof(CryptoKey)); - } - - /* Save data encryption keys to the disk */ - KmgrSaveCryptoKeys(LIVE_KMGR_DIR, bootstrap_keys_wrap); - - explicit_bzero(bootstrap_keys_wrap, sizeof(bootstrap_keys_wrap)); - pg_cipher_ctx_free(cluster_key_ctx); - } - - /* - * We are either decrypting keys we copied from an old cluster, or - * decrypting keys we just wrote above --- either way, we decrypt - * them here and store them in a file-scoped variable for use in - * later encrypting during bootstrap mode. - */ - - /* Get the crypto keys from the file */ - keys_wrap = kmgr_get_cryptokeys(LIVE_KMGR_DIR, &nkeys); - Assert(nkeys == KMGR_MAX_INTERNAL_KEYS); - - if (!kmgr_verify_cluster_key(cluster_key, keys_wrap, bootstrap_keys, - KMGR_MAX_INTERNAL_KEYS)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("supplied cluster key does not match expected cluster_key"))); - - /* bzero keys on exit */ - on_proc_exit(bzeroKmgrKeys, 0); - - explicit_bzero(cluster_key_hex, cluster_key_hex_len); - explicit_bzero(cluster_key, KMGR_CLUSTER_KEY_LEN); -} - -/* Report shared-memory space needed by KmgrShmem */ -Size -KmgrShmemSize(void) -{ - if (!file_encryption_keylen) - return 0; - - return MAXALIGN(sizeof(KmgrShmemData)); -} - -/* Allocate and initialize key manager memory */ -void -KmgrShmemInit(void) -{ - bool found; - - if (!file_encryption_keylen) - return; - - KmgrShmem = (KmgrShmemData *) ShmemInitStruct("File encryption key manager", - KmgrShmemSize(), &found); - - on_shmem_exit(bzeroKmgrKeys, 0); -} - -/* - * Get cluster key and verify it, then get the data encryption keys. - * This function is called by postmaster at startup time. - */ -void -InitializeKmgr(void) -{ - CryptoKey *keys_wrap; - int nkeys; - char cluster_key_hex[ALLOC_KMGR_CLUSTER_KEY_LEN]; - int cluster_key_hex_len; - struct stat buffer; - char live_path[MAXPGPATH]; - unsigned char cluster_key[KMGR_CLUSTER_KEY_LEN]; - - if (!file_encryption_keylen) - return; - - elog(DEBUG1, "starting up cluster file encryption manager"); - - if (stat(KMGR_DIR, &buffer) != 0 || !S_ISDIR(buffer.st_mode)) - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - (errmsg("cluster file encryption directory %s is missing", KMGR_DIR)))); - - if (stat(KMGR_DIR_PID, &buffer) == 0) - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - (errmsg("cluster had a pg_alterckey failure that needs repair or pg_alterckey is running"), - errhint("Run pg_alterckey --repair or wait for it to complete.")))); - - /* - * We want OLD deleted since it allows access to the data encryption - * keys using the old cluster key. If NEW exists, it means either - * NEW is partly written, or NEW wasn't renamed to LIVE --- in either - * case, it needs to be repaired. - */ - if (stat(OLD_KMGR_DIR, &buffer) == 0 || stat(NEW_KMGR_DIR, &buffer) == 0) - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - (errmsg("cluster had a pg_alterckey failure that needs repair"), - errhint("Run pg_alterckey --repair.")))); - - /* If OLD, NEW, and LIVE do not exist, there is a serious problem. */ - if (stat(LIVE_KMGR_DIR, &buffer) != 0 || !S_ISDIR(buffer.st_mode)) - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - (errmsg("cluster has no data encryption keys")))); - - /* Get cluster key */ - snprintf(live_path, sizeof(live_path), "%s/%s", DataDir, LIVE_KMGR_DIR); - cluster_key_hex_len = kmgr_run_cluster_key_command(cluster_key_command, - cluster_key_hex, - ALLOC_KMGR_CLUSTER_KEY_LEN, - live_path); - - if (hex_decode(cluster_key_hex, cluster_key_hex_len, (char*) cluster_key) != - KMGR_CLUSTER_KEY_LEN) - ereport(ERROR, - (errmsg("cluster key must be %d hexadecimal characters", - KMGR_CLUSTER_KEY_LEN * 2))); - - /* Get the crypto keys from the file */ - keys_wrap = kmgr_get_cryptokeys(LIVE_KMGR_DIR, &nkeys); - Assert(nkeys == KMGR_MAX_INTERNAL_KEYS); - - /* - * Verify cluster key and prepare a data encryption key in plaintext in shared memory. - */ - if (!kmgr_verify_cluster_key(cluster_key, keys_wrap, KmgrShmem->intlKeys, - KMGR_MAX_INTERNAL_KEYS)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("supplied cluster key does not match expected cluster key"))); - - explicit_bzero(cluster_key_hex, cluster_key_hex_len); - explicit_bzero(cluster_key, KMGR_CLUSTER_KEY_LEN); -} - -static void -bzeroKmgrKeys(int status, Datum arg) -{ - if (IsBootstrapProcessingMode()) - explicit_bzero(bootstrap_keys, sizeof(bootstrap_keys)); - else - explicit_bzero(KmgrShmem->intlKeys, sizeof(KmgrShmem->intlKeys)); -} - -const CryptoKey * -KmgrGetKey(int id) -{ - Assert(id < KMGR_MAX_INTERNAL_KEYS); - - return (const CryptoKey *) (IsBootstrapProcessingMode() ? - &(bootstrap_keys[id]) : &(KmgrShmem->intlKeys[id])); -} - -/* Generate an empty CryptoKey */ -static CryptoKey * -generate_crypto_key(int len) -{ - CryptoKey *newkey; - - Assert(len <= KMGR_MAX_KEY_LEN); - newkey = (CryptoKey *) palloc0(sizeof(CryptoKey)); - - /* We store the key as length + key into 'encrypted_key' */ - memcpy(newkey->encrypted_key, &len, sizeof(len)); - - if (!pg_strong_random(newkey->encrypted_key + sizeof(len), len)) - elog(ERROR, "failed to generate new file encryption key"); - - return newkey; -} - -/* - * Save the given file encryption keys to the disk. - */ -static void -KmgrSaveCryptoKeys(const char *dir, CryptoKey *keys) -{ - elog(DEBUG2, "saving all cryptographic keys"); - - for (int i = 0; i < KMGR_MAX_INTERNAL_KEYS; i++) - { - int fd; - char path[MAXPGPATH]; - - CryptoKeyFilePath(path, dir, i); - - if ((fd = BasicOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY)) < 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not open file \"%s\": %m", - path))); - - errno = 0; - pgstat_report_wait_start(WAIT_EVENT_KEY_FILE_WRITE); - if (write(fd, &(keys[i]), sizeof(CryptoKey)) != sizeof(CryptoKey)) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not write file \"%s\": %m", - path))); - } - pgstat_report_wait_end(); - - pgstat_report_wait_start(WAIT_EVENT_KEY_FILE_SYNC); - if (pg_fsync(fd) != 0) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not fsync file \"%s\": %m", - path))); - pgstat_report_wait_end(); - - if (close(fd) != 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not close file \"%s\": %m", - path))); - } -} diff --git a/src/backend/crypto/ssl_passphrase.sh.sample b/src/backend/crypto/ssl_passphrase.sh.sample deleted file mode 100755 index 6859f1bbb58..00000000000 --- a/src/backend/crypto/ssl_passphrase.sh.sample +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -# This uses a passphrase supplied by the user. - -[ "$#" -lt 1 ] && echo "ssl_passphrase_command usage: $0 %R [\"%p\"]" 1>&2 && exit 1 - -FD="$1" -[ ! -t "$FD" ] && echo "file descriptor $FD does not refer to a terminal" 1>&2 && exit 1 -# Supports environment variable PROMPT - -[ "$2" ] && PROMPT="$2" - - -# ---------------------------------------------------------------------- - -[ ! "$PROMPT" ] && PROMPT='Enter cluster passphrase: ' - -stty -echo <&"$FD" - -echo 1>&"$FD" -echo -n "$PROMPT" 1>&"$FD" -read PASS <&"$FD" - -stty echo <&"$FD" - -if [ ! "$PASS" ] -then echo 'invalid: empty passphrase' 1>&2 - exit 1 -fi - -echo "$PASS" - -exit 0 diff --git a/src/backend/libpq/be-secure-common.c b/src/backend/libpq/be-secure-common.c index 1b712cfbba3..94cdf4c8874 100644 --- a/src/backend/libpq/be-secure-common.c +++ b/src/backend/libpq/be-secure-common.c @@ -22,7 +22,6 @@ #include <sys/stat.h> #include <unistd.h> -#include "postmaster/postmaster.h" #include "common/string.h" #include "libpq/libpq.h" #include "storage/fd.h" @@ -62,19 +61,6 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, appendStringInfoString(&command, prompt); p++; break; - case 'R': - { - char fd_str[20]; - - if (terminal_fd == -1) - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("ssl_passphrase_command referenced %%R, but -R not specified"))); - p++; - snprintf(fd_str, sizeof(fd_str), "%d", terminal_fd); - appendStringInfoString(&command, fd_str); - break; - } case '%': appendStringInfoChar(&command, '%'); p++; diff --git a/src/backend/main/main.c b/src/backend/main/main.c index 19aa502614e..b6e51288326 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -324,7 +324,6 @@ help(const char *progname) #endif printf(_(" -N MAX-CONNECT maximum number of allowed connections\n")); printf(_(" -p PORT port number to listen on\n")); - printf(_(" -R fd prompt for the cluster key\n")); printf(_(" -s show statistics after each query\n")); printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n")); printf(_(" -V, --version output version information, then exit\n")); @@ -352,9 +351,7 @@ help(const char *progname) printf(_("\nOptions for bootstrapping mode:\n")); printf(_(" --boot selects bootstrapping mode (must be first argument)\n")); printf(_(" DBNAME database name (mandatory argument in bootstrapping mode)\n")); - printf(_(" -K LEN enable cluster file encryption with specified key length\n")); printf(_(" -r FILENAME send stdout and stderr to given file\n")); - printf(_(" -u DATADIR copy encryption keys from datadir\n")); printf(_(" -x NUM internal use\n")); printf(_("\nPlease read the documentation for the complete list of run-time\n" diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 71f2b90ca86..d87d9d06ee2 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -4152,15 +4152,6 @@ pgstat_get_wait_io(WaitEventIO w) case WAIT_EVENT_DSM_FILL_ZERO_WRITE: event_name = "DSMFillZeroWrite"; break; - case WAIT_EVENT_KEY_FILE_READ: - event_name = "KeyFileRead"; - break; - case WAIT_EVENT_KEY_FILE_WRITE: - event_name = "KeyFileWrite"; - break; - case WAIT_EVENT_KEY_FILE_SYNC: - event_name = "KeyFileSync"; - break; case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ: event_name = "LockFileAddToDataDirRead"; break; diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index bf883184b11..fff4227e0b6 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -100,7 +100,6 @@ #include "common/file_perm.h" #include "common/ip.h" #include "common/string.h" -#include "crypto/kmgr.h" #include "lib/ilist.h" #include "libpq/auth.h" #include "libpq/libpq.h" @@ -232,7 +231,6 @@ static int SendStop = false; /* still more option variables */ bool EnableSSL = false; -int terminal_fd = -1; int PreAuthDelay = 0; int AuthenticationTimeout = 60; @@ -689,7 +687,7 @@ PostmasterMain(int argc, char *argv[]) * tcop/postgres.c (the option sets should not conflict) and with the * common help() function in main/main.c. */ - while ((opt = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOPp:r:R:S:sTt:W:-:")) != -1) + while ((opt = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOPp:r:S:sTt:W:-:")) != -1) { switch (opt) { @@ -780,10 +778,6 @@ PostmasterMain(int argc, char *argv[]) /* only used by single-user backend */ break; - case 'R': - terminal_fd = atoi(optarg); - break; - case 'S': SetConfigOption("work_mem", optarg, PGC_POSTMASTER, PGC_S_ARGV); break; @@ -1332,11 +1326,6 @@ PostmasterMain(int argc, char *argv[]) */ RemovePgTempFiles(); - InitializeKmgr(); - - if (terminal_fd != -1) - close(terminal_fd); - /* * Initialize stats collection subsystem (this does NOT start the * collector process!) diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index c9fc2f4b4e1..1d8d1742a73 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -18,7 +18,6 @@ #include "access/xlog_internal.h" /* for pg_start/stop_backup */ #include "catalog/pg_type.h" -#include "common/kmgr_utils.h" #include "common/file_perm.h" #include "commands/progress.h" #include "lib/stringinfo.h" @@ -153,10 +152,6 @@ struct exclude_list_item */ static const char *const excludeDirContents[] = { - /* Skip temporary crypto key directories */ - NEW_KMGR_DIR, - OLD_KMGR_DIR, - /* * Skip temporary statistics files. PG_STAT_TMP_DIR must be skipped even * when stats_temp_directory is set because PGSS_TEXT_FILE is always diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 64fe10ca2a7..96c2aaabbd6 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -23,7 +23,6 @@ #include "access/syncscan.h" #include "access/twophase.h" #include "commands/async.h" -#include "crypto/kmgr.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/autovacuum.h" @@ -150,7 +149,6 @@ CreateSharedMemoryAndSemaphores(void) size = add_size(size, BTreeShmemSize()); size = add_size(size, SyncScanShmemSize()); size = add_size(size, AsyncShmemSize()); - size = add_size(size, KmgrShmemSize()); #ifdef EXEC_BACKEND size = add_size(size, ShmemBackendArraySize()); #endif @@ -269,7 +267,6 @@ CreateSharedMemoryAndSemaphores(void) BTreeShmemInit(); SyncScanShmemInit(); AsyncShmemInit(); - KmgrShmemInit(); #ifdef EXEC_BACKEND diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt index a44805d5c39..774292fd942 100644 --- a/src/backend/storage/lmgr/lwlocknames.txt +++ b/src/backend/storage/lmgr/lwlocknames.txt @@ -53,4 +53,3 @@ XactTruncationLock 44 # 45 was XactTruncationLock until removal of BackendRandomLock WrapLimitsVacuumLock 46 NotifyQueueTailLock 47 -KmgrFileLock 48 diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 81e64616d43..d35c5020ea6 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -42,7 +42,6 @@ #include "catalog/pg_type.h" #include "commands/async.h" #include "commands/prepare.h" -#include "crypto/kmgr.h" #include "executor/spi.h" #include "jit/jit.h" #include "libpq/libpq.h" @@ -3579,7 +3578,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, * postmaster/postmaster.c (the option sets should not conflict) and with * the common help() function in main/main.c. */ - while ((flag = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOPp:r:R:S:sTt:v:W:-:")) != -1) + while ((flag = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOPp:r:S:sTt:v:W:-:")) != -1) { switch (flag) { @@ -3671,16 +3670,6 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, strlcpy(OutputFileName, optarg, MAXPGPATH); break; - case 'R': - terminal_fd = atoi(optarg); - if (terminal_fd == -1) - /* - * Allow file descriptor closing to be bypassed via -1. - * We just dup sterr. This is useful for single-user mode. - */ - terminal_fd = dup(2); - break; - case 'S': SetConfigOption("work_mem", optarg, ctx, gucsource); break; @@ -3933,18 +3922,6 @@ PostgresMain(int argc, char *argv[], BaseInit(); /* - * Initialize kmgr for cluster encryption. Since kmgr needs to attach to - * shared memory the initialization must be called after BaseInit(). - */ - if (!IsUnderPostmaster) - { - InitializeKmgr(); - - if (terminal_fd != -1) - close(terminal_fd); - } - - /* * Create a per-backend PGPROC struct in shared memory, except in the * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do * this before we can use LWLocks (and in the EXEC_BACKEND case we already diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index bbaf037bc6e..878fcc22365 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -47,7 +47,6 @@ #include "commands/vacuum.h" #include "commands/variable.h" #include "common/string.h" -#include "crypto/kmgr.h" #include "funcapi.h" #include "jit/jit.h" #include "libpq/auth.h" @@ -746,8 +745,6 @@ const char *const config_group_names[] = gettext_noop("Statistics / Monitoring"), /* STATS_COLLECTOR */ gettext_noop("Statistics / Query and Index Statistics Collector"), - /* ENCRYPTION */ - gettext_noop("Encryption"), /* AUTOVACUUM */ gettext_noop("Autovacuum"), /* CLIENT_CONN */ @@ -3392,17 +3389,6 @@ static struct config_int ConfigureNamesInt[] = check_huge_page_size, NULL, NULL }, - { - {"file_encryption_keylen", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the bit length of the file encryption key."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &file_encryption_keylen, - 0, 0, 256, - NULL, NULL, NULL - }, - /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL @@ -4398,16 +4384,6 @@ static struct config_string ConfigureNamesString[] = }, { - {"cluster_key_command", PGC_SIGHUP, ENCRYPTION, - gettext_noop("Command to obtain cluster key for cluster file encryption."), - NULL - }, - &cluster_key_command, - "", - NULL, NULL, NULL - }, - - { {"application_name", PGC_USERSET, LOGGING_WHAT, gettext_noop("Sets the application name to be reported in statistics and logs."), NULL, diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index 6fcab311721..d50d87a6021 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -263,8 +263,8 @@ pg_control_recovery(PG_FUNCTION_ARGS) Datum pg_control_init(PG_FUNCTION_ARGS) { - Datum values[12]; - bool nulls[12]; + Datum values[11]; + bool nulls[11]; TupleDesc tupdesc; HeapTuple htup; ControlFileData *ControlFile; @@ -274,7 +274,7 @@ pg_control_init(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(12); + tupdesc = CreateTemplateTupleDesc(11); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "max_data_alignment", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database_block_size", @@ -297,8 +297,6 @@ pg_control_init(PG_FUNCTION_ARGS) BOOLOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 11, "data_page_checksum_version", INT4OID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 12, "file_encryption_keylen", - INT4OID, -1, 0); tupdesc = BlessTupleDesc(tupdesc); /* read the control file */ @@ -340,9 +338,6 @@ pg_control_init(PG_FUNCTION_ARGS) values[10] = Int32GetDatum(ControlFile->data_checksum_version); nulls[10] = false; - values[11] = Int32GetDatum(ControlFile->file_encryption_keylen); - nulls[11] = false; - htup = heap_form_tuple(tupdesc, values, nulls); PG_RETURN_DATUM(HeapTupleGetDatum(htup)); diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index f19cfe5f6ae..b7fb2ec1feb 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -632,11 +632,6 @@ # autovacuum, -1 means use # vacuum_cost_limit -#------------------------------------------------------------------------------ -# ENCRYPTION -#------------------------------------------------------------------------------ - -#cluster_key_command = '' #------------------------------------------------------------------------------ # CLIENT CONNECTION DEFAULTS |