001 /*
002 * Copyright 2008-2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2016 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.util.ssl;
022
023
024
025 import java.io.File;
026 import java.io.FileInputStream;
027 import java.io.Serializable;
028 import java.security.KeyStore;
029 import java.security.KeyStoreException;
030 import javax.net.ssl.KeyManager;
031 import javax.net.ssl.KeyManagerFactory;
032
033
034 import static com.unboundid.util.Debug.*;
035 import static com.unboundid.util.Validator.*;
036 import static com.unboundid.util.ssl.SSLMessages.*;
037
038
039
040 /**
041 * This class provides an SSL key manager that may be used to retrieve
042 * certificates from a key store file. By default it will use the default key
043 * store format for the JVM (e.g., "JKS" for Sun-provided Java implementations),
044 * but alternate formats like PKCS12 may be used.
045 */
046 public final class KeyStoreKeyManager
047 extends WrapperKeyManager
048 implements Serializable
049 {
050 /**
051 * The serial version UID for this serializable class.
052 */
053 private static final long serialVersionUID = -5202641256733094253L;
054
055
056
057 // The path to the key store file.
058 private final String keyStoreFile;
059
060 // The format to use for the key store file.
061 private final String keyStoreFormat;
062
063
064
065 /**
066 * Creates a new instance of this key store key manager that provides the
067 * ability to retrieve certificates from the specified key store file. It
068 * will use the default key store format.
069 *
070 * @param keyStoreFile The path to the key store file to use. It must not
071 * be {@code null}.
072 * @param keyStorePIN The PIN to use to access the contents of the key
073 * store. It may be {@code null} if no PIN is required.
074 *
075 * @throws KeyStoreException If a problem occurs while initializing this key
076 * manager.
077 */
078 public KeyStoreKeyManager(final File keyStoreFile, final char[] keyStorePIN)
079 throws KeyStoreException
080 {
081 this(keyStoreFile.getAbsolutePath(), keyStorePIN, null, null);
082 }
083
084
085
086 /**
087 * Creates a new instance of this key store key manager that provides the
088 * ability to retrieve certificates from the specified key store file. It
089 * will use the default key store format.
090 *
091 * @param keyStoreFile The path to the key store file to use. It must not
092 * be {@code null}.
093 * @param keyStorePIN The PIN to use to access the contents of the key
094 * store. It may be {@code null} if no PIN is required.
095 *
096 * @throws KeyStoreException If a problem occurs while initializing this key
097 * manager.
098 */
099 public KeyStoreKeyManager(final String keyStoreFile, final char[] keyStorePIN)
100 throws KeyStoreException
101 {
102 this(keyStoreFile, keyStorePIN, null, null);
103 }
104
105
106
107 /**
108 * Creates a new instance of this key store key manager that provides the
109 * ability to retrieve certificates from the specified key store file.
110 *
111 * @param keyStoreFile The path to the key store file to use. It must
112 * not be {@code null}.
113 * @param keyStorePIN The PIN to use to access the contents of the key
114 * store. It may be {@code null} if no PIN is
115 * required.
116 * @param keyStoreFormat The format to use for the key store. It may be
117 * {@code null} if the default format should be
118 * used.
119 * @param certificateAlias The nickname of the certificate that should be
120 * selected. It may be {@code null} if any
121 * acceptable certificate found in the keystore may
122 * be used.
123 *
124 * @throws KeyStoreException If a problem occurs while initializing this key
125 * manager.
126 */
127 public KeyStoreKeyManager(final File keyStoreFile, final char[] keyStorePIN,
128 final String keyStoreFormat,
129 final String certificateAlias)
130 throws KeyStoreException
131 {
132 this(keyStoreFile.getAbsolutePath(), keyStorePIN, keyStoreFormat,
133 certificateAlias);
134 }
135
136
137
138 /**
139 * Creates a new instance of this key store key manager that provides the
140 * ability to retrieve certificates from the specified key store file.
141 *
142 * @param keyStoreFile The path to the key store file to use. It must
143 * not be {@code null}.
144 * @param keyStorePIN The PIN to use to access the contents of the key
145 * store. It may be {@code null} if no PIN is
146 * required.
147 * @param keyStoreFormat The format to use for the key store. It may be
148 * {@code null} if the default format should be
149 * used.
150 * @param certificateAlias The nickname of the certificate that should be
151 * selected. It may be {@code null} if any
152 * acceptable certificate found in the keystore may
153 * be used.
154 *
155 * @throws KeyStoreException If a problem occurs while initializing this key
156 * manager.
157 */
158 public KeyStoreKeyManager(final String keyStoreFile, final char[] keyStorePIN,
159 final String keyStoreFormat,
160 final String certificateAlias)
161 throws KeyStoreException
162 {
163 super(getKeyManagers(keyStoreFile, keyStorePIN, keyStoreFormat),
164 certificateAlias);
165
166 this.keyStoreFile = keyStoreFile;
167
168 if (keyStoreFormat == null)
169 {
170 this.keyStoreFormat = KeyStore.getDefaultType();
171 }
172 else
173 {
174 this.keyStoreFormat = keyStoreFormat;
175 }
176 }
177
178
179
180 /**
181 * Retrieves the set of key managers that will be wrapped by this key manager.
182 *
183 * @param keyStoreFile The path to the key store file to use. It must
184 * not be {@code null}.
185 * @param keyStorePIN The PIN to use to access the contents of the key
186 * store. It may be {@code null} if no PIN is
187 * required.
188 * @param keyStoreFormat The format to use for the key store. It may be
189 * {@code null} if the default format should be
190 * used.
191 *
192 * @return The set of key managers that will be wrapped by this key manager.
193 *
194 * @throws KeyStoreException If a problem occurs while initializing this key
195 * manager.
196 */
197 private static KeyManager[] getKeyManagers(final String keyStoreFile,
198 final char[] keyStorePIN,
199 final String keyStoreFormat)
200 throws KeyStoreException
201 {
202 ensureNotNull(keyStoreFile);
203
204 String type = keyStoreFormat;
205 if (type == null)
206 {
207 type = KeyStore.getDefaultType();
208 }
209
210 final File f = new File(keyStoreFile);
211 if (! f.exists())
212 {
213 throw new KeyStoreException(ERR_KEYSTORE_NO_SUCH_FILE.get(keyStoreFile));
214 }
215
216 final KeyStore ks = KeyStore.getInstance(type);
217 FileInputStream inputStream = null;
218 try
219 {
220 inputStream = new FileInputStream(f);
221 ks.load(inputStream, keyStorePIN);
222 }
223 catch (Exception e)
224 {
225 debugException(e);
226
227 throw new KeyStoreException(
228 ERR_KEYSTORE_CANNOT_LOAD.get(keyStoreFile, type, String.valueOf(e)),
229 e);
230 }
231 finally
232 {
233 if (inputStream != null)
234 {
235 try
236 {
237 inputStream.close();
238 }
239 catch (Exception e)
240 {
241 debugException(e);
242 }
243 }
244 }
245
246 try
247 {
248 final KeyManagerFactory factory = KeyManagerFactory.getInstance(
249 KeyManagerFactory.getDefaultAlgorithm());
250 factory.init(ks, keyStorePIN);
251 return factory.getKeyManagers();
252 }
253 catch (Exception e)
254 {
255 debugException(e);
256
257 throw new KeyStoreException(ERR_KEYSTORE_CANNOT_GET_KEY_MANAGERS.get(
258 keyStoreFile, keyStoreFormat, String.valueOf(e)), e);
259 }
260 }
261
262
263
264 /**
265 * Retrieves the path to the key store file to use.
266 *
267 * @return The path to the key store file to use.
268 */
269 public String getKeyStoreFile()
270 {
271 return keyStoreFile;
272 }
273
274
275
276 /**
277 * Retrieves the name of the key store file format.
278 *
279 * @return The name of the key store file format.
280 */
281 public String getKeyStoreFormat()
282 {
283 return keyStoreFormat;
284 }
285 }