From d5d398540fb378225e39d7fc7b57999cdc545af0 Mon Sep 17 00:00:00 2001 From: Umar Hayat Date: Wed, 19 Feb 2020 13:32:06 +0500 Subject: [PATCH] Add support for CRL (Certificate Revocation List) Add new configuration variable ssl_crl_file to let the user configure path for CRL file. ssl_crl_file will be loaded at startup. If a certificate is revoked by CA and revoked entry is available in CRL file, client authentication will fail. --- doc/src/sgml/ssl.sgml | 19 ++++++++++ src/config/pool_config_variables.c | 10 +++++ src/include/pool_config.h | 1 + src/sample/pgpool.conf.sample | 3 ++ src/sample/pgpool.conf.sample-logical | 3 ++ src/sample/pgpool.conf.sample-master-slave | 3 ++ src/sample/pgpool.conf.sample-replication | 3 ++ src/sample/pgpool.conf.sample-stream | 3 ++ src/test/regression/tests/024.cert_auth/cert.sh | 27 ++++++++++++++ src/test/regression/tests/024.cert_auth/test.sh | 49 +++++++++++++++++++++++++ src/utils/pool_process_reporting.c | 5 +++ src/utils/pool_ssl.c | 37 +++++++++++++++++++ 12 files changed, 163 insertions(+) diff --git a/doc/src/sgml/ssl.sgml b/doc/src/sgml/ssl.sgml index c7a2693..986fa4e 100644 --- a/doc/src/sgml/ssl.sgml +++ b/doc/src/sgml/ssl.sgml @@ -128,6 +128,25 @@ + + ssl_crl_file (string) + + ssl_crl_file configuration parameter + + + + + Specifies the name of the file containing the SSL server + certificate revocation list (CRL). The default is empty, + meaning no CRL file is loaded. + + + + This parameter can only be set at server start. + + + + ssl_ciphers (string) diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c index ee19ce3..61df400 100644 --- a/src/config/pool_config_variables.c +++ b/src/config/pool_config_variables.c @@ -1062,6 +1062,16 @@ static struct config_string ConfigureNamesString[] = }, { + {"ssl_crl_file", CFGCXT_INIT, SSL_CONFIG, + "Path to the SSL certificate revocation list file", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.ssl_crl_file, + "", + NULL, NULL, NULL, NULL + }, + + { {"ssl_ciphers", CFGCXT_INIT, SSL_CONFIG, "Allowed SSL ciphers.", CONFIG_VAR_TYPE_STRING, false, 0 diff --git a/src/include/pool_config.h b/src/include/pool_config.h index b5dfa2c..559b52f 100644 --- a/src/include/pool_config.h +++ b/src/include/pool_config.h @@ -352,6 +352,7 @@ typedef struct char *ssl_ca_cert; /* path to root (CA) certificate */ char *ssl_ca_cert_dir; /* path to directory containing CA * certificates */ + char *ssl_crl_file; /* path to the SSL certificate revocation list file */ char *ssl_ciphers; /* allowed ssl ciphers */ bool ssl_prefer_server_ciphers; /*Use SSL cipher preferences, rather than the client's*/ char *ssl_ecdh_curve; /* the curve to use in ECDH key exchange */ diff --git a/src/sample/pgpool.conf.sample b/src/sample/pgpool.conf.sample index d46ba49..21037ee 100644 --- a/src/sample/pgpool.conf.sample +++ b/src/sample/pgpool.conf.sample @@ -122,6 +122,9 @@ ssl = off #ssl_ca_cert_dir = '' # Directory containing CA root certificate(s) # (change requires restart) +#ssl_crl_file = '' + # Path to the SSL certificate revocation list file + # (change requires restart) ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # Allowed SSL ciphers diff --git a/src/sample/pgpool.conf.sample-logical b/src/sample/pgpool.conf.sample-logical index dbe0db3..f2752b1 100644 --- a/src/sample/pgpool.conf.sample-logical +++ b/src/sample/pgpool.conf.sample-logical @@ -122,6 +122,9 @@ ssl = off #ssl_ca_cert_dir = '' # Directory containing CA root certificate(s) # (change requires restart) +#ssl_crl_file = '' + # Path to the SSL certificate revocation list file + # (change requires restart) ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # Allowed SSL ciphers diff --git a/src/sample/pgpool.conf.sample-master-slave b/src/sample/pgpool.conf.sample-master-slave index f3e4eeb..9dad52f 100644 --- a/src/sample/pgpool.conf.sample-master-slave +++ b/src/sample/pgpool.conf.sample-master-slave @@ -118,6 +118,9 @@ ssl = off #ssl_ca_cert_dir = '' # Directory containing CA root certificate(s) # (change requires restart) +#ssl_crl_file = '' + # Path to the SSL certificate revocation list file + # (change requires restart) ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # Allowed SSL ciphers diff --git a/src/sample/pgpool.conf.sample-replication b/src/sample/pgpool.conf.sample-replication index e16d5eb..900c5d1 100644 --- a/src/sample/pgpool.conf.sample-replication +++ b/src/sample/pgpool.conf.sample-replication @@ -117,6 +117,9 @@ ssl = off #ssl_ca_cert_dir = '' # Directory containing CA root certificate(s) # (change requires restart) +#ssl_crl_file = '' + # Path to the SSL certificate revocation list file + # (change requires restart) ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # Allowed SSL ciphers diff --git a/src/sample/pgpool.conf.sample-stream b/src/sample/pgpool.conf.sample-stream index ef20c0f..4065c2b 100644 --- a/src/sample/pgpool.conf.sample-stream +++ b/src/sample/pgpool.conf.sample-stream @@ -122,6 +122,9 @@ ssl = off #ssl_ca_cert_dir = '' # Directory containing CA root certificate(s) # (change requires restart) +#ssl_crl_file = '' + # Path to the SSL certificate revocation list file + # (change requires restart) ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # Allowed SSL ciphers diff --git a/src/test/regression/tests/024.cert_auth/cert.sh b/src/test/regression/tests/024.cert_auth/cert.sh index e363432..8751a69 100755 --- a/src/test/regression/tests/024.cert_auth/cert.sh +++ b/src/test/regression/tests/024.cert_auth/cert.sh @@ -1,5 +1,24 @@ #!/usr/bin/env bash +touch index.txt +echo '1000' > serial +echo 'unique_subject = yes/no' > index.txt.attr +echo '1000' > crlnumber + +cat >> crl_openssl.conf <> etc/pgpool.conf + +export PGPORT=$PGPOOL_PORT + +wait_for_pgpool_startup + +export PGSSLCERT=$FRONTEND_CRT +export PGSSLKEY=$FRONTEND_KEY + +$PSQL -h localhost -c "select 1" test + +grep "SSL certificate authentication for user" log/pgpool.log|grep successful +if [ $? != 0 ];then + echo "Checking cert auth between Pgpool-II and frontend with clean CRL failed." + ./shutdownall + exit 1 +fi + +echo "Checking cert auth between Pgpool-II and frontend with clean CRL was ok." + +./shutdownall + +./startall + +sed -i 's/server.crl/server_revoked.crl/' etc/pgpool.conf + +export PGPORT=$PGPOOL_PORT + +wait_for_pgpool_startup + +export PGSSLCERT=$FRONTEND_CRT +export PGSSLKEY=$FRONTEND_KEY + +$PSQL -h localhost -c "select 1" test + +grep "certificate verify failed" log/pgpool.log +if [ $? != 0 ];then + echo "Checking cert auth between Pgpool-II and frontend with revoked entry in CRL failed." + ./shutdownall + exit 1 +fi + +echo "Checking cert auth between Pgpool-II and frontend with revoked entry in CRL was ok." + +./shutdownall + exit 0 diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c index f153676..5d44e36 100644 --- a/src/utils/pool_process_reporting.c +++ b/src/utils/pool_process_reporting.c @@ -259,6 +259,11 @@ get_config(int *nrows) StrNCpy(status[i].desc, "directory containing CA root certificate(s)", POOLCONFIG_MAXDESCLEN); i++; + StrNCpy(status[i].name, "ssl_crl_file", POOLCONFIG_MAXNAMELEN); + snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->ssl_crl_file); + StrNCpy(status[i].desc, "path to the SSL certificate revocation list file", POOLCONFIG_MAXDESCLEN); + i++; + StrNCpy(status[i].name, "ssl_ciphers", POOLCONFIG_MAXNAMELEN); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->ssl_ciphers); StrNCpy(status[i].desc, "allowed SSL ciphers", POOLCONFIG_MAXDESCLEN); diff --git a/src/utils/pool_ssl.c b/src/utils/pool_ssl.c index 346477e..9dfa236 100644 --- a/src/utils/pool_ssl.c +++ b/src/utils/pool_ssl.c @@ -694,6 +694,43 @@ SSL_ServerSide_init(void) SSL_CTX_set_client_CA_list(context, root_cert_list); } + /*---------- + * Load the Certificate Revocation List (CRL). + * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html + *---------- + */ + if (pool_config->ssl_crl_file && strlen(pool_config->ssl_crl_file)) + { + X509_STORE *cvstore = SSL_CTX_get_cert_store(context); + + if (cvstore) + { + /* Set the flags to check against the complete CRL chain */ + if (X509_STORE_load_locations(cvstore, pool_config->ssl_crl_file, NULL) == 1) + { + /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */ +#ifdef X509_V_FLAG_CRL_CHECK + X509_STORE_set_flags(cvstore, + X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); +#else + ereport(LOG, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("SSL certificate revocation list file \"%s\" ignored", + pool_config->ssl_crl_file), + errdetail("SSL library does not support certificate revocation lists."))); +#endif + } + else + { + ereport(WARNING, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("could not load SSL certificate revocation list file \"%s\": %s", + pool_config->ssl_crl_file, SSLerrmessage(ERR_get_error())))); + goto error; + } + } + } + /* * Success! Replace any existing SSL_context. */ -- 2.8.1