View Javadoc

1   /*
2    * Copyright 2008-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.util.test.security;
17  
18  import java.io.BufferedInputStream;
19  import java.io.InputStream;
20  import java.security.KeyStore;
21  import java.security.KeyStoreException;
22  import java.security.NoSuchAlgorithmException;
23  import java.security.PrivateKey;
24  import java.security.UnrecoverableKeyException;
25  import java.security.cert.Certificate;
26  
27  import org.apache.commons.io.IOUtils;
28  
29  /**
30   * Helper to read a key store and make its keys and certificates easily
31   * accessible.
32   *
33   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
34   * @version $Revision:591 $
35   */
36  public final class KeyStoreTestHelper
37  {
38    // ********************************* Fields *********************************
39  
40    // --- constants ------------------------------------------------------------
41  
42    // --- members --------------------------------------------------------------
43  
44    /**
45     * The test key store.
46     */
47    private final KeyStore keyStore;
48  
49    // ****************************** Initializer *******************************
50  
51    // ****************************** Constructors ******************************
52  
53    /**
54     * Default constructor.
55     *
56     * @param keyStore the test key store.
57     */
58    private KeyStoreTestHelper(final KeyStore keyStore)
59    {
60      this.keyStore = keyStore;
61    }
62  
63    // ****************************** Inner Classes *****************************
64  
65    // ********************************* Methods ********************************
66  
67    // --- init -----------------------------------------------------------------
68  
69    // --- get&set --------------------------------------------------------------
70  
71    /**
72     * Returns the test key store.
73     *
74     * @return the test key store.
75     */
76    public KeyStore getKeyStore()
77    {
78      return keyStore;
79    }
80  
81    // --- create ---------------------------------------------------------------
82  
83    /**
84     * Creates an instance of the key store helper read from the class path.
85     *
86     * @param classLoader the class loader to locate the key store specified by
87     *          <code>name</code>.
88     * @param name the name of the key store to be read from the class path.
89     * @param type the type of the key store to be read.
90     * @param password the password to access the key store.
91     * @return the created instance.
92     * @throws IllegalArgumentException if the key store cannot be read with the
93     *           information given.
94     */
95    public static KeyStoreTestHelper createFromClassPath(
96        final ClassLoader classLoader, final String name, final String type,
97        final char[] password) throws IllegalArgumentException
98    {
99      InputStream input = classLoader.getResourceAsStream(name);
100     if (input != null)
101     {
102       try
103       {
104         input = new BufferedInputStream(input);
105         return createFromStream(input, type, password);
106       }
107       catch (final Exception e)
108       {
109         final String message =
110             "The key store '" + name + "' cannot be read from the class path.";
111         throw new IllegalArgumentException(message, e);
112       }
113       finally
114       {
115         IOUtils.closeQuietly(input);
116       }
117     }
118     final String message =
119         "The key store '" + name + "' cannot be found on the class path.";
120     throw new IllegalStateException(message);
121   }
122 
123   /**
124    * Creates an instance of the key store helper read from the class path.
125    *
126    * @param referenceType the type whose class loader is to be used to locate
127    *          the key store specified by <code>name</code>.
128    * @param name the name of the key store to be read from the class path.
129    * @param type the type of the key store to be read.
130    * @param password the password to access the key store.
131    * @return the created instance.
132    * @throws IllegalArgumentException if the key store cannot be read with the
133    *           information given.
134    */
135   public static KeyStoreTestHelper createFromClassPath(
136       final Class<?> referenceType, final String name, final String type,
137       final char[] password) throws IllegalArgumentException
138   {
139     return createFromClassPath(referenceType.getClassLoader(), name, type,
140         password);
141   }
142 
143   /**
144    * Creates an instance of the key store helper read from the class path.
145    *
146    * @param referenceType the type whose class loader is to be used to locate
147    *          the key store specified by <code>relativeName</code>.
148    * @param relativeName the relative name of the key store to be read from the
149    *          class path.
150    * @param type the type of the key store to be read.
151    * @param password the password to access the key store.
152    * @return the created instance.
153    * @throws IllegalArgumentException if the key store cannot be read with the
154    *           information given.
155    */
156   public static KeyStoreTestHelper createFromClassPathRelative(
157       final Class<?> referenceType, final String relativeName,
158       final String type, final char[] password) throws IllegalArgumentException
159   {
160     return createFromStream(referenceType.getResourceAsStream(relativeName),
161         type, password);
162   }
163 
164   /**
165    * Creates an instance of the key store helper read from the class path.
166    *
167    * @param input the stream to read the key store from.
168    * @param type the type of the key store to be read.
169    * @param password the password to access the key store.
170    * @return the created instance.
171    * @throws IllegalArgumentException if the key store cannot be read with the
172    *           information given.
173    */
174   public static KeyStoreTestHelper createFromStream(final InputStream input,
175       final String type, final char[] password) throws IllegalArgumentException
176   {
177     try
178     {
179       final KeyStore keyStore = KeyStore.getInstance(type);
180       keyStore.load(input, password);
181       return new KeyStoreTestHelper(keyStore);
182     }
183     catch (final Exception e)
184     {
185       final String message = "The key store cannot be read.";
186       throw new IllegalArgumentException(message, e);
187     }
188   }
189 
190   // --- business -------------------------------------------------------------
191 
192   /**
193    * Reads the private key from the key store.
194    *
195    * @param alias the alias of the private key.
196    * @param password the password to access the private key.
197    * @return the private key from the key store.
198    * @throws IllegalArgumentException if the information is not sufficient to
199    *           access the private key.
200    */
201   public PrivateKey readPrivateKey(final String alias, final char[] password)
202     throws IllegalArgumentException
203   {
204     try
205     {
206       return (PrivateKey) keyStore.getKey(alias, password);
207     }
208     catch (final KeyStoreException e)
209     {
210       final String message =
211           "Key with alias '" + alias + "' cannot be read from key store."; // NOPMD
212       throw new IllegalArgumentException(message, e);
213     }
214     catch (final NoSuchAlgorithmException e)
215     {
216       final String message =
217           "Key with alias '" + alias + "' cannot be read from key store.";
218       throw new IllegalArgumentException(message, e);
219     }
220     catch (final UnrecoverableKeyException e)
221     {
222       final String message =
223           "Key with alias '" + alias + "' cannot be read from key store.";
224       throw new IllegalArgumentException(message, e);
225     }
226   }
227 
228   /**
229    * Reads the certificate from the key store.
230    *
231    * @param alias the alias of the certificate.
232    * @return the certificate from the key store.
233    * @throws IllegalArgumentException if the certificate cannot be read from the
234    *           key store.
235    */
236   public Certificate readCertificate(final String alias)
237     throws IllegalArgumentException
238   {
239     try
240     {
241       final Certificate certificate = keyStore.getCertificate(alias);
242       return certificate;
243     }
244     catch (final KeyStoreException e)
245     {
246       final String message =
247           "The certificate with alias '" + alias
248               + "' cannot be read from key store.";
249       throw new IllegalArgumentException(message, e);
250     }
251   }
252 
253   // --- object basics --------------------------------------------------------
254 
255 }