26
26
import java .security .UnrecoverableKeyException ;
27
27
import java .security .cert .X509Certificate ;
28
28
import 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 ;
29
33
30
34
import javax .net .ssl .KeyManager ;
31
35
import javax .net .ssl .KeyManagerFactory ;
42
46
* {@link KeyManagerFactory#getKeyManagers()} is final.
43
47
*
44
48
* @author Scott Frederick
49
+ * @author Stéphane Gobancé
45
50
*/
46
51
final class AliasKeyManagerFactory extends KeyManagerFactory {
47
52
@@ -105,23 +110,27 @@ private AliasX509ExtendedKeyManager(X509ExtendedKeyManager keyManager, String al
105
110
}
106
111
107
112
@ 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 ));
110
116
}
111
117
112
118
@ 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 ));
115
122
}
116
123
117
124
@ 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 ));
120
128
}
121
129
122
130
@ Override
123
131
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 ));
125
134
}
126
135
127
136
@ Override
@@ -144,6 +153,50 @@ public String[] getServerAliases(String keyType, Principal[] issuers) {
144
153
return this .delegate .getServerAliases (keyType , issuers );
145
154
}
146
155
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
+
147
200
}
148
201
149
202
}
0 commit comments