Package org.ejbca.core.protocol.xkms.client

Source Code of org.ejbca.core.protocol.xkms.client.LocateCommand

/*************************************************************************
*                                                                       *
*  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.core.protocol.xkms.client;

import java.io.FileOutputStream;
import java.io.IOException;
import java.security.cert.CRLException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.xml.bind.JAXBElement;

import org.apache.log4j.Logger;
import org.ejbca.core.protocol.xkms.common.XKMSConstants;
import org.ejbca.ui.cli.ErrorAdminCommandException;
import org.ejbca.ui.cli.IAdminCommand;
import org.ejbca.ui.cli.IllegalAdminCommandException;
import org.ejbca.util.Base64;
import org.ejbca.util.CertTools;
import org.w3._2000._09.xmldsig_.KeyInfoType;
import org.w3._2000._09.xmldsig_.X509DataType;
import org.w3._2002._03.xkms_.KeyBindingType;
import org.w3._2002._03.xkms_.LocateRequestType;
import org.w3._2002._03.xkms_.LocateResultType;
import org.w3._2002._03.xkms_.ObjectFactory;
import org.w3._2002._03.xkms_.QueryKeyBindingType;
import org.w3._2002._03.xkms_.UnverifiedKeyBindingType;
import org.w3._2002._03.xkms_.UseKeyWithType;
import org.w3._2002._03.xkms_.ValidateRequestType;
import org.w3._2002._03.xkms_.ValidateResultType;





/**
* Performes KISS calls to an web service.
*
* @version $Id: LocateCommand.java 10227 2010-10-19 14:23:57Z anatom $
* @author Philip Vendil
*/
public class LocateCommand extends XKMSCLIBaseCommand implements IAdminCommand{

  private static Logger log = Logger.getLogger(LocateCommand.class);
     
  private ObjectFactory xKMSObjectFactory = new ObjectFactory();
  private org.w3._2000._09.xmldsig_.ObjectFactory sigFactory = new org.w3._2000._09.xmldsig_.ObjectFactory();
 
  private static final int ARG_QUERYTYPE          = 1;
  private static final int ARG_QUERYVALUE         = 2;
  private static final int ARG_KEYUSAGE           = 3;
  private static final int ARG_RESPONDWITH        = 4;
  private static final int ARG_VALIDATEFLAG       = 5;
  private static final int ARG_ENCODING           = 6;
  private static final int ARG_OUTPUTPATH         = 7;
 

 

       
    private static final String VALIDATION_VALIDATE        = "validate";
    private static final String VALIDATION_NOVALIDATION    = "novalidation";


 
    /**
     * Creates a new instance of RaAddUserCommand
     *
     * @param args command line arguments
     */
    public LocateCommand(String[] args) {
        super(args);
    }

    /**
     * Runs the command
     *
     * @throws IllegalAdminCommandException Error in command args
     * @throws ErrorAdminCommandException Error running command
     */
    public void execute() throws IllegalAdminCommandException, ErrorAdminCommandException {
     
        try {  
          
            if(args.length < 7 || args.length > 8){
              usage();
              System.exit(-1); // NOPMD, this is not a JEE app
            }
           
            boolean isCertQuery = args[ARG_QUERYTYPE].equalsIgnoreCase(QUERYTYPE_CERT);
           
            String queryType = getQueryType(args[ARG_QUERYTYPE]);
           
            byte[] queryCert = null;
            String queryVal = null;
            if(isCertQuery){
              queryCert = loadCert(args[ARG_QUERYVALUE]);
            }else{
              queryVal = args[ARG_QUERYVALUE];
            }
           
            boolean validate = getValidate(args[ARG_VALIDATEFLAG]);
            boolean pEMEncoding = usePEMEncoding(args[ARG_ENCODING]);
            String keyUsage = getKeyUsage(args[ARG_KEYUSAGE]);
            Collection respondWith = getResponseWith(args[ARG_RESPONDWITH]);
            String outputPath = "";
            if(args.length >= ARG_OUTPUTPATH +1){
              if(args[ARG_OUTPUTPATH] != null){
                outputPath = args[ARG_OUTPUTPATH] + "/";                           
              }
            }

           
            QueryKeyBindingType queryKeyBindingType = xKMSObjectFactory.createQueryKeyBindingType();
            if(isCertQuery){
              X509DataType x509DataType = sigFactory.createX509DataType();
                x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509Certificate(queryCert));
                KeyInfoType keyInfoType = sigFactory.createKeyInfoType();
                keyInfoType.getContent().add(sigFactory.createX509Data(x509DataType));
                queryKeyBindingType.setKeyInfo(keyInfoType);
            }else{
              UseKeyWithType useKeyWithType = xKMSObjectFactory.createUseKeyWithType();
              useKeyWithType.setApplication(queryType);
              useKeyWithType.setIdentifier(queryVal);
              queryKeyBindingType.getUseKeyWith().add(useKeyWithType);
            }
            if(keyUsage != null){
              queryKeyBindingType.getKeyUsage().add(keyUsage);
            }
           
            String reqId = genId();
           
            List keyBindings = new ArrayList();
            if(validate){
              ValidateRequestType validationRequestType = xKMSObjectFactory.createValidateRequestType();
              validationRequestType.setId(reqId);
                Iterator iter = respondWith.iterator();
                while(iter.hasNext()){
                  validationRequestType.getRespondWith().add((String) iter.next());
                }
                validationRequestType.setQueryKeyBinding(queryKeyBindingType);
                getPrintStream().println("Sending validation request with id " + reqId + " to XKMS Service");
                if (clientCert == null) {
                    log.info("Client cert was not found and will not be used.");
                }
                ValidateResultType validateResult = getXKMSInvoker().validate(validationRequestType, clientCert, privateKey);               
                keyBindings = validateResult.getKeyBinding();                               
               
            }else{
              LocateRequestType locateRequestType = xKMSObjectFactory.createLocateRequestType();
              locateRequestType.setId(reqId);
                Iterator iter = respondWith.iterator();
                while(iter.hasNext()){
                  locateRequestType.getRespondWith().add((String) iter.next());
                }
                locateRequestType.setQueryKeyBinding(queryKeyBindingType);
               
                getPrintStream().println("Sending locate request with id " + reqId + " to XKMS Service");
                if (clientCert == null) {
                    log.info("Client cert was not found and will not be used.");
                }
                LocateResultType locateResult = getXKMSInvoker().locate(locateRequestType, clientCert, privateKey);
                keyBindings = locateResult.getUnverifiedKeyBinding();                                               
            }

            if(keyBindings.size() > 0){
              getPrintStream().println("\n  The query matched " + keyBindings.size() + " certificates :");
              Iterator iter = keyBindings.iterator();
              while(iter.hasNext()){
                UnverifiedKeyBindingType next = (UnverifiedKeyBindingType) iter.next();
                displayAndOutputCert(next, outputPath, pEMEncoding);               
                if(next instanceof KeyBindingType){
                  displayStatus((KeyBindingType) next);
                }                               
                getPrintStream().println("\n\n\n");
              }
            }else{
              getPrintStream().println("\n  The query didn't match any certificates");
            }
       
        } catch (Exception e) {
            throw new ErrorAdminCommandException(e);
        }
    }


  private void displayAndOutputCert(UnverifiedKeyBindingType next, String outputPath, boolean pEMEncoding) throws CertificateException, CRLException, IOException {
    List keyInfos = next.getKeyInfo().getContent();

    Iterator iter = keyInfos.iterator();
    while(iter.hasNext()){
      Object obj = iter.next();
      if(obj instanceof JAXBElement){
        JAXBElement<X509DataType> jAXBX509Data = (JAXBElement<X509DataType>) obj;
        Iterator iter2 = jAXBX509Data.getValue().getX509IssuerSerialOrX509SKIOrX509SubjectName().iterator();
        while(iter2.hasNext()){
          JAXBElement next2 = (JAXBElement) iter2.next();         
          String filename = "";
          if(next2.getName().getLocalPart().equals("X509Certificate")){
            byte[] encoded = (byte[]) next2.getValue();
            Certificate nextCert = CertTools.getCertfromByteArray(encoded);
            getPrintStream().println("  Found certificate with DN " + CertTools.getSubjectDN(nextCert) + " issued by " + CertTools.getIssuerDN(nextCert));

            if(pEMEncoding){
              filename = outputPath + CertTools.getPartFromDN(CertTools.getSubjectDN(nextCert), "CN") + ".pem";
              FileOutputStream fos = new FileOutputStream(filename);
              ArrayList certs = new ArrayList();
              certs.add(nextCert);
              byte[] pemData = CertTools.getPEMFromCerts(certs);
              fos.write(pemData);
              fos.close();           
            }else{
              filename = outputPath + CertTools.getPartFromDN(CertTools.getSubjectDN(nextCert), "CN") + ".cer";
              FileOutputStream fos = new FileOutputStream(filename);
              fos.write(nextCert.getEncoded());
              fos.close();
            }           
          }
          if(next2.getName().getLocalPart().equals("X509CRL")){         
            byte[] encoded = (byte[]) next2.getValue();
            X509CRL nextCRL = CertTools.getCRLfromByteArray(encoded);

            getPrintStream().println("  Found CRLissued by " + CertTools.getIssuerDN(nextCRL));
            if(pEMEncoding){
              filename = outputPath  + CertTools.getPartFromDN(CertTools.getIssuerDN(nextCRL), "CN") + "-crl.pem";
              FileOutputStream fos = new FileOutputStream(filename);
              fos.write("-----BEGIN X509 CRL-----\n".getBytes());
              fos.write(Base64.encode(nextCRL.getEncoded(), true));
              fos.write("\n-----END X509 CRL-----\n".getBytes());           
              fos.close();           
            }else{
              filename = outputPath  + CertTools.getPartFromDN(CertTools.getIssuerDN(nextCRL), "CN") + ".crl";
              FileOutputStream fos = new FileOutputStream(filename);
              fos.write(nextCRL.getEncoded());
              fos.close();
            }
          }
          getPrintStream().println("  Written to : " + filename + "\n");
        }

        // Display use key with
        displayUseKeyWith(next);

        // Display key usage
        displayKeyUsage(next);
      }
    }   
  }



  /**
     * Returns tru if 'validation' is set
     * @param arg
     */
    private boolean getValidate(String arg) {
    if(arg.equalsIgnoreCase(VALIDATION_VALIDATE)){
      return true;
    }
   
    if(arg.equalsIgnoreCase(VALIDATION_NOVALIDATION)){
      return false;
    }
   
    getPrintStream().println("Illegal validation flag " + arg);
        usage();
      System.exit(-1); // NOPMD, this is not a JEE app
    return false;
  }

  /**
     * Returns the query usekeywith type or null
     * if it is a certificate query
     * @param arg
     */
    private String getQueryType(String arg) {
        if(arg.equalsIgnoreCase(QUERYTYPE_CERT)){
          return null;
        }
       
        if(arg.equalsIgnoreCase(QUERYTYPE_IPSEC)){
          return XKMSConstants.USEKEYWITH_IPSEC;
        }
       
        if(arg.equalsIgnoreCase(QUERYTYPE_PKIX)){
          return XKMSConstants.USEKEYWITH_PKIX;
        }
       
        if(arg.equalsIgnoreCase(QUERYTYPE_SMIME)){
          return XKMSConstants.USEKEYWITH_SMIME;
        }
       
        if(arg.equalsIgnoreCase(QUERYTYPE_TLS)){
          return XKMSConstants.USEKEYWITH_TLS;
        }
       
        if(arg.equalsIgnoreCase(QUERYTYPE_TLSHTTP)){
          return XKMSConstants.USEKEYWITH_TLSHTTP;
        }

        if(arg.equalsIgnoreCase(QUERYTYPE_TLSSMTP)){
          return XKMSConstants.USEKEYWITH_TLSSMTP;
        }
       
    getPrintStream().println("Illegal query type " + arg);
        usage();
      System.exit(-1); // NOPMD, this is not a JEE app
    return null;
  }

  /**
     * Mthod returning the keyUsage tag or null if all i acceptable
     * @param keyusage from args
     * @return
     */
  private String getKeyUsage(String arg) {
    if(arg.equalsIgnoreCase(KEYUSAGE_ALL)){
      return null;
    }
    if(arg.equalsIgnoreCase(KEYUSAGE_SIGNATURE)){
      return XKMSConstants.KEYUSAGE_SIGNATURE;
    }
    if(arg.equalsIgnoreCase(KEYUSAGE_ENCRYPTION)){
      return XKMSConstants.KEYUSAGE_ENCRYPTION;
    }
    if(arg.equalsIgnoreCase(KEYUSAGE_EXCHANGE)){
      return XKMSConstants.KEYUSAGE_EXCHANGE;
    }   
     
    getPrintStream().println("Illegal key usage " + arg);
        usage();
      System.exit(-1); // NOPMD, this is not a JEE app
    return null;
  }
 
 
  /**
   * Returns true if encoding is PEM othervise DER
   * @return
   */
  private boolean usePEMEncoding(String arg){
    if(arg.equalsIgnoreCase(ENCODING_PEM)){
      return true;
    }

    if(arg.equalsIgnoreCase(ENCODING_DER)){
      return false;
    }
   
    getPrintStream().println("Illegal encoding (should be pem or der) : " + arg);
        usage();
      System.exit(-1); // NOPMD, this is not a JEE app
      return false;
  }

 
  protected void usage() {
    getPrintStream().println("Command used to locate and optionaly validate a certificate");
    getPrintStream().println("Usage : locate <querytype> <queryvalue> <keyusage> <respondwith> <"+VALIDATION_VALIDATE+"|"+VALIDATION_NOVALIDATION+"> <der|pem> <outputpath (optional)> \n\n");
        getPrintStream().println("Querytypes are:");
        getPrintStream().println(" CERT     : Use a existing certificate from file, queryvalue should be path to certificate.\n"
                            +" SMIME    : Lookup by the RFC882 Name of certificate\n"
                            +" TLS      : Lookup by the URI in the certificate\n"
                            +" TLSHTTP  : Lookup by the CN in the certificate\n"
                            +" TSLSMTP  : Lookup by the DNS Name of the certificate\n"
                            +" IPSEC    : Lookup by the IP address of the certificate\n"
                            +" PKIX     : Lookup by the SubjectDN of the certificate\n");
        getPrintStream().println("Available Keyusages are:");
        getPrintStream().println(" ALL        : Any key usage will do\n"
                                +" SIGNATURE  : Return certificate that can be used for signing\n"
                                +" ENCRYPTION : Return certificate that can be used for encryption\n"
                                +" EXCHANGE   : Return certificate that can be used for exchange\n");
        getPrintStream().println("Available Respond With values are:");               
        getPrintStream().println(" X509CERT        : Respond with the certificate.\n"
                                +" X509CHAIN       : Respond with the entire certificate chain\n"
                                +" X509CHAINANDCRL : Respond with the chain and CRL\n");
        getPrintStream().println("Use 'validate' if you want the status of the certificate, othervise use 'novalidation'.\n");
        getPrintStream().println("Use 'pem' or 'der' depending on prefered encoding.\n");
        getPrintStream().println("Outputpath specifies to which directory to write certificate and CRLs, current directory is used if omitted\n\n");
        getPrintStream().println("Example: locate TLSHTTP \"John Doe\" SIGNATURE X509CERT "+VALIDATION_VALIDATE+" pem");
        getPrintStream().println("Returns the signing certificate belonging to CN=John Doe and specifies if it is valid to the current directory");
       
                     
  }


}
TOP

Related Classes of org.ejbca.core.protocol.xkms.client.LocateCommand

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.