From d29da544e84d36170b8befe992dba71b99f28ba2 Mon Sep 17 00:00:00 2001
From: tknall <tknall@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>
Date: Mon, 7 Jan 2008 13:09:41 +0000
Subject: incremental update check reintroduced

git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@244 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
---
 .../pdfas/impl/vfilter/VerificationFilterImpl.java | 272 +++++++++++++--------
 1 file changed, 168 insertions(+), 104 deletions(-)

(limited to 'src/main')

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 d192f7a..2aa5c28 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
@@ -55,6 +55,8 @@ public class VerificationFilterImpl implements VerificationFilter
 
   // 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";
   
   /**
    * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilter#extractSignatureHolders(at.gv.egiz.pdfas.framework.input.PdfDataSource,
@@ -81,6 +83,26 @@ public class VerificationFilterImpl implements VerificationFilter
       debugIUBlocks(blocks);
     }
 
+    
+    SettingsReader settings;
+    try {
+      settings = SettingsReader.getInstance();
+    } catch (SettingsException e) {
+      throw new VerificationFilterException(e);
+    }
+    String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
+
+    // tzefferer: check document for textual sigs here here if binary_only is set    
+    if ("true".equalsIgnoreCase(check_doc) &&
+      parameters.extractBinarySignaturesOnly()) {
+
+      checkBinaryOnly(pdf, parameters.scanForOldSignatures());
+      log.debug("checkDocument: " + sw.getTime() + "ms.");
+    } else {
+      log.debug("Skipping checkDocument for textual sigs.");
+    }
+    // end add
+    
     List signatureHolderChain = null;
 
     if (parameters.extractBinarySignaturesOnly())
@@ -116,26 +138,7 @@ public class VerificationFilterImpl implements VerificationFilter
     sw.stop();
     log.debug("extractSignatureHolders: " + sw.getTime() + "ms.");
     
-    SettingsReader settings;
-    try {
-      settings = SettingsReader.getInstance();
-    } catch (SettingsException e) {
-      throw new VerificationFilterException(e);
-    }
-    String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
-
-    // tzefferer: check document here
-    // check doesn't make sense if we don't have any signatures
-    if (signatureHolderChain != null && !signatureHolderChain.isEmpty() && "true".equalsIgnoreCase(check_doc)) {
-   	 sw.reset();
-   	 sw.start();
-   	 checkDocument(pdf, blocks, parameters);
-   	 sw.stop();
-   	 log.debug("checkDocument: " + sw.getTime() + "ms.");
-    } else {
-   	 log.debug("Skipping checkDocument.");
-    }
-    // end add
+    
     
     return signatureHolderChain;
   }
@@ -268,10 +271,23 @@ public class VerificationFilterImpl implements VerificationFilter
     List flattedOutPartitions = flattenOutTextPartitions(partitions, blocks);
     partitions = flattedOutPartitions;
 
+    SettingsReader settings;
+    try {
+      settings = SettingsReader.getInstance();
+    } catch (SettingsException e) {
+      throw new VerificationFilterException(e);
+    }
+    String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
+    
+    // flags for determination of illegal incremental update
+    int sigs_found = 0; 
+    int sigs_found_prev = 0;
+    
     List partitionResults = new ArrayList(partitions.size());
     for (int i = 0; i < partitions.size(); i++)
     {
       Partition p = (Partition) partitions.get(i);
+      
 
       if (p instanceof TextPartition)
       {
@@ -290,9 +306,27 @@ public class VerificationFilterImpl implements VerificationFilter
         {
           partitionResult = extractSignaturesFromPartition(pdf, tp);
         }
-
+        
+        sigs_found_prev = sigs_found;
+        sigs_found = partitionResult.size();
         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) 
+          sigs_found = sigs_found + binpart.blocks.size();
+          
+        }
       }
+      
+      // throw an Exception if there were already signatures, but current block does not contain any signatures
+      if((check_doc.equalsIgnoreCase("true"))&& ((sigs_found_prev > 0) && !(sigs_found > sigs_found_prev)) ) {
+        log.error("Illegal document modification!");
+        throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
+      }
+      
     }
 
     List extractedSignatures = new ArrayList();
@@ -493,6 +527,16 @@ public class VerificationFilterImpl implements VerificationFilter
    */
   protected List extractBinarySignaturesOnly(PdfDataSource pdf, List blocks) throws VerificationFilterException
   {
+    SettingsReader settings;
+    try {
+      settings = SettingsReader.getInstance();
+    } catch (SettingsException e) {
+      throw new VerificationFilterException(e);
+    }
+    String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
+    String binary_only = settings.getSetting(BINARY_ONLY, "false");
+    String assume_sigs_only = settings.getSetting(ASSUME_ONLY_SIGNATURE_BLOCKS, "false");
+    
     try
     {
       // PERF: extract binary signatures needs byte array
@@ -502,6 +546,7 @@ public class VerificationFilterImpl implements VerificationFilter
 
       Iterator it = blocks.iterator();
       int prev_end = 0;
+      boolean sig_detected = false;
       while (it.hasNext())
       {
         FooterParseResult fpr = (FooterParseResult) it.next();
@@ -515,6 +560,24 @@ public class VerificationFilterImpl implements VerificationFilter
           List binary_holders = verificator.parseBlock(pdf, data, fpr, prev_end);
 
           binarySignatures.addAll(binary_holders);
+          if(binary_holders.size() > 0) {
+            sig_detected = true;
+          }
+        } else {
+          // an Exception is thrown here if:
+          // 1) check_document is activated
+          // 2) assume_only_signature_blocks is false - otherwise we permit updates
+          // 3) binary_only is true - otherwise updates are handled in method performFullConservative(). 
+          //    when binary-only is true, we can be sure that a block that contains no egiz-dict is no textual 
+          //    signature either but an illegal update, otherwise an Exception (doc contains textual sig) would have been thrown before
+          // 4) a binary signature has been detected in a previous block
+          if(check_doc.equalsIgnoreCase("true") && 
+             binary_only.equalsIgnoreCase("true") &&
+             assume_sigs_only.equalsIgnoreCase("false") &&
+             sig_detected) {            
+            
+            throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
+          }
         }
 
         prev_end = fpr.next_index;
@@ -595,6 +658,7 @@ public class VerificationFilterImpl implements VerificationFilter
        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);
 
       SignaturesAndOld sao = extractSignaturesAndOld(extractedText);
 
@@ -606,90 +670,90 @@ 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 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.");
-      }       
-    }            
-  }
+//  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 {
     
-- 
cgit v1.2.3