1 /* 2 * Copyright 2008-2012 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 }