2626import java .security .UnrecoverableKeyException ;
2727import java .security .cert .X509Certificate ;
2828import java .util .Arrays ;
29+ import java .util .Objects ;
30+ import java .util .Optional ;
31+ import java .util .function .BiFunction ;
32+ import java .util .stream .Stream ;
2933
3034import javax .net .ssl .KeyManager ;
3135import javax .net .ssl .KeyManagerFactory ;
4246 * {@link KeyManagerFactory#getKeyManagers()} is final.
4347 *
4448 * @author Scott Frederick
49+ * @author Stéphane Gobancé
4550 */
4651final class AliasKeyManagerFactory extends KeyManagerFactory {
4752
@@ -105,23 +110,27 @@ private AliasX509ExtendedKeyManager(X509ExtendedKeyManager keyManager, String al
105110 }
106111
107112 @ Override
108- public String chooseEngineClientAlias (String [] strings , Principal [] principals , SSLEngine sslEngine ) {
109- return this .delegate .chooseEngineClientAlias (strings , principals , sslEngine );
113+ public String chooseEngineClientAlias (String [] keyTypes , Principal [] issuers , SSLEngine sslEngine ) {
114+ return findFirstMatchingAlias (keyTypes , issuers , this ::getClientAliases )
115+ .orElseGet (() -> this .delegate .chooseEngineClientAlias (keyTypes , issuers , sslEngine ));
110116 }
111117
112118 @ Override
113- public String chooseEngineServerAlias (String s , Principal [] principals , SSLEngine sslEngine ) {
114- return this .alias ;
119+ public String chooseEngineServerAlias (String keyType , Principal [] issuers , SSLEngine sslEngine ) {
120+ return findFirstMatchingAlias (keyType , issuers , this ::getServerAliases )
121+ .orElseGet (() -> this .delegate .chooseEngineServerAlias (keyType , issuers , sslEngine ));
115122 }
116123
117124 @ Override
118- public String chooseClientAlias (String [] keyType , Principal [] issuers , Socket socket ) {
119- return this .delegate .chooseClientAlias (keyType , issuers , socket );
125+ public String chooseClientAlias (String [] keyTypes , Principal [] issuers , Socket socket ) {
126+ return findFirstMatchingAlias (keyTypes , issuers , this ::getClientAliases )
127+ .orElseGet (() -> this .delegate .chooseClientAlias (keyTypes , issuers , socket ));
120128 }
121129
122130 @ Override
123131 public String chooseServerAlias (String keyType , Principal [] issuers , Socket socket ) {
124- return this .delegate .chooseServerAlias (keyType , issuers , socket );
132+ return findFirstMatchingAlias (keyType , issuers , this ::getServerAliases )
133+ .orElseGet (() -> this .delegate .chooseServerAlias (keyType , issuers , socket ));
125134 }
126135
127136 @ Override
@@ -144,6 +153,50 @@ public String[] getServerAliases(String keyType, Principal[] issuers) {
144153 return this .delegate .getServerAliases (keyType , issuers );
145154 }
146155
156+ /**
157+ * Typed-BiFunction for better readability.
158+ */
159+ private interface KeyAliasFinder extends BiFunction <String , Principal [], String []> {
160+
161+ }
162+
163+ /**
164+ * Gets this key manager's alias if it matches the given key algorithm and has
165+ * been issued by any of the specified issuers (might be {@code null}, meaning
166+ * issuer does not matter) otherwise returns an {@link Optional#empty() empty
167+ * result }.
168+ * @param keyType the required key algorithm.
169+ * @param issuers the list of acceptable CA issuer subject names or {@code null}
170+ * if it does not matter which issuers are used.
171+ * @param finder the function to find the underlying available key aliases.
172+ * @return this key manager's alias if appropriate or an empty result otherwise.
173+ */
174+ private Optional <String > findFirstMatchingAlias (String keyType , Principal [] issuers , KeyAliasFinder finder ) {
175+ return findFirstMatchingAlias (new String [] { keyType }, issuers , finder );
176+ }
177+
178+ /**
179+ * Gets this key manager's alias if it matches any of the given key algorithms and
180+ * has been issued by any of the specified issuers (might be {@code null}, meaning
181+ * issuer does not matter) otherwise returns an {@link Optional#empty() empty
182+ * result }.
183+ * @param keyTypes the required key algorithms.
184+ * @param issuers the list of acceptable CA issuer subject names or {@code null}
185+ * if it does not matter which issuers are used.
186+ * @param finder the function to find the underlying available key aliases.
187+ * @return this key manager's alias if appropriate or an empty result otherwise.
188+ */
189+ private Optional <String > findFirstMatchingAlias (String [] keyTypes , Principal [] issuers , KeyAliasFinder finder ) {
190+ return Optional .ofNullable (keyTypes )
191+ .flatMap (types -> Stream .of (types )
192+ .filter (Objects ::nonNull )
193+ .map (type -> finder .apply (type , issuers ))
194+ .filter (Objects ::nonNull )
195+ .flatMap (Stream ::of )
196+ .filter (this .alias ::equals )
197+ .findFirst ());
198+ }
199+
147200 }
148201
149202}
0 commit comments