1 17 18 package org.apache.geronimo.console.core.keystore; 19 20 import java.io.ByteArrayInputStream ; 21 import java.io.ByteArrayOutputStream ; 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.InputStream ; 26 import java.math.BigInteger ; 27 import java.security.KeyPair ; 28 import java.security.KeyPairGenerator ; 29 import java.security.KeyStore ; 30 import java.security.KeyStoreException ; 31 import java.security.PrivateKey ; 32 import java.security.PublicKey ; 33 import java.security.cert.Certificate ; 34 import java.security.cert.CertificateFactory ; 35 import java.security.cert.X509Certificate ; 36 import java.util.ArrayList ; 37 import java.util.Collection ; 38 import java.util.Date ; 39 import java.util.Enumeration ; 40 import java.util.Hashtable ; 41 import java.util.Iterator ; 42 import java.util.List ; 43 import java.util.Vector ; 44 45 import org.apache.commons.logging.Log; 46 import org.apache.commons.logging.LogFactory; 47 import org.apache.geronimo.gbean.GBeanInfo; 48 import org.apache.geronimo.gbean.GBeanInfoBuilder; 49 import org.apache.geronimo.gbean.GBeanLifecycle; 50 import org.apache.geronimo.gbean.WaitingException; 51 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 52 import org.apache.geronimo.system.serverinfo.ServerInfo; 53 import org.apache.geronimo.util.asn1.ASN1Set; 54 import org.apache.geronimo.util.asn1.DEROutputStream; 55 import org.apache.geronimo.util.asn1.x509.X509Name; 56 import org.apache.geronimo.util.encoders.Base64; 57 import org.apache.geronimo.util.jce.PKCS10CertificationRequest; 58 import org.apache.geronimo.util.jce.X509Principal; 59 import org.apache.geronimo.util.jce.X509V1CertificateGenerator; 60 61 public class KeyStoreGBean implements GBeanLifecycle { 62 63 private static Log log = LogFactory.getLog(KeyStoreGBean.class); 64 65 private String keyStoreType; 66 67 private String keyStoreProvider; 68 69 private String keyStoreLocation; 70 71 private String keyStorePassword; 72 73 private String keyPassword; 74 75 private KeyStore keystore; 76 77 private ServerInfo serverInfo; 79 80 public KeyStoreGBean() { 81 keyPassword = new String (""); 82 } 83 84 public void doStart() throws WaitingException, Exception { 85 86 88 this.keystore = KeyStore.getInstance(keyStoreType); 89 90 boolean keystoreExistsFlag = true; 91 InputStream is = null; 92 93 try { 94 File keyStore = serverInfo.resolveServer(this.keyStoreLocation); 95 log.debug("loading keystore from " + keyStore); 96 is = new java.io.FileInputStream (keyStore); 97 this.keystore.load(is, this.keyStorePassword.toCharArray()); 98 } catch (java.io.FileNotFoundException e) { 99 keystoreExistsFlag = false; 100 } finally { 101 try { 102 if (is != null) { 103 is.close(); 104 } 105 } catch (Exception e) { 106 } 107 } 108 109 if (keystoreExistsFlag == false) { 110 keystore.load(null, keyStorePassword.toCharArray()); 111 } 112 } 113 114 public void doStop() throws WaitingException, Exception { 115 } 116 117 public void doFail() { 118 } 119 120 public void setKeyStoreType(String keyStoreType) { 121 this.keyStoreType = keyStoreType; 122 } 123 124 public String getKeyStoreType() { 125 return this.keyStoreType; 126 } 127 128 public void setKeyStoreProvider(String keyStoreProvider) { 129 this.keyStoreProvider = keyStoreProvider; 130 } 131 132 public String getKeyStoreProvider() { 133 return this.keyStoreProvider; 134 } 135 136 public void setKeyStoreLocation(String keyStoreLocation) { 137 this.keyStoreLocation = keyStoreLocation; 138 } 139 140 public ServerInfo getServerInfo() { 141 return serverInfo; 142 } 143 144 public void setServerInfo(ServerInfo serverInfo) { 145 this.serverInfo = serverInfo; 146 } 147 148 public String getKeyStoreLocation() { 149 return this.keyStoreLocation; 150 } 151 152 public void setKeyStorePassword(String keyStorePassword) { 153 this.keyStorePassword = keyStorePassword; 154 } 155 156 public String getKeyStorePassword() { 157 return this.keyStorePassword; 158 } 159 160 public int getKeyStoreSize() throws KeyStoreException { 161 return this.keystore.size(); 162 } 163 164 public KeyEntryInfo getKeyEntryInfo(String alias) throws KeyStoreException { 165 KeyEntryInfo info = null; 166 167 if (this.keystore.isCertificateEntry(alias)) { 168 info = new KeyEntryInfo(alias, "trusted certificate", keystore 170 .getCreationDate(alias)); 171 } else if (this.keystore.isKeyEntry(alias)) { 172 info = new KeyEntryInfo(alias, "private key", keystore 174 .getCreationDate(alias)); 175 } else { 176 throw new KeyStoreException ("invalid key entry type"); 177 } 178 return info; 179 } 180 181 public List getKeyStoreEntries() throws KeyStoreException { 182 List list = new ArrayList (); 183 184 Enumeration aliases = this.keystore.aliases(); 185 186 while (aliases.hasMoreElements()) { 187 String alias = (String ) aliases.nextElement(); 188 list.add(getKeyEntryInfo(alias)); 189 } 190 return list; 191 } 192 193 public Certificate [] getCertificateChain(String alias) 194 throws KeyStoreException { 195 Certificate [] certs = null; 196 197 if (keystore.isCertificateEntry(alias)) { 198 Certificate cert = keystore.getCertificate(alias); 199 certs = new Certificate [1]; 200 certs[0] = cert; 201 } else if (keystore.isKeyEntry(alias)) { 202 certs = keystore.getCertificateChain(alias); 203 } else if (keystore.containsAlias(alias)) { 204 throw new KeyStoreException ("Unsupported key-store-entry, alias = " 205 + alias); 206 } else { 207 throw new KeyStoreException ( 208 "Key-store-entry alias not found, alias = " + alias); 209 } 210 211 return certs; 212 } 213 214 public String generateCSR(String alias) throws Exception { 215 216 X509Certificate cert = (X509Certificate ) keystore.getCertificate(alias); 218 219 PrivateKey key = (PrivateKey ) keystore.getKey(alias, new String ("") 221 .toCharArray()); 222 223 String csr = generateCSR(cert, key); 225 return csr; 226 } 227 228 public String generateCSR(X509Certificate cert, PrivateKey signingKey) 229 throws Exception { 230 231 String sigalg = cert.getSigAlgName(); 232 X509Name subject = new X509Name(cert.getSubjectDN().toString()); 233 PublicKey publicKey = cert.getPublicKey(); 234 ASN1Set attributes = null; 235 236 PKCS10CertificationRequest csr = new PKCS10CertificationRequest(sigalg, 237 subject, publicKey, attributes, signingKey); 238 239 if (!csr.verify()) { 240 throw new KeyStoreException ("CSR verification failed"); 241 } 242 243 ByteArrayOutputStream os = new ByteArrayOutputStream (); 244 DEROutputStream deros = new DEROutputStream(os); 245 deros.writeObject(csr.getDERObject()); 246 String b64 = new String (Base64.encode(os.toByteArray())); 247 248 final String BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----"; 249 final String END_CERT_REQ = "-----END CERTIFICATE REQUEST-----"; 250 final int CERT_REQ_LINE_LENGTH = 70; 251 252 StringBuffer sbuf = new StringBuffer (BEGIN_CERT_REQ).append('\n'); 253 254 int idx = 0; 255 while (idx < b64.length()) { 256 257 int len = (idx + CERT_REQ_LINE_LENGTH > b64.length()) ? b64 258 .length() 259 - idx : CERT_REQ_LINE_LENGTH; 260 261 String chunk = b64.substring(idx, idx + len); 262 263 sbuf.append(chunk).append('\n'); 264 idx += len; 265 } 266 267 sbuf.append(END_CERT_REQ); 268 return sbuf.toString(); 269 } 270 271 public void generateKeyPair(String alias, String keyalg, Integer keysize, 272 String sigalg, Integer validity, String cn, String ou, String o, 273 String l, String st, String c) 274 throws java.security.NoSuchAlgorithmException , 275 java.security.KeyStoreException , java.security.SignatureException , 276 java.security.InvalidKeyException , 277 java.security.cert.CertificateException , java.io.IOException { 278 279 KeyPairGenerator kpgen = KeyPairGenerator.getInstance(keyalg); 280 281 kpgen.initialize(keysize.intValue()); 282 283 KeyPair keyPair = kpgen.generateKeyPair(); 284 285 X509Certificate cert = generateCert(keyPair.getPublic(), keyPair 286 .getPrivate(), sigalg, validity.intValue(), cn, ou, o, l, st, c); 287 288 keystore.setKeyEntry(alias, keyPair.getPrivate(), new String () 289 .toCharArray(), new Certificate [] { cert }); 290 291 saveKeyStore(); 292 } 293 294 public void saveKeyStore() throws java.io.IOException , 295 java.security.KeyStoreException , 296 java.security.cert.CertificateException , 297 java.security.NoSuchAlgorithmException { 298 299 FileOutputStream os = null; 300 301 try { 302 File keyStore = serverInfo.resolveServer(this.keyStoreLocation); 303 os = new FileOutputStream (keyStore); 304 305 keystore.store(os, keyStorePassword.toCharArray()); 306 } finally { 307 if (os != null) { 308 try { 309 os.close(); 310 } catch (Exception ex) { 311 } 312 } 313 } 314 } 315 316 public X509Certificate generateCert(PublicKey publicKey, 317 PrivateKey privateKey, String sigalg, int validity, String cn, 318 String ou, String o, String l, String st, String c) 319 throws java.security.SignatureException , 320 java.security.InvalidKeyException { 321 X509V1CertificateGenerator certgen = new X509V1CertificateGenerator(); 322 323 Vector order = new Vector (); 325 Hashtable attrmap = new Hashtable (); 326 327 if (cn != null) { 328 attrmap.put(X509Principal.CN, cn); 329 order.add(X509Principal.CN); 330 } 331 332 if (ou != null) { 333 attrmap.put(X509Principal.OU, ou); 334 order.add(X509Principal.OU); 335 } 336 337 if (o != null) { 338 attrmap.put(X509Principal.O, o); 339 order.add(X509Principal.O); 340 } 341 342 if (l != null) { 343 attrmap.put(X509Principal.L, l); 344 order.add(X509Principal.L); 345 } 346 347 if (st != null) { 348 attrmap.put(X509Principal.ST, st); 349 order.add(X509Principal.ST); 350 } 351 352 if (c != null) { 353 attrmap.put(X509Principal.C, c); 354 order.add(X509Principal.C); 355 } 356 357 X509Principal issuerDN = new X509Principal(order, attrmap); 358 certgen.setIssuerDN(issuerDN); 359 360 long curr = System.currentTimeMillis(); 362 long untill = curr + (long) validity * 24 * 60 * 60 * 1000; 363 364 certgen.setNotBefore(new Date (curr)); 365 certgen.setNotAfter(new Date (untill)); 366 367 certgen.setSubjectDN(issuerDN); 369 370 certgen.setPublicKey(publicKey); 372 373 certgen.setSignatureAlgorithm(sigalg); 375 376 certgen.setSerialNumber(new BigInteger (String.valueOf(curr))); 378 379 X509Certificate cert = certgen.generateX509Certificate(privateKey); 381 return cert; 382 } 383 384 public void importTrustedX509Certificate(String alias, String certfile) 385 throws java.io.FileNotFoundException , 386 java.security.cert.CertificateException , 387 java.security.KeyStoreException , java.io.IOException , 388 java.security.NoSuchAlgorithmException , 389 java.security.NoSuchProviderException { 390 InputStream is = null; 391 392 try { 393 CertificateFactory cf = CertificateFactory.getInstance("X.509", 394 keyStoreProvider); 395 396 is = new FileInputStream (certfile); 397 Certificate cert = cf.generateCertificate(is); 398 399 keystore.setCertificateEntry(alias, cert); 400 401 saveKeyStore(); 402 } finally { 403 if (is != null) { 404 try { 405 is.close(); 406 } catch (Exception e) { 407 } 408 } 409 } 410 } 411 412 public void importPKCS7Certificate(String alias, String certbuf) 413 throws java.security.cert.CertificateException , 414 java.security.NoSuchProviderException , 415 java.security.KeyStoreException , 416 java.security.NoSuchAlgorithmException , 417 java.security.UnrecoverableKeyException , java.io.IOException { 418 419 InputStream is = null; 420 421 try { 422 is = new ByteArrayInputStream (certbuf.getBytes()); 423 importPKCS7Certificate(alias, is); 424 } finally { 425 if (is != null) { 426 try { 427 is.close(); 428 } catch (Exception e) { 429 } 430 } 431 } 432 } 433 434 public void importPKCS7Certificate(String alias, InputStream is) 435 throws java.security.cert.CertificateException , 436 java.security.NoSuchProviderException , 437 java.security.KeyStoreException , 438 java.security.NoSuchAlgorithmException , 439 java.security.UnrecoverableKeyException , java.io.IOException { 440 441 CertificateFactory cf = CertificateFactory.getInstance("X.509", 442 keyStoreProvider); 443 Collection certcoll = cf.generateCertificates(is); 444 445 Certificate [] chain = new Certificate [certcoll.size()]; 446 447 Iterator iter = certcoll.iterator(); 448 for (int i = 0; iter.hasNext(); i++) { 449 chain[i] = (Certificate ) iter.next(); 450 } 451 452 char[] password = keyPassword.toCharArray(); 453 keystore.setKeyEntry(alias, keystore.getKey(alias, password), password, 454 chain); 455 456 saveKeyStore(); 457 } 458 459 460 public static final GBeanInfo GBEAN_INFO; 461 462 static { 463 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(KeyStoreGBean.class); 464 465 infoFactory.addAttribute("keyStoreType", String .class, true); 466 infoFactory.addAttribute("keyStoreProvider", String .class, true); 467 infoFactory.addAttribute("keyStoreLocation", String .class, true); 468 infoFactory.addAttribute("keyStorePassword", String .class, true); 469 470 infoFactory.addReference("serverInfo", ServerInfo.class, NameFactory.GERONIMO_SERVICE); 471 472 infoFactory.addOperation("getKeyEntryInfo", 473 new Class [] { String .class }); 474 infoFactory.addOperation("getKeyStoreSize"); 475 infoFactory.addOperation("getKeyStoreEntries"); 476 infoFactory.addOperation("getCertificateChain", 477 new Class [] { String .class }); 478 infoFactory.addOperation("generateCSR", new Class [] { String .class }); 479 480 infoFactory.addOperation("generateKeyPair", new Class [] { String .class, 481 String .class, Integer .class, String .class, Integer .class, 482 String .class, String .class, String .class, String .class, 483 String .class, String .class }); 484 485 infoFactory.addOperation("importTrustedX509Certificate", new Class [] { 486 String .class, String .class }); 487 infoFactory.addOperation("importPKCS7Certificate", new Class [] { 488 String .class, String .class }); 489 490 GBEAN_INFO = infoFactory.getBeanInfo(); 491 } 492 493 public static GBeanInfo getGBeanInfo() { 494 return GBEAN_INFO; 495 } 496 497 } 498 | Popular Tags |