[ 
https://issues.apache.org/jira/browse/THRIFT-6073?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Hongzhi Gao updated THRIFT-6073:
--------------------------------
    Description: 
h2. Summary

Extend the C++ TSSLSocket stack with a backend-neutral hook so applications can 
inject a pre-configured OpenSSL SSL_CTX through the existing SSLContextFactory 
/ TSSLSocketFactory path.

h2. Problem

Thrift C++ provides SSL/TLS via TSSLSocket / TSSLSocketFactory 
(OpenSSL-backed). TSSLSocketFactory already accepts a custom SSLContextFactory, 
but SSLContext could only be constructed from SSLProtocol. Applications that 
need non-default TLS setup — including TLCP/NTLS dual-certificate configuration 
via an OpenSSL-compatible library such as Tongsuo — cannot supply an externally 
configured SSL_CTX without patching Thrift locally.

Specific gaps today:
* loadCertificate() / loadPrivateKey() assume a single cert/key pair; TLCP uses 
separate signing and encryption credentials.
* Provider-specific protocol and cipher setup (e.g. NTLS_method(), dual-cert 
APIs) has no injection point at the SSLContext level.

h2. Proposed solution

Add SSLContext(SSL_CTX* ctx, bool takeOwnership = true) to wrap an 
application-owned SSL_CTX. Applications configure the context with their chosen 
TLS provider, then pass it through the existing SSLContextFactory hook. Thrift 
continues to handle handshake, I/O, and certificate verification policy via 
TSSLSocketFactory.

No Tongsuo-specific build options, protocol enums, or dual-certificate APIs in 
libthrift.

h2. Scope

*In scope:*
* SSLContext wrapper constructor and ownership-aware destructor
* Documentation in lib/cpp/README.md
* SecurityTest coverage for wrapped and null contexts

h2. Acceptance criteria

* SSLContext can be constructed from an application-provided SSL_CTX*
* takeOwnership=true frees the context on destruction; takeOwnership=false 
leaves ownership with the caller
* Existing default OpenSSL / SSLProtocol code path is unchanged
* SecurityTest passes on standard OpenSSL CI builds
* (Optional) Local verification demonstrates NTLS handshake using injected 
SSL_CTX

h2. References

* GitHub PR: https://github.com/apache/thrift/pull/3606
* Motivation: TLCP/NTLS deployments in regulated environments; avoid 
maintaining a private transport fork

  was:
h2. Problem

Thrift C++ provides SSL/TLS via TSSLSocket/TSSLSocketFactory (OpenSSL). 
Deployments that require TLCP (Transport Layer Cryptography Protocol), commonly 
implemented as NTLS in Tongsuo/BabaSSL, cannot use the existing API as-is:

* TLCP requires dual certificates (signing + encryption), while 
TSSLSocketFactory only exposes single cert/key loading 
(loadCertificate/loadPrivateKey).
* TLCP uses SM2/SM3/SM4 cipher suites and a different handshake path than 
standard TLS.

Today, teams must maintain private forks or replace the transport layer to run 
Thrift over TLCP.

h2. Proposed solution

Add an opt-in build path and API extensions:

* CMake: -DWITH_TONGSUO=ON and -DTONGSUO_ROOT_DIR=... to link libthrift against 
Tongsuo (OpenSSL-compatible).
* Runtime feature detection: THRIFT_HAVE_NTLS when NTLS APIs are available.
* TSSLSocketFactory: SSLProtocol::NTLS and dual-certificate APIs (loadSign* / 
loadEnc*, including buffer variants).
* Unit tests: TNTLSSocketTest with SM2 dual-cert fixtures under test/keys/ntls/.

Default OpenSSL builds and standard TLS behavior remain unchanged when 
-DWITH_TONGSUO is not enabled.

h2. Scope

* Client: cpp
* In scope: lib/cpp TSSLSocket, CMake, tests
* Out of scope: Ruby/Java/other language bindings; non-blocking server changes

h2. Pull request

GitHub PR: https://github.com/apache/thrift/pull/3606

    Environment: C++ libthrift, OpenSSL 3.x default build; TLCP/NTLS verified 
locally with Tongsuo (OpenSSL-compatible).  (was: * OS: Linux (Ubuntu 24.04 / 
WSL2)
* Compiler: GCC 13
* CMake: 3.28+
* Boost: 1.83 (for unit tests)
* Tongsuo: 8.5.x, built with ./config enable-ntls, installed to <prefix>
* Thrift: feature/cpp-tongsuo-ntls

Build:
{code}
cmake .. -DWITH_TONGSUO=ON -DTONGSUO_ROOT_DIR=<prefix> \
  -DBUILD_TESTING=ON -DBUILD_COMPILER=ON \
  -DWITH_LIBEVENT=OFF -DWITH_ZLIB=OFF
make TNTLSSocketTest
{code}

Test:
{code}
ctest -R TNTLSSocketTest
{code}

Note: Tongsuo must be built with enable-ntls. Standard OpenSSL build is 
unaffected.)
        Summary: Allow injecting external SSL_CTX into C++ SSLContext  (was: 
Add optional TLCP/NTLS support to C++ TSSLSocket)

> Allow injecting external SSL_CTX into C++ SSLContext
> ----------------------------------------------------
>
>                 Key: THRIFT-6073
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6073
>             Project: Thrift
>          Issue Type: New Feature
>          Components: C++ - Library
>    Affects Versions: 0.24.0
>         Environment: C++ libthrift, OpenSSL 3.x default build; TLCP/NTLS 
> verified locally with Tongsuo (OpenSSL-compatible).
>            Reporter: Hongzhi Gao
>            Priority: Major
>             Fix For: 0.24.0
>
>          Time Spent: 1h 10m
>  Remaining Estimate: 0h
>
> h2. Summary
> Extend the C++ TSSLSocket stack with a backend-neutral hook so applications 
> can inject a pre-configured OpenSSL SSL_CTX through the existing 
> SSLContextFactory / TSSLSocketFactory path.
> h2. Problem
> Thrift C++ provides SSL/TLS via TSSLSocket / TSSLSocketFactory 
> (OpenSSL-backed). TSSLSocketFactory already accepts a custom 
> SSLContextFactory, but SSLContext could only be constructed from SSLProtocol. 
> Applications that need non-default TLS setup — including TLCP/NTLS 
> dual-certificate configuration via an OpenSSL-compatible library such as 
> Tongsuo — cannot supply an externally configured SSL_CTX without patching 
> Thrift locally.
> Specific gaps today:
> * loadCertificate() / loadPrivateKey() assume a single cert/key pair; TLCP 
> uses separate signing and encryption credentials.
> * Provider-specific protocol and cipher setup (e.g. NTLS_method(), dual-cert 
> APIs) has no injection point at the SSLContext level.
> h2. Proposed solution
> Add SSLContext(SSL_CTX* ctx, bool takeOwnership = true) to wrap an 
> application-owned SSL_CTX. Applications configure the context with their 
> chosen TLS provider, then pass it through the existing SSLContextFactory 
> hook. Thrift continues to handle handshake, I/O, and certificate verification 
> policy via TSSLSocketFactory.
> No Tongsuo-specific build options, protocol enums, or dual-certificate APIs 
> in libthrift.
> h2. Scope
> *In scope:*
> * SSLContext wrapper constructor and ownership-aware destructor
> * Documentation in lib/cpp/README.md
> * SecurityTest coverage for wrapped and null contexts
> h2. Acceptance criteria
> * SSLContext can be constructed from an application-provided SSL_CTX*
> * takeOwnership=true frees the context on destruction; takeOwnership=false 
> leaves ownership with the caller
> * Existing default OpenSSL / SSLProtocol code path is unchanged
> * SecurityTest passes on standard OpenSSL CI builds
> * (Optional) Local verification demonstrates NTLS handshake using injected 
> SSL_CTX
> h2. References
> * GitHub PR: https://github.com/apache/thrift/pull/3606
> * Motivation: TLCP/NTLS deployments in regulated environments; avoid 
> maintaining a private transport fork



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to