pgsql: Add key management system

Started by Bruce Momjianover 5 years ago13 messageshackers
Jump to latest
#1Bruce Momjian
bruce@momjian.us

Add key management system

This adds a key management system that stores (currently) two data
encryption keys of length 128, 192, or 256 bits. The data keys are
AES256 encrypted using a key encryption key, and validated via GCM
cipher mode. A command to obtain the key encryption key must be
specified at initdb time, and will be run at every database server
start. New parameters allow a file descriptor open to the terminal to
be passed. pg_upgrade support has also been added.

Discussion: /messages/by-id/CA+fd4k7q5o6Nc_AaX6BcYM9yqTbC6_pnH-6nSD=54Zp6NBQTCQ@mail.gmail.com
Discussion: /messages/by-id/20201202213814.GG20285@momjian.us

Author: Masahiko Sawada, me, Stephen Frost

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/978f869b992f9fca343e99d6fdb71073c76e869a

Modified Files
--------------
doc/src/sgml/config.sgml | 62 ++++
doc/src/sgml/database-encryption.sgml | 97 +++++
doc/src/sgml/filelist.sgml | 1 +
doc/src/sgml/installation.sgml | 5 +-
doc/src/sgml/postgres.sgml | 1 +
doc/src/sgml/ref/initdb.sgml | 46 +++
doc/src/sgml/ref/pg_ctl-ref.sgml | 13 +
doc/src/sgml/ref/pgupgrade.sgml | 18 +-
doc/src/sgml/ref/postgres-ref.sgml | 13 +
doc/src/sgml/storage.sgml | 5 +
src/backend/Makefile | 2 +-
src/backend/access/transam/xlog.c | 21 ++
src/backend/bootstrap/bootstrap.c | 21 +-
src/backend/crypto/Makefile | 18 +
src/backend/crypto/kmgr.c | 372 +++++++++++++++++++
src/backend/main/main.c | 3 +
src/backend/postmaster/pgstat.c | 9 +
src/backend/postmaster/postmaster.c | 13 +-
src/backend/replication/basebackup.c | 5 +
src/backend/storage/ipc/ipci.c | 3 +
src/backend/storage/lmgr/lwlocknames.txt | 1 +
src/backend/tcop/postgres.c | 25 +-
src/backend/utils/misc/guc.c | 24 ++
src/backend/utils/misc/pg_controldata.c | 11 +-
src/backend/utils/misc/postgresql.conf.sample | 5 +
src/bin/initdb/initdb.c | 116 +++++-
src/bin/pg_controldata/pg_controldata.c | 3 +
src/bin/pg_ctl/pg_ctl.c | 59 ++-
src/bin/pg_resetwal/pg_resetwal.c | 2 +
src/bin/pg_rewind/filemap.c | 8 +
src/bin/pg_upgrade/check.c | 34 ++
src/bin/pg_upgrade/controldata.c | 42 ++-
src/bin/pg_upgrade/file.c | 2 +
src/bin/pg_upgrade/option.c | 7 +-
src/bin/pg_upgrade/pg_upgrade.h | 3 +
src/bin/pg_upgrade/server.c | 5 +-
src/common/Makefile | 3 +
src/common/cipher.c | 67 ++++
src/common/cipher_openssl.c | 268 ++++++++++++++
src/common/kmgr_utils.c | 507 ++++++++++++++++++++++++++
src/include/catalog/pg_control.h | 5 +-
src/include/common/cipher.h | 62 ++++
src/include/common/kmgr_utils.h | 98 +++++
src/include/crypto/kmgr.h | 29 ++
src/include/pgstat.h | 3 +
src/include/postmaster/postmaster.h | 2 +
src/include/utils/guc_tables.h | 1 +
src/test/Makefile | 2 +-
src/tools/msvc/Mkvcbuild.pm | 4 +-
49 files changed, 2091 insertions(+), 35 deletions(-)

#2Erik Rijkers
er@xs4all.nl
In reply to: Bruce Momjian (#1)
Re: pgsql: Add key management system

On 2020-12-25 16:19, Bruce Momjian wrote:

Add key management system
doc/src/sgml/database-encryption.sgml | 97 +++++

Attached are a few typos.

I also noticed that this option does not occur in the initdb --help:

-u --copy-encryption-keys

Was that deliberate?

Thanks,

Erik Rijkers

Attachments:

database-encryption.sgml.20201225.difftext/x-diff; name=database-encryption.sgml.20201225.diffDownload+4-4
#3Bruce Momjian
bruce@momjian.us
In reply to: Erik Rijkers (#2)
Re: pgsql: Add key management system

On Fri, Dec 25, 2020 at 07:30:01PM +0100, Erik Rijkers wrote:

On 2020-12-25 16:19, Bruce Momjian wrote:

Add key management system
doc/src/sgml/database-encryption.sgml | 97 +++++

Attached are a few typos.

I also noticed that this option does not occur in the initdb --help:

-u --copy-encryption-keys

Was that deliberate?

No. :-( Attached patch applied. Thanks.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

Attachments:

master.difftext/x-diff; charset=us-asciiDownload+6-4
#4Justin Pryzby
pryzby@telsasoft.com
In reply to: Bruce Momjian (#1)
Re: pgsql: Add key management system

I think cipher_failure() should be marked pg_attribute_noreturn().

gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2 -I./src/include -D_GNU_SOURCE -I/usr/include/libxml2 -c -o src/common/cipher.o src/common/cipher.c
src/common/cipher.c: In function ‘pg_cipher_ctx_create’:
src/common/cipher.c:28:1: warning: control reaches end of non-void function [-Wreturn-type]
28 | }

--
Justin

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Justin Pryzby (#4)
Re: pgsql: Add key management system

Justin Pryzby <pryzby@telsasoft.com> writes:

I think cipher_failure() should be marked pg_attribute_noreturn().

Perhaps more to the point, it still doesn't build at all without
--with-openssl.

https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=sifaka&amp;dt=2020-12-25%2019%3A13%3A19

regards, tom lane

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#5)
Re: pgsql: Add key management system

I wrote:

Justin Pryzby <pryzby@telsasoft.com> writes:

I think cipher_failure() should be marked pg_attribute_noreturn().

Perhaps more to the point, it still doesn't build at all without
--with-openssl.

[ looks closer ... ] Oh, we're on about the same thing -- the difference
is that sifaka is using -Werror.

pg_attribute_noreturn() seems like a good idea, but we're also going to
need dummy return statements in the callers, to satisfy compilers that
don't understand that.

regards, tom lane

#7Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#6)
Re: pgsql: Add key management system

On Fri, Dec 25, 2020 at 02:37:06PM -0500, Tom Lane wrote:

I wrote:

Justin Pryzby <pryzby@telsasoft.com> writes:

I think cipher_failure() should be marked pg_attribute_noreturn().

Perhaps more to the point, it still doesn't build at all without
--with-openssl.

[ looks closer ... ] Oh, we're on about the same thing -- the difference
is that sifaka is using -Werror.

pg_attribute_noreturn() seems like a good idea, but we're also going to
need dummy return statements in the callers, to satisfy compilers that
don't understand that.

Yes, done. I tested it with a non-OpenSSL configure run now and it
worked. Thanks for the report.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#7)
Re: pgsql: Add key management system

Bruce Momjian <bruce@momjian.us> writes:

On Fri, Dec 25, 2020 at 02:37:06PM -0500, Tom Lane wrote:

pg_attribute_noreturn() seems like a good idea, but we're also going to
need dummy return statements in the callers, to satisfy compilers that
don't understand that.

Yes, done. I tested it with a non-OpenSSL configure run now and it
worked. Thanks for the report.

Now that it compiles cleanly, what about test cases? It looks
to me like you broke src/test/Makefile:

@@ -30,7 +30,7 @@ endif
endif
ifeq ($(with_openssl),yes)
ifneq (,$(filter ssl,$(PG_TEST_EXTRA)))
-SUBDIRS += ssl
+SUBDIRS += ssl crypto
endif
endif

because there is no such subdirectory. Assuming that that's a
case of forgetting to "git add" the whole subdirectory, I still
don't much care for this implementation: the user should be able
to decide which subdirectories get run. Maybe more like

 ifeq ($(with_openssl),yes)
 ifneq (,$(filter ssl,$(PG_TEST_EXTRA)))
 SUBDIRS += ssl
 endif
+ifneq (,$(filter crypto,$(PG_TEST_EXTRA)))
+SUBDIRS += crypto
+endif
 endif

regards, tom lane

#9Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#8)
Re: pgsql: Add key management system

On Fri, Dec 25, 2020 at 02:53:10PM -0500, Tom Lane wrote:

Bruce Momjian <bruce@momjian.us> writes:

On Fri, Dec 25, 2020 at 02:37:06PM -0500, Tom Lane wrote:

pg_attribute_noreturn() seems like a good idea, but we're also going to
need dummy return statements in the callers, to satisfy compilers that
don't understand that.

Yes, done. I tested it with a non-OpenSSL configure run now and it
worked. Thanks for the report.

Now that it compiles cleanly, what about test cases? It looks
to me like you broke src/test/Makefile:

@@ -30,7 +30,7 @@ endif
endif
ifeq ($(with_openssl),yes)
ifneq (,$(filter ssl,$(PG_TEST_EXTRA)))
-SUBDIRS += ssl
+SUBDIRS += ssl crypto
endif
endif

Odd I am running the regression tests.

because there is no such subdirectory. Assuming that that's a
case of forgetting to "git add" the whole subdirectory, I still
don't much care for this implementation: the user should be able
to decide which subdirectories get run. Maybe more like

ifeq ($(with_openssl),yes)
ifneq (,$(filter ssl,$(PG_TEST_EXTRA)))
SUBDIRS += ssl
endif
+ifneq (,$(filter crypto,$(PG_TEST_EXTRA)))
+SUBDIRS += crypto
+endif
endif

There are no tests yet. I need to write those in TAP, and I am going to
wait until I have something more substantial to test. I do have a test
framework here I am using.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#10Andres Freund
andres@anarazel.de
In reply to: Bruce Momjian (#9)
Re: pgsql: Add key management system

Hi,

On 2020-12-25 15:12:44 -0500, Bruce Momjian wrote:

There are no tests yet. I need to write those in TAP, and I am going to
wait until I have something more substantial to test. I do have a test
framework here I am using.

That's not great. It's not a tiny amount of code, and not having
anything to exercise it until some unclear future time means that other
people will have a hard time working anywhere in the vicinity. And that
might quite plausibly stay that way for v14?

Greetings,

Andres Freund

#11Bruce Momjian
bruce@momjian.us
In reply to: Andres Freund (#10)
Re: pgsql: Add key management system

On Fri, Dec 25, 2020 at 03:12:08PM -0800, Andres Freund wrote:

Hi,

On 2020-12-25 15:12:44 -0500, Bruce Momjian wrote:

There are no tests yet. I need to write those in TAP, and I am going to
wait until I have something more substantial to test. I do have a test
framework here I am using.

That's not great. It's not a tiny amount of code, and not having
anything to exercise it until some unclear future time means that other
people will have a hard time working anywhere in the vicinity. And that
might quite plausibly stay that way for v14?

It might. It depends on who else wants to work on it, and who wants to
write tests. I did test Stephen's GCM changes.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#12Shinoda, Noriyoshi (PN Japan FSIP)
noriyoshi.shinoda@hpe.com
In reply to: Bruce Momjian (#3)
RE: pgsql: Add key management system

Hi,

Thank you for developing a great feature. I tested it immediately.
The attached patch changes the value of the --file-encryption-keylen option of the initdb command to mandatory. No value is currently required.
I also changed the help message and the manual.

Regards,
Noriyoshi Shinoda

-----Original Message-----
From: Bruce Momjian [mailto:bruce@momjian.us]
Sent: Saturday, December 26, 2020 4:01 AM
To: Erik Rijkers <er@xs4all.nl>
Cc: pgsql-hackers@lists.postgresql.org
Subject: Re: pgsql: Add key management system

On Fri, Dec 25, 2020 at 07:30:01PM +0100, Erik Rijkers wrote:

On 2020-12-25 16:19, Bruce Momjian wrote:

Add key management system
doc/src/sgml/database-encryption.sgml | 97 +++++

Attached are a few typos.

I also noticed that this option does not occur in the initdb --help:

-u --copy-encryption-keys

Was that deliberate?

No. :-( Attached patch applied. Thanks.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

Attachments:

keylength.diffapplication/octet-stream; name=keylength.diffDownload+4-4
#13Bruce Momjian
bruce@momjian.us
In reply to: Shinoda, Noriyoshi (PN Japan FSIP) (#12)
Re: pgsql: Add key management system

On Sat, Dec 26, 2020 at 02:38:40PM +0000, Shinoda, Noriyoshi (PN Japan FSIP) wrote:

Hi,

Thank you for developing a great feature. I tested it immediately.
The attached patch changes the value of the --file-encryption-keylen option of the initdb command to mandatory. No value is currently required.
I also changed the help message and the manual.

Thank you, applied.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee