On 23/01/18 02:57, Nitkalya (Ing) Wiriyanuparb wrote:
> 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?).

Yes they will. As per the comment at line 255, non-PKCS#8 keystores will
use the original key store.

> 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.

And there is the problem.

Tomcat is jumping through quite a few hoops to handle various use cases:
- PEM encoded keys
- keystores with multiple keys each with their own password

That last one is the cause of most of the trouble. Key stores allow this
but the KeyManagerFactory API doesn't. This is why we now always create
the in-memory key store. When we do this, we can't just use JKS for the
in-memory key store type as that creates issues like BZ 61557.

> 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?

I don't think you are missing anything obvious. We could look at adding
(even more) configuration options to separately control the type and
provider for the in-memory key store (assuming using JKS here would work
for you) but I'm a little concerned about how complex that code is getting.

I think I'd look at modifying your key store implementation but if that
is a lot of work, we can explore some additional configuration options
in Tomcat.

Cheers,

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to