aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/libpq/be-secure-openssl.c49
1 files changed, 27 insertions, 22 deletions
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 8c37381add3..ad33122e0ed 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -81,7 +81,6 @@ static const char *ssl_protocol_version_to_string(int v);
int
be_tls_init(bool isServerStart)
{
- STACK_OF(X509_NAME) * root_cert_list = NULL;
SSL_CTX *context;
int ssl_ver_min = -1;
int ssl_ver_max = -1;
@@ -100,6 +99,10 @@ be_tls_init(bool isServerStart)
}
/*
+ * Create a new SSL context into which we'll load all the configuration
+ * settings. If we fail partway through, we can avoid memory leakage by
+ * freeing this context; we don't install it as active until the end.
+ *
* We use SSLv23_method() because it can negotiate use of the highest
* mutually supported protocol version, while alternatives like
* TLSv1_2_method() permit only one specific version. Note that we don't
@@ -272,6 +275,8 @@ be_tls_init(bool isServerStart)
*/
if (ssl_ca_file[0])
{
+ STACK_OF(X509_NAME) * root_cert_list;
+
if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
(root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
{
@@ -281,6 +286,25 @@ be_tls_init(bool isServerStart)
ssl_ca_file, SSLerrmessage(ERR_get_error()))));
goto error;
}
+
+ /*
+ * Tell OpenSSL to send the list of root certs we trust to clients in
+ * CertificateRequests. This lets a client with a keystore select the
+ * appropriate client certificate to send to us. Also, this ensures
+ * that the SSL context will "own" the root_cert_list and remember to
+ * free it when no longer needed.
+ */
+ SSL_CTX_set_client_CA_list(context, root_cert_list);
+
+ /*
+ * Always ask for SSL client cert, but don't fail if it's not
+ * presented. We might fail such connections later, depending on what
+ * we find in pg_hba.conf.
+ */
+ SSL_CTX_set_verify(context,
+ (SSL_VERIFY_PEER |
+ SSL_VERIFY_CLIENT_ONCE),
+ verify_cb);
}
/*----------
@@ -297,7 +321,7 @@ be_tls_init(bool isServerStart)
/* Set the flags to check against the complete CRL chain */
if (X509_STORE_load_locations(cvstore,
ssl_crl_file[0] ? ssl_crl_file : NULL,
- ssl_crl_dir[0] ? ssl_crl_dir : NULL)
+ ssl_crl_dir[0] ? ssl_crl_dir : NULL)
== 1)
{
X509_STORE_set_flags(cvstore,
@@ -331,26 +355,6 @@ be_tls_init(bool isServerStart)
}
}
- if (ssl_ca_file[0])
- {
- /*
- * Always ask for SSL client cert, but don't fail if it's not
- * presented. We might fail such connections later, depending on what
- * we find in pg_hba.conf.
- */
- SSL_CTX_set_verify(context,
- (SSL_VERIFY_PEER |
- SSL_VERIFY_CLIENT_ONCE),
- verify_cb);
-
- /*
- * Tell OpenSSL to send the list of root certs we trust to clients in
- * CertificateRequests. This lets a client with a keystore select the
- * appropriate client certificate to send to us.
- */
- SSL_CTX_set_client_CA_list(context, root_cert_list);
- }
-
/*
* Success! Replace any existing SSL_context.
*/
@@ -369,6 +373,7 @@ be_tls_init(bool isServerStart)
return 0;
+ /* Clean up by releasing working context. */
error:
if (context)
SSL_CTX_free(context);