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 --- .../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 + 4 files changed, 93 insertions(+), 174 deletions(-) delete mode 100644 src/main/java/at/gv/egiz/pdfas/test/APITest.java (limited to 'src/main/java/at/gv/egiz') 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)) { -- cgit v1.2.3