pgpool2.git / summary / log / commit / refs
commit dc3116c797aab862635f2f7c73c6cbd35cd167cc
Author: Tatsuo Ishii <ishii@sraoss.co.jp>
Date: Sat Mar 14 02:54:38 2020 +0000
Add support for SSL CRL (Certificate Revocation List).
Patch created by Umar Hayat, along with Japanese document by Tatsuo
Ishii.
Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2020-February/003505.html
doc.ja/src/sgml/ssl.sgml | 18 ++++++
doc/src/sgml/ssl.sgml | 19 ++++++
src/config/pool_config_variables.c | 10 ++++
src/include/pool_config.h | 1 +
src/sample/pgpool.conf.sample-logical | 3 +
src/sample/pgpool.conf.sample-raw | 3 +
src/sample/pgpool.conf.sample-replication | 3 +
src/sample/pgpool.conf.sample-slony | 3 +
src/sample/pgpool.conf.sample-stream | 3 +
src/test/regression/tests/024.cert_auth/cert.sh | 72 +++++++++++++++++++++--
src/test/regression/tests/024.cert_auth/test.sh | 78 +++++++++++++++++++++++++
src/utils/pool_process_reporting.c | 5 ++
src/utils/pool_ssl.c | 42 ++++++++++++-
13 files changed, 254 insertions(+), 6 deletions(-)
diff --git a/doc.ja/src/sgml/ssl.sgml b/doc.ja/src/sgml/ssl.sgml
index 18e071475..755d40f1b 100644
--- a/doc.ja/src/sgml/ssl.sgml
+++ b/doc.ja/src/sgml/ssl.sgml
@@ -198,6 +198,24 @@
</listitem>
</varlistentry>
+ <varlistentry id="guc-ssl-crl-file" xreflabel="ssl_crl_file">
+ <term><varname>ssl_crl_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_crl_file</varname>設定パラメータ</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ SSSLサーバ証明書失効リスト(CRL)が入っているファイルのパス名を設定します。
+ デフォルトは空で、この場合<acronym>CRL</acronym>ファイルは読み込まれません。
+ </para>
+
+ <para>
+ このパラメータはサーバ起動時にのみ設定可能です。
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-ssl-ciphers" xreflabel="ssl_ciphers">
<term><varname>ssl_ciphers</varname> (<type>string</type>)
<indexterm>
diff --git a/doc/src/sgml/ssl.sgml b/doc/src/sgml/ssl.sgml
index c7a269317..0b04b2448 100644
--- a/doc/src/sgml/ssl.sgml
+++ b/doc/src/sgml/ssl.sgml
@@ -128,6 +128,25 @@
</listitem>
</varlistentry>
+ <varlistentry id="guc-ssl-crl-file" xreflabel="ssl_crl_file">
+ <term><varname>ssl_crl_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_crl_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the path to the file containing the SSL server
+ certificate revocation list (CRL). The default is empty,
+ meaning no <acronym>CRL</acronym> file is loaded.
+ </para>
+
+ <para>
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-ssl-ciphers" xreflabel="ssl_ciphers">
<term><varname>ssl_ciphers</varname> (<type>string</type>)
<indexterm>
diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c
index 1c1736e54..30114da19 100644
--- a/src/config/pool_config_variables.c
+++ b/src/config/pool_config_variables.c
@@ -1069,6 +1069,16 @@ static struct config_string ConfigureNamesString[] =
NULL, NULL, NULL, NULL
},
+ {
+ {"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.",
diff --git a/src/include/pool_config.h b/src/include/pool_config.h
index ec1bbf7db..a14ead1c4 100644
--- a/src/include/pool_config.h
+++ b/src/include/pool_config.h
@@ -362,6 +362,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-logical b/src/sample/pgpool.conf.sample-logical
index 44060d8a1..6158ed89e 100644
--- a/src/sample/pgpool.conf.sample-logical
+++ b/src/sample/pgpool.conf.sample-logical
@@ -128,6 +128,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-raw b/src/sample/pgpool.conf.sample-raw
index 3c7845d0f..de25b5697 100644
--- a/src/sample/pgpool.conf.sample-raw
+++ b/src/sample/pgpool.conf.sample-raw
@@ -129,6 +129,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 ce5e4daf6..b17912918 100644
--- a/src/sample/pgpool.conf.sample-replication
+++ b/src/sample/pgpool.conf.sample-replication
@@ -124,6 +124,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-slony b/src/sample/pgpool.conf.sample-slony
index f34b40fbb..ef840938f 100644
--- a/src/sample/pgpool.conf.sample-slony
+++ b/src/sample/pgpool.conf.sample-slony
@@ -125,6 +125,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 847424020..2cc7bda59 100644
--- a/src/sample/pgpool.conf.sample-stream
+++ b/src/sample/pgpool.conf.sample-stream
@@ -129,6 +129,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 e3634323e..673d6980a 100755
--- a/src/test/regression/tests/024.cert_auth/cert.sh
+++ b/src/test/regression/tests/024.cert_auth/cert.sh
@@ -1,10 +1,72 @@
#!/usr/bin/env bash
+[ -e "index.txt" ] && rm "index.txt"
+touch index.txt
+echo '1000' > serial
+echo 'unique_subject = yes/no' > index.txt.attr
+echo '1000' > crlnumber
+if [ -d "certrecord" ]; then rm -Rf certrecord; fi
+mkdir certrecord
+if [ -d "newcerts" ]; then rm -Rf newcerts; fi
+mkdir newcerts
+
+cat > crl_openssl.conf <<EOF
+
+[ ca ]
+default_ca = CA_default
+
+[ CA_default ]
+dir = .
+database = index.txt
+serial = serial
+certs = newcerts
+new_certs_dir = certrecord
+
+default_md = sha256
+crlnumber = crlnumber
+default_crl_days = 365
+
+name_opt = ca_default
+cert_opt = ca_default
+default_days = 375
+preserve = no
+policy = policy_loose
+
+# The root key and root certificate.
+private_key = root.key
+certificate = root.crt
+
+[ policy_loose ]
+# Allow the intermediate CA to sign a more diverse range of certificates.
+# See the POLICY FORMAT section of the `ca` man page.
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+[req]
+distinguished_name = req_distinguished_name
+
+[req_distinguished_name]
+
+EOF
+
# Create root cert
-openssl req -new -x509 -nodes -out root.crt -keyout root.key -days 365 -subj /CN=MyRootCA
+openssl req -new -x509 -nodes -out root.crt -keyout root.key -config crl_openssl.conf -days 365 -subj /CN=MyRootCA
# PostgreSQL/Pgpool cert
-openssl req -new -out server.req -keyout server.key -nodes -subj "/CN=postgresql"
-openssl x509 -req -in server.req -CAkey root.key -CA root.crt -days 365 -CAcreateserial -out server.crt
+openssl req -new -out server.req -keyout server.key -config crl_openssl.conf -nodes -subj "/CN=postgresql"
+openssl ca -batch -in server.req -config crl_openssl.conf -days 375 -notext -md sha256 -out server.crt
+
# Frontend Cert
-openssl req -new -out postgresql.req -keyout frontend.key -nodes -subj "/CN=$USER"
-openssl x509 -req -in postgresql.req -CAkey root.key -CA root.crt -days 365 -CAcreateserial -out frontend.crt
+openssl req -new -out frontend.req -keyout frontend.key -config crl_openssl.conf -nodes -subj "/CN=$USER"
+openssl ca -batch -in frontend.req -config crl_openssl.conf -days 375 -notext -md sha256 -out frontend.crt
+
+# Generate clean CRL (No revocation so far)
+openssl ca -gencrl -config crl_openssl.conf -out server.crl -cert root.crt -keyfile root.key
+# Revoke Frontend Cert
+openssl ca -revoke frontend.crt -config crl_openssl.conf -keyfile root.key -cert root.crt -out root.crl
+# Generate CRL after revocation
+openssl ca -gencrl -config crl_openssl.conf -out server_revoked.crl -cert root.crt -keyfile root.key
diff --git a/src/test/regression/tests/024.cert_auth/test.sh b/src/test/regression/tests/024.cert_auth/test.sh
index 6fc59b656..1ff6ab435 100755
--- a/src/test/regression/tests/024.cert_auth/test.sh
+++ b/src/test/regression/tests/024.cert_auth/test.sh
@@ -14,6 +14,7 @@ export PGDATABASE=test
dir=`pwd`
SSL_KEY=$dir/server.key
SSL_CRT=$dir/server.crt
+SSL_CRL=$dir/server.crl
ROOT_CRT=$dir/root.crt
FRONTEND_KEY=$dir/frontend.key
FRONTEND_CRT=$dir/frontend.crt
@@ -52,6 +53,7 @@ wait_for_pgpool_startup
export PGSSLCERT=$FRONTEND_CRT
export PGSSLKEY=$FRONTEND_KEY
+export PGSSLROOTCERT=$ROOT_CRT
$PSQL -h localhost -c "select 1" test
@@ -65,4 +67,80 @@ fi
echo "Checking cert auth between Pgpool-II and frontend was ok."
./shutdownall
+
+
+# Starting CRL verfication
+# Adding valid CRL file in pgpool.conf file.
+echo "ssl_crl_file = '$SSL_CRL'" >> etc/pgpool.conf
+
+# Check pgpool configuration is updated successfully
+grep "server.crl" etc/pgpool.conf
+if [ $? != 0 ];then
+ echo "pgpool.conf is not updated with CRL file."
+ ./shutdownall
+ exit 1
+fi
+
+# Start Server and PgPool
+./startall
+
+export PGPORT=$PGPOOL_PORT
+
+wait_for_pgpool_startup
+
+export PGSSLCERT=$FRONTEND_CRT
+export PGSSLKEY=$FRONTEND_KEY
+export PGSSLROOTCERT=$ROOT_CRT
+
+$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
+
+
+# Adding CRL file with revoked certification entry in pgpool.conf file.
+echo "Updating pgpool.conf with revoked CRL file"
+
+sed -i 's/server.crl/server_revoked.crl/' etc/pgpool.conf
+
+# Check pgpool configuration is updated successfully
+grep "server_revoked.crl" etc/pgpool.conf
+if [ $? != 0 ];then
+ echo "pgpool.conf is not updated with revoked CRL file."
+ ./shutdownall
+ exit 1
+fi
+
+# Start Server and PgPool
+./startall
+
+export PGPORT=$PGPOOL_PORT
+
+wait_for_pgpool_startup
+
+export PGSSLCERT=$FRONTEND_CRT
+export PGSSLKEY=$FRONTEND_KEY
+export PGSSLROOTCERT=$ROOT_CRT
+
+$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 25728b0ed..126de0e6c 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 346477e34..59f4dcf9a 100644
--- a/src/utils/pool_ssl.c
+++ b/src/utils/pool_ssl.c
@@ -5,7 +5,7 @@
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2016 PgPool Global Development Group
+ * Copyright (c) 2003-2020 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
@@ -675,7 +675,47 @@ SSL_ServerSide_init(void)
pool_config->ssl_ca_cert, SSLerrmessage(ERR_get_error()))));
goto error;
}
+ }
+
+ /*----------
+ * 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.9.6 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;
+ }
+ }
+ }
+ if (pool_config->ssl_ca_cert && strlen(pool_config->ssl_ca_cert))
+ {
/*
* Always ask for SSL client cert, but don't fail if it's not
* presented. We might fail such connections later, depending on what
[parent: face0f278ddd]