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+ * Gets this key manager's alias if it matches the given key algorithm and has
158+ * been issued by any of the specified issuers (might be {@code null}, meaning
159+ * issuer does not matter) otherwise returns an {@link Optional#empty() empty
160+ * result }.
161+ * @param keyType the required key algorithm.
162+ * @param issuers the list of acceptable CA issuer subject names or {@code null}
163+ * if it does not matter which issuers are used.
164+ * @param finder the function to find the underlying available key aliases.
165+ * @return this key manager's alias if appropriate or an empty result otherwise.
166+ */
167+ private Optional <String > findFirstMatchingAlias (String keyType , Principal [] issuers , KeyAliasFinder finder ) {
168+ return findFirstMatchingAlias (new String [] { keyType }, issuers , finder );
169+ }
170+
171+ /**
172+ * Gets this key manager's alias if it matches any of the given key algorithms and
173+ * has been issued by any of the specified issuers (might be {@code null}, meaning
174+ * issuer does not matter) otherwise returns an {@link Optional#empty() empty
175+ * result }.
176+ * @param keyTypes the required key algorithms.
177+ * @param issuers the list of acceptable CA issuer subject names or {@code null}
178+ * if it does not matter which issuers are used.
179+ * @param finder the function to find the underlying available key aliases.
180+ * @return this key manager's alias if appropriate or an empty result otherwise.
181+ */
182+ private Optional <String > findFirstMatchingAlias (String [] keyTypes , Principal [] issuers , KeyAliasFinder finder ) {
183+ return Optional .ofNullable (keyTypes )
184+ .flatMap ((types ) -> Stream .of (types )
185+ .filter (Objects ::nonNull )
186+ .map ((type ) -> finder .apply (type , issuers ))
187+ .filter (Objects ::nonNull )
188+ .flatMap (Stream ::of )
189+ .filter (this .alias ::equals )
190+ .findFirst ());
191+ }
192+
193+ /**
194+ * Typed-BiFunction for better readability.
195+ */
196+ private interface KeyAliasFinder extends BiFunction <String , Principal [], String []> {
197+
198+ }
199+
147200 }
148201
149202}
0 commit comments