Package org.ejbca.extra.ra

Source Code of org.ejbca.extra.ra.ExtRATestClient

/*************************************************************************
*                                                                       *
*  EJBCA: The OpenSource Certificate Authority                          *
*                                                                       *
*  This software is free software; you can redistribute it and/or       *
*  modify it under the terms of the GNU Lesser General Public           *
*  License as published by the Free Software Foundation; either         *
*  version 2.1 of the License, or any later version.                    *
*                                                                       *
*  See terms of license at gnu.org.                                     *
*                                                                       *
*************************************************************************/
package org.ejbca.extra.ra;

import java.io.FileInputStream;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Vector;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ejbca.extra.db.Message;
import org.ejbca.extra.db.MessageHome;
import org.ejbca.extra.db.PKCS10Request;
import org.ejbca.extra.db.PKCS10Response;
import org.ejbca.extra.db.PKCS12Request;
import org.ejbca.extra.db.PKCS12Response;
import org.ejbca.extra.db.SubMessages;
import org.ejbca.extra.util.RAKeyStore;
import org.ejbca.util.CertTools;
import org.ejbca.util.CryptoProviderTools;

/**
* A test client for the External RA API that can be used for simple load and performance test and
* to figure out expected response times for different types of requests.
*
* Important, if signing is used must the RA server key store be configured as an 'Super
* Administrator' in EJBCA.
*
* @version $Id: ExtRATestClient.java 10226 2010-10-19 12:59:56Z anatom $
*/
public class ExtRATestClient {
 
  private static final Log log = LogFactory.getLog(ExtRATestClient.class);
 
  //private static final String TYPE_CERT     = "CERT";
  private static final String TYPE_KEYSTORE = "KEYSTORE";
 
  private static final String SECURITY_UNSECURED       = "UNSECURED";
  private static final String SECURITY_SIGNED          = "SIGNED";
  private static final String SECURITY_ENCRYPTED       = "ENCRYPTED";
  private static final String SECURITY_SIGNEDENCRYPTED = "SIGNEDENCRYPTED";
 
  private static final int ARG_TYPE            = 0;
  private static final int ARG_KEYSTOREPATH    = 1;
  private static final int ARG_PASSWORD        = 2;
  private static final int ARG_ENCRYPTIONCERT  = 3;
  private static final int ARG_SECURITYLEVEL   = 4;
  private static final int ARG_REQUESTSPERMIN  = 5;
  private static final int ARG_CONCURRENTRAS   = 6;
  private static final int ARG_WAITTIME        = 7;

    protected PrivateKey raKey = null;
    protected X509Certificate raCert = null;
    protected Vector cAChain = null;
    protected X509Certificate encCert = null;
    protected String securitylevel = SECURITY_UNSECURED;
 
    protected boolean requestKeyStore = false;
 
  protected int reqPerMin = 10;
  private int concurrentRAs = 2;
    protected int waitTime = 30;
 
    protected int generateUserRequests = 0;
 
  protected SecureRandom random = new SecureRandom();   
 
    protected static final String pkcs10_1 =
     "MIIBkzCB/QIBADBUMQswCQYDVQQGEwJTRTETMBEGA1UECBMKU29tZS1TdGF0ZTEh"
    +"MB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ0wCwYDVQQDEwRUZXN0"
    +"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDczgi13kcTGTMmOdMU/QzvH6JV"
    +"QxL23dqdYpsV//XHO2bjKlgqqc3MpGH4QQkz/80rzFi4EwuqBpOnXo0P09I2jztk"
    +"IG4TSM+RwOfvaAMDJ1B6eeih6JX+v0A5PaWJlx1nshUuikcYJK3iNVepy39li0m3"
    +"OBwub9NnnVWXuClUGwIDAQABoAAwDQYJKoZIhvcNAQEEBQADgYEAz4NpjNraufWg"
    +"ZDv5J1muOHwZvOO9Is1L8WvMLG+jgH8Q2rPpDq8buIIWDy6VK8ghr7xhZzEZznTX"
    +"5HLSLB1a6KvktiVSKB0nmAmDU28xXLWWwkA7/68J6DvAipk00bHdxuEJ4+Mg8UJ0"
    +"Mr+aXDlmZUfghzlB70dDUy/Np/YJVb8=";
 
  private MessageHome msghome = null;

  ExtRATestClient(String[] args) throws Exception {
      CryptoProviderTools.installBCProvider();
    if(args.length != 8){
      log.debug("Number of arguments: " + args.length);
      help();
      System.exit(-1); // NOPMD, it's not a JEE app
    }else{
      requestKeyStore = args[ARG_TYPE].equalsIgnoreCase(TYPE_KEYSTORE);
      EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("external-ra-cli");
            msghome = new MessageHome(entityManagerFactory, MessageHome.MESSAGETYPE_EXTRA, true);
      securitylevel = args[ARG_SECURITYLEVEL];
      if(!securitylevel.equalsIgnoreCase(SECURITY_UNSECURED) &&
         !securitylevel.equalsIgnoreCase(SECURITY_SIGNED) &&
         !securitylevel.equalsIgnoreCase(SECURITY_ENCRYPTED) &&
         !securitylevel.equalsIgnoreCase(SECURITY_SIGNEDENCRYPTED)){
        throw new Exception("Invalid SecurityLevel: "+securitylevel);
      }
      if(securitylevel.equalsIgnoreCase(SECURITY_SIGNED) || securitylevel.equalsIgnoreCase(SECURITY_SIGNEDENCRYPTED)){
        RAKeyStore rakeystore = new RAKeyStore(args[ARG_KEYSTOREPATH], args[ARG_PASSWORD]);      
        Certificate[] chain = rakeystore.getKeyStore().getCertificateChain(rakeystore.getAlias());
        cAChain = new Vector();
        for(int i=0; i< chain.length ; i++){
          if(((X509Certificate) chain[i]).getBasicConstraints() != -1){
            cAChain.add(chain[i]);
          }
        }
        raKey = (PrivateKey) rakeystore.getKeyStore().getKey(rakeystore.getAlias(), args[ARG_PASSWORD].toCharArray());
        raCert = (X509Certificate) rakeystore.getKeyStore().getCertificate(rakeystore.getAlias());
      }
      if(securitylevel.equalsIgnoreCase(SECURITY_ENCRYPTED) || securitylevel.equalsIgnoreCase(SECURITY_SIGNEDENCRYPTED)){
            CertificateFactory cf = CertTools.getCertificateFactory();
            encCert = (X509Certificate) cf.generateCertificate(new FileInputStream(args[ARG_ENCRYPTIONCERT]));
      }
      reqPerMin = Integer.parseInt(args[ARG_REQUESTSPERMIN]);
      concurrentRAs = Integer.parseInt(args[ARG_CONCURRENTRAS]);
      waitTime = Integer.parseInt(args[ARG_WAITTIME]);     
    }
  }


  public static void main(String[] args) throws Exception {
      ExtRATestClient testclient = new ExtRATestClient(args);
      testclient.run();
  }
 
 
  public void help(){
    System.out.println("External RA API Test Client");
    System.out.println("Usage :  <CERT | KEYSTORE> <KeyStorePath> <KeyStorePwd> <EncCert> <SecurityLevel> <RequestsPerMin> <ConcurrentRAs> <WaitTime>");
    System.out.println("Where :");
    System.out.println(" <CERT | KEYSTORE> : Type of test, CERT creates single PKCS10 requests, KEYSTORE creates one PKCS10 and one PKCS12 request for each message" );
    System.out.println(" <KeyStorePath>    : The path to the keystore used to sign/encrypt messages. Use NOKEYSTORE for unencrypted security level.");
    System.out.println(" <KeyStorePwd>     : Password to unlock the keystore,. Use NOPWD for unencrypted security level.");
    System.out.println(" <EncCert>         : Path to certificate (DER) used to encrypt messages,. Use NOCERT for unencrypted security level.");
    System.out.println(" <SecurityLevel>   : Security Level, Valid values are " + SECURITY_UNSECURED + ", " + SECURITY_SIGNED + ", " + SECURITY_ENCRYPTED + ", " + SECURITY_SIGNEDENCRYPTED +"");
    System.out.println(" <RequestsPerMin>  : Requests to generate every minute per concurrent RA.");
    System.out.println(" <ConcurrentRAs>   : Number of concurrent RAs that will create requests.");
    System.out.println(" <WaitTime>        : Number of seconds to wait for answer before exception is thrown.\n\n");
    System.out.println("The database connection is configured in META-INF/persistence.xml. The JDBC driver JAR should be copied to the endorsed directory.\n");
    System.out.println("Examples : ");
    System.out.println("  Simple test sending unsecured requests every 5 s in one thread ");
    System.out.println("  expecting an answer within 60 s :");
    System.out.println("    java -jar externalra-cli.jar CERT NOKEYSTORE NOPWD NOCERT " + SECURITY_UNSECURED + " 12 1 60 \n");
    System.out.println("  Advanced test using encrypted and signed requests for pkcs10 cert and a pkcs12 keystore ");
    System.out.println("  every 1 min in two threads, expecting an answer within 60 s :");
    System.out.println("    java -jar externalra-cli.jar KEYSTORE rakeystore.p12 foo123 enccert.cer SIGNEDENCRYPTED 1 2 60 \n");
  }
 
  /**
   * Starts the test application
   */
  public void run(){
    for(int i=1; i <= concurrentRAs; i++){
      ConcurrentRAThread rAThread = new ConcurrentRAThread("Thread-"+i);
      println("Starting new Thread : " + "Thread-"+i);
      rAThread.start();         
    }
  }
 
  public synchronized void createUser(String username, SubMessages submessages){
     msghome.create(username, submessages);
    }
 
  public synchronized Message findByUser(String username){
    return msghome.findByMessageId(username);
  }
 
  public synchronized void println(String message){
      System.out.println(message);
      System.out.flush();
  }
   
  private class ConcurrentRAThread extends Thread { // NOPMD, it's not a JEE app
    private boolean run = false;
    private String threadName = "";   
    private long serialNumber = 0;
   
    public ConcurrentRAThread(String threadName) {
         this.threadName = threadName;
    }

    public void run() {    
      run=true;
      while(run) {
        try {
          // Start Request Thread
          RequestThread reqThread = new RequestThread(threadName, serialNumber++);
          reqThread.start();                       

        } catch(Exception e) {
          e.printStackTrace();
        }
        try {
          sleep(getTimeToNextRequests())
        } catch( InterruptedException e) {}
      }
    }

    private long getTimeToNextRequests() {     
      return (60000 / reqPerMin) + (random.nextLong() % 1000);
    }

    public void stopThread() {
      this.run = false;
    }
  }
 
  private class RequestThread extends Thread { // NOPMD, it's not a JEE app
    private boolean run = false;
    private String threadName = "";
    private long serialNumber = 0;
   
    public RequestThread(String threadName, long serialNumber) {
         this.threadName = threadName;
         this.serialNumber = serialNumber;
    }

    public void run() {
      // Generate request
      String username = "TEST_" + threadName + "_REQ-" + serialNumber;
      long pkcs10RequestId = 0;
      long pkcs12RequestId = 0;
      long starttime = new Date().getTime();
      SubMessages submgs = generateSubMessage();
      pkcs10RequestId = createPKCS10Request(username,submgs);
      if (requestKeyStore) {
        pkcs12RequestId = createPKCS12Request(username,submgs);
      }
      createUser(username, submgs);     

      run=true;
      // Wait for response
      boolean processed = false;
      Message msg = null;
      int wait = waitTime;
      while (wait >= 0 && run) {
        msg = findByUser(username);
        if (msg != null && msg.getStatus().equals(Message.STATUS_PROCESSED)) {
          processed = true;
          break;
        }
        try {
          sleep(1000);
        } catch (InterruptedException e) {
        }
        wait--;
      }
      if (!processed) {
        println("Error : Couldn't get processed response within the specified waitTime : Username :" + username + ", WaitTime : " + waitTime);

      } else {
        SubMessages respmsgs = null;
        if (raKey != null) {         
          respmsgs = msg.getSubMessages(raKey,cAChain,null);
        } else {
          respmsgs = msg.getSubMessages(null,null,null);
        }
        PKCS10Response pkcs10resp = (PKCS10Response) respmsgs.getSubMessages().get(0);
        PKCS12Response pkcs12resp = null;
        if (requestKeyStore) {
          pkcs12resp = (PKCS12Response) respmsgs.getSubMessages().get(1);
        }
        if (pkcs10resp.getRequestId() !=  pkcs10RequestId) {
          println("Error in PKCS10 Request requestId doesn't match responseId for user : " + username + ", request Id : " + pkcs10RequestId + " = " +  pkcs10resp.getRequestId());
        }
        if (requestKeyStore && pkcs12resp.getRequestId() !=  pkcs12RequestId) {
          println("Error in PKCS12 Request requestId doesn't match responseId for user : " + username + ", request Id : " + pkcs12RequestId + " = " +  pkcs12resp.getRequestId());
        }
        if (!pkcs10resp.isSuccessful()) {
          println("Error in PKCS10 Request for user : " + username + ", message : " + pkcs10resp.getFailInfo());
        }
        if (requestKeyStore && !pkcs12resp.isSuccessful()) {
          println("Error in PKCS12 Request for user : " + username + ", message : " + pkcs12resp.getFailInfo());                   
        }
        long endtime = new Date().getTime();
        float processtime = ((float) (endtime - starttime)) / 1000;
        if (pkcs10resp.isSuccessful() && !requestKeyStore) {          
          println("  " + username + " Generated Sucessfully in " + processtime + " seconds, Total Requests " + ++generateUserRequests);
        }
        if (requestKeyStore && pkcs10resp.isSuccessful() && pkcs12resp.isSuccessful()) {
          println("  " + username + " Generated Sucessfully in " + processtime + " seconds, Total Requests " + ++generateUserRequests);
        }
      }

    }

    private long createPKCS10Request(String username, SubMessages submessages) {
      long requestId = random.nextLong();     
      submessages.addSubMessage(new PKCS10Request(requestId,username, "CN=PKCS10REQ", "RFC822NAME=PKCS10Request@test.com",
                    "PKCS10Request@test.com", null, "EMPTY", "ENDUSER", "AdminCA1",pkcs10_1));         
      return requestId;
    }
   
    private long createPKCS12Request(String username, SubMessages submessages) {
      long requestId = random.nextLong();     
      submessages.addSubMessage(new PKCS12Request(requestId,username, "CN=PKCS12REQ", "RFC822NAME=PKCS12Request@test.com",
                    "PKCS12Request@test.com", null, "EMPTY", "ENDUSER",
                    "AdminCA1","foo123",PKCS12Request.KEYALG_RSA, "1024", true));
      return requestId;
    }
   
    private SubMessages generateSubMessage() {
      if(securitylevel.equalsIgnoreCase(SECURITY_SIGNEDENCRYPTED)){
        return new SubMessages(raCert,raKey, encCert);                         
      }
      if(securitylevel.equalsIgnoreCase(SECURITY_SIGNED)){
        return new SubMessages(raCert,raKey,null);                 
      }
      if(securitylevel.equalsIgnoreCase(SECURITY_ENCRYPTED)){
        return new SubMessages(null,null,encCert);                         
      }
      return new SubMessages(null,null,null);
    }

    public void stopThread() {
        this.run = false;
    }
  }
}
TOP

Related Classes of org.ejbca.extra.ra.ExtRATestClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.