Reject mixing keyManager and sslContext in TlsConfigHelper - #8710
Reject mixing keyManager and sslContext in TlsConfigHelper#8710thswlsqls wants to merge 1 commit into
Conversation
TlsConfigHelper documents that the PEM-based higher level API and the lower level setSslContext are mutually exclusive, but only the trustManager side enforced it. Calling setClientTls followed by setSslContext passed without error and the client certificate was silently dropped, because production senders read getSslContext() and getTrustManager() only. Add the two missing cross-checks so the documented IllegalStateException is thrown in both directions, and extend the existing tests to cover them.
Pull request dashboard statusWaiting on the author · refreshed 2026-08-21 21:40 UTC Respond to 1 review item (e.g. link a commit, explain why not, ask a follow-up):
Status above doesn't look right?
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8710 +/- ##
=========================================
Coverage 91.65% 91.65%
- Complexity 10352 10354 +2
=========================================
Files 1003 1003
Lines 27210 27214 +4
Branches 3199 3201 +2
=========================================
+ Hits 24939 24943 +4
Misses 1566 1566
Partials 705 705 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| } | ||
| if (this.keyManager != null) { | ||
| throw new IllegalStateException("keyManager has been previously configured"); |
There was a problem hiding this comment.
Not blocking, but consider also adding an explicit sslContext guard to setTrustManagerFromCerts for full symmetry with the two new guards here and in setKeyManagerFromCerts.
Today the setSslContext → setTrustManagerFromCerts case is caught transitively, because setSslContext also assigns this.trustManager, so the existing trustManager != null check fires. Two small downsides:
- The resulting message is
"trustManager has been previously configured", which is a little misleading when the user actually calledsetSslContext. - It silently relies on
setSslContextrequiring a non-nullX509TrustManager. If that ever loosens, the guard vanishes.
Proposed addition in setTrustManagerFromCerts, mirroring the pattern used elsewhere in this PR:
public void setTrustManagerFromCerts(byte[] trustedCertsPem) {
if (trustManager != null) {
throw new IllegalStateException("trustManager has been previously configured");
}
if (sslContext != null) {
throw new IllegalStateException("sslContext has been previously configured");
}
...
}With this, all three setters follow the same "reject each other mode explicitly" shape.
Fixes #8708
Description
TlsConfigHelper.setSslContextdid not checkkeyManagerandsetKeyManagerFromCertsdid not checksslContext, so both APIs could be used on one builder.OtlpHttpSpanExporterBuilder.setSslContexttells users to "call this or set raw certificate bytes, but not both".getSslContext()andgetTrustManager()to the transport and never readgetKeyManager(), so the client certificate was silently dropped.trustManageris already guarded in both directions;keyManagerwas the only asymmetric case.if.Testing done
TlsConfigHelperTest#createKeyManager_AlreadyExists_Throwsand#setSslContext_AlreadyExists_Throwswith opposite-direction blocks, matching the trust manager tests../gradlew :exporters:common:check— 70 tests passed.io.opentelemetry.exporter.internalis excluded from japicmp and no signature changed.