From e210f9d25fb530a2650059390f12a7e8ecec48b3 Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Tue, 28 Jan 2014 13:49:33 +0100 Subject: PDF-AS cleanups --- .../exceptions/PdfAsValidationException.java | 5 ++- .../resources/resources/messages/common.properties | 2 + .../at/gv/egiz/pdfas/lib/api/PdfAsFactory.java | 11 ++++-- .../java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java | 15 +++++++- .../gv/egiz/pdfas/web/config/WebConfiguration.java | 4 ++ .../at/gv/egiz/pdfas/web/helper/DigestHelper.java | 27 ++++++++++++++ .../at/gv/egiz/pdfas/web/helper/PdfAsHelper.java | 43 +++++++++++++++++++--- .../pdfas/web/helper/PdfAsParameterExtractor.java | 12 ------ .../gv/egiz/pdfas/web/helper/RemotePDFFetcher.java | 1 + .../egiz/pdfas/web/servlets/ExternSignServlet.java | 14 +++++-- .../at/gv/egiz/pdfas/web/servlets/PDFData.java | 24 ++++++++++++ 11 files changed, 130 insertions(+), 28 deletions(-) create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/DigestHelper.java diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java index 61bfffda..b8a5fc62 100644 --- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java @@ -18,6 +18,9 @@ public class PdfAsValidationException extends PdfAsException { @Override protected String localizeMessage(String msgId) { - return String.format(MessageResolver.resolveMessage(msgId), parameter); + if(parameter != null) { + return String.format(MessageResolver.resolveMessage(msgId), parameter); + } + return MessageResolver.resolveMessage(msgId); } } diff --git a/pdf-as-common/src/main/resources/resources/messages/common.properties b/pdf-as-common/src/main/resources/resources/messages/common.properties index ef3b4949..0191bdd9 100644 --- a/pdf-as-common/src/main/resources/resources/messages/common.properties +++ b/pdf-as-common/src/main/resources/resources/messages/common.properties @@ -34,6 +34,8 @@ error.pdf.sig.06=Failed to finish signature process error.pdf.sig.07=Failed to determine Signature Profile error.pdf.sig.08=Signature created by the BKU is not valid error.pdf.sig.09=Signature profile %s not available +error.pdf.sig.10=No signature data available +error.pdf.sig.11=No data sink available #Signature verification errors diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java index 284573e0..3f5888fc 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java @@ -1,5 +1,6 @@ package at.gv.egiz.pdfas.lib.api; +import iaik.cms.IaikCCProvider; import iaik.security.ec.provider.ECCelerate; import iaik.security.provider.IAIK; @@ -40,16 +41,18 @@ public class PdfAsFactory { static { - System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - System.out.println("+ PDF-AS: " + getVersion()); - System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - /* * PropertyConfigurator.configure(ClassLoader * .getSystemResourceAsStream("resources/log4j.properties")); */ IAIK.addAsProvider(); ECCelerate.addAsProvider(); + + System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + System.out.println("+ PDF-AS: " + getVersion()); + System.out.println("+ IAIK-JCE Version: " + IAIK.getVersionInfo()); + System.out.println("+ ECCelerate Version: " + ECCelerate.getInstance().getVersion()); + System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); } private static boolean log_configured = false; diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java index 04b385f7..540fd572 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java @@ -87,6 +87,14 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { } } + if(parameter.getDataSource() == null || parameter.getDataSource().getByteData() == null) { + throw new PdfAsValidationException("error.pdf.sig.10", null); + } + + if(parameter.getOutput() == null) { + throw new PdfAsValidationException("error.pdf.sig.11", null); + } + // TODO: verify Sign Parameter } @@ -96,6 +104,10 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { if (!(parameter.getConfiguration() instanceof ISettings)) { throw new PdfAsSettingsException("Invalid settings object!"); } + + if(parameter.getDataSource() == null || parameter.getDataSource().getByteData() == null) { + throw new PdfAsValidationException("error.pdf.verify.01", null); + } // TODO: verify Verify Parameter } @@ -279,7 +291,8 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { public StatusRequest startSign(SignParameter parameter) throws PdfAsException { - // TODO: VERIFY PARAMETERS + verifySignParameter(parameter); + StatusRequestImpl request = new StatusRequestImpl(); try { diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java index 3c6a7f21..6609e51d 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java @@ -108,4 +108,8 @@ public class WebConfiguration { return false; } + public static boolean isProvidePdfURLinWhitelist(String url) { + //TODO implement whitelisting for pdfURLS + return false; + } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/DigestHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/DigestHelper.java new file mode 100644 index 00000000..af002da4 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/DigestHelper.java @@ -0,0 +1,27 @@ +package at.gv.egiz.pdfas.web.helper; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.apache.commons.codec.binary.Hex; + +public class DigestHelper { + + public static final String SHA1 = "SHA-1"; + public static final String SHA224 = "SHA-224"; + public static final String SHA256 = "SHA-256"; + public static final String SHA384 = "SHA-384"; + public static final String SHA512 = "SHA-512"; + + public static String DefaulAlgorithm = SHA256; + + public static String getHexEncodedHash(byte[] data) throws NoSuchAlgorithmException { + return getHexEncodedHash(data, DefaulAlgorithm); + } + + public static String getHexEncodedHash(byte[] data, String algorithm) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance(algorithm); + byte[] hash = md.digest(data); + return Hex.encodeHexString(hash); + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java index e61a113a..2f62269b 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory; import com.lowagie.text.html.WebColors; +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.lib.api.ByteArrayDataSink; import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource; import at.gv.egiz.pdfas.lib.api.Configuration; @@ -65,6 +66,8 @@ public class PdfAsHelper { private static final String PDF_ERR_URL = "PDF_ERR_URL"; private static final String PDF_INVOKE_URL = "PDF_INVOKE_URL"; private static final String REQUEST_FROM_DU = "REQ_DATA_URL"; + private static final String SIGNATURE_DATA_HASH = "SIGNATURE_DATA_HASH"; + private static final String SIGNATURE_ACTIVE = "SIGNATURE_ACTIVE"; private static final Logger logger = LoggerFactory .getLogger(PdfAsHelper.class); @@ -110,7 +113,7 @@ public class PdfAsHelper { } } } - + private static String buildPosString(HttpServletRequest request, HttpServletResponse response) throws PdfAsWebException { String posP = PdfAsParameterExtractor.getSigPosP(request); @@ -177,11 +180,6 @@ public class PdfAsHelper { return sb.toString(); } - public static void doSignature(HttpServletRequest request, - HttpServletResponse response, byte[] pdfData) throws Exception { - - } - /** * Create synchronous PDF Signature * @@ -242,6 +240,13 @@ public class PdfAsHelper { HttpServletResponse response, ServletContext context, byte[] pdfData) throws Exception { + // TODO: Protect session so that only one PDF can be signed during one session + /*if(PdfAsHelper.isSignatureActive(request)) { + throw new PdfAsException("Signature is active in this session"); + } + + PdfAsHelper.setSignatureActive(request, true);*/ + validatePdfSize(request, response, pdfData); HttpSession session = request.getSession(); @@ -609,4 +614,30 @@ public class PdfAsHelper { } return false; } + + public static void setSignatureDataHash(HttpServletRequest request, String value) { + request.setAttribute(SIGNATURE_DATA_HASH, value); + } + + public static String getSignatureDataHash(HttpServletRequest request) { + Object obj = request.getAttribute(SIGNATURE_DATA_HASH); + if (obj != null) { + return obj.toString(); + } + return ""; + } + + public static void setSignatureActive(HttpServletRequest request, boolean value) { + request.setAttribute(SIGNATURE_ACTIVE, new Boolean(value)); + } + + public static boolean isSignatureActive(HttpServletRequest request) { + Object obj = request.getAttribute(SIGNATURE_ACTIVE); + if (obj != null) { + if (obj instanceof Boolean) { + return ((Boolean) obj).booleanValue(); + } + } + return false; + } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java index 5a79bb4a..4d6ad1fe 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java @@ -70,16 +70,4 @@ public class PdfAsParameterExtractor { public static String getSigPosW(HttpServletRequest request) { return (String)request.getAttribute(PARAM_SIG_POS_W); } - - // legacy Parameter - public static final String PARAM_PDF_ID = "pdf-id"; - public static final String PARAM_SESSION_ID = "session-id"; - - public static String getPdfId(HttpServletRequest request) { - return (String)request.getAttribute(PARAM_PDF_ID); - } - - public static String getSessionId(HttpServletRequest request) { - return (String)request.getAttribute(PARAM_SESSION_ID); - } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java index 7c90dbc8..9532e074 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java @@ -17,6 +17,7 @@ public class RemotePDFFetcher { throw new PdfAsWebException("Not a valid URL!", e); } if(url.getProtocol().equals("http") || url.getProtocol().equals("https")) { + try { InputStream is = url.openStream(); return StreamUtils.inputStreamToByteArray(is); diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java index c96225bd..3a6bc971 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java @@ -2,7 +2,6 @@ package at.gv.egiz.pdfas.web.servlets; import java.io.File; import java.io.IOException; -import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; @@ -18,14 +17,12 @@ import org.slf4j.LoggerFactory; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; -import at.gv.egiz.pdfas.sigs.pades.PAdESSigner; import at.gv.egiz.pdfas.web.config.WebConfiguration; import at.gv.egiz.pdfas.web.exception.PdfAsWebException; +import at.gv.egiz.pdfas.web.helper.DigestHelper; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor; import at.gv.egiz.pdfas.web.helper.RemotePDFFetcher; -import at.gv.egiz.sl.util.BKUSLConnector; -import at.gv.egiz.sl.util.MOAConnector; /** * Servlet implementation class Sign @@ -209,6 +206,15 @@ public class ExternSignServlet extends HttpServlet { String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); PdfAsHelper.setErrorURL(request, response, errorUrl); + if(pdfData == null) { + throw new PdfAsException("No Signature data available"); + } + + String pdfDataHash = DigestHelper.getHexEncodedHash(pdfData); + + PdfAsHelper.setSignatureDataHash(request, pdfDataHash); + logger.debug("Storing signatures data hash: " + pdfDataHash); + logger.debug("Starting signature creation with: " + connector); IPlainSigner signer; diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java index 6ce0e1c9..9bf66fe9 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java @@ -8,14 +8,23 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import at.gv.egiz.pdfas.web.helper.PdfAsHelper; /** * Servlet implementation class PDFData */ public class PDFData extends HttpServlet { + private static final long serialVersionUID = 1L; + private static final Logger logger = LoggerFactory + .getLogger(PDFData.class); + + private static String ORIGINAL_DIGEST = "origdigest"; + /** * @see HttpServlet#HttpServlet() */ @@ -45,7 +54,22 @@ public class PDFData extends HttpServlet { HttpServletResponse response) throws ServletException, IOException { byte[] signedData = PdfAsHelper.getSignedPdf(request, response); + String plainPDFDigest = request.getParameter(ORIGINAL_DIGEST); + if (signedData != null) { + if(plainPDFDigest != null) { + String signatureDataHash = PdfAsHelper.getSignatureDataHash(request); + if(!plainPDFDigest.equalsIgnoreCase(signatureDataHash)) { + logger.error("Digest Hash mismatch!"); + logger.error("Requested digest: " + plainPDFDigest); + logger.error("Saved digest: " + signatureDataHash); + + PdfAsHelper.setSessionException(request, response, + "Signature Data digest do not match!", null); + PdfAsHelper.gotoError(getServletContext(), request, response); + return; + } + } response.setContentType("application/pdf"); OutputStream os = response.getOutputStream(); os.write(signedData); -- cgit v1.2.3