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

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

/*************************************************************************
*                                                                       *
*  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.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.ejbca.core.protocol.xkms.common.XKMSConstants;
import org.ejbca.core.protocol.xkms.common.XKMSUtil;
import org.ejbca.ui.cli.ErrorAdminCommandException;
import org.ejbca.ui.cli.IAdminCommand;
import org.ejbca.ui.cli.IllegalAdminCommandException;
import org.ejbca.util.CertTools;
import org.ejbca.util.keystore.KeyTools;
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_.ObjectFactory;
import org.w3._2002._03.xkms_.RecoverRequestType;
import org.w3._2002._03.xkms_.RecoverResultType;





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

  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_CERT               = 1;
  private static final int ARG_CERTENCODING       = 2;
  private static final int ARG_PASSWORD           = 3
  private static final int ARG_ENCODING           = 4;
  private static final int ARG_OUTPUTPATH         = 5;
     
  
 
    /**
     * Creates a new instance of RaAddUserCommand
     *
     * @param args command line arguments
     */
    public RecoverCommand(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 < 5 || args.length > 6){
              usage();
              System.exit(-1); // NOPMD, this is not a JEE app
           
 
            String certEncoding = getCertEncoding(args[ARG_CERTENCODING]);           
            Certificate orgCert = getCert(args[ARG_CERT],certEncoding);
            String password = args[ARG_PASSWORD];
                                               
            String encoding = useEncoding(args[ARG_ENCODING]);
        
            String outputPath = "";
            if(args.length >= ARG_OUTPUTPATH +1){
              if(args[ARG_OUTPUTPATH] != null){
                outputPath = args[ARG_OUTPUTPATH] + "/";                           
              }
            }

            String reqId = genId();
            RecoverRequestType recoverRequestType = xKMSObjectFactory.createRecoverRequestType();
            recoverRequestType.setId(reqId);
            recoverRequestType.getRespondWith().add(XKMSConstants.RESPONDWITH_X509CHAIN);           
            recoverRequestType.getRespondWith().add(XKMSConstants.RESPONDWITH_PRIVATEKEY);
           
            X509DataType x509DataType = sigFactory.createX509DataType();
            x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName().add(sigFactory.createX509DataTypeX509Certificate(orgCert.getEncoded()));
            KeyInfoType keyInfoType = sigFactory.createKeyInfoType();
            keyInfoType.getContent().add(sigFactory.createX509Data(x509DataType));
           
            String keyBindingId = "_" + CertTools.getSerialNumber(orgCert).toString();
            KeyBindingType keyBindingType = xKMSObjectFactory.createKeyBindingType();               
            keyBindingType.setKeyInfo(keyInfoType);
            keyBindingType.setId(keyBindingId);
            recoverRequestType.setRecoverKeyBinding(keyBindingType)
           
          
           
            RecoverResultType recoverResultType = getXKMSInvoker().recover(recoverRequestType, clientCert, privateKey, password,  keyBindingId);

           
            if(recoverResultType.getResultMajor().equals(XKMSConstants.RESULTMAJOR_SUCCESS) &&
               recoverResultType.getResultMinor() == null){
           
                if(recoverResultType.getKeyBinding().size() >0){
                  KeyBindingType keyBinding = recoverResultType.getKeyBinding().get(0);                 
                  List certs = getCertsFromKeyBinding(keyBinding);
                   
                  X509Certificate userCert = getUserCert(certs);                 
                  certs.remove(userCert);
                 
                  if(recoverResultType.getPrivateKey() != null){
                    PrivateKey serverKey = XKMSUtil.getPrivateKeyFromEncryptedXML(recoverResultType.getPrivateKey(), password);
                    createKeyStore(userCert, certs, serverKey,password,encoding,outputPath);
                  }else{
                  getPrintStream().println("Error: Response didn't contain any private key");                     
                    System.exit(-1); // NOPMD, this is not a JEE app
                  }

                }
  
            }else{
              displayRequestErrors(recoverResultType);
            }
   
        } catch (Exception e) {
            throw new ErrorAdminCommandException(e);
        }
    }

    private Certificate getCert(String filename, String certEncoding) {   
    Certificate retval = null;
   
    if(certEncoding.equals(ENCODING_PEM)){     
      try {
        Collection certs = CertTools.getCertsFromPEM(filename);
        if(certs.size() > 0){
          retval = (X509Certificate) certs.iterator().next();
        }
      } catch (Exception e) {}

    }
    if(certEncoding.equals(ENCODING_DER)){
      try {
        byte[] certdata = loadCert(filename);
        retval = CertTools.getCertfromByteArray(certdata);
      } catch (CertificateException e) {
      }
    }
   
    if(retval == null){
      getPrintStream().println("Error couldn't decode certificate " + filename);
          usage();
        System.exit(-1); // NOPMD, this is not a JEE app
    }
   
    return retval;
  }

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

  private X509Certificate getUserCert(Collection certs) {
    X509Certificate retval = null;
    Iterator iter = certs.iterator();
    while(iter.hasNext()){
      X509Certificate next = (X509Certificate) iter.next();
      if(next.getBasicConstraints() == -1){
        retval = next;
        break;
      }
    }
     
    return retval;
  }

  private void createKeyStore(X509Certificate userCert, List caCerts, PrivateKey privKey, String password, String encoding, String outputPath) throws Exception {
    boolean createJKS = false;
    boolean createPEM = false;
    if(encoding.equals(ENCODING_JKS)){
      createJKS = true;
    }
    if(encoding.equals(ENCODING_PEM)){
      createPEM = true;
    }
   
        String alias = getAlias(userCert);
       
        Certificate[] caChain = new Certificate[caCerts.size()];
        for(int i=0;i<caCerts.size();i++){
          caChain[i] = (Certificate) caCerts.get(i);
        }
   
        // Store keys and certificates in keystore.
        KeyStore ks = null;

        if (createJKS) {
            ks = KeyTools.createJKS(alias, privKey, password, userCert, caChain);
        } else {
            ks = KeyTools.createP12(alias, privKey,  userCert, caChain);
        }

        storeKeyStore(ks, alias, password, createJKS, createPEM, outputPath);
   
  }

  private String getAlias(X509Certificate userCert) {
        String alias = CertTools.getPartFromDN(CertTools.getSubjectDN(userCert), "CN");
        if (alias == null) {
          alias = "myKey";
        }
    return alias;
  }

  private void displayRequestErrors(RecoverResultType recoverResultType) {
    if(recoverResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOMATCH)){
      getPrintStream().println("Error no user with given certificate could be found");
    }else
      if(recoverResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_NOAUTHENTICATION)){
        getPrintStream().println("Error password couldn't be verified");
      }else
        if(recoverResultType.getResultMinor().equals(XKMSConstants.RESULTMINOR_REFUSED)){
          getPrintStream().println("The user doesn't seem to have the wrong status.");
        }else{
          getPrintStream().println("Error occured during processing : " + recoverResultType.getResultMinor());
        }
  }

 
  /**
   * Returns the encoding that the data should be written in
   * @return
   */
  private String useEncoding(String arg){
    if(arg.equalsIgnoreCase(ENCODING_PEM)){
      return ENCODING_PEM;
    }
   
    if(arg.equalsIgnoreCase(ENCODING_P12)){
      return ENCODING_P12;
    }
   
    if(arg.equalsIgnoreCase(ENCODING_JKS)){
      return ENCODING_JKS;
    }
   
    getPrintStream().println("Illegal encoding (should be pem, p12 or jks) : " + arg);
        usage();
      System.exit(-1); // NOPMD, this is not a JEE app
      return null;
  }


 
  protected void usage() {
    getPrintStream().println("Command used to recover the private key of a certificate");
    getPrintStream().println("Usage : recover <cert file name> <cert encoding (der|pem)> <password> <keystore encoding pem|p12|jks> <outputpath (optional)> \n\n");
    getPrintStream().println("Certificate encoding of the certificate about to recover key for, PEM and DER supported.\n");
    getPrintStream().println("Password used to authenticate to the XKMS service.\n");
        getPrintStream().println("Use pem, p12 or jks for encoding of the generated keystore.\n");
        getPrintStream().println("Outputpath specifies to which directory to write the keystore to, current directory is used if omitted\n\n");
        getPrintStream().println("Example: recover lostcert.pem pem \"foo123\"  pem");
        getPrintStream().println("Recovers the key to the lostcert.pem certificate and writes it in PEM encoding in the current directory");
       
                     
  }


}
TOP

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

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.