Skip to content

Add TLS/TLCP SSL support to the C++ client with bundled Tongsuo#18130

Open
hongzhi-gao wants to merge 28 commits into
apache:masterfrom
hongzhi-gao:feature/session-cpp-ntls
Open

Add TLS/TLCP SSL support to the C++ client with bundled Tongsuo#18130
hongzhi-gao wants to merge 28 commits into
apache:masterfrom
hongzhi-gao:feature/session-cpp-ntls

Conversation

@hongzhi-gao

Copy link
Copy Markdown
Contributor

Add NTLS (TLCP) support to the C++ client. Tongsuo is chosen because it is Apache-2.0 licensed and provides both standard TLS and NTLS in one OpenSSL-compatible stack; it is built from source by default and bundled into the SDK.

Description

NTLS / TLCP client support

  • Extend C++ and C Session builders with sslProtocol (TLS / TLCP), PKCS12 trustStore / keyStore, mirroring the Java Session API.
  • RpcSslUtils wires Thrift TSSLSocket for TLS and TLCP (including dual SM2 PKCS12 for mutual auth).

Why Tongsuo

  • License: Apache-2.0, suitable for bundling in the IoTDB SDK.
  • Protocol coverage: one dependency covers both TLS and NTLS; no separate GM/T stack.
  • Built from 8.4-stable at configure time (WITH_SSL=ON, default); libssl / libcrypto shipped in the SDK package.

Tests & CI

  • CTest phases: plainssl (IoTDB TLS) → ntls (openssl s_server).
  • TLS/TLCP examples and Catch2 unit/e2e tests with committed PKCS12 fixtures.

This PR has:

  • been self-reviewed.
  • added documentation for new or modified features or behaviors.
  • added or updated version, license, or notice information
  • added unit tests or modified existing tests to cover new code paths, ensuring the threshold for code coverage.
  • added integration tests.
  • been tested in a test IoTDB cluster.

Key changed/added classes
  • RpcSslUtils.{h,cpp} — TLS/TLCP SSL context and Thrift factory
  • SessionBuilder.h, SessionC.{h,cpp} — client SSL configuration API
  • cmake/FetchOpenSSL.cmake — Tongsuo source build and SDK bundling
  • test/scripts/run_cpp_it_phases.py — plain / TLS / NTLS IT phases

Replace official OpenSSL with Tongsuo 8.4-stable for ASF-compliant
bundled libssl/libcrypto. Pin Thrift to commit 6dfb0b26 and update CI,
docs, and examples to consume the bundled SSL runtime only.
…ackaging.

Expose PKCS12 trust/key store configuration across Session APIs, patch Thrift for custom SSL contexts, add SSL unit tests with fixtures, and copy bundled Tongsuo runtime libraries next to test/example binaries on Windows.
Use execv with the correct openssl argv on Unix, disable LeakSanitizer for rpcSslUtilsTest, and copy libiotdb_session plus OpenSSL shared libraries next to IT binaries on Linux.
Linux rpcSslUtilsTest e2e cases need the bundled Tongsuo lib64 directory on the loader path for the child openssl process.
OpenSSL/Tongsuo reports benign allocations at process exit; ASAN_OPTIONS=detect_leaks=0 keeps address checks without failing the SSL unit tests.
Free PKCS7 safes after PKCS12_pack_authsafes, add RAII for parsed PKCS12 identities, and remove LeakSanitizer workarounds for rpcSslUtilsTest.
Session IT and plain examples run against non-encrypted IoTDB; rpc SSL tests
restart IoTDB with TLS. NTLS rpc tests and TLCP handshake examples use local
openssl s_server. Add focused C++/C example smoke tests and IoTDB TLS E2E coverage.
Tongsuo openssl s_server needs the bundled libssl on LD_LIBRARY_PATH; rpc tests
already pass the install root but NTLS examples only set the executable path.
Git Bash MSYS perl lacks Locale::Maketext::Simple required by OpenSSL
Configure. Prefer C:/Strawberry/perl/bin/perl.exe and prepend it on CI bash steps.
Locate nmake next to cl.exe and invoke it via helper batch files so MSVC
tools are on PATH during the OpenSSL/Tongsuo source build.
Ship only legacy examples in the release zip; IT-only TLS/NTLS smoke
examples stay in-tree. Locate nmake/vcvars64 when CMAKE_CXX_COMPILER is
unset (VS2017 matrix on GHA).
Pass no-asm when configuring Tongsuo on Apple platforms, use brew Perl
explicitly, and default empty Windows verify matrix entries to VS 2022 x64.
Homebrew headers on GitHub macOS runners shadow the bundled Tongsuo
install and hide NTLS APIs required by RpcSslUtils.
Clear CPATH-style include env vars on macOS CI and prepend the Tongsuo
install include tree before linking iotdb_session.
Avoid Xcode SDK OpenSSL shadowing NTLS APIs by generating absolute-path
wrapper headers and linking imported Tongsuo libraries directly.
Place wrapper headers under openssl/ so angle-bracket includes resolve to
Tongsuo before the macOS SDK, and avoid pulling Thrift SSL headers into
RpcSslUtils.h.
Windows: use find_package(OpenSSL) so MSVC gets proper IMPORTED_IMPLIB targets.
macOS: apply openssl wrapper include dir directly on iotdb_session BEFORE PUBLIC.
Partial wrappers let nested <openssl/ossl_typ.h> resolve to Homebrew and
break Tongsuo-only types such as DELEGATED_CREDENTIAL in x509.h.
Set OPENSSL_SSL_LIBRARY on the macOS manual-find path so
iotdb_install_openssl_runtime copies libssl/libcrypto into lib/.
Fix multi-language-client Spotless check failures on Linux and Windows.
Generated PEM/P12 material under client-cpp/test/fixtures is test data,
not licensable source; unblocks multi-language-client server build.
Use client-cpp/test/fixtures/** relative to iotdb-client module.
Watch root pom.xml in multi-language-client and client-cpp-package.
On Linux/Windows find_package path has no iotdb_tongsuo_openssl_wrap;
unconditional link made ld search for -liotdb_tongsuo_openssl_wrap.
SslTestFixtures.cpp uses NTLS APIs; test binaries need the same BEFORE
wrap include path as iotdb_session on Homebrew macOS runners.
Route NTLS enablement through RpcSslUtils, set DYLD_LIBRARY_PATH for
forked Tongsuo openssl, fix macOS executableDir in SSL fixtures, and
apply the Tongsuo openssl header wrap to test targets.
@HTHou

HTHou commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

I reviewed this PR locally against head 696ca4872a2a5c03635048a8a990c49b7e1d54b5. I think there are a few issues worth addressing before merge:

  1. trustStore does not actually enable server certificate verification in the Thrift socket path.

    RpcSslUtils::createTlsClientContext() / createTlcpClientContext() load the trust store and set SSL_VERIFY_PEER, but RpcSslUtils::createSslSocketFactory() then calls factory->authenticate(false). In Thrift TSSLSocketFactory::authenticate(false) resets the context verify mode to SSL_VERIFY_NONE, so the configured trust store is effectively bypassed for normal Session / ThriftConnection connections. This means the documented TLS one-way/server-authentication and TLCP trust-store behavior is not enforced. The current handshake tests use SSL_connect directly, so they do not cover this Thrift socket factory path.

    Could we make this conditional, for example call authenticate(true) when config.effectiveTrustStore() is set and keep authenticate(false) only for the legacy no-trust-store mode? It would also be good to add a Session/Thrift-level negative test where a wrong CA must fail.

  2. The bundled Tongsuo source is not pinned to an immutable artifact.

    TONGSUO_GIT_REF defaults to 8.4-stable, and FetchOpenSSL.cmake downloads the branch tarball without an expected hash. Since that branch can move, the same IoTDB commit can produce different SDK binaries over time, which is risky for release reproducibility and dependency auditing. Please consider pinning a tag/commit and verifying the tarball hash.

  3. The packaged SDK examples are inconsistent with the updated examples README.

    examples/README.md documents cpp_tls_example, cpp_ntls_example, tls_tree_example, and c_ntls_example, but src/assembly/client-cpp.xml only packages the older example sources. Also, examples/CMakeLists.txt only creates the new TLS/TLCP example targets in the in-tree build path. After users unpack the released SDK zip, the documented TLS/TLCP examples are not available/buildable from the package.

  4. Architectural question: should Tongsuo be the default SSL provider for all C++ SDK builds?

    Since most users only need standard TLS, would it be possible to keep the default SDK on upstream OpenSSL and provide a Tongsuo/TLCP-specific build flavor only when TLCP is requested? For example, an explicit provider option/classifier such as IOTDB_SSL_PROVIDER=TONGSUO or a separate TLCP package could keep the default TLS path simpler, reduce the default dependency/build-toolchain surface, and limit the impact of Tongsuo to users who actually need TLCP.

@HTHou

HTHou commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

One more API/UX note about the new trustStore / keyStore naming:

It is reasonable to align the C++ Session API with the Java Session API, but in the C/C++ ecosystem this naming can be ambiguous. Some C/C++ clients use similar names, but often with different semantics. For example, Paho MQTT C has trustStore / keyStore fields but they point to PEM files, while librdkafka supports a PKCS#12 ssl.keystore.location for client authentication but still uses CA-style options such as ssl.ca.location / ssl.ca.pem for server trust. Many C++ APIs instead expose OpenSSL-style inputs directly (ca/root certs, cert chain, private key).

So if this PR keeps the Java-style names, please make the boundary explicit in docs and errors: JKS is not supported by the C++ client; .p12 / .pfx means PKCS#12, and PEM trust files are only supported through the legacy/path-style option. It may also be useful to keep or add OpenSSL-style configuration names (caFile, certFile, keyFile, etc.) so native C++ users do not have to think in Java keystore terms when they already have PEM material.

…nd packaging

Enforce Thrift peer verification when a trust store is configured, pin Tongsuo 8.4.0 with tarball SHA256 verification, package TLS/NTLS examples in the SDK, and document PKCS#12/PEM/JKS boundaries with Thrift-level negative tests.
@hongzhi-gao hongzhi-gao force-pushed the feature/session-cpp-ntls branch from 47b645d to dabb5bb Compare July 7, 2026 07:56
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.

2 participants