8000 PG-1506: Add separate parameters for kmip client cert and key by dutow · Pull Request #306 · percona/postgres · GitHub
[go: up one dir, main page]

Skip to content

PG-1506: Add separate parameters for kmip client cert and key #306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contrib/pg_tde/documentation/docs/command-line-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Depending on the provider type, the additional parameters are:
```
pg_tde_change_key_provider [-D <datadir>] <dbOid> <provider_name> file <filename>
pg_tde_change_key_provider [-D <datadir>] <dbOid> <provider_name> vault <token> <url> <mount_path> [<ca_path>]
pg_tde_change_key_provider [-D <datadir>] <dbOid> <provider_name> kmip <host> <port> <cert_path> [<ca_path>]
pg_tde_change_key_provider [-D <datadir>] <dbOid> <provider_name> kmip <host> <port> <cert_path> <key_path> [<ca_path>]
```

## pg_waldump
Expand Down
7 changes: 4 additions & 3 deletions contrib/pg_tde/documentation/docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Load the `pg_tde` at startup time. The extension requires additional shared memo
For testing purposes, you can use the PyKMIP server which enables you to set up required certificates. To use a real KMIP server, make sure to obtain the valid certificates issued by the key management appliance.

```sql
SELECT pg_tde_add_global_key_provider_kmip('provider-name','kmip-IP', 5696, '/path_to/server_certificate.pem', '/path_to/client_key.pem');
SELECT pg_tde_add_global_key_provider_kmip('provider-name','kmip-IP', 5696, '/path_to/server_certificate.pem', '/path_to/client_cert.pem', 'path_to/client_key.pem');
```

where:
Expand All @@ -62,14 +62,15 @@ Load the `pg_tde` at startup time. The extension requires additional shared memo
* `kmip-IP` is the IP address of a domain name of the KMIP server
* `port` is the port to communicate with the KMIP server. Typically used port is 5696.
* `server-certificate` is the path to the certificate file for the KMIP server.
* `client key` is the path to the client key.
* `client-cert` is the path to the client certificate.
* `client-key` (optional) is the path to the client key. If not specified, the certificate key has to contain both the certifcate and the key.

<i warning>:material-information: Warning:</i> Note that pg_tde_add_global_key_provider_kmip currently accepts only a combined client key + client certificate for the last parameter of this function named as `client key`.

<i warning>:material-information: Warning:</i> This example is for testing purposes only:

```
SELECT pg_tde_add_global_key_provider_kmip('kmip','127.0.0.1', 5696, '/tmp/server_certificate.pem', '/tmp/client_key_jane_doe.pem');
SELECT pg_tde_add_global_key_provider_kmip('kmip','127.0.0.1', 5696, '/tmp/server_certificate.pem', '/tmp/client_cert_jane_doe.pem', '/tmp/client_key_jane_doe.pem');
```

=== "With HashiCorp Vault"
Expand Down
18 changes: 18 additions & 0 deletions contrib/pg_tde/expected/kmip_test.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ SELECT pg_tde_add_database_key_provider_kmip('kmip-prov','127.0.0.1', 5696, '/tm
1
(1 row)

SELECT pg_tde_add_database_key_provider_kmip('kmip-prov2','127.0.0.1', 5696, '/tmp/server_certificate.pem', '/tmp/client_certificate_jane_smith.pem', '/tmp/client_key_jane_smith.pem');
pg_tde_add_database_key_provider_kmip
---------------------------------------
2
(1 row)

SELECT pg_tde_set_key_using_database_key_provider('kmip-key','kmip-prov');
pg_tde_set_key_using_database_key_provider
--------------------------------------------
Expand Down Expand Up @@ -33,6 +39,18 @@ SELECT pg_tde_verify_key();

(1 row)

SELECT pg_tde_set_key_using_database_key_provider('kmip-key2','kmip-prov2');
pg_tde_set_key_using_database_key_provider
--------------------------------------------< 10000 /span>

(1 row)

SELECT pg_tde_verify_key();
pg_tde_verify_key
-------------------

(1 row)

DROP TABLE test_enc;
-- Creating provider fails if we can't connect to kmip server
SELECT pg_tde_add_database_key_provider_kmip('will-not-work','127.0.0.1', 61, '/tmp/server_certificate.pem', '/tmp/client_key_jane_doe.pem');
Expand Down
48 changes: 32 additions & 16 deletions contrib/pg_tde/pg_tde--1.0-rc.sql
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ CREATE FUNCTION pg_tde_add_database_key_provider_kmip(provider_name TEXT,
kmip_host TEXT,
kmip_port INT,
kmip_ca_path TEXT,
kmip_cert_path TEXT)
kmip_cert_path TEXT,
kmip_key_path TEXT DEFAULT '')
RETURNS INT
LANGUAGE SQL
BEGIN ATOMIC
Expand All @@ -80,14 +81,16 @@ BEGIN ATOMIC
'host' VALUE COALESCE(kmip_host, ''),
'port' VALUE kmip_port,
'caPath' VALUE COALESCE(kmip_ca_path, ''),
'certPath' VALUE COALESCE(kmip_cert_path, '')));
'certPath' VALUE COALESCE(kmip_cert_path, ''),
'keyPath' VALUE COALESCE(kmip_key_path, '')));
END;

CREATE FUNCTION pg_tde_add_database_key_provider_kmip(provider_name TEXT,
kmip_host JSON,
kmip_port JSON,
kmip_ca_path JSON,
kmip_cert_path JSON)
kmip_cert_path JSON,
kmip_key_path JSON)
RETURNS INT
LANGUAGE SQL
BEGIN ATOMIC
Expand All @@ -98,7 +101,8 @@ BEGIN ATOMIC
'host' VALUE kmip_host,
'port' VALUE kmip_port,
'caPath' VALUE kmip_ca_path,
'certPath' VALUE kmip_cert_path));
'certPath' VALUE kmip_cert_path,
'keyPath' VALUE kmip_key_path));
END;


Expand Down Expand Up @@ -186,7 +190,8 @@ CREATE FUNCTION pg_tde_add_global_key_provider_kmip(provider_name TEXT,
kmip_host TEXT,
kmip_port INT,
kmip_ca_path TEXT,
kmip_cert_path TEXT)
kmip_cert_path TEXT,
kmip_key_path TEXT DEFAULT '')
RETURNS INT
LANGUAGE SQL
BEGIN ATOMIC
Expand All @@ -197,14 +202,16 @@ BEGIN ATOMIC
'host' VALUE COALESCE(kmip_host, ''),
'port' VALUE kmip_port,
'caPath' VALUE COALESCE(kmip_ca_path, ''),
'certPath' VALUE COALESCE(kmip_cert_path, '')));
'certPath' VALUE COALESCE(kmip_cert_path, ''),
'keyPath' VALUE COALESCE(kmip_key_path, '')));
END;

CREATE FUNCTION pg_tde_add_global_key_provider_kmip(provider_name TEXT,
kmip_host JSON,
kmip_port JSON,
kmip_ca_path JSON,
kmip_cert_path JSON)
kmip_cert_path JSON,
kmip_key_path JSON)
RETURNS INT
LANGUAGE SQL
BEGIN ATOMIC
Expand All @@ -215,7 +222,8 @@ BEGIN ATOMIC
'host' VALUE kmip_host,
'port' VALUE kmip_port,
'caPath' VALUE kmip_ca_path,
'certPath' VALUE kmip_cert_path));
'certPath' VALUE kmip_cert_path,
'keyPath' VALUE kmip_key_path));
END;

-- Key Provider Management
Expand Down Expand Up @@ -284,7 +292,8 @@ CREATE FUNCTION pg_tde_change_database_key_provider_kmip(provider_name TEXT,
kmip_host TEXT,
kmip_port INT,
kmip_ca_path TEXT,
kmip_cert_path TEXT)
kmip_cert_path TEXT,
kmip_key_path TEXT DEFAULT '')
RETURNS INT
LANGUAGE SQL
B 9E7A EGIN ATOMIC
Expand All @@ -295,14 +304,16 @@ BEGIN ATOMIC
'host' VALUE COALESCE(kmip_host, ''),
'port' VALUE kmip_port,
'caPath' VALUE COALESCE(kmip_ca_path, ''),
'certPath' VALUE COALESCE(kmip_cert_path, '')));
'certPath' VALUE COALESCE(kmip_cert_path, ''),
'keyPath' VALUE COALESCE(kmip_key_path, '')));
END;

CREATE FUNCTION pg_tde_change_database_key_provider_kmip(provider_name TEXT,
kmip_host JSON,
kmip_port JSON,
kmip_ca_path JSON,
kmip_cert_path JSON)
kmip_cert_path JSON,
kmip_key_path JSON)
RETURNS INT
LANGUAGE SQL
BEGIN ATOMIC
Expand All @@ -313,7 +324,8 @@ BEGIN ATOMIC
'host' VALUE kmip_host,
'port' VALUE kmip_port,
'caPath' VALUE kmip_ca_path,
'certPath' VALUE kmip_cert_path));
'certPath' VALUE kmip_cert_path,
'keyPath' VALUE kmip_key_path));
END;

-- Global Tablespace Key Provider Management
Expand Down Expand Up @@ -382,7 +394,8 @@ CREATE FUNCTION pg_tde_change_global_key_provider_kmip(provider_name TEXT,
kmip_host TEXT,
kmip_port INT,
kmip_ca_path TEXT,
kmip_cert_path TEXT)
kmip_cert_path TEXT,
kmip_key_path TEXT DEFAULT NULL)
RETURNS INT
LANGUAGE SQL
BEGIN ATOMIC
Expand All @@ -393,14 +406,16 @@ BEGIN ATOMIC
'host' VALUE COALESCE(kmip_host, ''),
'port' VALUE kmip_port,
'caPath' VALUE COALESCE(kmip_ca_path, ''),
'certPath' VALUE COALESCE(kmip_cert_path, '')));
'certPath' VALUE COALESCE(kmip_cert_path, ''),
'keyPath' VALUE COALESCE(kmip_key_path, '')));
END;

CREATE FUNCTION pg_tde_change_global_key_provider_kmip(provider_name TEXT,
kmip_host JSON,
kmip_port JSON,
kmip_ca_path JSON,
kmip_cert_path JSON)
kmip_cert_path JSON,
kmip_key_path JSON)
RETURNS INT
LANGUAGE SQL
BEGIN ATOMIC
Expand All @@ -411,7 +426,8 @@ BEGIN ATOMIC
'host' VALUE kmip_host,
'port' VALUE kmip_port,
'caPath' VALUE kmip_ca_path,
'certPath' VALUE kmip_cert_path));
'certPath' VALUE kmip_cert_path,
'keyPath' VALUE kmip_key_path));
END;

CREATE FUNCTION pg_tde_is_encrypted(relation regclass)
Expand Down
2 changes: 1 addition & 1 deletion contrib/pg_tde/pykmip-server.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ key_path=/tmp/server_key.pem
ca_path=/tmp/root_certificate.pem
auth_suite=TLS1.2
policy_path=/tmp/policies
enable_tls_client_auth=True
enable_tls_client_auth=False
tls_cipher_suites=
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
Expand Down
4 changes: 4 additions & 0 deletions contrib/pg_tde/sql/kmip_test.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
CREATE EXTENSION pg_tde;

SELECT pg_tde_add_database_key_provider_kmip('kmip-prov','127.0.0.1', 5696, '/tmp/server_certificate.pem', '/tmp/client_key_jane_doe.pem');
SELECT pg_tde_add_database_key_provider_kmip('kmip-prov2','127.0.0.1', 5696, '/tmp/server_certificate.pem', '/tmp/client_certificate_jane_smith.pem', '/tmp/client_key_jane_smith.pem');
SELECT pg_tde_set_key_using_database_key_provider('kmip-key','kmip-prov');

CREATE TABLE test_enc(
Expand All @@ -17,6 +18,9 @@ SELECT * from test_enc;

SELECT pg_tde_verify_key();

SELECT pg_tde_set_key_using_database_key_provider('kmip-key2','kmip-prov2');
SELECT pg_tde_verify_key();

DROP TABLE test_enc;

-- Creating provider fails if we can't connect to kmip server
Expand Down
14 changes: 10 additions & 4 deletions contrib/pg_tde/src/catalog/tde_keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -930,10 +930,16 @@ debug_print_kerying(GenericKeyring *keyring)
elog(debug_level, "Vault Keyring CA Path: %s", ((VaultV2Keyring *) keyring)->vault_ca_path);
break;
case KMIP_KEY_PROVIDER:
elog(debug_level, "KMIP Keyring Host: %s", ((KmipKeyring *) keyring)->kmip_host);
elog(debug_level, "KMIP Keyring Port: %s", ((KmipKeyring *) keyring)->kmip_port);
elog(debug_level, "KMIP Keyring CA Path: %s", ((KmipKeyring *) keyring)->kmip_ca_path);
elog(debug_level, "KMIP Keyring Cert Path: %s", ((KmipKeyring *) keyring)->kmip_cert_path);
{
KmipKeyring *kkeyring = (KmipKeyring *) keyring;
char *key_path = kkeyring->kmip_key_path == NULL ? "" : kkeyring->kmip_key_path;

elog(debug_level, "KMIP Keyring Host: %s", kkeyring->kmip_host);
elog(debug_level, "KMIP Keyring Port: %s", kkeyring->kmip_port);
elog(debug_level, "KMIP Keyring CA Path: %s", kkeyring->kmip_ca_path);
elog(debug_level, "KMIP Keyring Cert Path: %s", kkeyring->kmip_cert_path);
elog(debug_level, "KMIP Keyring Key Path: %s", key_path);
}
break;
case UNKNOWN_KEY_PROVIDER:
elog(debug_level, "Unknown Keyring ");
Expand Down
7 changes: 7 additions & 0 deletions contrib/pg_tde/src/catalog/tde_keyring_parse_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ typedef enum JsonKeyringField
JK_KMIP_PORT,
JK_KMIP_CA_PATH,
JK_KMIP_CERT_PATH,
JK_KMIP_KEY_PATH,

/* must be the last */
JK_FIELDS_TOTAL
Expand All @@ -99,6 +100,7 @@ static const char *JK_FIELD_NAMES[JK_FIELDS_TOTAL] = {
[JK_KMIP_PORT] = "port",
[JK_KMIP_CA_PATH] = "caPath",
[JK_KMIP_CERT_PATH] = "certPath",
[JK_KMIP_KEY_PATH] = "keyPath",
};

#define MAX_JSON_DEPTH 64
Expand Down Expand Up @@ -362,6 +364,8 @@ json_kring_object_field_start(void *state, char *fname, bool isnull)
*field = JK_KMIP_CA_PATH;
else if (strcmp(fname, JK_FIELD_NAMES[JK_KMIP_CERT_PATH]) == 0)
*field = JK_KMIP_CERT_PATH;
else if (strcmp(fname, JK_FIELD_NAMES[JK_KMIP_KEY_PATH]) == 0)
*field = JK_KMIP_KEY_PATH;
else
{
*field = JK_FIELD_UNKNOWN;
Expand Down Expand Up @@ -458,6 +462,9 @@ json_kring_assign_scalar(JsonKeyringState *parse, JsonKeyringField field, char *
case JK_KMIP_CERT_PATH:
kmip->kmip_cert_path = value;
break;
case JK_KMIP_KEY_PATH:
kmip->kmip_key_path = value;
break;

default:
elog(ERROR, "json keyring: unexpected scalar field %d", field);
Expand Down
1 change: 1 addition & 0 deletions contrib/pg_tde/src/include/keyring/keyring_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ typedef struct KmipKeyring
char *kmip_port;
char *kmip_ca_path;
char *kmip_cert_path;
char *kmip_key_path;
} KmipKeyring;

extern void RegisterKeyProviderType(const TDEKeyringRoutine *routine, ProviderType type);
Expand Down
5 changes: 3 additions & 2 deletions contrib/pg_tde/src/keyring/keyring_kmip.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ kmipSslConnect(KmipCtx *ctx, KmipKeyring *kmip_keyring, bool throw_error)
{
SSL *ssl = NULL;
int level = throw_error ? ERROR : WARNING;
char *key_path = kmip_keyring->kmip_key_path == NULL || strlen(kmip_keyring->kmip_key_path) == 0 ? kmip_keyring->kmip_cert_path : kmip_keyring->kmip_key_path;

ctx->ssl = SSL_CTX_new(SSLv23_method());

Expand All @@ -61,10 +62,10 @@ kmipSslConnect(KmipCtx *ctx, KmipKeyring *kmip_keyring, bool throw_error)
return false;
}

if (SSL_CTX_use_PrivateKey_file(ctx->ssl, kmip_keyring->kmip_cert_path, SSL_FILETYPE_PEM) != 1)
if (SSL_CTX_use_PrivateKey_file(ctx->ssl, key_path, SSL_FILETYPE_PEM) != 1)
{
SSL_CTX_free(ctx->ssl);
ereport(level, errmsg("SSL error: Loading the client key failed"));
ereport(level, errmsg("SSL error: Loading the client key failed: %s", key_path));
return false;
}

Expand Down
4 changes: 2 additions & 2 deletions contrib/pg_tde/src/pg_tde_change_key_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,15 @@ main(int argc, char *argv[])
{
provider_found = true;

if (argc - argstart != 7 && argc - argstart != 8)
if (argc - argstart != 8 && argc - argstart != 9)
{
help();
puts("\n");
printf("Error: wrong number of arguments.\n");
exit(1);
}

if (!build_json(json, 5, "type", "kmip", "host", argv[4 + argstart], "port", argv[5 + argstart], "caPath", (argc - argstart > 7 ? argv[7 + argstart] : ""), "certPath", argv[6 + argstart]))
if (!build_json(json, 6, "type", "kmip", "host", argv[4 + argstart], "port", argv[5 + argstart], "caPath", (argc - argstart > 8 ? argv[8 + argstart] : ""), "certPath", argv[6 + argstart], "keyPath", argv[7 + argstart]))
{
exit(1);
}
Expand Down
0