001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.util;
028
029
030
031 import java.net.Socket;
032 import java.security.Principal;
033 import java.security.PrivateKey;
034 import java.security.cert.X509Certificate;
035 import javax.net.ssl.KeyManager;
036 import javax.net.ssl.SSLEngine;
037 import javax.net.ssl.X509ExtendedKeyManager;
038 import javax.net.ssl.X509KeyManager;
039
040
041
042 /**
043 * This class implements an X.509 key manager that will be used to wrap an
044 * existing key manager and makes it possible to configure which certificate(s)
045 * should be used for client and/or server operations. The certificate
046 * selection will be based on the alias (also called the nickname) of the
047 * certificate.
048 */
049 @org.opends.server.types.PublicAPI(
050 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
051 mayInstantiate=true,
052 mayExtend=false,
053 mayInvoke=true)
054 public final class SelectableCertificateKeyManager
055 extends X509ExtendedKeyManager
056 {
057 // The alias of the certificate that should be selected from the key manager.
058 private String alias;
059
060 // The key manager that is wrapped by this key manager.
061 private X509KeyManager keyManager;
062
063
064
065 /**
066 * Creates a new instance of this key manager that will wrap the provided key
067 * manager and use the certificate with the specified alias.
068 *
069 * @param keyManager The key manager to be wrapped by this key manager.
070 * @param alias The nickname of the certificate that should be
071 * selected for operations involving this key manager.
072 */
073 public SelectableCertificateKeyManager(X509KeyManager keyManager,
074 String alias)
075 {
076 super();
077
078 this.keyManager = keyManager;
079 this.alias = alias;
080 }
081
082
083
084 /**
085 * Chooses the alias of the client certificate that should be used based on
086 * the provided critieria. This will either return the preferred alias
087 * configured for this key manager, or {@code null} if no client certificate
088 * with that alias is configured in the underlying key manager.
089 *
090 * @param keyType The set of key algorithm names, ordered with the most
091 * preferred key type first.
092 * @param issuers The list of acceptable issuer subject names, or
093 * {@code null} if any issuer may be used.
094 * @param socket The socket to be used for this connection.
095 *
096 * @return The alias configured for this key manager, or {@code null} if no
097 * such client certificate is available with that alias.
098 */
099 public String chooseClientAlias(String[] keyType, Principal[] issuers,
100 Socket socket)
101 {
102 for (String type : keyType)
103 {
104 String[] clientAliases = keyManager.getClientAliases(type, issuers);
105 if (clientAliases != null)
106 {
107 for (String clientAlias : clientAliases)
108 {
109 if (clientAlias.equals(alias))
110 {
111 return alias;
112 }
113 }
114 }
115 }
116
117 return null;
118 }
119
120
121
122 /**
123 * Chooses the alias of the client certificate that should be used based on
124 * the provided critieria. This will either return the preferred alias
125 * configured for this key manager, or {@code null} if no client certificate
126 * with that alias is configured in the underlying key manager.
127 *
128 * @param keyType The set of key algorithm names, ordered with the most
129 * preferred key type first.
130 * @param issuers The list of acceptable issuer subject names, or
131 * {@code null} if any issuer may be used.
132 * @param engine The SSL engine to be used for this connection.
133 *
134 * @return The alias configured for this key manager, or {@code null} if no
135 * such client certificate is available with that alias.
136 */
137 public String chooseEngineClientAlias(String[] keyType, Principal[] issuers,
138 SSLEngine engine)
139 {
140 for (String type : keyType)
141 {
142 String[] clientAliases = keyManager.getClientAliases(type, issuers);
143 if (clientAliases != null)
144 {
145 for (String clientAlias : clientAliases)
146 {
147 if (clientAlias.equals(alias))
148 {
149 return alias;
150 }
151 }
152 }
153 }
154
155 return null;
156 }
157
158
159
160 /**
161 * Chooses the alias of the server certificate that should be used based on
162 * the provided critieria. This will either return the preferred alias
163 * configured for this key manager, or {@code null} if no server certificate
164 * with that alias is configured in the underlying key manager.
165 *
166 * @param keyType The public key type for the certificate.
167 * @param issuers The list of acceptable issuer subject names, or
168 * {@code null} if any issuer may be used.
169 * @param socket The socket to be used for this connection.
170 *
171 * @return The alias configured for this key manager, or {@code null} if no
172 * such server certificate is available with that alias.
173 */
174 public String chooseServerAlias(String keyType, Principal[] issuers,
175 Socket socket)
176 {
177 String[] serverAliases = keyManager.getServerAliases(keyType, issuers);
178 if (serverAliases != null)
179 {
180 for (String serverAlias : serverAliases)
181 {
182 if (serverAlias.equals(alias))
183 {
184 return alias;
185 }
186 }
187 }
188
189 return null;
190 }
191
192
193
194 /**
195 * Chooses the alias of the server certificate that should be used based on
196 * the provided critieria. This will either return the preferred alias
197 * configured for this key manager, or {@code null} if no server certificate
198 * with that alias is configured in the underlying key manager.
199 *
200 * @param keyType The public key type for the certificate.
201 * @param issuers The list of acceptable issuer subject names, or
202 * {@code null} if any issuer may be used.
203 * @param engine The SSL engine to be used for this connection.
204 *
205 * @return The alias configured for this key manager, or {@code null} if no
206 * such server certificate is available with that alias.
207 */
208 public String chooseEngineServerAlias(String keyType, Principal[] issuers,
209 SSLEngine engine)
210 {
211 String[] serverAliases = keyManager.getServerAliases(keyType, issuers);
212 if (serverAliases != null)
213 {
214 for (String serverAlias : serverAliases)
215 {
216 if (serverAlias.equals(alias))
217 {
218 return alias;
219 }
220 }
221 }
222
223 return null;
224 }
225
226
227
228 /**
229 * Retrieves the certificate chain for the provided alias.
230 *
231 * @param alias The alias for the certificate chain to retrieve.
232 *
233 * @return The certificate chain for the provided alias, or {@code null} if
234 * no certificate is associated with the provided alias.
235 */
236 public X509Certificate[] getCertificateChain(String alias)
237 {
238 return keyManager.getCertificateChain(alias);
239 }
240
241
242
243 /**
244 * Retrieves the set of certificate aliases that may be used for client
245 * authentication with the given public key type and set of issuers.
246 *
247 * @param keyType The public key type for the aliases to retrieve.
248 * @param issuers The list of acceptable issuer subject names, or
249 * {@code null} if any issuer may be used.
250 *
251 * @return The set of certificate aliases that may be used for client
252 * authentication with the given public key type and set of issuers,
253 * or {@code null} if there were none.
254 */
255 public String[] getClientAliases(String keyType, Principal[] issuers)
256 {
257 return keyManager.getClientAliases(keyType, issuers);
258 }
259
260
261
262 /**
263 * Retrieves the private key for the provided alias.
264 *
265 * @param alias The alias for the private key to return.
266 *
267 * @return The private key for the provided alias, or {@code null} if no
268 * private key is available for the provided alias.
269 */
270 public PrivateKey getPrivateKey(String alias)
271 {
272 return keyManager.getPrivateKey(alias);
273 }
274
275
276
277 /**
278 * Retrieves the set of certificate aliases that may be used for server
279 * authentication with the given public key type and set of issuers.
280 *
281 * @param keyType The public key type for the aliases to retrieve.
282 * @param issuers The list of acceptable issuer subject names, or
283 * {@code null} if any issuer may be used.
284 *
285 * @return The set of certificate aliases that may be used for server
286 * authentication with the given public key type and set of issuers,
287 * or {@code null} if there were none.
288 */
289 public String[] getServerAliases(String keyType, Principal[] issuers)
290 {
291 return keyManager.getServerAliases(keyType, issuers);
292 }
293
294
295
296 /**
297 * Wraps the provided set of key managers in selectable certificate key
298 * managers using the provided alias.
299 *
300 * @param keyManagers The set of key managers to be wrapped.
301 * @param alias The alias to use for selecting the desired
302 * certificate.
303 *
304 * @return A key manager array
305 */
306 public static X509ExtendedKeyManager[] wrap(KeyManager[] keyManagers,
307 String alias)
308 {
309 X509ExtendedKeyManager[] newKeyManagers =
310 new X509ExtendedKeyManager[keyManagers.length];
311 for (int i=0; i < keyManagers.length; i++)
312 {
313 newKeyManagers[i] = new SelectableCertificateKeyManager(
314 (X509KeyManager) keyManagers[i], alias);
315 }
316
317 return newKeyManagers;
318 }
319 }
320