/** * Copyright 2006 by Know-Center, Graz, Austria * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a * joint initiative of the Federal Chancellery Austria and Graz University of * Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. * * $Id: Main.java,v 1.5 2006/10/31 08:06:56 wprinz Exp $ */ package at.gv.egiz.pdfas.commandline; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.gv.egiz.pdfas.PdfAsFactory; import at.gv.egiz.pdfas.api.PdfAs; import at.gv.egiz.pdfas.api.commons.Constants; import at.gv.egiz.pdfas.api.exceptions.ConfigUtilsException; import at.gv.egiz.pdfas.api.exceptions.PdfAsException; import at.gv.egiz.pdfas.api.io.DataSink; import at.gv.egiz.pdfas.api.io.DataSource; import at.gv.egiz.pdfas.api.sign.SignParameters; import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning; import at.gv.egiz.pdfas.api.sign.pos.axis.AbsoluteAxisAlgorithm; import at.gv.egiz.pdfas.api.sign.pos.page.AbsolutePageAlgorithm; import at.gv.egiz.pdfas.api.sign.pos.page.NewPageAlgorithm; import at.gv.egiz.pdfas.api.verify.VerifyParameters; import at.gv.egiz.pdfas.api.verify.VerifyResult; import at.gv.egiz.pdfas.api.verify.VerifyResults; import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.gv.egiz.pdfas.exceptions.ErrorCodeHelper; import at.gv.egiz.pdfas.framework.config.SettingsHelper; import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; import at.gv.egiz.pdfas.io.FileBasedDataSink; import at.gv.egiz.pdfas.io.FileBasedDataSource; import at.gv.egiz.pdfas.io.StringTextBasedDataSource; import at.gv.egiz.pdfas.utils.ConfigUtils; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; import at.knowcenter.wag.egov.egiz.pdf.TablePos; import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; import at.knowcenter.wag.egov.egiz.sig.ConnectorInformation; import at.knowcenter.wag.egov.egiz.sig.SignatureTypes; /** * The main program entry point of the commandline tool. * *

* The commandline uses the PDF-AS API. *

* * @author wprinz */ public abstract class Main { // 23.11.2010 changed by exthex - added parameters for placeholder handling /** * Command line parameter setting the application mode sign|verify */ protected static final String PARAMETER_MODE = "-mode"; /** * Command line parameter setting the application to connect */ protected static final String PARAMETER_CONNECTOR = "-connector"; /** * Command line parameter setting the signature mode. */ protected static final String PARAMETER_SIGNATURE_MODE = "-sigmode"; /** * Command line parameter setting the signature type. */ protected static final String PARAMETER_SIGNATURE_TYPE = "-sigtype"; /** * Command line parameter setting the username */ protected static final String PARAMETER_USER_NAME = "-username"; /** * Command line parameter setting the users password */ protected static final String PARAMETER_USER_PASSWORD = "-password"; /** * Command line parameter selecting the position of the signature. */ protected static final String PARAMETER_POS = "-pos"; /** * Command line parameter signaling to search the source document for a placeholder for the signature */ protected static final String PARAMETER_PLACEHOLDER_SEARCH = "-searchplaceholder"; /** * Command line parameter selecting the id of the placeholder to use */ protected static final String PARAMETER_PLACEHOLDER_ID = "-placeholder_id"; /** * Command line parameter selecting the match mode for the placeholder */ protected static final String PARAMETER_PLACEHOLDER_MATCH_MODE = "-placeholder_matchmode"; /** * Command line parameter selecting the signature which is going to be * verified. */ protected static final String PARAMETER_VERIFY_WHICH = "-verify_which"; /** * Command line parameter that starts the deployment of the default configuration to the current * user's home folder. * @see Constants#USERHOME_CONFIG_FOLDER */ protected static final String PARAMETER_DEPLOY_DEFAULT_CONFIGURATION = "-ddc"; /** * The application mode sign */ public static final String VALUE_MODE_SIGN = "sign"; /** * The application mode verify */ public static final String VALUE_MODE_VERIFY = "verify"; /** * The value for signature mode binary. */ public static final String VALUE_SIGNATURE_MODE_BINARY = Constants.SIGNATURE_TYPE_BINARY; /** * The value for signature mode textual. */ public static final String VALUE_SIGNATURE_MODE_TEXTUAL = Constants.SIGNATURE_TYPE_TEXTUAL; /** * The value for signature mode detached. */ public static final String VALUE_SIGNATURE_MODE_DETACHED = "detached"; /** * The value for signature mode detachedtextual. */ public static final String VALUE_SIGNATURE_MODE_DETACHED_TEXT = Constants.SIGNATURE_TYPE_DETACHEDTEXTUAL; /** * The placeholder match mode STRICT */ public static final String VALUE_PLACEHOLDER_MATCH_MODE_STRICT = "strict"; /** * The placeholder match mode STRICT */ public static final String VALUE_PLACEHOLDER_MATCH_MODE_MODERATE = "moderate"; /** * The placeholder match mode STRICT */ public static final String VALUE_PLACEHOLDER_MATCH_MODE_LENIENT = "lenient"; /** * The log. */ private static final Log logger_ = LogFactory.getLog(Main.class); /** * Main program entry point. * * @param args * The commandline arguments. * @throws IOException */ public static void main(String[] args) throws IOException { // ConfigLogger.setLevel(Level.DEBUG); // search for PARAMETER_DEPLOY_DEFAULT_CONFIGURATION before initializing the SettingsReader for (int i = 0; i < args.length; i++) { if (args[i].trim().equals(PARAMETER_DEPLOY_DEFAULT_CONFIGURATION)) { try { String defaultConfigurationDeployedTo = ConfigUtils.deployDefaultConfiguration(); if (defaultConfigurationDeployedTo != null) { System.out.println("Default configuration successfully deployed to \"" + defaultConfigurationDeployedTo + "\"."); } else { System.out.println("Default configuration has NOT been deployed. Maybe the configuration already exists."); } if (args.length == 1) { // no other parameters supplied; exit application System.exit(0); } } catch (ConfigUtilsException e) { System.err.println("Deployment of default configuration failed: " + e.getMessage()); System.exit(1); } } } SettingsReader.initializeForCommandLine(); ConfigUtils.initializeLogger(); // printUsage(System.out); String mode = null; String signature_mode = Constants.DEFAULT_SIGNATURE_TYPE; String connector = null; String signature_type = null; String user_name = null; String user_password = null; String pos_string = null; boolean search_placeholder = true; String placeholderId = null; int placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_MODERATE; int verify_which = -1; String input = null; String output = null; try { // force settings preload SettingsReader.getInstance(); // for (int i = 0; i < args.length; i++) // { // logger_.debug("arg[" + i + "] = " + args[i]); // } for (int i = 0; i < args.length; i++) { String cur_arg = args[i].trim(); if (cur_arg.equals(PARAMETER_DEPLOY_DEFAULT_CONFIGURATION)) { // already applied continue; } if (cur_arg.equals(PARAMETER_MODE)) { i++; if (i >= args.length) { printNoValue(PARAMETER_MODE); return; } mode = args[i]; if (!checkMode(mode)) { printUnrecognizedValue(PARAMETER_MODE, mode); return; } continue; } if (cur_arg.equals(PARAMETER_CONNECTOR)) { i++; if (i >= args.length) { printNoValue(PARAMETER_CONNECTOR); return; } connector = args[i]; if (!checkConnector(connector)) { printUnrecognizedValue(PARAMETER_CONNECTOR, connector); return; } continue; } if (cur_arg.equals(PARAMETER_SIGNATURE_MODE)) { i++; if (i >= args.length) { printNoValue(PARAMETER_SIGNATURE_MODE); return; } signature_mode = args[i]; if (!checkSignatureMode(signature_mode)) { printUnrecognizedValue(PARAMETER_SIGNATURE_MODE, signature_mode); return; } continue; } if (cur_arg.equals(PARAMETER_SIGNATURE_TYPE)) { i++; if (i >= args.length) { printNoValue(PARAMETER_SIGNATURE_TYPE); return; } signature_type = args[i]; if (!checkSignatureType(signature_type)) { printUnrecognizedValue(PARAMETER_SIGNATURE_TYPE, signature_type); return; } continue; } if (cur_arg.equals(PARAMETER_PLACEHOLDER_SEARCH)) { i++; if (i >= args.length) { printNoValue(PARAMETER_PLACEHOLDER_SEARCH); return; } search_placeholder = Boolean.valueOf(args[i]).booleanValue(); continue; } if (cur_arg.equals(PARAMETER_PLACEHOLDER_ID)) { i++; if (i >= args.length) { printNoValue(PARAMETER_PLACEHOLDER_ID); return; } placeholderId = args[i]; continue; } if (cur_arg.equals(PARAMETER_PLACEHOLDER_MATCH_MODE)) { i++; if (i >= args.length) { printNoValue(PARAMETER_PLACEHOLDER_MATCH_MODE); return; } String matchMode = args[i]; if (matchMode.equals(VALUE_PLACEHOLDER_MATCH_MODE_LENIENT)) placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_LENIENT; else if (matchMode.equals(VALUE_PLACEHOLDER_MATCH_MODE_MODERATE)) placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_MODERATE; else if (matchMode.equals(VALUE_PLACEHOLDER_MATCH_MODE_STRICT)) placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_STRICT; else printUnrecognizedValue(PARAMETER_PLACEHOLDER_MATCH_MODE, args[i]); continue; } if (cur_arg.equals(PARAMETER_USER_NAME)) { i++; if (i >= args.length) { printNoValue(PARAMETER_USER_NAME); return; } user_name = args[i]; continue; } if (cur_arg.equals(PARAMETER_USER_PASSWORD)) { i++; if (i >= args.length) { printNoValue(PARAMETER_USER_PASSWORD); return; } user_password = args[i]; continue; } if (cur_arg.equals(PARAMETER_POS)) { i++; if (i >= args.length) { printNoValue(PARAMETER_POS); return; } pos_string = args[i]; continue; } if (cur_arg.equals(PARAMETER_VERIFY_WHICH)) { i++; if (i >= args.length) { printNoValue(PARAMETER_VERIFY_WHICH); return; } String str_verify_which = args[i]; try { verify_which = Integer.parseInt(str_verify_which); } catch (NumberFormatException e) { printUnrecognizedValue(PARAMETER_VERIFY_WHICH, str_verify_which); return; } continue; } if (cur_arg.charAt(0) == '-') { printUnrecognizedOption(cur_arg); return; } if (input == null) { input = cur_arg; continue; } if (output == null) { output = cur_arg; continue; } printUnrecognizedAdditionalCommandlineArgument(cur_arg); return; } if (mode == null) { printMissingParameter("a mode", PARAMETER_MODE); return; } if (connector == null) { printMissingParameter("a connector", PARAMETER_CONNECTOR); return; } if (mode.equals(VALUE_MODE_SIGN)) { if (signature_mode == null) { printMissingParameter("a signature mode", PARAMETER_SIGNATURE_MODE); return; } if (signature_type == null) { SettingsReader settings = SettingsReader.getInstance(); String default_type = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE); signature_type = default_type; } if (user_name == null) { user_name = ""; // printMissingParameter("a user name", PARAMETER_USER_NAME); // return; } if (user_password == null) { user_password = ""; // printMissingParameter("a user password", PARAMETER_USER_PASSWORD); // return; } } if (input == null) { printMissing("an input document"); return; } File file = new File(input); if (!file.exists()) { System.err.println("The input file '" + input + "' doesn't exist."); return; } if (mode.equals(VALUE_MODE_SIGN) && output == null) { output = generateOutputFileNameFromInput(input, signature_mode); } carryOutCommand(mode, signature_mode, connector, signature_type, user_name, user_password, verify_which, input, output, pos_string, search_placeholder, placeholderId, placeholderMatchMode); } catch (PdfAsException e) { printPresentableException(e); if (output != null) { File oFile = new File(output); if (oFile.exists()) { logger_.debug("Deleting output file on error."); boolean deleted = oFile.delete(); if (!deleted) { logger_.error("Couldn't delete output file " + output); } } } } finally { SettingsReader.clearTemporaryDirectory(); } } protected static void carryOutCommand(final String mode, final String signature_mode, final String connector, final String signature_type, final String user_name, final String user_password, final int verify_which, final String input, String output, final String pos_string, boolean search_placeholder, String placeholderId, int placeholderMatchMode) throws PdfAsException { // File file = new File(input); // // byte[] input_bytes = null; // try // { // FileInputStream fis = new FileInputStream(file); // input_bytes = new byte[(int) file.length()]; // fis.read(input_bytes); // fis.close(); // } // catch (IOException e) // { // throw new PDFDocumentException(201); // } PrintWriter messageOutput = new PrintWriter(System.out); if (mode.equals(VALUE_MODE_SIGN)) { carryOutSign(input, connector, signature_mode, signature_type, pos_string, user_name, user_password, output, messageOutput, search_placeholder, placeholderId, placeholderMatchMode); } else { carryOutVerify(input, connector, verify_which, messageOutput); } messageOutput.flush(); } public static void carryOutSign(String input, String connector, String signature_mode, String signature_type, String pos_string, String user_name, String user_password, String output, PrintWriter messageOutput, boolean search_placeholder, String placeholderId, int placeholderMatchMode) throws PdfAsException { messageOutput.println("Signing " + input + "..."); // for performance measurement long startTime = 0; long fileSize = 0; if (logger_.isInfoEnabled()) { startTime = System.currentTimeMillis(); } DataSource dataSource = null; try { File file = new File(input); dataSource = new FileBasedDataSource(file, "application/pdf"); if (logger_.isDebugEnabled()) { fileSize = file.length(); } } catch (IOException e) { throw new PDFDocumentException(201, e); } DataSink dataSink = null; File outputFile = null; try { outputFile = new File(output); dataSink = new FileBasedDataSink(outputFile); } catch (IOException e) { throw new PDFDocumentException(ErrorCode.CANNOT_WRITE_PDF, e); } try { processSign(dataSource, connector, signature_mode, signature_type, pos_string, search_placeholder, placeholderId, placeholderMatchMode, dataSink); } catch (Exception e) { // Exception caught in order to delete file based datasink if (outputFile != null && outputFile.exists()) { logger_.debug("Deleting output file on error."); boolean deleted = outputFile.delete(); if (!deleted) { logger_.error("Couldn't delete output file " + output); } } if (e instanceof PresentableException) { throw (PresentableException)e; } else { logger_.error(e); throw new PresentableException(ErrorCode.UNKNOWN_ERROR, e); } } // for performance measurement if (logger_.isInfoEnabled()) { long endTime = System.currentTimeMillis(); String toReport = "SIGN;" + signature_mode + ";" + input + ";" + fileSize + ";" + (endTime - startTime); logger_.info(toReport); } messageOutput.println("Signing was successful (" + output + ")."); } public static void carryOutVerify(String input, String connector, int verify_which, PrintWriter messageOutput) throws PdfAsException { messageOutput.println("Verifying " + input + "..."); // for performance measurement long startTime = 0; long fileSize = 0; if (logger_.isInfoEnabled()) { startTime = System.currentTimeMillis(); } DataSource dataSource = null; try { File file = new File(input); if (logger_.isDebugEnabled()) { fileSize = file.length(); } String extension = extractExtension(input); if (extension != null && extension.equals("txt")) { try { FileInputStream fis = new FileInputStream(file); byte[] input_bytes = new byte[(int) file.length()]; fis.read(input_bytes); fis.close(); String text = new String(input_bytes, "UTF-8"); dataSource = new StringTextBasedDataSource(text); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Very strange: UTF-8 character encoding not supported.", e); } } else { dataSource = new FileBasedDataSource(file, "application/pdf"); } } catch (IOException e) { throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e); } VerifyResults results = processVerify(dataSource, connector, verify_which); messageOutput.println("Verification results:"); formatVerifyResults(results, messageOutput); // for performance measurement if (logger_.isInfoEnabled()) { long endTime = System.currentTimeMillis(); String toReport = "VERIFY;" + input + ";" + fileSize + ";" + (endTime - startTime) + ";" + debugVerifyResults(results); logger_.info(toReport); } } /** * Extracts the extension from a file name string. * *

* The extension of a file name is whatever text follows the last '.'. *

* * @param file_name * The file name. * @return Returns the extension. If the file name ends with the '.', then an * empty string is returned. If the file name doesn't contain any '.' * or file_name is null, null is returned. */ public static String extractExtension(String file_name) { if (file_name == null) { return null; } int dot_index = file_name.lastIndexOf('.'); if (dot_index < 0) { return null; } return file_name.substring(dot_index + 1); } public static void processSign(DataSource dataSource, String connector, String signature_mode, String signature_type, String pos_string, boolean search_placeholder, String placeholderId, int placeholderMatchMode, DataSink dataSink) throws PdfAsException { TablePos pos = null; if (pos_string != null) { try { pos = PdfAS.parsePositionFromPosString(pos_string); } catch (PDFDocumentException e) { printUnrecognizedValue(PARAMETER_POS, pos_string); return; } } SignaturePositioning posi = null; if (pos != null) { posi = new SignaturePositioning(); if (!pos.isXauto()) { posi.setXAlgorithm(new AbsoluteAxisAlgorithm(pos.getPosX())); } if (!pos.isYauto()) { posi.setYAlgorithm(new AbsoluteAxisAlgorithm(pos.getPosY())); } if (!pos.isWauto()) { posi.setWidthAlgorithm(new AbsoluteAxisAlgorithm(pos.getWidth())); } if (pos.isNewPage()) { posi.setPageAlgorithm(new NewPageAlgorithm()); } if (!pos.isPauto()) { posi.setPageAlgorithm(new AbsolutePageAlgorithm(pos.getPage())); } posi.setFooterLine(pos.getFooterLine()); } PdfAs pdfAs = PdfAsFactory.createPdfAs(new File(SettingsReader.RESOURCES_PATH)); SignParameters sp = new SignParameters(); sp.setDocument(dataSource); sp.setOutput(dataSink); sp.setSignatureType(signature_mode); // TODO detached signaturen! sp.setSignatureDevice(connector); sp.setSignatureProfileId(signature_type); sp.setSignaturePositioning(posi); sp.setCheckForPlaceholder(search_placeholder); sp.setPlaceholderId(placeholderId); sp.setPlaceholderMatchMode(placeholderMatchMode); pdfAs.sign(sp); } public static VerifyResults processVerify(DataSource dataSource, String connector, int verify_which) throws PdfAsException { String verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE; VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings(); if (parameters.extractBinarySignaturesOnly()) { verifyMode = Constants.VERIFY_MODE_BINARY_ONLY; } else { if (parameters.assumeOnlySignatureUpdateBlocks()) { verifyMode = Constants.VERIFY_MODE_SEMI_CONSERVATIVE; } else { verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE; } } PdfAs pdfAs = PdfAsFactory.createPdfAs(new File(SettingsReader.RESOURCES_PATH)); VerifyParameters vp = new VerifyParameters(); vp.setDocument(dataSource); vp.setVerifyMode(verifyMode); vp.setSignatureDevice(connector); vp.setReturnHashInputData(false); vp.setVerificationTime(null); vp.setSignatureToVerify(verify_which); VerifyResults vrs = pdfAs.verify(vp); return vrs; } protected static String generateOutputFileNameFromInput(String input, String sig_mode) { String output = input + "_out"; if (sig_mode.startsWith("detached")) { output += ".xml"; } else { output += ".pdf"; } return output; } /** * Prints that the provided option was unrecognized. * * @param option * The unrecognized option. * @throws PresentableException * Forwarded exception. */ protected static void printUnrecognizedOption(final String option) throws PresentableException { System.err.println("Unrecognized option '" + option + "'."); printUsage(System.out); } /** * Prints that the provided value was unrecognized. * * @param parameter * The parameter, which is missing a value. * @throws PresentableException * Forwarded exception. */ protected static void printNoValue(final String parameter) throws PresentableException { System.err.println("The parameter " + parameter + " requires a value as next argument."); printUsage(System.out); } /** * Prints that the provided value was unrecognized. * * @param value * The unrecognized value. * @throws PresentableException * Forwarded exception. */ protected static void printUnrecognizedValue(final String parameter, final String value) throws PresentableException { System.err.println("The parameter " + parameter + " doesn't recognize the provided value '" + value + "'."); printUsage(System.out); } /** * Prints that the provided additional commandline argument was unrecognized. * * @param argument * The unrecognized argument. * @throws PresentableException * Forwarded exception. */ protected static void printUnrecognizedAdditionalCommandlineArgument(final String argument) throws PresentableException { System.err.println("Unrecognized additional commandline argument '" + argument + "'."); printUsage(System.out); } /** * Prints that a certain parameter was missing. * * @param missing_term * A description of the missing parameter ("e.g. a mode"). * @param parameter * The missing parameter itself (e.g. "-mode"). * @throws PresentableException * Forwarded exception. */ protected static void printMissingParameter(final String missing_term, final String parameter) throws PresentableException { printMissing(missing_term + " ('" + parameter + "' parameter)"); } /** * Prints that something is missing. * * @param missing_term * A descriptive message of the missing thing. * @throws PresentableException * Forwarded exception. */ protected static void printMissing(final String missing_term) throws PresentableException { System.err.println("Please specify " + missing_term + "."); printUsage(System.out); } /** * Prints out the ErrorCodeException in a descriptive form. * * @param ece * The ErrorCodeException to be printed. */ protected static void printPresentableException(final PdfAsException e) { String errorMessage = ErrorCodeHelper.formErrorMessage(e); System.err.println(errorMessage); // if (e.getErrorCode() == ErrorCode.PLACEHOLDER_EXCEPTION) // { // PlaceholderException phe = null; // if (e instanceof PlaceholderException) // { // phe = (PlaceholderException) e; // } // else // { // phe = (PlaceholderException) e.getCause(); // } // // System.err.println("Der Platzhalter des Feldes " + phe.getField() + " ist um " + phe.getMissing() + " Bytes zu kurz. "); // } // // System.err.println("Fehler " + e.getErrorCode() + ": " + ErrorCodeHelper.getMessageForErrorCode(e.getErrorCode())); // // if (e instanceof ExternalErrorException) // { // ExternalErrorException eee = (ExternalErrorException) e; // System.err.println("Externer Fehlergrund: " + eee.getExternalErrorCode() + ": " + eee.getExternalErrorMessage()); // } logger_.error(e); } /** * Prints the usage text. * * @param writer * The writer to print the text to. * @throws PresentableException * Forwarded exception. */ public static void printUsage(PrintStream writer) throws PresentableException { writer.println("Usage: pdf-as [[OPTIONS] [output file]|UTILOPTIONS]"); writer.println(" Required OPTIONS:"); writer.println(" " + PARAMETER_MODE + " <" + VALUE_MODE_SIGN + "|" + VALUE_MODE_VERIFY + ">"); writer.println(" " + VALUE_MODE_SIGN + " ... signs a document"); writer.println(" " + VALUE_MODE_VERIFY + " ... verifies a document"); writer.print(" " + PARAMETER_CONNECTOR + " "); ConnectorInformation[] ci = ConnectorFactory.getConnectorInformationArray(); // prepare list of connectors available for commandline ArrayList ciList = new ArrayList(); for (int i = 0; i < ci.length; i++) { String id = ci[i].getIdentifier(); if (ConnectorFactory.isAvailableForCommandline(id)) { ciList.add(ci[i]); } } // list available connectors wrapped in <...|...> Iterator ciIt = ciList.iterator(); writer.print("<"); while (ciIt.hasNext()) { writer.print(((ConnectorInformation) ciIt.next()).getIdentifier()); if (ciIt.hasNext()) { writer.print("|"); } } writer.print(">"); writer.println(); // for (int i = 0; i < ci.length; i++) // { // String id = ci[i].getIdentifier(); // if (!ConnectorFactory.isAvailableForCommandline(id)) // { // continue; // } // writer.print(id); // if (i < ci.length - 1) // { // writer.print("|"); // } // } ciIt = ciList.iterator(); while (ciIt.hasNext()) { ConnectorInformation cinf = (ConnectorInformation) ciIt.next(); writer.println(" " + cinf.getIdentifier() + " ... " + cinf.getDescription()); } // for (int i = 0; i < ci.length; i++) // { // String id = ci[i].getIdentifier(); // if (!ConnectorFactory.isAvailableForCommandline(id)) // { // continue; // } // writer.println(" " + id + " ... " + ci[i].getDescription()); // } writer.println(" UTILity OPTIONS"); writer.println(" " + PARAMETER_DEPLOY_DEFAULT_CONFIGURATION + " ... deploys the default configuration to the current user's home"); writer.println(" OPTIONS for signation:"); writer.println(" " + PARAMETER_SIGNATURE_MODE + " <" + VALUE_SIGNATURE_MODE_BINARY + "|" + VALUE_SIGNATURE_MODE_TEXTUAL + "> [optional]"); writer.println(" " + VALUE_SIGNATURE_MODE_BINARY + " ... signs the complete binary document" + (Constants.DEFAULT_SIGNATURE_TYPE.equals(VALUE_SIGNATURE_MODE_BINARY) ? " (default)" : "")); writer.println(" " + VALUE_SIGNATURE_MODE_TEXTUAL + " ... signs only the textual portion of the document" + (Constants.DEFAULT_SIGNATURE_TYPE.equals(VALUE_SIGNATURE_MODE_TEXTUAL) ? " (default)" : "")); writer.println(" " + VALUE_SIGNATURE_MODE_DETACHED_TEXT + " ... signs the document using the textual mode and returns the xml signature of it." + (Constants.DEFAULT_SIGNATURE_TYPE.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXT) ? " (default)" : "")); writer.print(" " + PARAMETER_SIGNATURE_TYPE + " <"); SignatureTypes sig_types = SignatureTypes.getInstance(); SettingsReader settings = SettingsReader.getInstance(); Set types_array = sig_types.getSignatureTypes(); Iterator it = types_array.iterator(); while (it.hasNext()) { String type = (String) it.next(); writer.print(type); if (it.hasNext()) { writer.print("|"); } } writer.println(">"); writer.println(" ... [optional] the profile to be used. If omitted, the default"); writer.println(" profile is used."); String default_type = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE); it = types_array.iterator(); while (it.hasNext()) { String type = (String) it.next(); String descr_key = SignatureTypes.SIG_OBJ + type + "." + SignatureTypes.SIG_DESCR; String type_descr = settings.getValueFromKey(descr_key); writer.println(" " + type + " ... " + (type.equals(default_type) ? "(default) " : "") + type_descr); } writer.println(" " + PARAMETER_USER_NAME + " ... [optional] the user name"); writer.println(" " + PARAMETER_USER_PASSWORD + " ... [optional] the user password"); writer.println(" " + PARAMETER_POS + " ... [optional] the position of the signature block"); writer.println(" position has the format [x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo]"); writer.println(" if not present default is set to x:auto;y:auto;w:auto;p:auto;f:0"); writer.println(" x_algo:='auto' ... automatic positioning x"); writer.println(" floatvalue ... absolute x must be >= 0"); writer.println(" y_algo:='auto' ... automatic positioning y"); writer.println(" floatvalue ... absolute y must be >= 0"); writer.println(" w_algo:='auto' ... automatic width"); writer.println(" floatvalue ... absolute width must be > 0"); writer.println(" p_algo:='auto' ... automatic last page"); writer.println(" 'new' ... new page"); writer.println(" intvalue ... pagenumber must be > 0 if p>number of pages in document p-->handled like p:'new'"); writer.println(" f_algo floatvalue ... consider footerline must be >= 0 (only if y_algo is auto and p_algo is not 'new')"); writer.println(" " + PARAMETER_PLACEHOLDER_SEARCH + " ... [optional] if set to true, the source document will be scanned for signature placeholder images. If not set, the enable_placeholder_search value in the config file decides whether or not a search for placeholder images will be performed."); writer.println(" " + PARAMETER_PLACEHOLDER_ID + " ... [optional] search for signature placeholder images containing the given id"); writer.println(" " + PARAMETER_PLACEHOLDER_MATCH_MODE + " <" + VALUE_PLACEHOLDER_MATCH_MODE_LENIENT + "|" + VALUE_PLACEHOLDER_MATCH_MODE_MODERATE + "|" + VALUE_PLACEHOLDER_MATCH_MODE_STRICT + "> ... [optional] specify the behavior if no matching placeholder could be found. Default is ."); writer.println(" " + VALUE_PLACEHOLDER_MATCH_MODE_LENIENT + " ... sign in place of the first found placeholder, regardless if it matches exactly, or at the end of the document if none is found."); writer.println(" " + VALUE_PLACEHOLDER_MATCH_MODE_MODERATE + " ... sign in place of the first found placeholder which has no explicit id set, or at the end of the document if none is found."); writer.println(" " + VALUE_PLACEHOLDER_MATCH_MODE_STRICT + " ... throws a PlaceholderExtractionException."); writer.println(" OPTIONS for verification:"); writer.println(" " + PARAMETER_VERIFY_WHICH + " ... [optional] zero based number of the signature"); writer.println(" to be verified. If omitted, all signatures are verified."); writer.println(" Example usage:"); writer.println(" pdf-as " + PARAMETER_MODE + " " + VALUE_MODE_SIGN + " " + PARAMETER_CONNECTOR + " " + Constants.SIGNATURE_DEVICE_BKU + " " + PARAMETER_SIGNATURE_MODE + " " + VALUE_SIGNATURE_MODE_TEXTUAL + " some_document.pdf"); writer.println(" pdf-as " + PARAMETER_MODE + " " + VALUE_MODE_VERIFY + " " + PARAMETER_CONNECTOR + " " + Constants.SIGNATURE_DEVICE_BKU + " some_document.pdf_out.pdf"); writer.println(" pdf-as " + PARAMETER_DEPLOY_DEFAULT_CONFIGURATION); } /** * Checks the value for correctness. * * @param mode * The parameter's value. * @return Returns true, if the value is correct, false otherwise. */ protected static boolean checkMode(String mode) { return mode.equals(VALUE_MODE_SIGN) || mode.equals(VALUE_MODE_VERIFY); } /** * Checks the value for correctness. * * @param signature_mode * The parameter's value. * @return Returns true, if the value is correct, false otherwise. */ protected static boolean checkSignatureMode(String signature_mode) { return signature_mode.equals(VALUE_SIGNATURE_MODE_BINARY) || signature_mode.equals(VALUE_SIGNATURE_MODE_TEXTUAL) //|| signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED) || signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXT); } /** * Checks the value for correctness. * * @param connector * The parameter's value. * @return Returns true, if the value is correct, false otherwise. * @throws ConnectorFactoryException * F.e. */ protected static boolean checkConnector(String connector) throws ConnectorFactoryException { return ConnectorFactory.isValidConnectorIdentifier(connector) && ConnectorFactory.isAvailableForCommandline(connector); } /** * Checks the value for correctness (meaning if it exists) * * @param signature_type * The parameter's value. * @return Returns true, if the value is correct, false otherwise. */ protected static boolean checkSignatureType(String signature_type) throws SignatureTypesException { return SignatureTypes.getInstance().getSignatureTypes().contains(signature_type); } /** * Translates the commandline argument to a PDF-AS-ID. * * @param signature_mode * The signator mode commandline argument. * @return Returns the corresponding PDFASID. */ protected static PdfASID translateSignatureModeToPdfASID(String signature_mode) { if (signature_mode.equals(VALUE_SIGNATURE_MODE_BINARY)) { return SignatorFactory.MOST_RECENT_BINARY_SIGNATOR_ID; } if (signature_mode.equals(VALUE_SIGNATURE_MODE_TEXTUAL)) { return SignatorFactory.MOST_RECENT_TEXTUAL_SIGNATOR_ID; } if (signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED)) { return SignatorFactory.MOST_RECENT_DETACHED_SIGNATOR_ID; } if (signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXT)) { return SignatorFactory.MOST_RECENT_DETACHEDTEXT_SIGNATOR_ID; } return null; } /** * Formats the verification results. * * @param results * The List of SignatureResponse verification results. * @param writer * The output sink to write the formatted text to. * @throws SettingNotFoundException * Forwarded exception. */ protected static void formatVerifyResults(VerifyResults results, PrintWriter writer) throws SettingNotFoundException { Iterator it = results.getResults().iterator(); while (it.hasNext()) { VerifyResult result = (VerifyResult) it.next(); formatVerifyResult(result, writer); if (it.hasNext()) { writer.println(); } } } /** * Formats the verification results for debugging. Returns 0 if no error * occurs or the sum of all error-codes. * * @param results * * @param writer * The output sink to write the formatted text to. * @throws SettingNotFoundException * Forwarded exception. */ protected static int debugVerifyResults(VerifyResults results) throws SettingNotFoundException { int toreturn = 0; Iterator it = results.getResults().iterator(); while (it.hasNext()) { VerifyResult result = (VerifyResult) it.next(); toreturn += result.getValueCheckCode().getCode(); } return toreturn; } public static void formatVerifyResult(VerifyResult result, PrintWriter writer) throws SettingNotFoundException { if (result.isVerificationDone()) { writer.println(" Zertifikat:"); writer.println(" Signator: " + result.getSignerCertificate().getSubjectDN().toString()); writer.println(" Aussteller: " + result.getSignerCertificate().getIssuerDN().toString()); writer.println(" Seriennummer: " + result.getSignerCertificate().getSerialNumber()); List public_properties = result.getPublicProperties(); Iterator it = public_properties.iterator(); while (it.hasNext()) { String public_property = (String) it.next(); writer.println(" Eigenschaft: " + public_property); } writer.println(" Zertifikat-Check:"); writer.println(" " + result.getCertificateCheck().getCode() + " - " + result.getCertificateCheck().getMessage()); writer.println(" Signatur-Check:"); writer.println(" " + result.getValueCheckCode().getCode() + " - " + result.getValueCheckCode().getMessage()); writer.println(" Manifest-Check:"); writer.println(" " + result.getManifestCheckCode().getCode() + " - " + result.getManifestCheckCode().getMessage()); } else { PdfAsException ex = result.getVerificationException(); writer.println("\n Signaturpruefung fuer diese Signatur nicht moeglich: " + ErrorCodeHelper.formErrorMessage(ex)); } } }