diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 904d564afe..d8fdf0b2f0 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -82,7 +82,6 @@ static int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version); int be_tls_init(bool isServerStart) { - STACK_OF(X509_NAME) *root_cert_list = NULL; SSL_CTX *context; /* This stuff need be done only once. */ @@ -99,6 +98,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 @@ -254,6 +257,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) { @@ -263,6 +268,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); } /*---------- @@ -302,26 +326,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. */ @@ -340,6 +344,7 @@ be_tls_init(bool isServerStart) return 0; + /* Clean up by releasing working context. */ error: if (context) SSL_CTX_free(context);