From 137658e3a41c09b4aa7b9125e4d9f65f16e2facc Mon Sep 17 00:00:00 2001 From: tknall Date: Fri, 13 Jun 2008 11:45:39 +0000 Subject: Detection of incremental updates updated. Bug fixed. There was an error concerning empty HashInputData parsing a MOA CreateXMLSignatureResponse. Demo source for API usage created. Issue resolved: Prevent signature of empty document which leads to a meaningless error message from the bku. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@284 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- dok/Hinweise-zur-PDF-AS-Konfiguration.pdf | Bin 360126 -> 364228 bytes dok/Issues.txt | 28 ++- pom.xml | 14 +- .../java/at/gv/egiz/pdfas/commandline/Main.java | 7 +- .../pdfas/impl/vfilter/VerificationFilterImpl.java | 189 +++++++++------------ src/main/java/at/gv/egiz/pdfas/test/APITest.java | 65 ------- .../egiz/pdfas/web/helper/SignServletHelper.java | 6 + .../java/at/knowcenter/wag/egov/egiz/PdfAS.java | 2 +- .../egov/egiz/sig/connectors/bku/BKUHelper.java | 5 +- .../wag/egov/egiz/web/servlets/SignServlet.java | 2 +- src/main/java/demo/APIDemo.java | 169 ++++++++++++++++++ src/main/resources/DefaultConfiguration.zip | Bin 190303 -> 190303 bytes src/site/changes.xml | 7 + 13 files changed, 313 insertions(+), 181 deletions(-) delete mode 100644 src/main/java/at/gv/egiz/pdfas/test/APITest.java create mode 100644 src/main/java/demo/APIDemo.java diff --git a/dok/Hinweise-zur-PDF-AS-Konfiguration.pdf b/dok/Hinweise-zur-PDF-AS-Konfiguration.pdf index 52b239b..d6fdd13 100644 Binary files a/dok/Hinweise-zur-PDF-AS-Konfiguration.pdf and b/dok/Hinweise-zur-PDF-AS-Konfiguration.pdf differ diff --git a/dok/Issues.txt b/dok/Issues.txt index 5cb5fa0..36de44a 100644 --- a/dok/Issues.txt +++ b/dok/Issues.txt @@ -1,5 +1,31 @@ -Issue #1 +Issue #1 (Bug oder Feature ?) Bei der Signatur eines Dokuments, dem zuvor eine leere letzte Seite hinzugefügt wurde, befindet sich die Signaturmarke am Beginn dieser letzten leeren Seite selbst wenn auf der vorletzten Seite noch genügend Platz zu Verfügung stehen würde. +Issue #2 +Bei Aktivieren eines Minimallayout-Profils wurde bei der der Prüfung beliebiger Dokumente ein +Problem festgestellt: + +"java.lang.RuntimeException: There is no SIG_DATE in the list of found_keys. This must not happen." + +Bei der Definition eines Minimallayouts können bisher verpflichtende Einträge für die Signaturmarke +weggelassen werden (entsprechende Einträge SIG_XXX-cv in den Tabellen sowie entsprechende Keys +sig_obj.PROFIL.key.SIG_XXX=XXX). +In der eingecheckten Konfiguration (work-Verzeichnis) existieren zwei solche Minimallayouts. + +Da mit derselben Konfiguration auch Signaturen mit dem Minimallayout durchgeführt werden sollen, +kann dieses nicht einfach deaktiviert werden (für eine Verifikation binärer Signaturen benötigt man +keine aktiven Profile). + +Ein Hinzufügen der Zeilen: + +sig_obj.SIGNATURBLOCK_MINIMAL_DE.key.SIG_VALUE=Signaturwert +sig_obj.SIGNATURBLOCK_MINIMAL_DE.key.SIG_NAME=Unterzeichner +sig_obj.SIGNATURBLOCK_MINIMAL_DE.key.SIG_DATE=Datum/Zeit-UTC +sig_obj.SIGNATURBLOCK_MINIMAL_DE.key.SIG_ISSUER=Aussteller-Zertifikat +sig_obj.SIGNATURBLOCK_MINIMAL_DE.key.SIG_NUMBER=Serien-Nr. +sig_obj.SIGNATURBLOCK_MINIMAL_DE.key.SIG_KZ=Methode +sig_obj.SIGNATURBLOCK_MINIMAL_DE.key.SIG_ID=Parameter + +hat das Problem übrigens auch nicht gelöst. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 87f742a..91554f6 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ knowcenter pdf-as PDF-AS - 3.0.5-20080612 + 3.0.5-20080613 Amtssignatur fuer elektronische Aktenfuehrung @@ -51,6 +51,17 @@ +1 + + tzefferer + Thomas Zefferer + thomas.zefferer@egiz.gv.at + EGIZ + + developer + + +1 + + amavriqi Arian Mavriqi @@ -95,6 +106,7 @@ 1.4 at/gv/egiz/pdfas/test/*/ + demo/*/ diff --git a/src/main/java/at/gv/egiz/pdfas/commandline/Main.java b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java index 8330238..d65ef45 100644 --- a/src/main/java/at/gv/egiz/pdfas/commandline/Main.java +++ b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java @@ -182,7 +182,7 @@ public abstract class Main } else { System.out.println("Default configuration has NOT been deployed. Maybe the configuration already exists."); } - System.exit(0); +// System.exit(0); } catch (ConfigUtilsException e) { System.err.println("Deployment of default configuration failed: " + e.getMessage()); System.exit(1); @@ -221,6 +221,11 @@ public abstract class Main { String cur_arg = args[i].trim(); + if (cur_arg.equals(PARAMETER_DEPLOY_DEFAULT_CONFIGURATION)) { + // already applied + continue; + } + if (cur_arg.equals(PARAMETER_MODE)) { i++; diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java index d353b9a..3ca497b 100644 --- a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java @@ -4,8 +4,10 @@ package at.gv.egiz.pdfas.impl.vfilter; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.apache.commons.lang.time.StopWatch; import org.apache.commons.logging.Log; @@ -54,7 +56,6 @@ public class VerificationFilterImpl implements VerificationFilter private static final Log log = LogFactory.getLog(VerificationFilterImpl.class); - // tzefferer: added public static final String CHECK_DOCUMENT = "check_document"; public static final String BINARY_ONLY = "binary_only"; public static final String ASSUME_ONLY_SIGNATURE_BLOCKS = "assume_only_signature_blocks"; @@ -93,7 +94,7 @@ public class VerificationFilterImpl implements VerificationFilter } String check_doc = settings.getSetting(CHECK_DOCUMENT, "false"); - // tzefferer: check document for textual sigs here here if binary_only is set + // check document for textual sigs here here if binary_only is set if ("true".equalsIgnoreCase(check_doc) && parameters.extractBinarySignaturesOnly()) { @@ -215,8 +216,8 @@ public class VerificationFilterImpl implements VerificationFilter if (linearization_index >= 0) { - // logger_.debug("The document is linearized - unrolling - // linearization block " + linearization_index); +// logger_.debug("The document is linearized - unrolling +// linearization block " + linearization_index); blocks.remove(linearization_index); } } @@ -259,6 +260,19 @@ public class VerificationFilterImpl implements VerificationFilter { List binarySignatures = extractBinarySignaturesOnly(pdf, blocks); + // extract signature values of found binary signature blocks and store these values in a Set + // this set is later used to filter out the binary signatures that are recognized as text + // signatures. + Set binarySigValues = new HashSet(); + Iterator iterator = binarySignatures.iterator(); + while(iterator.hasNext()) { + + SignatureHolder sh = (SignatureHolder)iterator.next(); + + String sigVal = sh.getSignatureObject().getSignationValue(); + binarySigValues.add(sigVal); + } + SignatureHolder oldSignature = null; //List originalPartitions = partitions; @@ -278,23 +292,35 @@ public class VerificationFilterImpl implements VerificationFilter } String check_doc = settings.getSetting(CHECK_DOCUMENT, "false"); - // flags for determination of illegal incremental update - int sigsFound = 0; - int sigsFoundPrev = 0; + // flag indicating that the last IU-block of the document is a non-signature IU-block boolean lastBlockWasModified = false; + // counter of all signatures (textual and binary) of this document + int signatureCounter = 0; + + // counter of all textual signatures in this document + int txtSigsSoFar = 0; + + // counter of all textual signatures in the current partition + int txtSigsThisPartition = 0; + List partitionResults = new ArrayList(partitions.size()); - List nshList = new ArrayList(); + List nshList = new ArrayList(); + + boolean sigFound = false; for (int i = 0; i < partitions.size(); i++) { Partition p = (Partition) partitions.get(i); - + // updating flag and counter + boolean partitionContainsNewTextSignatures = true; + txtSigsSoFar = txtSigsThisPartition; + if (p instanceof TextPartition) { TextPartition tp = (TextPartition) p; - + List partitionResult = null; boolean scanThisPartitionForOldSignature = (i == 0) && scanForOldSignatures; @@ -309,27 +335,59 @@ public class VerificationFilterImpl implements VerificationFilter partitionResult = extractSignaturesFromPartition(pdf, tp); } - sigsFoundPrev = sigsFound; - sigsFound = partitionResult.size(); + // binary signature blocks that have been detected as well are identified by comparing their signature values + // with those stored in our Set above and are not considered for our IU-check + List onlyTextSignatures = new ArrayList(); + Iterator iter = partitionResult.iterator(); + while(iter.hasNext()) { + + SignatureHolder sh = (SignatureHolder)iter.next(); + if(!binarySigValues.contains(sh.getSignatureObject().getSignationValue())) { + + onlyTextSignatures.add(sh); + } + } + + // update signature counters + txtSigsThisPartition = onlyTextSignatures.size(); + int newTextSignatures = txtSigsThisPartition - txtSigsSoFar; + signatureCounter = signatureCounter + newTextSignatures; + + // update sigFound flag + if(txtSigsThisPartition > 0) { + + sigFound = true; + } + + // TextPartition is only valid, if at least one more text signature has been found than in the previous text partition + if(!(newTextSignatures > 0)) { + + partitionContainsNewTextSignatures = false; + } + partitionResults.add(partitionResult); } else { // should be binary partition if(p instanceof BinaryPartition) { + BinaryPartition binpart = (BinaryPartition)p; - // add number (n) of found binary signatures - if there is a subsequent textual partition, - // at least n+1 sigs have to be found (note: sig-blocks of binary signatures are also extracted and detected) - sigsFound = sigsFound + binpart.blocks.size(); + + // updating counter and flag + signatureCounter = signatureCounter + binpart.blocks.size(); + sigFound = true; } } - // add NoSignatureHolder object if there were already signatures, but current block does not contain any signatures - if((check_doc.equalsIgnoreCase("true"))&& ((sigsFoundPrev > 0) && !(sigsFound > sigsFoundPrev)) ) { - - nshList.add(new NoSignatureHolder(sigsFound)); - + // if document checking is enabled, at least one signature has been found so far, we are dealing with a + // non-signature IU-block + if((check_doc.equalsIgnoreCase("true"))&& (sigFound && !partitionContainsNewTextSignatures)) { + + nshList.add(new NoSignatureHolder(signatureCounter)); lastBlockWasModified = true; + } else { + lastBlockWasModified = false; } @@ -669,10 +727,10 @@ public class VerificationFilterImpl implements VerificationFilter { int endOfDocument = VerificationFilterHelper.getEndOfPartition(partition); - log.debug("Extracting text from 0 to " + endOfDocument + " (total document size = " + pdf.getLength() + "):"); +// log.debug("Extracting text from 0 to " + endOfDocument + " (total document size = " + pdf.getLength() + "):"); String extractedText = extractText(pdf, endOfDocument); - log.debug("Extracting text finished."); - log.debug("extracted text: " + extractedText); +// log.debug("Extracting text finished."); +// log.debug("extracted text: " + extractedText); SignaturesAndOld sao = extractSignaturesAndOld(extractedText); @@ -684,91 +742,6 @@ public class VerificationFilterImpl implements VerificationFilter } } -// // tzefferer: added method -// protected void checkDocument(PdfDataSource pdf, List blocks, VerificationFilterParameters parameters) throws VerificationFilterException { -// -// boolean consider_old_sigs = parameters.scanForOldSignatures(); -// boolean binary_only = parameters.extractBinarySignaturesOnly(); -// boolean assume_sigs_only = parameters.assumeOnlySignatureUpdateBlocks(); -// -// if(binary_only) { -// // check if document contains textual signatures -// checkBinaryOnly(pdf, consider_old_sigs); -// } -// if(!assume_sigs_only) { -// // check if document contains post-sign modifications -// checkUpdateBlocks(pdf, blocks, consider_old_sigs); -// } -// } - // tzefferer: added method -// protected void checkUpdateBlocks(PdfDataSource pdf, List blocks, boolean considerOldSigs) throws VerificationFilterException { -// -// boolean sig_detected = false; -// -// if (considerOldSigs) { -// -// DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, pdf.getLength()); -// String text = null; -// try { -// text = PdfAS.extractNormalizedTextTextual(dds); -// } catch (PresentableException e) { -// throw new VerificationFilterException(e); -// } -// -// SignaturesAndOld sao = extractSignaturesAndOld(text); -// -// if ((sao != null) && (sao.oldSignature != null)) { -// sig_detected = true; -// } -// } -// -// -// Iterator it = blocks.iterator(); -// String prev_text = null; -// -// while (it.hasNext()) -// { -// boolean sig_in_current_block = false; -// -// FooterParseResult fpr = (FooterParseResult) it.next(); -// -// DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, fpr.next_index); -// -// String text; -// try { -// text = PdfAS.extractNormalizedTextTextual(dds); -// } catch (PresentableException e) { -// throw new VerificationFilterException(e); -// } -// -// if (prev_text == null) { -// prev_text = text; -// } else { -// String texttmp = text.substring(prev_text.length()); -// prev_text = text; -// text = texttmp; -// } -// -// List sig_holders = null; -// try { -// sig_holders = AbsoluteTextSignature.extractSignatureHoldersFromText(text); -// } catch (SignatureException e) { -// throw new VerificationFilterException(e); -// } catch (SignatureTypesException e) { -// throw new VerificationFilterException(e); -// } -// -// if((sig_holders != null) && (sig_holders.size() > 0)) { -// sig_detected = true; -// sig_in_current_block = true; -// } -// -// if((sig_detected) && (!sig_in_current_block)) { -// throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed."); -// } -// } -// } - // tzefferer: added method protected void checkBinaryOnly(PdfDataSource pdf, boolean considerOldSigs) throws VerificationFilterException { DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, pdf.getLength()); diff --git a/src/main/java/at/gv/egiz/pdfas/test/APITest.java b/src/main/java/at/gv/egiz/pdfas/test/APITest.java deleted file mode 100644 index 9e52a41..0000000 --- a/src/main/java/at/gv/egiz/pdfas/test/APITest.java +++ /dev/null @@ -1,65 +0,0 @@ -package at.gv.egiz.pdfas.test; - -import java.io.File; -import java.io.IOException; - -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.PdfAsException; -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.io.FileBasedDataSink; -import at.gv.egiz.pdfas.io.FileBasedDataSource; - -public final class APITest { - - private APITest() { - } - - public static void main(String[] args) { - File configdir = new File("D:/downloads/testpdfas"); - File unsignedFile = new File("./test-files/blindtext.pdf"); - File signedFile = new File("d:/temp/blindtext_signed.pdf"); - String signatureMode = Constants.SIGNATURE_TYPE_BINARY; - String signatureDevice = Constants.SIGNATURE_DEVICE_MOA; - String signatureProfile = "SIGNATURBLOCK_MINIMAL_DE"; - SignaturePositioning signaturePos = null; - - PdfAs pdfasAPI = null; - - try { - - // instantiate api - pdfasAPI = PdfAsFactory.createPdfAs(configdir); - - // set source - DataSource dataSource = new FileBasedDataSource(unsignedFile, "application/pdf"); - - // set output - FileBasedDataSink dataSink = new FileBasedDataSink(signedFile); - - // configure signature - SignParameters signParameters = new SignParameters(); - signParameters.setDocument(dataSource); - signParameters.setOutput(dataSink); - signParameters.setSignatureType(signatureMode); - signParameters.setSignatureDevice(signatureDevice); - signParameters.setSignatureProfileId(signatureProfile); - signParameters.setSignaturePositioning(signaturePos); - - // sign - pdfasAPI.sign(signParameters); - - System.out.println("Successfully signed."); - - } catch (PdfAsException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - } - -} diff --git a/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java b/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java index 341b97c..f9cb809 100644 --- a/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java +++ b/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java @@ -22,6 +22,7 @@ import at.gv.egiz.pdfas.impl.output.ByteArrayDataSink; import at.gv.egiz.pdfas.impl.output.FileBasedDataSink; import at.gv.egiz.pdfas.web.SignSessionInformation; import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.framework.signators.DetachedSignator_1_0_0; import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; @@ -109,6 +110,11 @@ public class SignServletHelper { log.debug("finishSign:"); //$NON-NLS-1$ + // check if document is empty + if (si.si.getSignatureData() == null || si.si.getSignatureData().getDataSource().getLength() == 0) { + throw new PDFDocumentException(250, "The document is empty."); + } + log.debug("connector = " + si.connector); //$NON-NLS-1$ if (ConnectorFactory.isConnectorLocal(si.connector)) { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java index 1b4a210..7a15893 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -96,7 +96,7 @@ public abstract class PdfAS * The current version of the pdf-as library. This version string is logged on every invocation * of the api or the web application. */ - public static final String PDFAS_VERSION = "3.0.5-20080612"; + public static final String PDFAS_VERSION = "3.0.5-20080613"; /** * The key of the strict mode setting. diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java index 1ddd327..68fcad4 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java @@ -447,10 +447,9 @@ public final class BKUHelper Matcher b64_m_s = b64_p_s.matcher(hashInputData); Matcher b64_m_e = b64_p_e.matcher(hashInputData); - b64_m_s.find(); - b64_m_e.find(); + boolean hashInputDataFound = b64_m_s.find() && b64_m_e.find(); - String b64 = hashInputData.substring(b64_m_s.end(), b64_m_e.start()); + String b64 = hashInputDataFound ? hashInputData.substring(b64_m_s.end(), b64_m_e.start()) : ""; sig_res.setHashInputData(b64); } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java index a608b74..9b340e6 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java @@ -293,7 +293,7 @@ public class SignServlet extends HttpServlet return; } - + SignServletHelper.finishSign(si, request, response, getServletContext()); // for performance measurement diff --git a/src/main/java/demo/APIDemo.java b/src/main/java/demo/APIDemo.java new file mode 100644 index 0000000..d4ce5e7 --- /dev/null +++ b/src/main/java/demo/APIDemo.java @@ -0,0 +1,169 @@ +package demo; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; +import java.util.List; + +import at.gv.egiz.pdfas.PdfAsFactory; +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters; +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult; +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.exceptions.PdfAsException; +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.verify.VerifyAfterAnalysisParameters; +import at.gv.egiz.pdfas.api.verify.VerifyResult; +import at.gv.egiz.pdfas.commandline.Main; +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; + +public final class APIDemo { + + /** + * Disable instantiation. + */ + private APIDemo() { + } + + /** + * Verifies a pdf document. + * @param configuration The folder containing the pdf-as work directory (including the configuration). + * @param source The signed pdf document. + * @param verifyDevice The device used for verification + * (see {@link Constants#SIGNATURE_DEVICE_MOA} and {@link Constants#SIGNATURE_DEVICE_BKU}). + * @throws PdfAsException Thrown in case of an error. + * @throws IOException Thrown in case of an i/o error. + */ + public static void verify(File configuration, File source, String verifyDevice) throws PdfAsException, IOException { + + // instantiate api + PdfAs pdfasAPI = PdfAsFactory.createPdfAs(configuration); + + // set source + DataSource dataSource = new FileBasedDataSource(source, "application/pdf"); + + // evaluate settings + VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings(); + String verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE; + + 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; + } + + // configure analyze parameters + AnalyzeParameters analyzeParameters = new AnalyzeParameters(); + analyzeParameters.setDocument(dataSource); + analyzeParameters.setVerifyMode(verifyMode); + + // analyze + System.out.println("Analyzing..."); + AnalyzeResult analyzeResult = pdfasAPI.analyze(analyzeParameters); + System.out.println("Successfully analyzed."); + + // setup verification + VerifyAfterAnalysisParameters vaap = new VerifyAfterAnalysisParameters(); + vaap.setAnalyzeResult(analyzeResult); + vaap.setReturnHashInputData(true); + vaap.setSignatureDevice(verifyDevice); + vaap.setVerificationTime(null); + + // invoke verification + System.out.println("Verifying..."); + List verifyResults = pdfasAPI.verify(vaap).getResults(); + System.out.println("Verification complete."); + + // iterate over results + PrintWriter out = new PrintWriter(System.out); + Iterator it = verifyResults.iterator(); + while (it.hasNext()) { + VerifyResult result = (VerifyResult) it.next(); + Main.formatVerifyResult(result, out); + } + out.flush(); + out.close(); + + } + + /** + * Signs a pdf document. + * @param configuration The folder containing the pdf-as work directory (including the configuration). + * @param source The unsigned pdf document. + * @param signatureDevice The device used for signature + * (see {@link Constants#SIGNATURE_DEVICE_MOA} and {@link Constants#SIGNATURE_DEVICE_BKU}). + * @throws PdfAsException Thrown in case of an error. + * @throws IOException Thrown in case of an i/o error. + * @param destination The signed pdf document. + * @param signatureMode The mode used for signature (see {@link Constants#SIGNATURE_TYPE_BINARY} + * resp. {@link Constants#SIGNATURE_TYPE_TEXTUAL} or {@link Constants#SIGNATURE_TYPE_DETACHEDTEXTUAL}). + * @param signatureProfile The profile used for signature. + * @param signaturePos The position of the signature (see {@link SignaturePositioning}) or {@code null}. + */ + private static void sign(File configuration, File source, File destination, + String signatureMode, String signatureDevice, String signatureProfile, + SignaturePositioning signaturePos) throws PdfAsException, IOException { + + // instantiate api + PdfAs pdfasAPI = PdfAsFactory.createPdfAs(configuration); + + // set source + DataSource dataSource = new FileBasedDataSource(source, "application/pdf"); + + // set output + FileBasedDataSink dataSink = new FileBasedDataSink(destination); + + // configure signature + SignParameters signParameters = new SignParameters(); + signParameters.setDocument(dataSource); + signParameters.setOutput(dataSink); + signParameters.setSignatureType(signatureMode); + signParameters.setSignatureDevice(signatureDevice); + signParameters.setSignatureProfileId(signatureProfile); + signParameters.setSignaturePositioning(signaturePos); + + // sign + System.out.println("Signing..."); + pdfasAPI.sign(signParameters); + + System.out.println("Successfully signed."); + + } + + /** + * Start a demo that signs a document and performs a verification afterwards. + * @param args The parameter(s). + */ + public static void main(String[] args) { + + File configdir = new File("./work"); + File unsignedFile = new File("./test-files/blindtext.pdf"); + File signedFile = new File("./test-files/blindtext_signed.pdf"); + + String signatureMode = Constants.SIGNATURE_TYPE_BINARY; + String signatureDevice = Constants.SIGNATURE_DEVICE_MOA; + String signatureProfile = "SIGNATURBLOCK_DE"; + SignaturePositioning signaturePos = null; + + try { + + sign(configdir, unsignedFile, signedFile, signatureMode, signatureDevice, signatureProfile, signaturePos); + verify(configdir, signedFile, signatureDevice); + + } catch (PdfAsException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + +} diff --git a/src/main/resources/DefaultConfiguration.zip b/src/main/resources/DefaultConfiguration.zip index 4682add..b1cc550 100644 Binary files a/src/main/resources/DefaultConfiguration.zip and b/src/main/resources/DefaultConfiguration.zip differ diff --git a/src/site/changes.xml b/src/site/changes.xml index dc2183b..07f4504 100644 --- a/src/site/changes.xml +++ b/src/site/changes.xml @@ -13,6 +13,13 @@ --> + + Detection of incremental updates updated. + Bug fixed. There was an error concerning empty HashInputData parsing a MOA CreateXMLSignatureResponse. + Demo source for API usage created. + Issue resolved: Prevent signature of empty document which leads to a meaningless error message from the bku. + + A new check for the existence of a configuration has been implemented. The extraction is skipped if any files or folders would be overwritten. Files like log- or temp-files may exist and do not prevent the deployment of the default configuration. -- cgit v1.2.3