diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 1b659a58703..e987c436476 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -75,7 +75,6 @@ static bool ssl_is_server_start; int be_tls_init(bool isServerStart) { - STACK_OF(X509_NAME) *root_cert_list = NULL; SSL_CTX *context; /* This stuff need be done only once. */ @@ -92,6 +91,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 @@ -218,6 +221,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) { @@ -227,6 +232,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); } /*---------- @@ -266,26 +290,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. */ @@ -304,6 +308,7 @@ be_tls_init(bool isServerStart) return 0; + /* Clean up by releasing working context. */ error: if (context) SSL_CTX_free(context);