1 16 package org.mortbay.util; 17 18 import java.io.ByteArrayInputStream ; 19 import java.io.DataInputStream ; 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.FileNotFoundException ; 23 import java.io.FileOutputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.security.GeneralSecurityException ; 27 import java.security.KeyFactory ; 28 import java.security.KeyStore ; 29 import java.security.PrivateKey ; 30 import java.security.Provider ; 31 import java.security.Security ; 32 import java.security.cert.Certificate ; 33 import java.security.cert.CertificateFactory ; 34 import java.security.spec.PKCS8EncodedKeySpec ; 35 import java.util.ArrayList ; 36 37 39 40 54 public class KeyPairTool 55 { 56 private File keyStoreFile 58 = new File (System.getProperty("user.home"), ".keystore"); 59 private String keyStoreType = KeyStore.getDefaultType(); 60 private Password keyStorePassword = null; 61 private Password keyPassword = null; 62 private String alias = "mykey"; 63 private File privateKeyFile = null; 64 private File certFile = null; 65 private String providerClassName 66 = "org.bouncycastle.jce.provider.BouncyCastleProvider"; 67 68 69 private static final String usageString 70 = "Tool to insert a private key/certificate pair into a keystore.\n" 71 + "Parameters:\n" 72 + " -key FILENAME, location of private key [MANDATORY]\n" 73 + " -cert FILENAME, location of certificate [MANDATORY]\n" 74 + " -storepass PASSWORD, keystore password [OPTIONAL - security RISK!]\n" 75 + " -keypass PASSWORD, password for new entry [=STOREPASS]\n" 76 + " -keystore FILENAME, location of keystore, [~/.keystore]\n" 77 + " -storetype STRING, name/type of keystore, [" 78 + KeyStore.getDefaultType() + "]\n" 79 + " -alias NAME, alias used to store key [mykey]\n" 80 + " -provider NAME, name of provider class [org.bouncycastle.jce.provider.BouncyCastleProvider]\n\n" 81 + "The keystore and key passwords will be prompted for or can be\n" 82 + "set with the following JVM system properties:\n" 83 + " jetty.ssl.password\n" 84 + " jetty.ssl.keypassword"; 85 86 87 88 91 public static void main(String [] args) 92 { 93 KeyPairTool tool = new KeyPairTool(); 95 tool.doit(args); 96 } 97 98 99 104 private void doit(String [] args) 105 { 106 try 107 { 108 loadParameters(args); 110 111 importKeyPair(); 113 } 114 catch (Exception e) 115 { 116 System.out.println("Exception: " + e.getMessage()); 117 e.printStackTrace(); 118 119 System.exit(23); 120 } 121 } 122 123 124 132 private void importKeyPair() 133 throws IOException , GeneralSecurityException , Exception 134 { 135 PrivateKey privateKey = loadPrivateKey(privateKeyFile); 137 138 Certificate [] certChain = loadCertChain(certFile); 140 141 if (keyPassword == null) 143 keyPassword = keyStorePassword; 144 145 KeyStore keyStore = KeyStore.getInstance(keyStoreType); 146 InputStream keyStoreStream = null; 147 try 148 { 149 keyStoreStream = new FileInputStream (keyStoreFile); 150 System.out.println("Will load " + keyStoreType 151 + " keystore: " + keyStoreFile); 152 } 153 catch (FileNotFoundException e) 154 { 155 System.out.println("Creating keystore: " + keyStoreFile); 157 } 158 159 keyStore.load(keyStoreStream, keyStorePassword.toString().toCharArray()); 161 162 if (keyStoreStream != null) 163 { 164 keyStoreStream.close(); 165 System.out.println("Keystore loaded OK..."); 166 } 167 168 keyStore.setKeyEntry(alias, 170 privateKey, 171 keyPassword.toString().toCharArray(), 172 certChain); 173 174 FileOutputStream keyStoreOut = new FileOutputStream (keyStoreFile); 176 keyStore.store(keyStoreOut, 177 keyStorePassword.toString().toCharArray()); 178 keyStoreOut.close(); 179 180 System.out.println("Keys have been written to keystore"); 181 } 182 183 184 194 private Certificate [] loadCertChain(File certFile) 195 throws Exception 196 { 197 DataInputStream dis = null; 198 try 199 { 200 FileInputStream fis = new FileInputStream (certFile); 201 dis = new DataInputStream (fis); 202 byte[] bytes = new byte[dis.available()]; 203 dis.readFully(bytes); 204 ByteArrayInputStream bais = new ByteArrayInputStream (bytes); 205 206 CertificateFactory certificateFactory 207 = CertificateFactory.getInstance("X.509"); 208 209 ArrayList chain = new ArrayList (); 210 while (bais.available() > 0) { 211 Certificate cert 212 = certificateFactory.generateCertificate(bais); 213 chain.add(cert); 215 } 216 217 Certificate [] certChain 218 = (Certificate [])chain.toArray(new Certificate [chain.size()]); 219 220 System.out.println("Loaded the cert chain. Depth = " 221 + certChain.length); 222 return certChain; 223 } 224 finally 225 { 226 IO.close(dis); 227 } 228 } 229 230 231 237 private PrivateKey loadPrivateKey(File privateKeyFile) 238 throws Exception 239 { 240 System.out.println("Loading private key from " 242 + privateKeyFile 243 + ", using " + providerClassName 244 + " as the private key loading provider"); 245 FileInputStream privateKeyInputStream = null; 246 byte[] keyBytes; 247 248 try 249 { 250 privateKeyInputStream = new FileInputStream (privateKeyFile); 251 keyBytes = new byte[(int) privateKeyFile.length()]; 252 privateKeyInputStream.read(keyBytes); 253 } 254 finally 255 { 256 IO.close(privateKeyInputStream); 257 } 258 259 Class providerClass = Loader.loadClass(this.getClass(),providerClassName); 262 Provider provider = (Provider )providerClass.newInstance(); 263 Security.insertProviderAt(provider, 1); 264 try { 265 PKCS8EncodedKeySpec privateKeySpec 267 = new PKCS8EncodedKeySpec (keyBytes); 268 KeyFactory keyFactory 269 = KeyFactory.getInstance("RSA"); 270 PrivateKey privateKey 271 = keyFactory.generatePrivate(privateKeySpec); 272 273 System.out.println("Loaded " + privateKey.getAlgorithm() 274 + " " + privateKey.getFormat() 275 + " private key."); 276 return privateKey; 277 } finally { 278 Security.removeProvider(provider.getName()); 280 } 281 } 282 283 284 287 static private void usage() 288 { 289 System.out.println(usageString); 290 System.exit(23); 291 } 292 293 294 300 private void loadParameters(String [] args) 301 { 302 for (int i = 0; (i < args.length) && args[i].startsWith("-"); i++) 303 { 304 String parameterName = args[i]; 305 if (parameterName.equalsIgnoreCase("-key")) 306 privateKeyFile = new File (args[++i]); 307 else if (parameterName.equalsIgnoreCase("-cert")) 308 certFile = new File (args[++i]); 309 else if (parameterName.equalsIgnoreCase("-keystore")) 310 keyStoreFile = new File (args[++i]); 311 else if (parameterName.equalsIgnoreCase("-storetype")) 312 keyStoreType = args[++i]; 313 else if (parameterName.equalsIgnoreCase("-alias")) 314 alias = args[++i]; 315 else if (parameterName.equalsIgnoreCase("-provider")) 316 providerClassName = args[++i]; 317 else 318 { 319 System.err.println("Illegal parameter: " + parameterName); 320 usage(); 321 } 322 } 323 324 if (privateKeyFile == null || certFile == null) 326 { 327 usage(); 328 } 329 330 keyStorePassword = Password.getPassword("jetty.ssl.password",null,null); 331 keyPassword = Password.getPassword("jetty.ssl.keypassword", 332 null, 333 keyStorePassword.toString()); 334 } 335 } 336 | Popular Tags |