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 --- .../pdfas/impl/vfilter/VerificationFilterImpl.java | 189 +++++++++------------ 1 file changed, 81 insertions(+), 108 deletions(-) (limited to 'src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java') 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()); -- cgit v1.2.3