Repository navigation
TLS trust store does not iterate over multiple CA certificates with the same subject DN #370
Description
Activity
Can you reproduce this cleanly outside of LS environment, please?
Submit a PR with a unit test (cert fixtures) or just bare Ruby + OpenSSL usage, that passes under MRI but fails with JRuby + latest JOSSL gem.We don't really have the capacity to chase down the LS (embedded) setup and what might be at play around there...
Hi @kares,
Thank you for looking into this.
As requested, here is a standalone reproducer script (no Logstash dependency) that demonstrates the issue using bare Ruby + OpenSSL. The script passes on MRI Ruby but fails on JRuby with jruby-openssl 0.16.0.
MRI Ruby (using native OpenSSL) correctly iterates over all CAs with matching Subject DN and succeeds.
The attached script (reproduce_multi_ca_same_dn.rb) is fully self-contained — it generates all certificates in memory, no external fixtures required. It runs 3 tests:
- X509Store#verify with old CA chain added first, then new CA chain
- X509Store#verify with new CA chain added first (control test)
- Full TLS handshake — TLS server presents a cert signed by the new CA, TLS client trusts old-first bundle
Results:
MRI Ruby 3.0.2 + OpenSSL 3.0.2:
TEST 1: X509Store#verify (old CA first) → PASS
TEST 2: X509Store#verify (new CA first) → PASS
TEST 3: TLS handshake (old CA first) → PASSJRuby 10.0.6.0 + jruby-openssl 0.16.0:
TEST 1: X509Store#verify (old CA first) → FAIL (error 20: unable to get local issuer certificate)
TEST 2: X509Store#verify (new CA first) → PASS
TEST 3: TLS handshake (old CA first) → FAIL (OpenSSL::SSL::SSLError: certificate verify failed)TEST 2 passing on both confirms the certificates are valid. TEST 1 and TEST 3 failing only on JRuby (and only when the old CA is listed first) proves the issuer lookup in jruby-openssl stops at the first Subject DN match without trying alternatives.
How to run
MRI Ruby — should PASS all 3 tests
ruby reproduce_multi_ca_same_dn.rbJRuby — TEST 1 and TEST 3 should FAIL
jruby reproduce_multi_ca_same_dn.rbOr via Docker:
docker run --rm -v $(pwd):/test ruby:3.2 ruby /test/reproduce_multi_ca_same_dn.rb
docker run --rm -v $(pwd):/test jruby:9.4 jruby /test/reproduce_multi_ca_same_dn.rbThis breaks standard CA renewal workflows where old and new CA certificates (same Subject DN, different keys) coexist temporarily in the trust bundle. The certificate order in the bundle is not guaranteed, so verification randomly fails depending on which CA appears first.
Attaching the script
reproduce_multi_ca_same_dn.rb.txt
Note: The reproducer script is attached as .txt due to GitHub file type restrictions. Rename to reproduce_multi_ca_same_dn.rb before running.
Thanks & regards,
Sunanda N.- linked a pull request that will close this issue[fix] X509 store issuer lookup with duplicate subject DNs #379
on Sep 25, 2026
Creating a new issue for this github issue #362, as we are unable to re-open that and the issue is not resolved yet with jruby-openssl 0.16.1 version.
@kares Please find the below analysis and thanks for looking into this.
We attempted to verify the fix on jruby-openssl 0.19.0 in our environment, but ran into internal/unrelated errors when connecting
to our test syslog server (GnuTLS-side unexpected TLS handshake packet / illegal or unsupported version errors during the handshake), which blocked a clean
verification on 0.19.0 in that setup.
But as mentioned in previous comments, the fix was included from 0.11.1.
And we were, however, able to reproduce the original issue on jruby-openssl 0.16.1 using the following steps:
Setup:
authorityKeyIdentifier extensions
appearing first)
Result on 0.16.1:
TLS handshake fails with:
[logstash.outputs.syslog] SSL Error {exception: #<OpenSSL::SSL::SSLError: certificate verify failed>, ...
'org/jruby/ext/openssl/SSLSocket.java:280:in connect'
'.../logstash-output-syslog-3.1.0/lib/logstash/outputs/syslog.rb:263:in connect'
Thanks & regards,
Sunanda N.