1 13 14 package org.ejbca.ui.cli.batch; 15 16 import java.io.File ; 17 import java.io.FileOutputStream ; 18 import java.io.IOException ; 19 import java.rmi.RemoteException ; 20 import java.security.GeneralSecurityException ; 21 import java.security.KeyPair ; 22 import java.security.KeyStore ; 23 import java.security.KeyStoreException ; 24 import java.security.NoSuchAlgorithmException ; 25 import java.security.NoSuchProviderException ; 26 import java.security.UnrecoverableKeyException ; 27 import java.security.cert.Certificate ; 28 import java.security.cert.CertificateException ; 29 import java.security.cert.X509Certificate ; 30 import java.util.ArrayList ; 31 import java.util.Collection ; 32 import java.util.Iterator ; 33 34 import javax.ejb.CreateException ; 35 import javax.naming.Context ; 36 import javax.naming.NamingException ; 37 38 import org.apache.log4j.Logger; 39 import org.ejbca.core.ejb.InitialContextBuilder; 40 import org.ejbca.core.ejb.ca.auth.IAuthenticationSessionHome; 41 import org.ejbca.core.ejb.ca.auth.IAuthenticationSessionRemote; 42 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionHome; 43 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionRemote; 44 import org.ejbca.core.ejb.ca.sign.ISignSessionHome; 45 import org.ejbca.core.ejb.ca.sign.ISignSessionRemote; 46 import org.ejbca.core.ejb.keyrecovery.IKeyRecoverySessionHome; 47 import org.ejbca.core.ejb.keyrecovery.IKeyRecoverySessionRemote; 48 import org.ejbca.core.ejb.ra.IUserAdminSessionHome; 49 import org.ejbca.core.ejb.ra.IUserAdminSessionRemote; 50 import org.ejbca.core.ejb.ra.raadmin.IRaAdminSessionHome; 51 import org.ejbca.core.ejb.ra.raadmin.IRaAdminSessionRemote; 52 import org.ejbca.core.model.InternalResources; 53 import org.ejbca.core.model.SecConst; 54 import org.ejbca.core.model.ca.catoken.CATokenConstants; 55 import org.ejbca.core.model.keyrecovery.KeyRecoveryData; 56 import org.ejbca.core.model.log.Admin; 57 import org.ejbca.core.model.ra.UserAdminConstants; 58 import org.ejbca.core.model.ra.UserDataConstants; 59 import org.ejbca.core.model.ra.UserDataVO; 60 import org.ejbca.util.CertTools; 61 import org.ejbca.util.KeyTools; 62 import org.ejbca.util.P12toPEM; 63 64 65 66 67 73 public class BatchMakeP12 { 74 77 private static final Logger log = Logger.getLogger(BatchMakeP12.class); 78 79 private static final InternalResources intres = InternalResources.getInstance(); 80 81 BatchToolProperties props = new BatchToolProperties(); 82 83 84 87 private String mainStoreDir = ""; 88 private IUserAdminSessionHome adminhome; 89 private IRaAdminSessionHome raadminhome; 90 private ISignSessionHome signhome; 91 private ICAAdminSessionHome caadminhome; 92 private IKeyRecoverySessionHome keyrecoveryhome; 93 private IAuthenticationSessionHome authhome; 94 private Admin administrator; 95 private boolean usekeyrecovery = false; 96 97 103 public static Context getInitialContext() throws NamingException { 104 log.debug(">GetInitialContext"); 105 106 Context ctx = InitialContextBuilder.getInstance().getInitialContext(); 108 log.debug("<GetInitialContext"); 109 110 return ctx; 111 } 112 113 120 public BatchMakeP12() 121 throws javax.naming.NamingException , javax.ejb.CreateException , java.rmi.RemoteException , 122 java.io.IOException { 123 log.debug(">BatchMakeP12:"); 124 125 administrator = new Admin(Admin.TYPE_BATCHCOMMANDLINE_USER); 126 127 128 CertTools.installBCProvider(); 130 131 Context jndiContext = getInitialContext(); 132 Object obj = jndiContext.lookup("UserAdminSession"); 133 adminhome = (IUserAdminSessionHome) javax.rmi.PortableRemoteObject.narrow(obj, IUserAdminSessionHome.class); 134 obj = jndiContext.lookup("RaAdminSession"); 135 raadminhome = (IRaAdminSessionHome) javax.rmi.PortableRemoteObject.narrow(obj, IRaAdminSessionHome.class); 136 obj = jndiContext.lookup("RSASignSession"); 137 signhome = (ISignSessionHome) javax.rmi.PortableRemoteObject.narrow(obj, ISignSessionHome.class); 138 obj = jndiContext.lookup("CAAdminSession"); 139 caadminhome = (ICAAdminSessionHome) javax.rmi.PortableRemoteObject.narrow(obj, ICAAdminSessionHome.class); 140 obj = jndiContext.lookup("AuthenticationSession"); 141 authhome = (IAuthenticationSessionHome) javax.rmi.PortableRemoteObject.narrow(obj, IAuthenticationSessionHome.class); 142 143 IRaAdminSessionRemote raadmin = raadminhome.create(); 144 usekeyrecovery = (raadmin.loadGlobalConfiguration(administrator)).getEnableKeyRecovery(); 145 146 if (usekeyrecovery) { 147 obj = jndiContext.lookup("KeyRecoverySession"); 148 keyrecoveryhome = (IKeyRecoverySessionHome) javax.rmi.PortableRemoteObject.narrow(obj, IKeyRecoverySessionHome.class); 149 } 150 151 152 log.debug("<BatchMakeP12:"); 153 } 155 160 private Certificate [] getCACertChain(int caid) 161 throws Exception { 162 log.debug(">getCACertChain()"); 163 164 ISignSessionRemote ss = signhome.create(); 165 Certificate [] chain = (Certificate []) ss.getCertificateChain(administrator, caid).toArray(new Certificate [0]); 166 log.debug("<getCACertChain()"); 167 168 return chain; 169 } 171 177 public void setMainStoreDir(String dir) { 178 mainStoreDir = dir; 179 } 180 181 191 private void storeKeyStore(KeyStore ks, String username, String kspassword, boolean createJKS, 192 boolean createPEM) 193 throws IOException , KeyStoreException , UnrecoverableKeyException , NoSuchAlgorithmException , 194 NoSuchProviderException , CertificateException { 195 log.debug(">storeKeyStore: ks=" + ks.toString() + ", username=" + username); 196 197 if (mainStoreDir == null) { 199 throw new IOException ("Can't find directory to store keystore in."); 200 } 201 202 String keyStoreFilename = mainStoreDir + "/" + username; 203 204 if (createJKS) { 205 keyStoreFilename += ".jks"; 206 } else { 207 keyStoreFilename += ".p12"; 208 } 209 210 if (createPEM) { 212 String PEMfilename = mainStoreDir + "/pem"; 213 P12toPEM p12topem = new P12toPEM(ks, kspassword, true); 214 p12topem.setExportPath(PEMfilename); 215 p12topem.createPEM(); 216 } else { 217 FileOutputStream os = new FileOutputStream (keyStoreFilename); 218 ks.store(os, kspassword.toCharArray()); 219 } 220 221 log.debug("Keystore stored in " + keyStoreFilename); 222 log.debug("<storeKeyStore: ks=" + ks.toString() + ", username=" + username); 223 } 225 241 242 private void createUser(String username, String password, int caid, KeyPair rsaKeys, boolean createJKS, boolean createPEM, boolean savekeys, X509Certificate orgCert) 243 throws Exception { 244 log.debug(">createUser: username=" + username); 245 246 ISignSessionRemote ss = signhome.create(); 248 249 X509Certificate cert = null; 250 251 if(orgCert != null){ 252 cert = orgCert; 253 ICAAdminSessionRemote caadminsession = caadminhome.create(); 254 boolean finishUser = caadminsession.getCAInfo(administrator,caid).getFinishUser(); 255 if(finishUser){ 256 IAuthenticationSessionRemote authsession = authhome.create(); 257 authsession.finishUser(administrator, username, password); 258 } 259 260 261 }else{ 262 String sigAlg = CATokenConstants.SIGALG_SHA1_WITH_RSA; 264 if (props.getKeyAlg().equals("ECDSA")) { 265 sigAlg = CATokenConstants.SIGALG_SHA256_WITH_ECDSA; 266 } 267 X509Certificate selfcert = CertTools.genSelfCert("CN=selfsigned", 1, null, rsaKeys.getPrivate(), rsaKeys.getPublic(), sigAlg, false); 268 cert = (X509Certificate ) ss.createCertificate(administrator, username, 269 password, selfcert); 270 } 271 272 Certificate [] cachain = getCACertChain(caid); 275 if (CertTools.isSelfSigned((X509Certificate ) cachain[cachain.length - 1])) { 277 try { 278 cachain[cachain.length - 1].verify(cachain[cachain.length - 1].getPublicKey()); 279 } catch (GeneralSecurityException se) { 280 String errMsg = intres.getLocalizedMessage("batch.errorrootnotverify"); 281 throw new Exception (errMsg); 282 } 283 } else { 284 String errMsg = intres.getLocalizedMessage("batch.errorrootnotselfsigned"); 285 throw new Exception (errMsg); 286 } 287 288 try { 290 cert.verify(cachain[0].getPublicKey()); 291 } catch (GeneralSecurityException se) { 292 String errMsg = intres.getLocalizedMessage("batch.errorgennotverify"); 293 throw new Exception (errMsg); 294 } 295 296 if (usekeyrecovery && savekeys ) { 297 IKeyRecoverySessionRemote keyrecoverysession = keyrecoveryhome.create(); 299 keyrecoverysession.addKeyRecoveryData(administrator, cert, username, rsaKeys); 300 } 301 302 String alias = CertTools.getPartFromDN(CertTools.getSubjectDN(cert), "CN"); 304 if (alias == null) alias = username; 305 306 KeyStore ks = null; 308 309 if (createJKS) { 310 ks = KeyTools.createJKS(alias, rsaKeys.getPrivate(), password, cert, cachain); 311 } else { 312 ks = KeyTools.createP12(alias, rsaKeys.getPrivate(), cert, cachain); 313 } 314 315 storeKeyStore(ks, username, password, createJKS, createPEM); 316 String iMsg = intres.getLocalizedMessage("batch.createkeystore", username); 317 log.info(iMsg); 318 log.debug("<createUser: username=" + username); 319 } 321 330 private void processUser(UserDataVO data, boolean createJKS, boolean createPEM, 331 boolean keyrecoverflag) throws Exception { 332 KeyPair rsaKeys = null; 333 X509Certificate orgCert = null; 334 335 336 if (usekeyrecovery && keyrecoverflag) { 337 338 IRaAdminSessionRemote raadmin = raadminhome.create(); 339 boolean reusecertificate = raadmin.getEndEntityProfile(administrator, data.getEndEntityProfileId()).getReUseKeyRevoceredCertificate(); 340 341 IKeyRecoverySessionRemote keyrecoverysession = keyrecoveryhome.create(); 343 KeyRecoveryData recoveryData = keyrecoverysession.keyRecovery(administrator, data.getUsername(), data.getEndEntityProfileId()); 344 if(reusecertificate){ 345 keyrecoverysession.unmarkUser(administrator,data.getUsername()); 346 } 347 if (recoveryData != null) { 348 rsaKeys = recoveryData.getKeyPair(); 349 if(reusecertificate){ 350 orgCert = (X509Certificate ) recoveryData.getCertificate(); 351 } 352 } else { 353 String errMsg = intres.getLocalizedMessage("batch.errornokeyrecoverydata", data.getUsername()); 354 throw new Exception (errMsg); 355 } 356 } else { 357 rsaKeys = KeyTools.genKeys(props.getKeySpec(), props.getKeyAlg()); 358 } 359 if (rsaKeys != null) { 361 createUser(data.getUsername(), data.getPassword(), data.getCAId(), rsaKeys, createJKS, createPEM, !keyrecoverflag && data.getKeyRecoverable(), orgCert); 362 } 363 } 365 private boolean doCreate(IUserAdminSessionRemote admin, UserDataVO data, int status) throws Exception { 366 boolean ret = false; 367 int tokentype = SecConst.TOKEN_SOFT_BROWSERGEN; 368 boolean createJKS = false; 369 boolean createPEM = false; 370 boolean createP12 = false; 371 tokentype = data.getTokenType(); 373 createP12 = tokentype == SecConst.TOKEN_SOFT_P12; 374 createPEM = tokentype == SecConst.TOKEN_SOFT_PEM; 375 createJKS = tokentype == SecConst.TOKEN_SOFT_JKS; 376 377 if (createP12 || createPEM || createJKS) { 379 if (status == UserDataConstants.STATUS_KEYRECOVERY) { 380 String iMsg = intres.getLocalizedMessage("batch.retrieveingkeys", data.getUsername()); 381 log.info(iMsg); 382 } else { 383 String iMsg = intres.getLocalizedMessage("batch.generatingkeys", data.getUsername()); 384 log.info(iMsg); 385 } 386 387 admin.setUserStatus(administrator, data.getUsername(), 389 UserDataConstants.STATUS_INPROCESS); 390 processUser(data, createJKS, createPEM, 391 (status == UserDataConstants.STATUS_KEYRECOVERY)); 392 393 admin.setUserStatus(administrator, data.getUsername(), 395 UserDataConstants.STATUS_GENERATED); 396 397 admin.setClearTextPassword(administrator, data.getUsername(), null); 399 ret = true; 400 String iMsg = intres.getLocalizedMessage("batch.generateduser", data.getUsername()); 401 log.info(iMsg); 402 } else { 403 log.debug("Cannot batchmake browser generated token for user (wrong tokentype)- " + data.getUsername()); 404 } 405 return ret; 406 } 407 408 413 public void createAllNew() throws Exception { 414 log.debug(">createAllNew:"); 415 String iMsg = intres.getLocalizedMessage("batch.generatingallstatus", "NEW"); 416 log.info(iMsg); 417 createAllWithStatus(UserDataConstants.STATUS_NEW); 418 log.debug("<createAllNew:"); 419 } 421 426 public void createAllFailed() throws Exception { 427 log.debug(">createAllFailed:"); 428 String iMsg = intres.getLocalizedMessage("batch.generatingallstatus", "FAILED"); 429 log.info(iMsg); 430 createAllWithStatus(UserDataConstants.STATUS_FAILED); 431 log.debug("<createAllFailed:"); 432 } 434 439 public void createAllKeyRecover() throws Exception { 440 if (usekeyrecovery) { 441 log.debug(">createAllKeyRecover:"); 442 String iMsg = intres.getLocalizedMessage("batch.generatingallstatus", "KEYRECOVER"); 443 log.info(iMsg); 444 createAllWithStatus(UserDataConstants.STATUS_KEYRECOVERY); 445 log.debug("<createAllKeyRecover:"); 446 } 447 } 449 455 public void createAllWithStatus(int status) throws Exception { 456 log.debug(">createAllWithStatus: " + status); 457 458 ArrayList result; 459 IUserAdminSessionRemote admin = adminhome.create(); 460 boolean stopnow = false; 461 462 do { 464 465 Collection queryResult = admin.findAllUsersByStatusWithLimit(administrator, status, true); 466 result = new ArrayList (); 467 468 Iterator iter = queryResult.iterator(); 469 while(iter.hasNext()){ 470 UserDataVO data = (UserDataVO) iter.next(); 471 if(data.getTokenType() == SecConst.TOKEN_SOFT_JKS || 472 data.getTokenType() == SecConst.TOKEN_SOFT_PEM || 473 data.getTokenType() == SecConst.TOKEN_SOFT_P12 ){ 474 result.add(data); 475 } 476 } 477 478 String iMsg = intres.getLocalizedMessage("batch.generatingnoofusers", new Integer (result.size())); 479 log.info(iMsg); 480 481 int failcount = 0; 482 int successcount = 0; 483 484 if (result.size() > 0) { 485 if (result.size() < UserAdminConstants.MAXIMUM_QUERY_ROWCOUNT) { 486 stopnow = true; 487 } 488 Iterator it = result.iterator(); 489 String failedusers = ""; 490 String successusers = ""; 491 while (it.hasNext()) { 492 UserDataVO data = (UserDataVO) it.next(); 493 if ((data.getPassword() != null) && (data.getPassword().length() > 0)) { 494 try { 495 if (doCreate(admin, data, status)) { 496 successusers += (":" + data.getUsername()); 497 successcount++; 498 } 499 } catch (Exception e) { 500 String errMsg = intres.getLocalizedMessage("batch.errorsetstatus", "FAILED"); 502 log.error(errMsg, e); 503 failedusers += (":" + data.getUsername()); 504 failcount++; 505 if (status == UserDataConstants.STATUS_KEYRECOVERY) { 506 admin.setUserStatus(administrator, data.getUsername(), UserDataConstants.STATUS_KEYRECOVERY); 507 } else { 508 admin.setUserStatus(administrator, data.getUsername(), UserDataConstants.STATUS_FAILED); 509 } 510 } 511 } else { 512 iMsg = intres.getLocalizedMessage("batch.infonoclearpwd", data.getUsername()); 513 log.info(iMsg); 514 } 515 } 516 517 if (failedusers.length() > 0) { 518 String errMsg = intres.getLocalizedMessage("batch.errorbatchfailed", new Integer (failcount), new Integer (successcount), failedusers); 519 throw new Exception (errMsg); 520 } 521 522 iMsg = intres.getLocalizedMessage("batch.success", new Integer (successcount), successusers); 523 log.info(iMsg); 524 } 525 } while ((result.size() > 0) && !stopnow); 526 527 log.debug("<createAllWithStatus: " + status); 528 } 530 536 public void createUser(String username) throws Exception { 537 log.debug(">createUser(" + username + ")"); 538 539 IUserAdminSessionRemote admin = adminhome.create(); 540 UserDataVO data = admin.findUser(administrator, username); 541 int status = data.getStatus(); 542 543 if ((data != null) && (data.getPassword() != null) && (data.getPassword().length() > 0)) { 544 if ((status == UserDataConstants.STATUS_NEW) || 545 ((status == UserDataConstants.STATUS_KEYRECOVERY) && usekeyrecovery)) { 546 try { 547 doCreate(admin, data, status); 548 } catch (Exception e) { 549 String errMsg = intres.getLocalizedMessage("batch.errorsetstatus", "FAILED"); 551 log.error(errMsg, e); 552 if (status == UserDataConstants.STATUS_KEYRECOVERY) { 553 admin.setUserStatus(administrator, data.getUsername(), UserDataConstants.STATUS_KEYRECOVERY); 554 } else { 555 admin.setUserStatus(administrator, data.getUsername(), UserDataConstants.STATUS_FAILED); 556 } 557 errMsg = intres.getLocalizedMessage("batch.errorbatchfaileduser", username); 558 throw new Exception (errMsg); 559 } 560 } else { 561 String errMsg = intres.getLocalizedMessage("batch.errorbatchfaileduser", username); 562 log.error(errMsg); 563 throw new Exception (errMsg); 564 } 565 } 566 567 log.debug(">createUser(" + username + ")"); 568 } 570 575 public static void main(String [] args) { 576 try { 577 BatchMakeP12 makep12 = new BatchMakeP12(); 578 String username = null; 579 String directory = "p12"; 580 for (int i = 0; i < args.length; i++) { 581 if ("-?".equalsIgnoreCase(args[i]) || "--help".equalsIgnoreCase(args[i])){ 582 System.out.println("Usage: batch [username] [-dir directory]"); 583 System.out.println(" username: the name of the user to generate the key."); 584 System.out.println(" If omitted, keys will be generated for all users with status NEW or FAILED"); 585 System.out.println(" directory: the name of the directory to store the keys to"); 586 System.exit(1); 587 } else if ("-dir".equalsIgnoreCase(args[i])){ 588 directory = args[++i]; 589 } else { 590 username = args[i]; 591 } 592 } 593 594 File dir = new File (directory).getCanonicalFile(); 596 dir.mkdir(); 597 makep12.setMainStoreDir(directory); 598 String iMsg = intres.getLocalizedMessage("batch.generateindir", dir); 599 log.info(iMsg); 600 601 if (username != null) { 602 makep12.createUser(username); 603 } else { 604 makep12.createAllNew(); 606 607 makep12.createAllFailed(); 609 610 makep12.createAllKeyRecover(); 612 } 613 } catch (Exception e) { 614 e.printStackTrace(); 615 System.exit(1); 616 } 617 } 619 } | Popular Tags |