aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AdobeSignatureHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AdobeSignatureHelper.java')
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AdobeSignatureHelper.java272
1 files changed, 272 insertions, 0 deletions
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AdobeSignatureHelper.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AdobeSignatureHelper.java
new file mode 100644
index 0000000..e337e71
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AdobeSignatureHelper.java
@@ -0,0 +1,272 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import at.gv.egiz.pdfas.exceptions.ErrorCode;
+import at.gv.egiz.pdfas.framework.signator.SignatorInformation;
+import at.gv.egiz.pdfas.utils.OgnlUtil;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
+import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.pdf.AcroFields;
+import com.lowagie.text.pdf.PdfDictionary;
+import com.lowagie.text.pdf.PdfFormField;
+import com.lowagie.text.pdf.PdfName;
+import com.lowagie.text.pdf.PdfNumber;
+import com.lowagie.text.pdf.PdfObject;
+import com.lowagie.text.pdf.PdfSignature;
+import com.lowagie.text.pdf.PdfSignatureAppearance;
+import com.lowagie.text.pdf.PdfStamper;
+import com.lowagie.text.pdf.PdfString;
+
+/**
+ * Helper class for creating adobe signature attributes.
+ *
+ * @author dferbas
+ *
+ */
+public class AdobeSignatureHelper {
+ private static final String ADOBE_SIGN_FIELDNAME_KEY = "adobeSignFieldValue";
+
+ private static final String ADOBE_SIGN_REASONNAME_KEY = "adobeSignReasonValue";
+
+ private static final String ADOBE_SIG_ENABLED_KEY = "adobeSignEnabled";
+
+ private static Logger logger = Logger.getLogger(AdobeSignatureHelper.class);
+
+ public static final String ADOBE_SIG_FILTER = "Adobe.PDF-AS";
+
+ public static final String ADOBE_SIG_TEXT_KEY = "adobeSignText";
+
+ private static final String ADOBE_VERIFY_URL_KEY = "verifyURL";
+
+ /**
+ * Writes Adobe-pdf signature entry with itext
+ *
+ * @param stamper
+ * @param si
+ * @param so
+ * @param atp
+ * @throws PresentableException
+ */
+ public static void createAdobeSignatureField(PdfStamper stamper, SignatorInformation si,
+ SignatureObject so, ActualTablePos atp, StructContentHelper structHelper) throws PresentableException {
+
+ try {
+ logger.debug("Creating adobe signature field.");
+ PdfSignatureAppearance sap = stamper.getSignatureAppearance();
+
+ String profileId = so.getSignatureTypeDefinition().getType();
+ String fieldName = getAdobeFieldName(profileId);
+ // find field num
+ /*
+ int nexSigNum = 1;
+ String finalFieldName = fieldName + " #" + nexSigNum;
+
+ while (stamper.getAcroFields().getField(finalFieldName) != null) {
+ nexSigNum++;
+ finalFieldName = fieldName + " #" + nexSigNum;
+ }
+ */
+
+ AcroFields af = stamper.getAcroFields();
+ Iterator signatureNamesIt = af.getSignatureNames().iterator();
+ PdfName referenceFilterName = new PdfName(ADOBE_SIG_FILTER);
+ int nextSigNum = 1;
+ while (signatureNamesIt.hasNext()) {
+ PdfDictionary dictionary = (PdfDictionary) af.getSignatureDictionary((String) signatureNamesIt.next());
+ PdfObject filterName = dictionary.get(PdfName.FILTER);
+ if (filterName != null && filterName.isName()) {
+ PdfName name = (PdfName) filterName;
+ if (referenceFilterName.equals(name)) {
+ nextSigNum++;
+ }
+ }
+ }
+ String finalFieldName = fieldName + " #" + nextSigNum;
+
+ sap.setCrypto(null, null, null, null);
+ // supress overlay text for visible signatures
+ sap.setLayer2Text("");
+ sap.setLayer4Text("");
+
+ // the following line marks the sig block as adobe sig
+ // sap.setVisibleSignature(createRectangleFromTablePos(iui.actualTablePos),
+ // iui.actualTablePos.page, "PDF-AS-Signatur");
+ sap.setVisibleSignature(new Rectangle(0, 0, 0, 0), atp.page, finalFieldName);
+ String subfilter = "unknown";
+ if (so != null && so.getKZ() != null) {
+ subfilter = so.getKZ().toString();
+ } else if (si != null) {
+ subfilter = si.getSignSignatureObject().kz;
+ }
+ PdfSignature sig = new PdfSignature(new PdfName(ADOBE_SIG_FILTER), new PdfName(subfilter));
+ // the following fields are not shown by the reader, because its is no
+ // Standard filter
+ // sig.setLocation("location is not visible");
+ // sig.setReason("reason is not visible");
+
+ // contact field is used to embed signature verification url for adobe handler
+ String verifyURL = getVerifyUrl(profileId);
+ if (!StringUtils.isEmpty(verifyURL)) {
+ sig.setContact(getVerifyUrl(profileId));
+ } else {
+ logger.debug("No verify URL set -> verify URL is not embedded.");
+ }
+ // sig.setDate(new PdfDate());
+
+ String reason = getAdobeReasonName(profileId);
+ if (!StringUtils.isEmpty(reason)) {
+ sig.setReason(reason);
+ }
+
+
+ /* disabled in order to align adobe signature appearance for textual signatures with binary signatures
+ if (si != null) {
+ XMLGregorianCalendar c = DatatypeFactory.newInstance().newXMLGregorianCalendar(
+ si.getSignSignatureObject().date);
+ sig.setDate(new PdfDate(c.toGregorianCalendar()));
+ }
+ */
+
+ sig.setName(getAdobeSignText(profileId, si));
+ sap.setCryptoDictionary(sig);
+ sap.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
+
+ // content element is mandatory but empty
+ HashMap exc = new HashMap();
+ exc.put(PdfName.CONTENTS, new Integer(2));
+
+ PdfNumber parentNum = structHelper.buildAdobeSigStructParent();
+ if (parentNum != null) {
+ PdfFormField sigField = PdfFormField.createSignature(stamper.getWriter());
+ sap.setSigFormField(sigField);
+ sigField.put(PdfName.STRUCTPARENT, parentNum);
+ structHelper.buildAdobeSigStruct(sigField, finalFieldName);
+ }
+ sap.preClose(exc); // *2+2
+
+ PdfDictionary dic = new PdfDictionary();
+ dic.put(PdfName.CONTENTS, new PdfString((String) null).setHexWriting(true));
+ sap.close(dic);
+ } catch (Exception ex) {
+ logger.error("error", ex);
+ throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
+ "Error creating adobe signature attribute", ex);
+ }
+ }
+
+
+ /**
+ * Returns if adobe signature is enabled for the passed signature profile.
+ * Config key: {@value #ADOBE_SIG_ENABLED_KEY}
+ * @param sigProfile
+ * @return
+ */
+ public static boolean isAdobeSignatureFieldEnabled(String sigProfile) {
+ return "true".equalsIgnoreCase(
+ getDefaultableConfigProperty(sigProfile, ADOBE_SIG_ENABLED_KEY, "false"));
+ }
+
+ protected static Rectangle createRectangleFromTablePos(ActualTablePos pos) {
+ return new Rectangle(pos.x, pos.y, pos.x + pos.width, pos.y - pos.height);
+ }
+
+ private static String getAdobeFieldName(String sigProfile) {
+ return getDefaultableConfigProperty(sigProfile, ADOBE_SIGN_FIELDNAME_KEY, "PDF-AS Signatur");
+ }
+
+ private static String getAdobeReasonName(String sigProfile) {
+ return getDefaultableConfigProperty(sigProfile, ADOBE_SIGN_REASONNAME_KEY, "Informationen zur Prüfung finden Sie unter http://www.signaturpruefung.gv.at");
+ }
+
+ private static String getVerifyUrl(String sigProfile) {
+ return getDefaultableConfigProperty(sigProfile, ADOBE_VERIFY_URL_KEY, "http://www.signaturpruefung.gv.at");
+ }
+
+ public static String getDefaultableConfigProperty(String sigProfile, String propName, String defaultValue) {
+ String confVal;
+ try {
+ confVal = SettingsReader.getInstance().getSetting(
+ "sig_obj." + sigProfile + "." + propName,
+ "default." + propName,
+ defaultValue);
+ } catch (SettingsException e) {
+ logger.warn("error reading " + propName + " from config. Using default: " + defaultValue, e);
+ return defaultValue;
+ }
+ return confVal;
+ }
+
+ /**
+ * Evaluate name for adobe signature field. Get from config. Evaluate ognl if
+ * ok.
+ *
+ * @param sigProfile
+ * @param si
+ * @return
+ */
+ private static String getAdobeSignText(String sigProfile, SignatorInformation si) {
+ String defaultName = "PDF-AS";
+ try {
+ logger.debug("reading adobe sig name for profile: " + sigProfile);
+ String propKey = ADOBE_SIG_TEXT_KEY + ".textual";
+ if (si == null) {
+ propKey = propKey.replaceAll("textual", "binary");
+ }
+ String adobeStr = getDefaultableConfigProperty(sigProfile, propKey, defaultName);
+
+ HashMap ognlCtx = new HashMap();
+ OgnlUtil ognl = new OgnlUtil(ognlCtx);
+ if (ognl.containsExpression(adobeStr)) {
+ if (si == null) {
+ logger
+ .error(ADOBE_SIG_TEXT_KEY
+ + " ognl expressions not allowed for binary signatures (SignatorInformation not available)");
+ return defaultName;
+ }
+ ognlCtx.put("si", si);
+ ognlCtx.put("sso", si.getSignSignatureObject());
+ String res = ognl.compileMessage(adobeStr);
+ return res;
+ } else {
+ return adobeStr;
+ }
+
+ } catch (Exception ex) {
+ logger.warn("error creating adobe sign text, using default '" + defaultName + "'", ex);
+ return defaultName;
+ }
+ }
+
+}