@Override
  public CommandResult execute(ParameterContainer parameters) {

    boolean force = parameters.containsKey(FORCE_KEY);

    try {
      String username = parameters.get(USERNAME_KEY);
      int inp = 121;
      if (!force) {
        getLogger().info("Have you revoked the end entity [y/N]? ");
        try {
          inp = System.in.read();
        } catch (IOException e) {
          throw new IllegalStateException("Could not read console input.");
        }
      }
      if ((inp == 121) || (inp == 89)) {
        try {
          EjbRemoteHelper.INSTANCE
              .getRemoteSession(EndEntityManagementSessionRemote.class)
              .deleteUser(getAuthenticationToken(), username);
          getLogger().info("Deleted end entity with username: "******"ERROR: Not authorized to remove end entity.");
          return CommandResult.FUNCTIONAL_FAILURE;
        } catch (RemoveException e) {
          getLogger().error("ERROR: User could not be removed. " + e.getMessage());
          return CommandResult.FUNCTIONAL_FAILURE;
        }
      } else {
        getLogger().info("Deletion aborted!");
        getLogger()
            .info(
                "Please run '"
                    + new RevokeEndEntityCommand().getMainCommand()
                    + " "
                    + new RevokeEndEntityCommand().getMainCommand()
                    + " "
                    + username
                    + "'.");
        return CommandResult.FUNCTIONAL_FAILURE;
      }
    } catch (NotFoundException e) {
      getLogger().error("ERROR: No such end entity.");
      return CommandResult.FUNCTIONAL_FAILURE;
    }
  }
  @Override
  public CommandResult execute(ParameterContainer parameters) {

    final String issuerDNStr = parameters.get(DN_KEY);
    final String issuerDN = CertTools.stringToBCDNString(issuerDNStr);
    final String certserno = parameters.get(SERIAL_NUMBER_KEY);
    final BigInteger serno;
    try {
      serno = new BigInteger(certserno, 16);
    } catch (NumberFormatException e) {
      log.error("ERROR: Invalid hexadecimal certificate serial number string: " + certserno);
      return CommandResult.FUNCTIONAL_FAILURE;
    }
    int reason;
    try {
      reason = Integer.parseInt(parameters.get(REASON_KEY));
    } catch (NumberFormatException e) {
      log.error("ERROR: " + parameters.get(REASON_KEY) + " was not a number.");
      return CommandResult.FUNCTIONAL_FAILURE;
    }
    if ((reason == 7) || (reason < 0) || (reason > 10)) {
      getLogger().error("ERROR: Reason must be an integer between 0 and 10 except 7.");
      return CommandResult.FUNCTIONAL_FAILURE;
    } else {
      Certificate cert =
          EjbRemoteHelper.INSTANCE
              .getRemoteSession(CertificateStoreSessionRemote.class)
              .findCertificateByIssuerAndSerno(issuerDN, serno);
      if (cert != null) {
        getLogger().info("Found certificate:");
        getLogger().info("Subject DN=" + CertTools.getSubjectDN(cert));
        // We need the user this cert is connected with
        // Revoke or unrevoke, will throw appropriate exceptions if parameters are wrong, such as
        // trying to unrevoke a certificate
        // that was permanently revoked
        try {
          try {
            EjbRemoteHelper.INSTANCE
                .getRemoteSession(EndEntityManagementSessionRemote.class)
                .revokeCert(getAuthenticationToken(), serno, issuerDN, reason);
          } catch (ApprovalException e) {
            log.error(e.getMessage(), e);
            return CommandResult.FUNCTIONAL_FAILURE;
          } catch (AuthorizationDeniedException e) {
            log.error("ERROR: CLI user not authorized to revoke certificate.");
            return CommandResult.FUNCTIONAL_FAILURE;
          } catch (FinderException e) {
            log.error("ERROR: " + e.getMessage());
            return CommandResult.FUNCTIONAL_FAILURE;
          } catch (WaitingForApprovalException e) {
            log.error("ERROR: " + e.getMessage());
            return CommandResult.FUNCTIONAL_FAILURE;
          }
          getLogger()
              .info(
                  (reason == 8 ? "Unrevoked" : "Revoked")
                      + " certificate with issuerDN '"
                      + issuerDN
                      + "' and serialNumber "
                      + certserno
                      + ". Revocation reason="
                      + reason);
        } catch (AlreadyRevokedException e) {
          if (reason == 8) {
            getLogger()
                .info(
                    "Certificate with issuerDN '"
                        + issuerDN
                        + "' and serialNumber "
                        + certserno
                        + " is not revoked, nothing was done.");
          } else {
            getLogger()
                .info(
                    "Certificate with issuerDN '"
                        + issuerDN
                        + "' and serialNumber "
                        + certserno
                        + " is already revoked, nothing was done.");
          }
          getLogger().info(e.getMessage());
        }
      } else {
        getLogger()
            .info(
                "No certificate found with issuerDN '"
                    + issuerDN
                    + "' and serialNumber "
                    + certserno);
      }
    }
    return CommandResult.SUCCESS;
  }
 @Override
 public CommandResult execute(ParameterContainer parameters) {
   String inpath = parameters.get(DIRECTORY_KEY);
   Integer caid = null;
   String caName = parameters.get(CA_NAME_KEY);
   if (caName != null) {
     CAInfo ca;
     try {
       ca =
           EjbRemoteHelper.INSTANCE
               .getRemoteSession(CaSessionRemote.class)
               .getCAInfo(getAuthenticationToken(), caName);
     } catch (CADoesntExistsException e) {
       getLogger().error("CA '" + caName + "' does not exist.");
       return CommandResult.FUNCTIONAL_FAILURE;
     } catch (AuthorizationDeniedException e) {
       getLogger().error("CLI user not authorized to CA '" + caName);
       return CommandResult.AUTHORIZATION_FAILURE;
     }
     if (ca != null) {
       caid = ca.getCAId();
     } else {
       getLogger().error("CA '" + caName + "' does not exist.");
       return CommandResult.FUNCTIONAL_FAILURE;
     }
   }
   CryptoProviderTools.installBCProvider();
   // Mapping used to translate certificate profile ids when importing end entity profiles. Used
   // when the profile id of a cert profile changes
   // and we need to change the mapping from the ee profile to cert profiles
   HashMap<Integer, Integer> certificateProfileIdMapping = new HashMap<Integer, Integer>();
   getLogger().info("Importing certificate and end entity profiles: ");
   File inFile = new File(inpath);
   if (!inFile.isDirectory()) {
     getLogger().error("'" + inpath + "' is not a directory.");
     return CommandResult.FUNCTIONAL_FAILURE;
   }
   // List all filenames in the given directory, we will try to import them all
   File[] infiles = inFile.listFiles();
   FileTools.sortByName(infiles);
   try {
     for (int i = 0; i < infiles.length; i++) {
       getLogger().info("Filename: " + infiles[i].getName());
       if (infiles[i].isFile()
           && ((infiles[i].getName().indexOf("certprofile_") > -1)
               || (infiles[i].getName().indexOf("entityprofile_") > -1))) {
         boolean entityprofile = false;
         if (infiles[i].getName().indexOf("entityprofile_") > -1) {
           entityprofile = true;
         }
         int index1 = infiles[i].getName().indexOf("_");
         int index2 = infiles[i].getName().lastIndexOf("-");
         int index3 = infiles[i].getName().lastIndexOf(".xml");
         if (index1 < 0 || index2 < 0 || index3 < 0) {
           getLogger().error("Filename not as expected (cert/entityprofile_<name>-<id>.xml).");
         } else {
           final String filename = infiles[i].getName().substring(index1 + 1, index2);
           String profilename;
           try {
             profilename = URLDecoder.decode(filename, "UTF-8");
           } catch (UnsupportedEncodingException e) {
             throw new IllegalStateException("UTF-8 was not a known character encoding", e);
           }
           int profileid = Integer.parseInt(infiles[i].getName().substring(index2 + 1, index3));
           // We don't add the fixed profiles, EJBCA handles those automagically
           if (!entityprofile
               && CertificateProfileConstants.isFixedCertificateProfile(profileid)) {
             getLogger().error("Not adding fixed certificate profile '" + profilename + "'.");
           } else {
             if (entityprofile && profileid == SecConst.EMPTY_ENDENTITYPROFILE) {
               getLogger().error("Not adding fixed entity profile '" + profilename + "'.");
             } else {
               // Check if the profiles already exist, and change the name and id if already taken
               boolean error = false;
               // when we need to create a new certprofile id, this will hodl the original value so
               // we
               // can insert a mapping in certificateProfileIdMapping when we have created a new id
               int oldprofileid = -1;
               if (entityprofile) {
                 if (EjbRemoteHelper.INSTANCE
                         .getRemoteSession(EndEntityProfileSessionRemote.class)
                         .getEndEntityProfile(profilename)
                     != null) {
                   getLogger()
                       .error("Entity profile '" + profilename + "' already exist in database.");
                   error = true;
                 } else if (EjbRemoteHelper.INSTANCE
                         .getRemoteSession(EndEntityProfileSessionRemote.class)
                         .getEndEntityProfile(profileid)
                     != null) {
                   int newprofileid =
                       EjbRemoteHelper.INSTANCE
                           .getRemoteSession(EndEntityProfileSessionRemote.class)
                           .findFreeEndEntityProfileId();
                   getLogger()
                       .warn(
                           "Entity profileid '"
                               + profileid
                               + "' already exist in database. Using "
                               + newprofileid
                               + " instead.");
                   profileid = newprofileid;
                 }
               } else {
                 if (EjbRemoteHelper.INSTANCE
                         .getRemoteSession(CertificateProfileSessionRemote.class)
                         .getCertificateProfileId(profilename)
                     != CertificateProfileConstants.CERTPROFILE_NO_PROFILE) {
                   getLogger()
                       .error(
                           "Error: Certificate profile '"
                               + profilename
                               + "' already exist in database.");
                   error = true;
                 } else if (EjbRemoteHelper.INSTANCE
                         .getRemoteSession(CertificateProfileSessionRemote.class)
                         .getCertificateProfile(profileid)
                     != null) {
                   getLogger()
                       .warn(
                           "Certificate profile id '"
                               + profileid
                               + "' already exist in database. Adding with a new profile id instead.");
                   oldprofileid = profileid;
                   profileid = -1; // means we should create a new id when adding the cert profile
                 }
               }
               if (!error) {
                 CertificateProfile cprofile = null;
                 EndEntityProfile eprofile = null;
                 FileInputStream is;
                 try {
                   is = new FileInputStream(infiles[i]);
                 } catch (FileNotFoundException e) {
                   // Shouldn't happen, we've already vetted the file directory above
                   throw new IllegalStateException(
                       "An exception was encountered with an already vetted file directory", e);
                 }
                 XMLDecoder decoder = new XMLDecoder(is);
                 if (entityprofile) {
                   // Add end entity profile
                   eprofile = new EndEntityProfile();
                   eprofile.loadData(decoder.readObject());
                   // Translate cert profile ids that have changed after import
                   String availableCertProfiles = "";
                   String defaultCertProfile =
                       eprofile.getValue(EndEntityProfile.DEFAULTCERTPROFILE, 0);
                   // getLogger().debug("Debug: Org - AVAILCERTPROFILES " +
                   // eprofile.getValue(EndEntityProfile.AVAILCERTPROFILES,0) + "
                   // DEFAULTCERTPROFILE "+defaultCertProfile);
                   for (String currentCertProfile :
                       (Collection<String>) eprofile.getAvailableCertificateProfileIds()) {
                     Integer currentCertProfileId = Integer.parseInt(currentCertProfile);
                     Integer replacementCertProfileId =
                         certificateProfileIdMapping.get(currentCertProfileId);
                     if (replacementCertProfileId != null) {
                       if (!replacementCertProfileId.toString().equals(currentCertProfile)) {
                         getLogger()
                             .warn(
                                 "Replacing cert profile with id "
                                     + currentCertProfile
                                     + " with "
                                     + replacementCertProfileId
                                     + ".");
                       }
                       availableCertProfiles +=
                           (availableCertProfiles.equals("") ? "" : ";")
                               + replacementCertProfileId;
                       if (currentCertProfile.equals(defaultCertProfile)) {
                         defaultCertProfile = "" + replacementCertProfileId;
                       }
                     } else {
                       if (EjbRemoteHelper.INSTANCE
                                   .getRemoteSession(CertificateProfileSessionRemote.class)
                                   .getCertificateProfile(currentCertProfileId)
                               != null
                           || CertificateProfileConstants.isFixedCertificateProfile(
                               currentCertProfileId)) {
                         availableCertProfiles +=
                             (availableCertProfiles.equals("") ? "" : ";") + currentCertProfile;
                       } else {
                         getLogger()
                             .warn(
                                 "End Entity Profile '"
                                     + profilename
                                     + "' references certificate profile "
                                     + currentCertProfile
                                     + " that does not exist.");
                         if (currentCertProfile.equals(defaultCertProfile)) {
                           defaultCertProfile = "";
                         }
                       }
                     }
                   }
                   if (availableCertProfiles.equals("")) {
                     getLogger()
                         .warn(
                             "End Entity Profile only references certificate profile(s) that does not exist. Using ENDUSER profile.");
                     availableCertProfiles =
                         "1"; // At least make sure the default profile is available
                   }
                   if (defaultCertProfile.equals("")) {
                     defaultCertProfile =
                         availableCertProfiles
                             .split(";")[
                             0]; // Use first available profile from list as default if original
                                 // default was missing
                   }
                   eprofile.setValue(EndEntityProfile.AVAILCERTPROFILES, 0, availableCertProfiles);
                   eprofile.setValue(EndEntityProfile.DEFAULTCERTPROFILE, 0, defaultCertProfile);
                   // Remove any unknown CA and break if none is left
                   String defaultCA = eprofile.getValue(EndEntityProfile.DEFAULTCA, 0);
                   String availableCAs = eprofile.getValue(EndEntityProfile.AVAILCAS, 0);
                   // getOutputStream().println("Debug: Org - AVAILCAS " + availableCAs + "
                   // DEFAULTCA "+defaultCA);
                   List<String> cas = Arrays.asList(availableCAs.split(";"));
                   availableCAs = "";
                   for (String currentCA : cas) {
                     Integer currentCAInt = Integer.parseInt(currentCA);
                     // The constant ALLCAS will not be searched for among available CAs
                     try {
                       if (currentCAInt.intValue() != SecConst.ALLCAS) {
                         EjbRemoteHelper.INSTANCE
                             .getRemoteSession(CaSessionRemote.class)
                             .getCAInfo(getAuthenticationToken(), currentCAInt);
                       }
                       availableCAs +=
                           (availableCAs.equals("") ? "" : ";")
                               + currentCA; // No Exception means CA exists
                     } catch (CADoesntExistsException e) {
                       getLogger()
                           .warn(
                               "CA with id "
                                   + currentCA
                                   + " was not found and will not be used in end entity profile '"
                                   + profilename
                                   + "'.");
                       if (defaultCA.equals(currentCA)) {
                         defaultCA = "";
                       }
                     }
                   }
                   if (availableCAs.equals("")) {
                     if (caid == null) {
                       getLogger()
                           .error(
                               "No CAs left in end entity profile '"
                                   + profilename
                                   + "' and no CA specified on command line. Using ALLCAs.");
                       availableCAs = Integer.toString(SecConst.ALLCAS);
                     } else {
                       availableCAs = Integer.toString(caid);
                       getLogger()
                           .warn(
                               "No CAs left in end entity profile '"
                                   + profilename
                                   + "'. Using CA supplied on command line with id '"
                                   + caid
                                   + "'.");
                     }
                   }
                   if (defaultCA.equals("")) {
                     defaultCA = availableCAs.split(";")[0]; // Use first available
                     getLogger()
                         .warn(
                             "Changing default CA in end entity profile '"
                                 + profilename
                                 + "' to "
                                 + defaultCA
                                 + ".");
                   }
                   // getLogger().debug("New - AVAILCAS " + availableCAs + " DEFAULTCA
                   // "+defaultCA);
                   eprofile.setValue(EndEntityProfile.AVAILCAS, 0, availableCAs);
                   eprofile.setValue(EndEntityProfile.DEFAULTCA, 0, defaultCA);
                   try {
                     EjbRemoteHelper.INSTANCE
                         .getRemoteSession(EndEntityProfileSessionRemote.class)
                         .addEndEntityProfile(
                             getAuthenticationToken(), profileid, profilename, eprofile);
                     getLogger().info("Added entity profile '" + profilename + "' to database.");
                   } catch (EndEntityProfileExistsException eepee) {
                     getLogger()
                         .error("Error adding entity profile '" + profilename + "' to database.");
                   }
                 } else {
                   // Add certificate profile
                   cprofile = new CertificateProfile();
                   cprofile.loadData(decoder.readObject());
                   // Make sure CAs in profile exist
                   List<Integer> cas = cprofile.getAvailableCAs();
                   ArrayList<Integer> casToRemove = new ArrayList<Integer>();
                   for (Integer currentCA : cas) {
                     // If the CA is not ANYCA and the CA does not exist, remove it from the
                     // profile before import
                     if (currentCA != CertificateProfile.ANYCA) {
                       try {
                         EjbRemoteHelper.INSTANCE
                             .getRemoteSession(CaSessionRemote.class)
                             .getCAInfo(getAuthenticationToken(), currentCA);
                       } catch (CADoesntExistsException e) {
                         casToRemove.add(currentCA);
                       }
                     }
                   }
                   for (Integer toRemove : casToRemove) {
                     getLogger()
                         .warn(
                             "Warning: CA with id "
                                 + toRemove
                                 + " was not found and will not be used in certificate profile '"
                                 + profilename
                                 + "'.");
                     cas.remove(toRemove);
                   }
                   if (cas.size() == 0) {
                     if (caid == null) {
                       getLogger()
                           .error(
                               "Error: No CAs left in certificate profile '"
                                   + profilename
                                   + "' and no CA specified on command line. Using ANYCA.");
                       cas.add(Integer.valueOf(CertificateProfile.ANYCA));
                     } else {
                       getLogger()
                           .warn(
                               "Warning: No CAs left in certificate profile '"
                                   + profilename
                                   + "'. Using CA supplied on command line with id '"
                                   + caid
                                   + "'.");
                       cas.add(caid);
                     }
                   }
                   cprofile.setAvailableCAs(cas);
                   // Remove and warn about unknown publishers
                   List<Integer> publishers = cprofile.getPublisherList();
                   ArrayList<Integer> allToRemove = new ArrayList<Integer>();
                   for (Integer publisher : publishers) {
                     BasePublisher pub = null;
                     try {
                       pub =
                           EjbRemoteHelper.INSTANCE
                               .getRemoteSession(PublisherSessionRemote.class)
                               .getPublisher(getAuthenticationToken(), publisher);
                     } catch (Exception e) {
                       getLogger()
                           .warn(
                               "Warning: There was an error loading publisher with id "
                                   + publisher
                                   + ". Use debug logging to see stack trace: "
                                   + e.getMessage());
                       getLogger().debug("Full stack trace: ", e);
                     }
                     if (pub == null) {
                       allToRemove.add(publisher);
                     }
                   }
                   for (Integer toRemove : allToRemove) {
                     getLogger()
                         .warn(
                             "Warning: Publisher with id "
                                 + toRemove
                                 + " was not found and will not be used in certificate profile '"
                                 + profilename
                                 + "'.");
                     publishers.remove(toRemove);
                   }
                   cprofile.setPublisherList(publishers);
                   // Add profile
                   try {
                     if (profileid == -1) {
                       // id already existed, we need to create a new one
                       profileid =
                           EjbRemoteHelper.INSTANCE
                               .getRemoteSession(CertificateProfileSessionRemote.class)
                               .addCertificateProfile(
                                   getAuthenticationToken(), profilename, cprofile);
                       // make a mapping from the old id (that was already in use) to the new one
                       // so we can change end entity profiles
                       certificateProfileIdMapping.put(oldprofileid, profileid);
                     } else {
                       EjbRemoteHelper.INSTANCE
                           .getRemoteSession(CertificateProfileSessionRemote.class)
                           .addCertificateProfile(
                               getAuthenticationToken(), profileid, profilename, cprofile);
                     }
                     // Make a mapping from the new to the new id, so we have a mapping if the
                     // profile id did not change at all
                     certificateProfileIdMapping.put(
                         profileid,
                         EjbRemoteHelper.INSTANCE
                             .getRemoteSession(CertificateProfileSessionRemote.class)
                             .getCertificateProfileId(profilename));
                     getLogger()
                         .info(
                             "Added certificate profile '"
                                 + profilename
                                 + "', '"
                                 + profileid
                                 + "' to database.");
                   } catch (CertificateProfileExistsException cpee) {
                     getLogger()
                         .error(
                             "Error adding certificate profile '"
                                 + profilename
                                 + "', '"
                                 + profileid
                                 + "' to database.");
                   }
                 }
                 decoder.close();
                 try {
                   is.close();
                 } catch (IOException e) {
                   throw new IllegalStateException(
                       "Unknown IOException was caught when closing stream", e);
                 }
               }
             }
           }
         }
       }
     }
   } catch (AuthorizationDeniedException e) {
     log.error("Current CLI user doesn't have sufficient privileges to import profiles.");
     return CommandResult.AUTHORIZATION_FAILURE;
   }
   return CommandResult.SUCCESS;
 }
  @Override
  public CommandResult execute(ParameterContainer parameters) {
    String username = parameters.get(ENTITY_NAME);
    String password = parameters.get(ENTITY_PASSWORD);
    String csr = parameters.get(CSR);
    String certf = parameters.get(DESTINATION_FILE);

    byte[] bytes;
    try {
      bytes = FileTools.readFiletoBuffer(csr);
    } catch (FileNotFoundException e) {
      log.error("File " + csr + " not found.");
      return CommandResult.FUNCTIONAL_FAILURE;
    }
    RequestMessage req = RequestMessageUtils.parseRequestMessage(bytes);
    if (req instanceof PKCS10RequestMessage) {
      PKCS10RequestMessage p10req = (PKCS10RequestMessage) req;
      p10req.setUsername(username);
      p10req.setPassword(password);
    } else {
      log.error("Input file '" + csr + "' is not a PKCS#10 request.");
      return CommandResult.FUNCTIONAL_FAILURE;
    }
    final SignSessionRemote signSession =
        EjbRemoteHelper.INSTANCE.getRemoteSession(SignSessionRemote.class);
    // Call signsession to create a certificate
    ResponseMessage resp;
    try {
      resp =
          signSession.createCertificate(
              getAuthenticationToken(), req, X509ResponseMessage.class, null);
    } catch (EjbcaException e) {
      log.error("Could not create certificate: " + e.getMessage());
      return CommandResult.FUNCTIONAL_FAILURE;
    } catch (CesecoreException e) {
      log.error("Could not create certificate: " + e.getMessage());
      return CommandResult.FUNCTIONAL_FAILURE;
    } catch (AuthorizationDeniedException ee) {
      log.error(
          "CLI user with username "
              + parameters.get(USERNAME_KEY)
              + " was not authorized to create a certificate.");
      return CommandResult.AUTHORIZATION_FAILURE;
    } catch (CertificateExtensionException e) {
      log.error("CSR specified extensions which were invalid: " + e.getMessage());
      return CommandResult.FUNCTIONAL_FAILURE;
    }
    byte[] pembytes;
    try {
      pembytes =
          CertTools.getPemFromCertificateChain(
              Arrays.asList(((X509ResponseMessage) resp).getCertificate()));
    } catch (CertificateException e) {
      throw new IllegalStateException(
          "Newly created certificate could not be parsed. This should not happen.", e);
    }
    // Write the resulting cert to file
    try {
      FileOutputStream fos = new FileOutputStream(certf);
      fos.write(pembytes);
      fos.close();
    } catch (IOException e) {
      log.error("Could not write to certificate file " + certf + ". " + e.getMessage());
      return CommandResult.FUNCTIONAL_FAILURE;
    }
    log.info("PEM certificate written to file '" + certf + "'");
    return CommandResult.SUCCESS;
  }