Skip to content

Follow up on EKU of certificates - #1098

Open
dsoumis wants to merge 20 commits into
apache:mainfrom
dsoumis:follow-up-on-eku-certifcate
Open

dsoumis wants to merge 20 commits into
apache:mainfrom
dsoumis:follow-up-on-eku-certifcate

Conversation

@dsoumis

@dsoumis dsoumis commented Oct 22, 2026

Copy link
Copy Markdown
Member

No description provided.

@dsoumis dsoumis changed the title Follow up on eku certifcate Follow up on EKU of certificates Oct 22, 2026
@dsoumis
dsoumis force-pushed the follow-up-on-eku-certifcate branch from d917629 to c1d3cb3 Compare October 22, 2026 15:38
A key store can hold more than one certificate for a host. For example, a Windows-MY store populated by AD CS autoenrollment may contain both a TLS server certificate and a client authentication certificate. When no key alias was configured, automatic selection used the first key entry regardless of its key usage and could pick a certificate that is not valid for TLS server authentication. When no certificateKeyAlias is configured, skip key entries whose certificate is not valid for TLS server authentication. A certificate qualifies if its Extended Key Usage includes serverAuth or anyExtendedKeyUsage, or if it has no Extended Key Usage extension. A malformed Extended Key Usage is treated as not valid and ignored. If no eligible key entry is found, connector initialization fails.

A configured certificateKeyAlias is always used unchanged, even if its certificate is not valid for server authentication.
@dsoumis
dsoumis force-pushed the follow-up-on-eku-certifcate branch from c1d3cb3 to a87c327 Compare October 22, 2026 15:48

@markt-asf markt-asf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR appears to be missing some key points.

The Java KeyStore API assumes that aliases are unique. The original problem was related to multiple keys of different types with the same alias.

It looks like for current versions of Java (including latest 8) those duplicate aliases get a number appended to the end:

  • alias
  • alias (1)
  • alias (2)

We need to handle this when looking for alias and checking the EKU value.

@dsoumis
dsoumis marked this pull request as draft October 22, 2026 16:46
@dsoumis

dsoumis commented Oct 23, 2026

Copy link
Copy Markdown
Member Author

This PR appears to be missing some key points.

The Java KeyStore API assumes that aliases are unique. The original problem was related to multiple keys of different types with the same alias.

It looks like for current versions of Java (including latest 8) those duplicate aliases get a number appended to the end:

  • alias
  • alias (1)
  • alias (2)

We need to handle this when looking for alias and checking the EKU value.

@markt-asf I have been thinking on how to resolve this, but no idea seems concise enough to implement.

I am considering the scenario where:

Java alias Actual original name EKU
tomcat tomcat clientAuth
tomcat (1) tomcat (1) serverAuth
tomcat (2) tomcat serverAuth

so treating aliases only by their number suffix is not an option.

Running on debug I noticed that the original alias is available, but KeyStore.keyStoreSpi is private.
From my point of view, this is something that should be addressed on the jdk's side.
see:

image

I've looked around openjdk source code and resulted in sending the following email.

https://mail.openjdk.org/archives/list/security-dev@openjdk.org/thread/XUCB6BURVVSJEFJMCEHP34XNUOSPVAGR/

It's noteworthy that, per https://bugs.openjdk.org/browse/JDK-8187634, it seems there is a mismatch on what getCertificateAlias returns before and after java 23.

@markt-asf

Copy link
Copy Markdown
Contributor

Thanks for looking into this in more depth. I agree this needs to be fixed on the JRE side. The proper fix looks like it would need a breaking API change.

As much as it pains me to hack a solution, we do have a user with a genuine issue. How about the following approach:

  • document the JRE's keystore behaviour
  • implement
    1. look for the configured alias
    2. if no cert found, fail
    3. if EKU is for servers use this alias
    4. if EKU not for servers look for next alias in JDK order "alias (1)", "alias (2)" etc
    5. goto 2

It isn't perfect. Aliases genuinely ending in (1) are going to conflict but is that very likely? And it does solve the problem reported on users@ (at least I think it does). WDYT?

@dsoumis
dsoumis marked this pull request as ready for review October 26, 2026 12:45
@dsoumis

dsoumis commented Oct 26, 2026

Copy link
Copy Markdown
Member Author

Thanks for looking into this in more depth. I agree this needs to be fixed on the JRE side. The proper fix looks like it would need a breaking API change.

As much as it pains me to hack a solution, we do have a user with a genuine issue. How about the following approach:

  • document the JRE's keystore behaviour

  • implement

    1. look for the configured alias
    2. if no cert found, fail
    3. if EKU is for servers use this alias
    4. if EKU not for servers look for next alias in JDK order "alias (1)", "alias (2)" etc
    5. goto 2

It isn't perfect. Aliases genuinely ending in (1) are going to conflict but is that very likely? And it does solve the problem reported on users@ (at least I think it does). WDYT?

I implemented this behavior, but limited it only for SunMSCAPI provider. Documented also the reason behind this decision.

@dsoumis

dsoumis commented Oct 26, 2026

Copy link
Copy Markdown
Member Author

Openjdk tracker for reference: https://bugs.openjdk.org/browse/JDK-8395755

@dsoumis
dsoumis force-pushed the follow-up-on-eku-certifcate branch 2 times, most recently from fbf9f88 to 6f4accf Compare October 28, 2026 14:16
@dsoumis

dsoumis commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

@markt-asf I've reworked the branch and I would appreciate your input on this.

As discussed, for a SunMSCAPI Windows-MY store, when the configured certificateKeyAlias isn't valid for server auth, fall back to enumeration order. When no valid duplicate is found, the configured alias is kept rather than failing.

I noticed that there were other places that this change affected, and tried to address them.

When a Certificate is configured from a key store and no certificateKeyAlias
is set, ignore key entries whose certificate is not valid for TLS server
authentication when automatically selecting the key to use. A configured
certificateKeyAlias is used even if its certificate is not valid, except in a
Windows-MY key store accessed through the SunMSCAPI provider: there, if the
configured certificate is not valid but a numbered duplicate of the alias
("alias (1)", "alias (2)", ...) carries a valid one, the duplicate is used
instead - including when the configured alias is a keyless (trusted) entry,
and continuing past gaps in the numbering.
The configured certificateKeyAlias can differ from the certificate actually
served once the SunMSCAPI Windows-MY numbered-duplicate resolution has selected
a different alias. Consumers that looked the certificate up by the configured
alias therefore reported or monitored the wrong certificate.
@dsoumis
dsoumis force-pushed the follow-up-on-eku-certifcate branch from 6f4accf to 11adba4 Compare October 28, 2026 14:34

@markt-asf markt-asf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is heading in the right direction. A couple of minor comments I'd recommend addressing before merging.

@dsoumis
dsoumis marked this pull request as draft October 28, 2026 15:29
@dsoumis
dsoumis marked this pull request as ready for review October 29, 2026 19:14
@dsoumis
dsoumis marked this pull request as draft October 29, 2026 19:24
…d, so Tomcat cannot reliably predict which alias a handshake will serve: the socket-based chooseServerAlias callback used elsewhere to probe the served alias may disagree with the chooseEngineServerAlias callback that an SSLEngine handshake actually uses. The alias the operator configured is therefore the only dependable answer for certificate monitoring.
@dsoumis
dsoumis marked this pull request as ready for review October 29, 2026 23:03
@dsoumis

dsoumis commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

@markt-asf I have addressed the issues raised and others discovered.

I would appreciate your review on these again.

If that looks good, I will also commit the test keys/certs to the svn repo.

@dsoumis
dsoumis requested a review from markt-asf October 30, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants