fix(ha-bootstrap): use TLS client context for outgoing vote RPCs

ha->ssl_ctx is created with TLS_server_method() (for incoming iomgr
connections). vote_request_thread was calling SSL_connect() on this
server-method context, which OpenSSL rejects immediately — causing
every vote thread to fail with SSL_ERROR_SSL and goto deny.

Fix: create a fresh TLS_client_method() context with SSL_VERIFY_NONE
for each outgoing vote connection. This is safe because the election
protocol is authenticated by the vote RPC payload (term, config_tag)
not by the TLS certificate chain.

The SSL_CTX_free after SSL_new is correct — SSL_new increments the
reference count internally, so freeing the ctx leaves the ssl object
valid.
This commit is contained in:
Rongsong Shen 2026-05-30 03:37:13 +00:00
parent 80950ffbba
commit 289c4daaa2

View file

@ -1080,9 +1080,15 @@ static void *vote_request_thread(void *arg)
fcntl(sock, F_SETFL, flags & ~O_NONBLOCK);
}
/* ── 2. SSL handshake ────────────────────────────────── */
/* ── 2. SSL handshake (client side) ─────────────────── */
if (ha->ssl_ctx) {
ssl = SSL_new((SSL_CTX *)ha->ssl_ctx);
/* ha->ssl_ctx was created with TLS_server_method (for incoming connections).
* SSL_connect requires a client-method context, so create one on-demand. */
SSL_CTX *client_ctx = SSL_CTX_new(TLS_client_method());
if (!client_ctx) goto deny;
SSL_CTX_set_verify(client_ctx, SSL_VERIFY_NONE, NULL);
ssl = SSL_new(client_ctx);
SSL_CTX_free(client_ctx); /* ssl holds a reference; safe to free ctx */
if (!ssl) goto deny;
SSL_set_fd(ssl, sock);
int sr;