-
Notifications
You must be signed in to change notification settings - Fork 41.1k
Fix AliasX509ExtendedKeyManager to process both server and client aliases properly #44629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix AliasX509ExtendedKeyManager to process both server and client aliases properly #44629
Conversation
190f7f1
to
1a9d178
Compare
Hi, |
I don't think anybody has missed anything. We're just a small team with plenty to do. Some PRs are easier to digest than others which can lead to them being processed more quickly as they're easier to fit in when only a small chunk of time is available.
I've approved the workflow. Thanks for the nudge on that. We'll review this in more detail as soon as we can. Thanks for your patience in the meantime. |
No problem Andy. I understand you are overwhelmed with lots of other stuff. I only wanted to be sure that my PR would be considered. |
1a9d178
to
c9710e4
Compare
I have just rebased my branch on the main with last changes. Waiting for the workflow to be re-rerun. |
@ecnabogs Thanks, workflows should run automatically now the first one has been approved. |
} | ||
|
||
@Test | ||
void chooseEngineServerAliasReturnsDelegateAliasWhenTestAliasIsUnknown() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this is the behavior that we want. If the user's configured a particular alias, I would not expect another alias to be used. The same applies to the other …WhenTestAliasIsUnknown
tests below but I may well be missing something and we don't need to have the same discussion multiple times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since all chooseXXXAlias(...)
methods in the current Spring Boot implementation, except chooseEngineServerAlias(...)
one, are delegating their behavior to the internal delegate factory, I was assuming that it was a fallback choice. If we consider that we should return our configured alias (if available and compatible) or nothing, I can change the implementation and the tests. The JDK default implementation returns the first alias whose associated key's algorithm and issuer match the ones requested. Then, the key point now is to choose between the strategy selecting an exclusive configured key alias or the one selecting a preferred one and falling back to another one if unavailable. I have no preference regarding this choice. Maybe it could also be parameterized, couldn't it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thus far, we'd only really considered the server and SSLEngine side of things and it, as you noted above, always returns the user's configured alias.
Then, the key point now is to choose between the strategy selecting an exclusive configured key alias or the one selecting a preferred one and falling back to another one if unavailable
My preference is for the former. I think it could be considered a regression if we changed the behaviour to return an alias that isn't the user-configured alias.
I have no preference regarding this choice. Maybe it could also be parameterized, couldn't it ?
If there's demand for it, that's certainly something that we could consider. I could also imagine some users may want to be able to configure multiple aliases which can then be part of the negotiation to determine the preferred alias. I'd wait for some demand before adding that complexity too, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I had not considered regression issues. I agree not to return delegate choice in this case. However, in the current implementation, key's algorithm and issuer are not taken into account while selecting the alias. If we keep returning the configured alias unconditionally, it might also be considered as a bug. If the configured key's algorithm and issuer do not match the passed parameters, we should return null
, right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the configured key's algorithm and issuer do not match the passed parameters, we should return null, right?
Yes, I think so. It's returned too broadly now and it should be fine to narrow things down. AIUI, with the current implementation we may return an alias that can't actually be used which violates the contract of the choose…
methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, fine. I will update the code and the tests accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix done. Awaiting for approval to run the worklow.
…ases properly Signed-off-by: Stéphane Gobancé <[email protected]>
03417b1
to
680515a
Compare
Signed-off-by: Stéphane Gobancé <[email protected]>
SpringBoot provides a default implementation of the
org.springframework.boot.ssl.SslManagerBundle
interface (DefaultSslManagerBundle
) that allows to specify aSslBundleKey
(referencing the private key within the associatedKeyStore
) to be used for establishing an SSL connection. This feature, added in SpringBoot 3.1.0, is really appreciable as it simplifies a lot the selection of the private key to be used during SSL handshake.However, the thing is that the underlying implementation (
AliasX509ExtendedKeyManager
) only considers the server-side of an SSL connection. If a client has to communicate with multiple partners through mTLS protocol and has a single KeyStore containing its private keys, it cannot select the appropriate key alias to be used with the related partner.My proposal is to support this use case and to make
AliasX509ExtendedKeyManager
working similarly for both server and client sides. That's the first point.Then, looking more in details at the implementation, I noticed that the selected alias was returned unconditionally at the server side. I think it is not correct as SSL handshake is expected to reach an agreement between client and server, especially regarding the key algorithm to be used. Here, this algorithm is not taken into account meaning that although the key with the specified alias could exist in the underlying
KeyStore
, it could also be of the wrong type.Thus, my implementation gets inspired by the JDK default implementation (
sun.security.ssl.SunX509KeyManagerImpl
) in which the alias selection is made by calling the getServerAliases(keyType, ...) or getClientAliases(keyType, ...) for restricting the choice to compatible keys only.Finally, the
AliasX509ExtendedKeyManager
current implementation also only considers the transport-independent SSLEngine but not theSocket
-specific one. To cover all use cases, the implementation should also apply the same alias selection logic to theSocket
-specific methods. That's what I did actually and factorized this logic for all contexts.