Skip to content

ZOOKEEPER-4929: Make c client side cert optional in connecting to tls server #2257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

eseabrook1
Copy link

@eseabrook1 eseabrook1 commented May 6, 2025

In the Zookeeper C library it is possible to initiate a connection using SSL by providing a "cert" string to zookeeper_init_ssl(). However in order to call this function, it is my understanding that callers must provide four things:

  1. The path to a Server CA file to validate the server's certificate
  2. The path to a Client CA file, with a complete certificate chain
  3. The path to a file containing the Client Private Key
  4. The password for the key file

This understanding is based on the implementation of init_ssl_for_socket

SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
/*SERVER CA FILE*/
if (SSL_CTX_load_verify_locations(*ctx, fd->cert->ca, 0) != 1) {
SSL_CTX_free(*ctx);
LOG_ERROR(LOGCALLBACK(zh), "Failed to load CA file %s", fd->cert->ca);
errno = EINVAL;
return ZBADARGUMENTS;
}
if (SSL_CTX_set_default_verify_paths(*ctx) != 1) {
SSL_CTX_free(*ctx);
LOG_ERROR(LOGCALLBACK(zh), "Call to SSL_CTX_set_default_verify_paths failed");
errno = EINVAL;
return ZBADARGUMENTS;
}
/*CLIENT CA FILE (With Certificate Chain)*/
if (SSL_CTX_use_certificate_chain_file(*ctx, fd->cert->cert) != 1) {
SSL_CTX_free(*ctx);
LOG_ERROR(LOGCALLBACK(zh), "Failed to load client certificate chain from %s", fd->cert->cert);
errno = EINVAL;
return ZBADARGUMENTS;
}
/*CLIENT PRIVATE KEY*/
SSL_CTX_set_default_passwd_cb_userdata(*ctx, fd->cert->passwd);
if (SSL_CTX_use_PrivateKey_file(*ctx, fd->cert->key, SSL_FILETYPE_PEM) != 1) {
SSL_CTX_free(*ctx);
LOG_ERROR(LOGCALLBACK(zh), "Failed to load client private key from %s", fd->cert->key);
errno = EINVAL;
return ZBADARGUMENTS;
}
/*CHECK*/
if (SSL_CTX_check_private_key(*ctx) != 1) {
SSL_CTX_free(*ctx);
LOG_ERROR(LOGCALLBACK(zh), "SSL_CTX_check_private_key failed");
errno = EINVAL;
return ZBADARGUMENTS;
}

For our use case, connecting to a server that does not support mTLS, it would be useful if we could specify only the CA for the server certificate, omitting the client parameters completely. This is something this is already possible with other Zookeeper client libraries, for example Kazoo: https://github.com/python-zk/kazoo/blob/c5ab98819b3a797e12a0315e97e51851525da70f/kazoo/handlers/utils.py#L253-L260

This Pull Request proposes a change to relax the requirements for the client SSL certificates and allow just a sever certificate to be provided.

@kezhuw kezhuw changed the title C Client Library: Relax requirement for client SSL certs ZOOKEEPER-4929: Make c client side cert optional in connecting to tls server May 12, 2025
Copy link
Member

@kezhuw kezhuw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Would you mind test this and document zookeeper_init_ssl somehow ?

LOG_ERROR(LOGCALLBACK(zh), "SSL_CTX_check_private_key failed");
errno = EINVAL;
return ZBADARGUMENTS;
if (fd->cert->cert != NULL && fd->cert->passwd != NULL && fd->cert->key != NULL)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe need SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL); in client when skip cert.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not particularly familiar with the SSL APIs, but my assumption was that we would be in client mode, and still want to validate the server certificate so the existing settings are still correct. We only want the TLS handshake to continue if ths server certificate is valid

https://docs.openssl.org/master/man3/SSL_CTX_set_verify/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants