On Fri, 23 Oct 2026 16:09:48 GMT, Thejasvi Voniadka <[email protected]> 
wrote:

> The sun.security.ssl.TrustStoreManager.TrustAnchorManager keeps one cached 
> TrustStoreDescriptor (path, type, provider, password, last-modified time). It 
> uses that descriptor to validate two caches: the loaded KeyStore (ksRef) and 
> the extracted trusted certificates (csRef).
> 
> getTrustedCerts() replaces the descriptor, ksRef and csRef together when the 
> descriptor has changed. getKeyStore() replaces the descriptor and ksRef but 
> leaves csRef alone.
> 
> If getTrustedKeyStore() runs after the trust store file was modified, the 
> cached descriptor is updated while csRef still holds the old certificates. A 
> following getTrustedCerts() call finds a matching descriptor and returns the 
> old set.
> 
> TrustManagerFactory.init((KeyStore) null) then builds a trust manager that 
> does not include the new certificates, until the JVM restarts or the weakly 
> referenced csRef is cleared by the garbage collector.
> 
> The only caller of getTrustedKeyStore() in the JDK is 
> SSLContextImpl.DefaultManagersHolder.getTrustManagers(). It runs when the 
> default TrustManagerFactory provider is not SunJSSE, so the problem is 
> reachable with public APIs only.
> 
> Steps to Reproduce:
> 
> Create a PKCS12 trust store with one certificate and point 
> javax.net.ssl.trustStore, trustStorePassword and trustStoreType at it.
> Build a default trust manager with TrustManagerFactory.getInstance("PKIX", 
> "SunJSSE") and init((KeyStore) null), and keep a reference to it. It has 1 
> accepted issuer.
> Add a second certificate to the file, making sure its last-modified time 
> changes.
> Register a TrustManagerFactory provider that is not SunJSSE at position 1 
> (for example, one that delegates to SunJSSE), and call 
> SSLContext.getDefault().
> Build another default SunJSSE trust manager as in step 2.
> 
> Results
> Expected: The new trust manager has 2 accepted issuers.
> Actual: It has 1.
> 
> The new test StaleTrustedCerts implements these steps. It fails on an 
> unpatched 21.0.11 and passes with the fix.
> 
> Fix
> Clear the cached certificates in getKeyStore() together with the other caches:
> 
> this.descriptor = descriptor;
> this.ksRef = new WeakReference<>(ks);
> this.csRef = new WeakReference<>(null);
> 
> csRef is private and read only by getTrustedCerts(), which already reloads 
> when get() returns null.
> 
> Testing
> Included test 
> test/jdk/sun/security/ssl/TrustStoreManager/StaleTrustedCerts.java that 
> reproduces the issue, and verifies the fix.
> 
> 
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK 
> Interim AI Policy](https://openjdk.org/leg...

Looks good to me.  Thank you!

-------------

Marked as reviewed by xuelei (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/33545#pullrequestreview-5635444961

Reply via email to