Hi all,

I'm on Java 8 and Tomcat 8.5.26 (built from tag) moving from 7.0.41.

I have a little problem with how JSSEUtil#getKeyManagers creates key
managers. This essentially causes Tomcat to sometimes serves an incorrect
server certificate chain during ServerHello.
-Djavax.net.debug=all gave me a clue as it printed out multiple "matching
alias", so I believe it's because the key manager (and key store) returned
from that method doesn't contain only one key. From what I see, when
switching to in-memory key store getKeyManagers creates a new key store of
the configured type, calls setKeyEntry and expects the new key store to
have only this one key in it.

Note that we have our own implementation of the key store, but please bear
with me.

I'm also aware of this following bit of documentation and I suspect that
the second sentence is very much related to my problem here. I'm also sure
the certificateKeyAlias is set correctly and SSLHostConfigCertificate has
all the expected values when I checked in debug mode.

> The alias used for the server key and certificate in the keystore. If not
specified, the first key read from the keystore will be used. The order in
which keys are read from the keystore is implementation dependent.

We didn't have this problem in 7.0.41 because it's doing something less
complex and eventually just creates a JSSEKeyManager with the expected key
alias with the key store as a delegate – see
https://github.com/apache/tomcat70/blob/TOMCAT_7_0_41/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java#L563

But in 8.5,
https://github.com/apache/tomcat85/blob/TOMCAT_8_5_26/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java#L267
the identity comparison "ksUsed == ks" looks kind of weird to me as
KeyStore.getInstance (at least in Oracle Java 8) always returns a new
instance of KeyStore, so the checks will never be true (or will it?).

Ideally, I'd want to find a way to get into that if block so the end state
is like in 7.0.41.

As I mentioned, we have our own key store implementation and it always
loads all keys it's supposed to know about so reassigning "ksUsed =
KeyStore.getInstance..." doesn't make a difference for us – it actually
makes it worse as without it "ksUsed == ks" would have been true.

We technically can just modify or introduce a new key store implementation
to cater for Tomcat implementation – locally patching Tomcat to remove the
identity check would work for us as well.

Before doing that, am I missing something obvious? is reimplementing our
key store the way to go here?

Cheers,
Nitkalya

Reply via email to