aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorafitzek <afitzek@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2012-05-09 05:59:09 +0000
committerafitzek <afitzek@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2012-05-09 05:59:09 +0000
commit28c303923ec7bb96b18c54d660630bfab86f3b8c (patch)
treee153cdc179161bf2042d7dd851efa7b65b06953a
parent99039fc36b6ead3c11e2984e8d8e86de01a81993 (diff)
downloadpdf-as-3-28c303923ec7bb96b18c54d660630bfab86f3b8c.tar.gz
pdf-as-3-28c303923ec7bb96b18c54d660630bfab86f3b8c.tar.bz2
pdf-as-3-28c303923ec7bb96b18c54d660630bfab86f3b8c.zip
Fixing A-Trust ANSI Encodings for special characters like &#252;
git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@919 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
-rw-r--r--src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java949
1 files changed, 502 insertions, 447 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
index 46e46cb..7f18f0a 100644
--- 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
@@ -29,10 +29,15 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
@@ -92,452 +97,502 @@ import com.lowagie.text.pdf.PdfPTable;
*
* @author wprinz
*/
-public class BinarySignator_1_0_0 implements Signator
-{
-// 04.11.2010 changed by exthex - fillReplacesWithValue no longer removes multiple newlines from values
-
- private static Log log = LogFactory.getLog(BinarySignator_1_0_0.class);
-
- /**
- * Settings key for baik enables signatures
- */
- public static final String SIG_BAIK_ENABLED = "SIG_BAIK_ENABLED";
-
- /**
- * 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);
-
- private Normalizer normalizer;
-
- /**
- * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
- */
- public PdfASID getMyId()
- {
- return MY_ID;
- }
-
- /**
- * Default constructor.
- */
- public BinarySignator_1_0_0()
- {
- try
- {
- this.normalizer = new Normalizer();
- }
- catch (NormalizeException e)
- {
- String msg = "Normalizer can not be initialized";
- throw new RuntimeException(msg, new SignatureException(400, msg, e));
- }
- }
-
- /**
- * @see at.gv.egiz.pdfas.framework.signator.Signator#prepareSign(PdfDataSource, String, TablePos, TimeStamper)
- */
- public SignatorInformation prepareSign(PdfDataSource pdfDataSource, String profile, TablePos pos, TimeStamper timeStamper) throws SignatorException
- {
- try
- {
- // dferbas: has to be true everytime
- boolean has_SIG_ID = true;
-
- String baikStr = SettingsReader.getInstance().getSetting("sig_obj." +profile+".key."+SIG_BAIK_ENABLED, "default."+SIG_BAIK_ENABLED, "false");
- boolean baikEnabled = "true".equalsIgnoreCase(baikStr);
-
- if (baikEnabled) {
- log.debug("BAIK enabled signature");
- }
-
- SignatureObject signature_object = PdfAS.createSignatureObjectFromType(profile);
- signature_object.fillValues((char) BinarySignature.LAYOUT_PLACEHOLDER, has_SIG_ID, baikEnabled);
-
- 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;
- }
-
- if (sfd.field_name.equals(SignatureTypes.SIG_ALG) && baikEnabled == false) {
- continue;
- }
-
- variable_field_definitions.add(sfd);
- }
- }
-
- List all_invisible_field_definitions = signature_object.getSignatureTypeDefinition().getInvisibleFieldDefinitions();
- List invisible_field_definitions = new ArrayList();
- boolean isKZInvisible = false;
- String invKZString = null;
-
- for (int i = 0; i < all_invisible_field_definitions.size(); i++)
- {
- SignatureFieldDefinition sfd = (SignatureFieldDefinition) all_invisible_field_definitions.get(i);
- if (sfd.field_name.equals(SignatureTypes.SIG_KZ))
- {
- isKZInvisible = true;
- invKZString = signature_object.getKZ().toString();
- continue;
- }
- if (sfd.field_name.equals(SignatureTypes.SIG_ID) && has_SIG_ID == false)
- {
- continue;
- }
-
- if (sfd.field_name.equals(SignatureTypes.SIG_ALG) && baikEnabled == false) {
- continue;
- }
- invisible_field_definitions.add(sfd);
- }
-
- //check if signature block is invisible, and if so and if also signature block is positioned
- //on a new page, prevent pdf-as to do that, because why should make a new page just for an invisible block
- //added by rpiazzi
- if (signature_object.getSignatureTypeDefinition().getInvisibleFieldDefinitions().size()==SignatureTypes.REQUIRED_SIG_KEYS.length) {
- if (pi.isMakeNewPage()) {
- int pageNumber = pi.getPage();
- pi = new PositioningInstruction(false, pageNumber-1, 0, 0);
- }
- }
- //end added
-
- IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdate(pdfDataSource, pdf_table, profile, pi, variable_field_definitions, all_field_definitions, invisible_field_definitions, invKZString, timeStamper, null, signature_object);
-
- iui.invisible_field_definitions = invisible_field_definitions;
-
- iui.invisibleKZString = invKZString;
-
- String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj"; //$NON-NLS-1$//$NON-NLS-2$
- byte[] temp_bytes = ArrayUtils.add(temp_string.getBytes("US-ASCII"), 0, (byte) 0x0A);
- 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:
- if (!isKZInvisible)
- {
- 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);
-
- // This is needed so that certificates are stored
- try
- {
- iui.signed_signature_object.kz = getMyId().toString();
- SignatureObjectHelper.convertSignSignatureObjectToSignatureObject(iui.signed_signature_object, iui.signProfile);
- }
- catch (PresentableException e)
- {
- throw new SignatorException(e);
- }
-
- BinarySignature.replaceCertificate(iui);
- BinarySignature.replaceTimestamp(iui);
- BinarySignature.replacePlaceholders(iui);
- // dferbas: alternative sign attrib creation
-// PdfReader reader = new PdfReader(iui.signed_pdf);
-//
-// OutputStream os = dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE);
-//
-// try {
-// PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
-//
-// BinarySignature.createAdobeSigAttrib(stamper, signatorInformation, signatorInformation.getActualTablePos());
-//
-// } catch (DocumentException e) {
-// log.error("pdf error", e);
-// throw new SignatorException(ErrorCode.CANNOT_WRITE_PDF, e);
-// }
-
- OutputStream os = dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE);
- os.write(iui.signed_pdf);
- os.close();
- }
- 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(final IncrementalUpdateInformation iui)
- {
- try {
- Iterator it = iui.replaces.iterator();
- HashMap ognlCtx = new HashMap();
- ognlCtx.put("iui", iui);
- ognlCtx.put("sso", iui.signed_signature_object);
- ognlCtx.put("issuer", iui.signed_signature_object.getIssuerDNMap());
- ognlCtx.put("subject", iui.signed_signature_object.getSubjectDNMap());
- OgnlUtil ognl = new OgnlUtil(ognlCtx);
-
- OverridePropertyHolder.setOgnlUtil(ognl);
- while (it.hasNext()) {
- ReplaceInfo ri = (ReplaceInfo) it.next();
- String overrideVal = OverridePropertyHolder.getProperty(ri.sfd.field_name);
- if (overrideVal != null) {
- ri.sfd.value = overrideVal;
- ri.value = overrideVal;
- } else if (ognl.containsExpression(ri.sfd.value)) { // dferbas
- // evaluate expression
- String res = ognl.compileMessage(ri.sfd.value);
- ri.value = this.normalizer.normalize(res, true);
- //Workaround added by rpiazzi
- //a-trust wrongly encodes since July 2011, therefore some special characters (e.g. Umlaute) have
- //to replaced by their right character
- if ((ri.value.contains("&#252;") || ri.value.contains("&#228;") || ri.value.contains("&#246;") ||
- ri.value.contains("&#225;") || ri.value.contains("&#223;") || ri.value.contains("&#214;") ||
- ri.value.contains("&#224;") || ri.value.contains("&#233;") || ri.value.contains("&#250;") ||
- ri.value.contains("&#231;")) && (ri.sfd.field_name.equals(SignatureTypes.SIG_SUBJECT))) {
- if (ri.value.contains("&#252;")) {
- ri.sfd.value = ri.sfd.value.replace("&#252;", "ü");
- ri.value = ri.value.replace("&#252;", "ü");
- }
- if (ri.value.contains("&#228;")) {
- ri.sfd.value = ri.sfd.value.replace("&#228;", "ä");
- ri.value = ri.value.replace("&#228;", "ä");
- }
- if (ri.value.contains("&#246;")) {
- ri.sfd.value = ri.sfd.value.replace("&#246;", "ö");
- ri.value = ri.value.replace("&#246;", "ö");
- }
- if (ri.value.contains("&#225;")) {
- ri.sfd.value = ri.sfd.value.replace("&#225;", "á");
- ri.value = ri.value.replace("&#225;", "á");
- }
- if (ri.value.contains("&#223;")) {
- ri.sfd.value = ri.sfd.value.replace("&#223;", "ß");
- ri.value = ri.value.replace("&#223;", "ß");
- }
- if (ri.value.contains("&#214;")) {
- ri.sfd.value = ri.sfd.value.replace("&#214;", "Ö");
- ri.value = ri.value.replace("&#214;", "Ö");
- }
- if (ri.value.contains("&#224;")) {
- ri.sfd.value = ri.sfd.value.replace("&#224;", "à");
- ri.value = ri.value.replace("&#224;", "à");
- }
- if (ri.value.contains("&#233;")) {
- ri.sfd.value = ri.sfd.value.replace("&#233;", "é");
- ri.value = ri.value.replace("&#233;", "é");
- }
- if (ri.value.contains("&#250;")) {
- ri.sfd.value = ri.sfd.value.replace("&#250;", "ú");
- ri.value = ri.value.replace("&#250;", "ú");
- }
- if (ri.value.contains("&#231;")) {
- ri.sfd.value = ri.sfd.value.replace("&#231;", "ç");
- ri.value = ri.value.replace("&#231;", "ç");
- }
- }
- //end added
- } else if (overrideVal == null) {
- //If SUBJECT is not overridden and and also isn't an expression
- //check whether a set value for subject exists.
- //In this case take the value from the config file.
- //Added by rpiazzi to make a static signator possible without having
- //to override it any time
- if (ri.sfd.field_name.equals(SignatureTypes.SIG_SUBJECT)) {
- if (ri.sfd.value.length()!=0) {
- ri.value = ri.sfd.value;
- }
- else {
- ri.value = iui.signed_signature_object.retrieveStringValue(ri.sfd.field_name);
- }
- }
- else {
- ri.value = iui.signed_signature_object.retrieveStringValue(ri.sfd.field_name);
- }
- }
- }
- } finally {
- OverridePropertyHolder.removeOgnlUtil();
- }
- }
-
- /**
- * 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;
- bsi.atp = iui.actualTablePos;
- bsi.signProfile = iui.signProfile;
- bsi.timestamp_length = iui.timestamp_length;
- bsi.timestamp_start = iui.timestamp_start;
-
- 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.actualTablePos = bsi.atp;
- iui.signProfile = bsi.signProfile;
- iui.timestamp_length = bsi.timestamp_length;
- iui.timestamp_start = bsi.timestamp_start;
-
- 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);
- }
-
- public String getEncoding() {
- // not used for binary signature
- return "utf-8";
-
- }
+public class BinarySignator_1_0_0 implements Signator {
+ // 04.11.2010 changed by exthex - fillReplacesWithValue no longer removes
+ // multiple newlines from values
+
+ private static Log log = LogFactory.getLog(BinarySignator_1_0_0.class);
+
+ /**
+ * Settings key for baik enables signatures
+ */
+ public static final String SIG_BAIK_ENABLED = "SIG_BAIK_ENABLED";
+
+ /**
+ * 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);
+
+ private Normalizer normalizer;
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
+ */
+ public PdfASID getMyId() {
+ return MY_ID;
+ }
+
+ /**
+ * Default constructor.
+ */
+ public BinarySignator_1_0_0() {
+ try {
+ this.normalizer = new Normalizer();
+ } catch (NormalizeException e) {
+ String msg = "Normalizer can not be initialized";
+ throw new RuntimeException(msg, new SignatureException(400, msg, e));
+ }
+ }
+
+ /**
+ * @see at.gv.egiz.pdfas.framework.signator.Signator#prepareSign(PdfDataSource,
+ * String, TablePos, TimeStamper)
+ */
+ public SignatorInformation prepareSign(PdfDataSource pdfDataSource,
+ String profile, TablePos pos, TimeStamper timeStamper)
+ throws SignatorException {
+ try {
+ // dferbas: has to be true everytime
+ boolean has_SIG_ID = true;
+
+ String baikStr = SettingsReader.getInstance().getSetting(
+ "sig_obj." + profile + ".key." + SIG_BAIK_ENABLED,
+ "default." + SIG_BAIK_ENABLED, "false");
+ boolean baikEnabled = "true".equalsIgnoreCase(baikStr);
+
+ if (baikEnabled) {
+ log.debug("BAIK enabled signature");
+ }
+
+ SignatureObject signature_object = PdfAS
+ .createSignatureObjectFromType(profile);
+ signature_object.fillValues(
+ (char) BinarySignature.LAYOUT_PLACEHOLDER, has_SIG_ID,
+ baikEnabled);
+
+ 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;
+ }
+
+ if (sfd.field_name.equals(SignatureTypes.SIG_ALG)
+ && baikEnabled == false) {
+ continue;
+ }
+
+ variable_field_definitions.add(sfd);
+ }
+ }
+
+ List all_invisible_field_definitions = signature_object
+ .getSignatureTypeDefinition()
+ .getInvisibleFieldDefinitions();
+ List invisible_field_definitions = new ArrayList();
+ boolean isKZInvisible = false;
+ String invKZString = null;
+
+ for (int i = 0; i < all_invisible_field_definitions.size(); i++) {
+ SignatureFieldDefinition sfd = (SignatureFieldDefinition) all_invisible_field_definitions
+ .get(i);
+ if (sfd.field_name.equals(SignatureTypes.SIG_KZ)) {
+ isKZInvisible = true;
+ invKZString = signature_object.getKZ().toString();
+ continue;
+ }
+ if (sfd.field_name.equals(SignatureTypes.SIG_ID)
+ && has_SIG_ID == false) {
+ continue;
+ }
+
+ if (sfd.field_name.equals(SignatureTypes.SIG_ALG)
+ && baikEnabled == false) {
+ continue;
+ }
+ invisible_field_definitions.add(sfd);
+ }
+
+ // check if signature block is invisible, and if so and if also
+ // signature block is positioned
+ // on a new page, prevent pdf-as to do that, because why should make
+ // a new page just for an invisible block
+ // added by rpiazzi
+ if (signature_object.getSignatureTypeDefinition()
+ .getInvisibleFieldDefinitions().size() == SignatureTypes.REQUIRED_SIG_KEYS.length) {
+ if (pi.isMakeNewPage()) {
+ int pageNumber = pi.getPage();
+ pi = new PositioningInstruction(false, pageNumber - 1, 0, 0);
+ }
+ }
+ // end added
+
+ IncrementalUpdateInformation iui = IncrementalUpdateHelper
+ .writeIncrementalUpdate(pdfDataSource, pdf_table, profile,
+ pi, variable_field_definitions,
+ all_field_definitions, invisible_field_definitions,
+ invKZString, timeStamper, null, signature_object);
+
+ iui.invisible_field_definitions = invisible_field_definitions;
+
+ iui.invisibleKZString = invKZString;
+
+ String temp_string = iui.temp_ir_number
+ + " " + iui.temp_ir_generation + " obj"; //$NON-NLS-1$//$NON-NLS-2$
+ byte[] temp_bytes = ArrayUtils.add(
+ temp_string.getBytes("US-ASCII"), 0, (byte) 0x0A);
+ 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:
+ if (!isKZInvisible) {
+ 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);
+
+ // This is needed so that certificates are stored
+ try {
+ iui.signed_signature_object.kz = getMyId().toString();
+ SignatureObjectHelper
+ .convertSignSignatureObjectToSignatureObject(
+ iui.signed_signature_object, iui.signProfile);
+ } catch (PresentableException e) {
+ throw new SignatorException(e);
+ }
+
+ BinarySignature.replaceCertificate(iui);
+ BinarySignature.replaceTimestamp(iui);
+ BinarySignature.replacePlaceholders(iui);
+ // dferbas: alternative sign attrib creation
+ // PdfReader reader = new PdfReader(iui.signed_pdf);
+ //
+ // OutputStream os =
+ // dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE);
+ //
+ // try {
+ // PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0',
+ // null, true);
+ //
+ // BinarySignature.createAdobeSigAttrib(stamper,
+ // signatorInformation, signatorInformation.getActualTablePos());
+ //
+ // } catch (DocumentException e) {
+ // log.error("pdf error", e);
+ // throw new SignatorException(ErrorCode.CANNOT_WRITE_PDF, e);
+ // }
+
+ OutputStream os = dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE);
+ os.write(iui.signed_pdf);
+ os.close();
+ } 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(final IncrementalUpdateInformation iui) {
+ try {
+ Iterator it = iui.replaces.iterator();
+ HashMap ognlCtx = new HashMap();
+ ognlCtx.put("iui", iui);
+ ognlCtx.put("sso", iui.signed_signature_object);
+ ognlCtx.put("issuer", iui.signed_signature_object.getIssuerDNMap());
+ ognlCtx.put("subject",
+ iui.signed_signature_object.getSubjectDNMap());
+ OgnlUtil ognl = new OgnlUtil(ognlCtx);
+
+ OverridePropertyHolder.setOgnlUtil(ognl);
+ while (it.hasNext()) {
+ ReplaceInfo ri = (ReplaceInfo) it.next();
+ String overrideVal = OverridePropertyHolder
+ .getProperty(ri.sfd.field_name);
+ if (overrideVal != null) {
+ ri.sfd.value = overrideVal;
+ ri.value = overrideVal;
+ } else if (ognl.containsExpression(ri.sfd.value)) { // dferbas
+ // evaluate expression
+ String res = ognl.compileMessage(ri.sfd.value);
+ ri.value = this.normalizer.normalize(res, true);
+ // Workaround added by rpiazzi
+ // a-trust wrongly encodes since July 2011, therefore some
+ // special characters (e.g. Umlaute) have
+ // to replaced by their right character
+ /*if ((ri.value.contains("&#252;")
+ || ri.value.contains("&#228;")
+ || ri.value.contains("&#246;")
+ || ri.value.contains("&#225;")
+ || ri.value.contains("&#223;")
+ || ri.value.contains("&#214;")
+ || ri.value.contains("&#224;")
+ || ri.value.contains("&#233;")
+ || ri.value.contains("&#250;") || ri.value
+ .contains("&#231;"))
+ && (ri.sfd.field_name
+ .equals(SignatureTypes.SIG_SUBJECT))) {
+ if (ri.value.contains("&#252;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#252;", "�");
+ ri.value = ri.value.replace("&#252;", "�");
+ }
+ if (ri.value.contains("&#228;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#228;", "�");
+ ri.value = ri.value.replace("&#228;", "�");
+ }
+ if (ri.value.contains("&#246;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#246;", "�");
+ ri.value = ri.value.replace("&#246;", "�");
+ }
+ if (ri.value.contains("&#225;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#225;", "�");
+ ri.value = ri.value.replace("&#225;", "�");
+ }
+ if (ri.value.contains("&#223;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#223;", "�");
+ ri.value = ri.value.replace("&#223;", "�");
+ }
+ if (ri.value.contains("&#214;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#214;", "�");
+ ri.value = ri.value.replace("&#214;", "�");
+ }
+ if (ri.value.contains("&#224;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#224;", "�");
+ ri.value = ri.value.replace("&#224;", "�");
+ }
+ if (ri.value.contains("&#233;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#233;", "�");
+ ri.value = ri.value.replace("&#233;", "�");
+ }
+ if (ri.value.contains("&#250;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#250;", "�");
+ ri.value = ri.value.replace("&#250;", "�");
+ }
+ if (ri.value.contains("&#231;")) {
+ ri.sfd.value = ri.sfd.value.replace("&#231;", "�");
+ ri.value = ri.value.replace("&#231;", "�");
+ }
+ }*/
+ FixHandyAnsiEncoding(ri);
+ // end added
+ } else if (overrideVal == null) {
+ // If SUBJECT is not overridden and and also isn't an
+ // expression
+ // check whether a set value for subject exists.
+ // In this case take the value from the config file.
+ // Added by rpiazzi to make a static signator possible
+ // without having
+ // to override it any time
+ if (ri.sfd.field_name.equals(SignatureTypes.SIG_SUBJECT)) {
+ if (ri.sfd.value.length() != 0) {
+ ri.value = ri.sfd.value;
+ } else {
+ ri.value = iui.signed_signature_object
+ .retrieveStringValue(ri.sfd.field_name);
+ }
+ } else {
+ ri.value = iui.signed_signature_object
+ .retrieveStringValue(ri.sfd.field_name);
+ }
+ }
+ }
+ } finally {
+ OverridePropertyHolder.removeOgnlUtil();
+ }
+ }
+
+ private void FixHandyAnsiEncoding(ReplaceInfo ri) {
+ Pattern p = Pattern.compile("&#([0-9]+);");
+ Matcher m = p.matcher(ri.value);
+
+ int value = -1;
+
+ while (m.find()) {
+ value = Integer.parseInt(m.group(1));
+
+ if (value > 0 && value < 256) {
+
+ log.debug("Replacing Encoding &#" + m.group(1) + ";");
+
+ byte[] buffer = new byte[1];
+
+ buffer[0] = (byte) value;
+
+ ByteBuffer bb = ByteBuffer.wrap(buffer);
+
+ CharBuffer cb = Charset.forName("CP1252").decode(bb);
+
+ String str = cb.toString();
+
+ ri.value = ri.value.replace("&#" + m.group(1) + ";", str);
+ }
+ }
+ }
+
+ /**
+ * 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;
+ bsi.atp = iui.actualTablePos;
+ bsi.signProfile = iui.signProfile;
+ bsi.timestamp_length = iui.timestamp_length;
+ bsi.timestamp_start = iui.timestamp_start;
+
+ 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.actualTablePos = bsi.atp;
+ iui.signProfile = bsi.signProfile;
+ iui.timestamp_length = bsi.timestamp_length;
+ iui.timestamp_start = bsi.timestamp_start;
+
+ 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);
+ }
+
+ public String getEncoding() {
+ // not used for binary signature
+ return "utf-8";
+
+ }
}