diff options
| -rw-r--r-- | src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java | 136 | 
1 files changed, 133 insertions, 3 deletions
| diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java index 24840e6..d0cd951 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java @@ -34,6 +34,7 @@ import java.util.List;  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
 +import at.gv.egiz.pdfas.api.timestamp.TimeStamper;
  import at.gv.egiz.pdfas.exceptions.ErrorCode;
  import at.gv.egiz.pdfas.exceptions.pdf.CaptionNotFoundException;
  import at.gv.egiz.pdfas.exceptions.pdf.KZSettingNotFoundException;
 @@ -94,6 +95,11 @@ public abstract class BinarySignature     * The number of bytes left out for the certificate placeholder.
     */
    public static final int CERTIFICATE_PLACEHOLDER_LENGTH = 10000;
 +  
 +  /**
 +   * The number of bytes left out for the timestamp placeholder.
 +   */
 +  public static final int TIMESTAMP_PLACEHOLDER_LENGTH = 5000;  
    /**
     * The placeholder character used to fill out Strings in the layout process.
 @@ -135,6 +141,11 @@ public abstract class BinarySignature     * The SIG_ID brev.
     */
    public static final byte[] BREV_SID = { 's', 'i', 'd' };
 +  
 +  /**
 +   * The SIG_ALG brev.
 +   */
 +  public static final byte[] BREV_ALG = { 'a', 'l', 'g' };  
    /**
     * No explicit encoding.
 @@ -194,6 +205,11 @@ public abstract class BinarySignature     * The PdfName of the certificate array.
     */
    public static final PdfName EGIZ_CERTIFICATE_NAME = new PdfName("Cert");
 +  
 +  /**
 +   * The PdfName of the Timestamp
 +   */
 +  public static final PdfName EGIZ_TIMESTAMP_NAME = new PdfName("TimeStamp");
    /**
     * The PdfName of the data array that contains various egiz-dict data.
 @@ -700,6 +716,26 @@ public abstract class BinarySignature      }
      return certLen;
    }
 +  
 +  protected static int getTimestampPlaceholderLength(IncrementalUpdateInformation iui) throws SettingNotFoundException
 +  {
 +    SettingsReader settings;
 +    try
 +    {
 +      settings = SettingsReader.getInstance();
 +    }
 +    catch (SettingsException e)
 +    {
 +      throw new SettingNotFoundException(e);
 +    }
 +    String phLen = SignatureTypeDefinition.readPhLenStringFromSettings(settings, iui.signProfile, "timestamp");
 +    int tsLen = TIMESTAMP_PLACEHOLDER_LENGTH;
 +    if (phLen != null)
 +    {
 +      tsLen = Integer.parseInt(phLen);
 +    }
 +    return tsLen;
 +  }
    /**
     * Signs a document with the given signature table using the Incremental
 @@ -739,7 +775,7 @@ public abstract class BinarySignature     *           Forwarded exception.
     */
    public static IncrementalUpdateInformation writeIncrementalUpdate(PdfDataSource original_document, DataSink written_pdf, PdfPTable pdf_table, String profile, PositioningInstruction pi,
 -      List variable_field_definitions, List all_field_definitions, List invisible_field_definitions, String invisibleKZString) throws PresentableException
 +      List variable_field_definitions, List all_field_definitions, List invisible_field_definitions, String invisibleKZString, TimeStamper timeStamper) throws PresentableException
    {
      try
      {
 @@ -747,6 +783,7 @@ public abstract class BinarySignature        iui.original_document = original_document;
        iui.start_index = original_document.getLength();
        iui.signProfile = profile;
 +      iui.timeStamper = timeStamper;
        Document.compress = false;
 @@ -940,6 +977,10 @@ public abstract class BinarySignature      int num_holes = num_replaces + 1 + 1;
      // +1 = the /encodings hole
      // +1 = the /Cert
 +    // +1 = the /Timestamp
 +    if (iui.timeStamper != null) {
 +       num_holes += 1;
 +    }
      boolean has_hidden_variable_fields = invisible_field_definitions != null && !invisible_field_definitions.isEmpty();
      if (has_hidden_variable_fields)
      {
 @@ -966,6 +1007,12 @@ public abstract class BinarySignature      // /encodings
      replaces_array.add(new PdfName(new String(BREV_NIL, "US-ASCII"))); // the
      // /Cert
 +    
 +    if (iui.timeStamper != null) {
 +       encodings_array.add(new PdfName(new String(ENCODING_NIL))); // the /Timestamp
 +       replaces_array.add(new PdfName(new String(BREV_NIL, "US-ASCII"))); // the /timestamp
 +       
 +    }
      // hidden replaces
      List hidden_replaces = null;
 @@ -1022,6 +1069,21 @@ public abstract class BinarySignature      PdfString cert_placeholder = new PdfString(cert_bytes);
      cert_array.add(cert_placeholder);
      egiz_dict.put(EGIZ_CERTIFICATE_NAME, cert_array); 
 +    
 +    // Timestamp    
 +    if (iui.timeStamper != null) {
 +       // only if handler is available
 +       PdfArray timestamp_array = new PdfArray();
 +       iui.timestamp_length = getTimestampPlaceholderLength(iui);
 +       byte[] timestamp_bytes = new byte[iui.timestamp_length];
 +       for (int i = 0; i < timestamp_bytes.length; i++)
 +       {
 +          timestamp_bytes[i] = 0;
 +       }
 +       PdfString timestamp_placeholder = new PdfString(timestamp_bytes);
 +       timestamp_array.add(timestamp_placeholder);
 +       egiz_dict.put(EGIZ_TIMESTAMP_NAME, timestamp_array); 
 +    }
      // /Data array with hidden information
 @@ -1102,6 +1164,11 @@ public abstract class BinarySignature      {
        return BREV_SID;
      }
 +    if (type.equals(SignatureTypes.SIG_ALG))
 +    {
 +      return BREV_ALG;
 +    }
 +
      return BREV_NIL;
    }
 @@ -1157,19 +1224,34 @@ public abstract class BinarySignature        byte[] cert_bytes = cert_str.getBytes("US-ASCII");
        int cert_index = ByteArrayUtils.indexOf(signed_pdf, obj_start, cert_bytes);
        int cert_start = cert_index + cert_bytes.length;
 +      
 +      //Timestamp
 +      int timestamp_index = 0;
 +      int timestamp_start = 0;
 +      if (iui.timeStamper != null) {
 +         String timestamp_str = "/TimeStamp[(";
 +         byte[] timestamp_bytes = timestamp_str.getBytes("US-ASCII");
 +         timestamp_index = ByteArrayUtils.indexOf(signed_pdf, obj_start, timestamp_bytes);
 +         timestamp_start = timestamp_index + timestamp_bytes.length;
 +      }
        replaceNumber(signed_pdf, ods_start, signed_pdf.length, num_digits);
        int cur_pos = array_start;
        int cur_br_start = 0;
 +      
        // write the /encodings byte range
        {
          int num_replaces = calcNumReps(iui.replaces);
 -        int num_holes = num_replaces + 1 + 1;
 +        int num_holes = num_replaces + 1 + 1; 
          // +1 = the /encodings hole
 -        // +1 = the /Cert
 +        // +1 = the /Cert        
 +        //  +1 = the /Timestamp
 +        if (iui.timeStamper != null) {
 +           num_holes += 1;
 +        }
          int enc_length = (1 + 3) * num_holes;
 @@ -1209,6 +1291,25 @@ public abstract class BinarySignature          iui.cert_start = cert_start;
        }
 +      
 +      // write the /Timestamp byte range
 +      if (iui.timeStamper != null) {
 +        StringInfo byte_range = new StringInfo();
 +        byte_range.string_start = cur_br_start;
 +        byte_range.string_length = timestamp_start - cur_br_start;
 +        iui.byte_ranges.add(byte_range);
 +
 +        replaceNumber(signed_pdf, cur_pos, byte_range.string_start, num_digits);
 +        cur_pos += num_digits;
 +        cur_pos += 1;
 +        replaceNumber(signed_pdf, cur_pos, byte_range.string_length, num_digits);
 +        cur_pos += num_digits;
 +        cur_pos += 1;
 +
 +        cur_br_start = timestamp_start + iui.timestamp_length;
 +
 +        iui.timestamp_start = timestamp_start;
 +      }      
        // determine the /Data byte ranges if any
        List ifd = iui.invisible_field_definitions;
 @@ -1362,6 +1463,27 @@ public abstract class BinarySignature    }
    /**
 +   * Replaces the timestam placeholder with the timestamp from the signed
 +   * Signature Object.
 +   * 
 +   * @param iui
 +   *          The IncrementalUpdateInformation.
 +   * @throws PDFDocumentException
 +   */
 +  public static void replaceTimestamp(IncrementalUpdateInformation iui) throws PDFDocumentException
 +  {
 +    String timestamp = iui.signed_signature_object.getSigTimeStamp();
 +    if (timestamp != null) {       
 +      byte[] escaped = Placeholder.escapePDFString(timestamp.getBytes());
 +      if (escaped.length > iui.timestamp_length)
 +      {
 +        throw new PlaceholderException("timestamp", escaped.length - iui.timestamp_length);
 +      }
 +      System.arraycopy(escaped, 0, iui.signed_pdf, iui.timestamp_start, escaped.length);       
 +    }
 +  }
 +  
 +  /**
     * Replaces the placeholders with values from the signed SignatureObject.
     * 
     * @param iui
 @@ -1392,6 +1514,13 @@ public abstract class BinarySignature        System.arraycopy(ENCODING_NIL, 0, signed_pdf, enc_offset + 1, ENCODING_NIL.length);
        encoding_entry_index++;
      }
 +    if (iui.signed_signature_object.getSigTimeStamp() != null)
 +    {// /Timestamp itself
 +       int enc_offset = iui.enc_start + encoding_entry_index * 4;
 +       signed_pdf[enc_offset] = '/';
 +       System.arraycopy(ENCODING_NIL, 0, signed_pdf, enc_offset + 1, ENCODING_NIL.length);
 +       encoding_entry_index++;
 +     }
      for (int i = 0; i < iui.replaces.size(); i++)
      {
 @@ -1897,6 +2026,7 @@ public abstract class BinarySignature      }
    }
 +
    // TODO old code - remove
    // /**
    // * For debugging purposes.
 | 
