From 28c303923ec7bb96b18c54d660630bfab86f3b8c Mon Sep 17 00:00:00 2001 From: afitzek Date: Wed, 9 May 2012 05:59:09 +0000 Subject: Fixing A-Trust ANSI Encodings for special characters like ü git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@919 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../impl/signator/binary/BinarySignator_1_0_0.java | 949 +++++++++++---------- 1 file changed, 502 insertions(+), 447 deletions(-) (limited to 'src/main/java/at') 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("ü") || ri.value.contains("ä") || ri.value.contains("ö") || - ri.value.contains("á") || ri.value.contains("ß") || ri.value.contains("Ö") || - ri.value.contains("à") || ri.value.contains("é") || ri.value.contains("ú") || - ri.value.contains("ç")) && (ri.sfd.field_name.equals(SignatureTypes.SIG_SUBJECT))) { - if (ri.value.contains("ü")) { - ri.sfd.value = ri.sfd.value.replace("ü", "ü"); - ri.value = ri.value.replace("ü", "ü"); - } - if (ri.value.contains("ä")) { - ri.sfd.value = ri.sfd.value.replace("ä", "ä"); - ri.value = ri.value.replace("ä", "ä"); - } - if (ri.value.contains("ö")) { - ri.sfd.value = ri.sfd.value.replace("ö", "ö"); - ri.value = ri.value.replace("ö", "ö"); - } - if (ri.value.contains("á")) { - ri.sfd.value = ri.sfd.value.replace("á", "á"); - ri.value = ri.value.replace("á", "á"); - } - if (ri.value.contains("ß")) { - ri.sfd.value = ri.sfd.value.replace("ß", "ß"); - ri.value = ri.value.replace("ß", "ß"); - } - if (ri.value.contains("Ö")) { - ri.sfd.value = ri.sfd.value.replace("Ö", "Ö"); - ri.value = ri.value.replace("Ö", "Ö"); - } - if (ri.value.contains("à")) { - ri.sfd.value = ri.sfd.value.replace("à", "à"); - ri.value = ri.value.replace("à", "à"); - } - if (ri.value.contains("é")) { - ri.sfd.value = ri.sfd.value.replace("é", "é"); - ri.value = ri.value.replace("é", "é"); - } - if (ri.value.contains("ú")) { - ri.sfd.value = ri.sfd.value.replace("ú", "ú"); - ri.value = ri.value.replace("ú", "ú"); - } - if (ri.value.contains("ç")) { - ri.sfd.value = ri.sfd.value.replace("ç", "ç"); - ri.value = ri.value.replace("ç", "ç"); - } - } - //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("ü") + || ri.value.contains("ä") + || ri.value.contains("ö") + || ri.value.contains("á") + || ri.value.contains("ß") + || ri.value.contains("Ö") + || ri.value.contains("à") + || ri.value.contains("é") + || ri.value.contains("ú") || ri.value + .contains("ç")) + && (ri.sfd.field_name + .equals(SignatureTypes.SIG_SUBJECT))) { + if (ri.value.contains("ü")) { + ri.sfd.value = ri.sfd.value.replace("ü", "�"); + ri.value = ri.value.replace("ü", "�"); + } + if (ri.value.contains("ä")) { + ri.sfd.value = ri.sfd.value.replace("ä", "�"); + ri.value = ri.value.replace("ä", "�"); + } + if (ri.value.contains("ö")) { + ri.sfd.value = ri.sfd.value.replace("ö", "�"); + ri.value = ri.value.replace("ö", "�"); + } + if (ri.value.contains("á")) { + ri.sfd.value = ri.sfd.value.replace("á", "�"); + ri.value = ri.value.replace("á", "�"); + } + if (ri.value.contains("ß")) { + ri.sfd.value = ri.sfd.value.replace("ß", "�"); + ri.value = ri.value.replace("ß", "�"); + } + if (ri.value.contains("Ö")) { + ri.sfd.value = ri.sfd.value.replace("Ö", "�"); + ri.value = ri.value.replace("Ö", "�"); + } + if (ri.value.contains("à")) { + ri.sfd.value = ri.sfd.value.replace("à", "�"); + ri.value = ri.value.replace("à", "�"); + } + if (ri.value.contains("é")) { + ri.sfd.value = ri.sfd.value.replace("é", "�"); + ri.value = ri.value.replace("é", "�"); + } + if (ri.value.contains("ú")) { + ri.sfd.value = ri.sfd.value.replace("ú", "�"); + ri.value = ri.value.replace("ú", "�"); + } + if (ri.value.contains("ç")) { + ri.sfd.value = ri.sfd.value.replace("ç", "�"); + ri.value = ri.value.replace("ç", "�"); + } + }*/ + 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"; + + } } -- cgit v1.2.3