aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java')
-rw-r--r--src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java326
1 files changed, 326 insertions, 0 deletions
diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
new file mode 100644
index 0000000..6c6ba29
--- /dev/null
+++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
@@ -0,0 +1,326 @@
+/**
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $Id: BinarySignator_1_0_0.java,v 1.1 2006/08/25 17:07:35 wprinz Exp $
+ */
+package at.gv.egiz.pdfas.impl.signator.binary;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import at.gv.egiz.pdfas.exceptions.ErrorCode;
+import at.gv.egiz.pdfas.exceptions.framework.SignatorException;
+import at.gv.egiz.pdfas.framework.input.DataSource;
+import at.gv.egiz.pdfas.framework.input.PdfDataSource;
+import at.gv.egiz.pdfas.framework.output.DataSink;
+import at.gv.egiz.pdfas.framework.signator.Signator;
+import at.gv.egiz.pdfas.framework.signator.SignatorInformation;
+import at.gv.egiz.pdfas.impl.input.CompoundPdfDataSourceImpl;
+import at.gv.egiz.pdfas.impl.signator.IncrementalUpdateHelper;
+import at.knowcenter.wag.egov.egiz.PdfAS;
+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.SignatorFactory;
+import at.knowcenter.wag.egov.egiz.pdf.BinarySignature;
+import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+import at.knowcenter.wag.egov.egiz.pdf.ReplaceInfo;
+import at.knowcenter.wag.egov.egiz.pdf.StringInfo;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
+import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
+import at.knowcenter.wag.egov.egiz.sig.SignatureFieldDefinition;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObjectHelper;
+import at.knowcenter.wag.exactparser.ByteArrayUtils;
+
+import com.lowagie.text.pdf.PdfPTable;
+
+/**
+ * Signs the document binary.
+ *
+ * <p>
+ * In prepareSign, an Incremental Update is created that contains the Signature
+ * block and the egiz dictionary. For formatting the layout, variable values are
+ * filled with placeholders. After the layout has been fixed, all variable
+ * fields (all holes in the byte ranges) are replaced with 0. This document is
+ * then base64 encoded and signed.
+ * </p>
+ * <p>
+ * In finishSign, the variable fields (values, /Cert) are replaced with the
+ * values according to the encoding.
+ * </p>
+ *
+ * @author wprinz
+ */
+public class BinarySignator_1_0_0 implements Signator
+{
+ /**
+ * The Pdf-AS ID of this Signator.
+ */
+ public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_0_0);
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
+ */
+ public PdfASID getMyId()
+ {
+ return MY_ID;
+ }
+
+ /**
+ * Default constructor.
+ */
+ public BinarySignator_1_0_0()
+ {
+ // Default constructor.
+ }
+
+ /**
+ * @see at.gv.egiz.pdfas.framework.signator.Signator#prepareSign(at.gv.egiz.pdfas.framework.input.PdfDataSource,
+ * java.lang.String, at.knowcenter.wag.egov.egiz.pdf.TablePos, boolean)
+ */
+ public SignatorInformation prepareSign(PdfDataSource pdfDataSource, String profile, TablePos pos, boolean has_SIG_ID) throws SignatorException
+ {
+ try
+ {
+ SignatureObject signature_object = PdfAS.createSignatureObjectFromType(profile);
+ signature_object.fillValues((char) BinarySignature.LAYOUT_PLACEHOLDER, has_SIG_ID);
+
+ signature_object.setKZ(getMyId());
+
+ PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(signature_object);
+
+ PositioningInstruction pi = PdfAS.determineTablePositioning(pos, profile, pdfDataSource, pdf_table);
+
+ List all_field_definitions = signature_object.getSignatureTypeDefinition().getFieldDefinitions();
+ List variable_field_definitions = new ArrayList();
+ for (int i = 0; i < all_field_definitions.size(); i++)
+ {
+ SignatureFieldDefinition sfd = (SignatureFieldDefinition) all_field_definitions.get(i);
+ if (sfd.placeholder_length > 0)
+ {
+ if (sfd.field_name.equals(SignatureTypes.SIG_ID) && has_SIG_ID == false)
+ {
+ continue;
+ }
+ variable_field_definitions.add(sfd);
+ }
+ }
+
+ IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdate(pdfDataSource, pdf_table, pi, variable_field_definitions, all_field_definitions);
+
+ String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj"; //$NON-NLS-1$//$NON-NLS-2$
+ byte[] temp_bytes = temp_string.getBytes("US-ASCII"); //$NON-NLS-1$
+ int temp_start = ByteArrayUtils.lastIndexOf(iui.signed_pdf, temp_bytes);
+ byte[] stream_bytes = new byte[] { '>', '>', 's', 't', 'r', 'e', 'a', 'm', 0x0A };
+ int stream_start = ByteArrayUtils.indexOf(iui.signed_pdf, temp_start, stream_bytes);
+ iui.content_stream_start = stream_start + stream_bytes.length;
+
+ // update the stream indices
+ Iterator it = iui.replaces.iterator();
+ while (it.hasNext())
+ {
+ ReplaceInfo ri = (ReplaceInfo) it.next();
+
+ Iterator sit = ri.replaces.iterator();
+ while (sit.hasNext())
+ {
+ StringInfo si = (StringInfo) sit.next();
+ si.string_start += iui.content_stream_start;
+ }
+ }
+ // update KZ list indices:
+ it = iui.kz_list.iterator();
+ while (it.hasNext())
+ {
+ StringInfo si = (StringInfo) it.next();
+ si.string_start += iui.content_stream_start;
+ }
+
+ BinarySignature.markByteRanges(iui);
+
+ // byte [] old_signed_pdf = iui.signed_pdf;
+ iui.signed_pdf = BinarySignature.prepareDataToSign(iui.signed_pdf, iui.byte_ranges);
+
+ BinarySignatorInformation bsi = compressIUI(iui);
+ return bsi;
+
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new SignatorException(201, e);
+ }
+ catch (PDFDocumentException e)
+ {
+ throw new SignatorException(e.getErrorCode(), e);
+ }
+ catch (PresentableException e)
+ {
+ throw new SignatorException(201, e);
+ }
+ }
+
+ /**
+ * @see at.gv.egiz.pdfas.framework.signator.Signator#finishSign(at.gv.egiz.pdfas.framework.signator.SignatorInformation,
+ * at.gv.egiz.pdfas.framework.output.DataSink)
+ */
+ public void finishSign(SignatorInformation signatorInformation, DataSink dataSink) throws SignatorException
+ {
+ try
+ {
+ IncrementalUpdateInformation iui = uncompressIUI((BinarySignatorInformation) signatorInformation);
+
+ // PERF: need to keep the whole pdf in mem for processing
+
+ // PdfAS.prefixID(iui.signed_signature_object, PdfAS.BINARY_ID);
+ fillReplacesWithValues(iui);
+
+ BinarySignature.replaceCertificate(iui);
+ BinarySignature.replacePlaceholders(iui);
+
+ OutputStream os = dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE);
+ os.write(iui.signed_pdf);
+ os.close();
+
+ //SignResult sign_result = new SignResult(PdfAS.PDF_MIME_TYPE, iui.signed_pdf);
+ //return sign_result;
+ }
+ catch (PDFDocumentException e)
+ {
+ throw new SignatorException(e.getErrorCode(), e);
+ }
+ catch (IOException e)
+ {
+ throw new SignatorException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e);
+ }
+ }
+
+ /**
+ * Reads the signature values from the signed signature object and fills the
+ * corresponding value in the Replaces array.
+ *
+ * @param iui
+ * The IncrementalUpdateInformation.
+ */
+ protected void fillReplacesWithValues(IncrementalUpdateInformation iui)
+ {
+ Iterator it = iui.replaces.iterator();
+ while (it.hasNext())
+ {
+ ReplaceInfo ri = (ReplaceInfo) it.next();
+
+ ri.value = SignSignatureObjectHelper.retrieveStringValueFromSignatureObject(iui.signed_signature_object, ri.sfd.field_name);
+ }
+ }
+
+ /**
+ * Forms the SignatureData to be used for signing.
+ *
+ * @param iui
+ * The IncrementalUpdateInformation.
+ * @return Returns the SignatureData to be used for signing.
+ */
+ protected SignatureData formSignatureData(IncrementalUpdateInformation iui)
+ {
+ // String document_text =
+ // BinarySignature.retrieveSignableTextFromData(iui.signed_pdf,
+ // iui.signed_pdf.length); // signed_pdf.length);
+ //
+ // byte[] data;
+ // try
+ // {
+ // data = document_text.getBytes("UTF-8"); //$NON-NLS-1$
+ // }
+ // catch (UnsupportedEncodingException e)
+ // {
+ // throw new RuntimeException("Very strange: UTF-8 character encoding not
+ // supported.", e); //$NON-NLS-1$
+ // }
+ DataSource ds = new CompoundPdfDataSourceImpl(iui.original_document, iui.sign_iui_block);
+ SignatureData signature_data = new SignatureDataImpl(ds, PdfAS.PDF_MIME_TYPE);
+
+ return signature_data;
+ }
+
+ protected BinarySignatorInformation compressIUI(IncrementalUpdateInformation iui)
+ {
+ iui.sign_iui_block = new byte[iui.signed_pdf.length - iui.original_document.getLength()];
+ System.arraycopy(iui.signed_pdf, iui.original_document.getLength(), iui.sign_iui_block, 0, iui.sign_iui_block.length);
+
+ iui.signature_data = formSignatureData(iui);
+
+ // remove the signed pdf from memory
+ iui.signed_pdf = null;
+
+ BinarySignatorInformation bsi = new BinarySignatorInformation();
+ bsi.originalDocument = iui.original_document;
+ bsi.incrementalUpdateBlock = iui.sign_iui_block;
+ bsi.signatureData = iui.signature_data;
+ bsi.replaces = iui.replaces;
+ bsi.cert_start = iui.cert_start;
+ bsi.cert_length = iui.cert_length;
+ bsi.enc_start = iui.enc_start;
+ bsi.enc_length = iui.enc_length;
+
+ return bsi;
+ }
+
+ protected IncrementalUpdateInformation uncompressIUI(BinarySignatorInformation bsi)
+ {
+ IncrementalUpdateInformation iui = new IncrementalUpdateInformation();
+
+ iui.original_document = bsi.originalDocument;
+ iui.sign_iui_block = bsi.incrementalUpdateBlock;
+ iui.signature_data = bsi.signatureData;
+ iui.replaces = bsi.replaces;
+ iui.cert_start = bsi.cert_start;
+ iui.cert_length = bsi.cert_length;
+ iui.enc_start = bsi.enc_start;
+ iui.enc_length = bsi.enc_length;
+
+ iui.signed_signature_object = bsi.signSignatureObject;
+
+ restoreSignedPdf(iui);
+
+ return iui;
+ }
+
+ protected void restoreSignedPdf(IncrementalUpdateInformation iui)
+ {
+ iui.signed_pdf = new byte[iui.original_document.getLength() + iui.sign_iui_block.length];
+
+ try
+ {
+ InputStream is = iui.original_document.createInputStream();
+ is.read(iui.signed_pdf, 0, iui.original_document.getLength());
+ is.close();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+
+ System.arraycopy(iui.sign_iui_block, 0, iui.signed_pdf, iui.original_document.getLength(), iui.sign_iui_block.length);
+ }
+
+}