aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/libpq/be-secure-openssl.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 9fce426bf00..a37b5e47c2e 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
@@ -269,6 +272,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)
{
@@ -278,6 +283,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);
}
/*----------
@@ -308,26 +332,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.
*/
@@ -346,6 +350,7 @@ be_tls_init(bool isServerStart)
return 0;
+ /* Clean up by releasing working context. */
error:
if (context)
SSL_CTX_free(context);