From 11c4bfac46f66ab3ba24b6354a6a372da40c0b1f Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Thu, 9 Jan 2014 12:52:06 +0100 Subject: PDF-AS web Developments --- .../java/at/gv/egiz/pdfas/cli/DeveloperMain.java | 4 - .../at/gv/egiz/pdfas/lib/api/PdfAsFactory.java | 4 +- .../egiz/sl/util/ISignatureConnectorSLWrapper.java | 3 +- pdf-as-lib/src/main/resources/config/config.zip | Bin 1039811 -> 1039807 bytes pdf-as-web/build.gradle | 1 + .../gv/egiz/pdfas/web/config/WebConfiguration.java | 24 + .../at/gv/egiz/pdfas/web/config/package-info.java | 8 + .../pdfas/web/exception/PdfAsWebException.java | 17 + .../gv/egiz/pdfas/web/exception/package-info.java | 8 + .../pdfas/web/filter/ExceptionCatchFilter.java | 75 + .../at/gv/egiz/pdfas/web/helper/HTMLFormater.java | 13 + .../at/gv/egiz/pdfas/web/helper/PdfAsHelper.java | 567 +- .../pdfas/web/helper/PdfAsParameterExtractor.java | 85 + .../gv/egiz/pdfas/web/helper/RemotePDFFetcher.java | 30 + .../gv/egiz/pdfas/web/servlets/DataURLServlet.java | 7 +- .../at/gv/egiz/pdfas/web/servlets/ErrorPage.java | 101 + .../egiz/pdfas/web/servlets/ExternSignServlet.java | 205 + .../at/gv/egiz/pdfas/web/servlets/PDFData.java | 62 + .../egiz/pdfas/web/servlets/ProvidePDFServlet.java | 75 +- .../at/gv/egiz/pdfas/web/servlets/SignServlet.java | 102 - .../at/gv/egiz/pdfas/web/servlets/TestServlet.java | 43 + .../gv/egiz/pdfas/web/servlets/VerifyServlet.java | 1 - .../main/resources/template_error_redirect.html | 56 + .../main/resources/template_invoke_redirect.html | 56 + pdf-as-web/src/main/webapp/WEB-INF/decorators.xml | 13 + .../webapp/WEB-INF/decorators/default_layout.jsp | 41 + pdf-as-web/src/main/webapp/WEB-INF/sitemesh.xml | 16 + pdf-as-web/src/main/webapp/WEB-INF/web.xml | 74 +- .../src/main/webapp/assets/css/bootstrap-theme.css | 397 ++ .../main/webapp/assets/css/bootstrap-theme.min.css | 7 + .../src/main/webapp/assets/css/bootstrap.css | 7118 ++++++++++++++++++++ .../src/main/webapp/assets/css/bootstrap.min.css | 7 + pdf-as-web/src/main/webapp/assets/css/pdfas.css | 79 + .../assets/fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20290 bytes .../assets/fonts/glyphicons-halflings-regular.svg | 229 + .../assets/fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41236 bytes .../assets/fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23292 bytes pdf-as-web/src/main/webapp/assets/js/bootstrap.js | 2006 ++++++ .../src/main/webapp/assets/js/bootstrap.min.js | 7 + pdf-as-web/src/main/webapp/index.jsp | 21 + pdf-as-web/src/main/webapp/signstart.jsp | 14 - 41 files changed, 11347 insertions(+), 229 deletions(-) create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/package-info.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsWebException.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/package-info.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/HTMLFormater.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java delete mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/TestServlet.java create mode 100644 pdf-as-web/src/main/resources/template_error_redirect.html create mode 100644 pdf-as-web/src/main/resources/template_invoke_redirect.html create mode 100644 pdf-as-web/src/main/webapp/WEB-INF/decorators.xml create mode 100644 pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp create mode 100644 pdf-as-web/src/main/webapp/WEB-INF/sitemesh.xml create mode 100644 pdf-as-web/src/main/webapp/assets/css/bootstrap-theme.css create mode 100644 pdf-as-web/src/main/webapp/assets/css/bootstrap-theme.min.css create mode 100644 pdf-as-web/src/main/webapp/assets/css/bootstrap.css create mode 100644 pdf-as-web/src/main/webapp/assets/css/bootstrap.min.css create mode 100644 pdf-as-web/src/main/webapp/assets/css/pdfas.css create mode 100644 pdf-as-web/src/main/webapp/assets/fonts/glyphicons-halflings-regular.eot create mode 100644 pdf-as-web/src/main/webapp/assets/fonts/glyphicons-halflings-regular.svg create mode 100644 pdf-as-web/src/main/webapp/assets/fonts/glyphicons-halflings-regular.ttf create mode 100644 pdf-as-web/src/main/webapp/assets/fonts/glyphicons-halflings-regular.woff create mode 100644 pdf-as-web/src/main/webapp/assets/js/bootstrap.js create mode 100644 pdf-as-web/src/main/webapp/assets/js/bootstrap.min.js create mode 100644 pdf-as-web/src/main/webapp/index.jsp delete mode 100644 pdf-as-web/src/main/webapp/signstart.jsp diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java index 2c8114a8..7b8d4a95 100644 --- a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java +++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java @@ -86,16 +86,12 @@ public class DeveloperMain { pdfas.verify(verify); } catch (FileNotFoundException e1) { - // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e1) { - // TODO Auto-generated catch block e1.printStackTrace(); }catch (PdfAsException e) { - // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); } } 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 bd7c9d3e..b73cc9af 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 @@ -31,8 +31,8 @@ public class PdfAsFactory { private static final String DEFAULT_CONFIG_RES = "config/config.zip"; static { - PropertyConfigurator.configure(ClassLoader - .getSystemResourceAsStream("resources/log4j.properties")); + /*PropertyConfigurator.configure(ClassLoader + .getSystemResourceAsStream("resources/log4j.properties"));*/ IAIK.addAsProvider(); ECCelerate.addAsProvider(); } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java index 273f08ab..75b10c4c 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java @@ -54,8 +54,7 @@ public class ISignatureConnectorSLWrapper implements ISignatureConnector { } } } catch (CertificateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + throw new PdfAsSignatureException("error.pdf.sig.01", e); } return certificate; } diff --git a/pdf-as-lib/src/main/resources/config/config.zip b/pdf-as-lib/src/main/resources/config/config.zip index dd8892c2..f277bd76 100644 Binary files a/pdf-as-lib/src/main/resources/config/config.zip and b/pdf-as-lib/src/main/resources/config/config.zip differ diff --git a/pdf-as-web/build.gradle b/pdf-as-web/build.gradle index b5290c49..44cc93d6 100644 --- a/pdf-as-web/build.gradle +++ b/pdf-as-web/build.gradle @@ -25,6 +25,7 @@ dependencies { compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.2' compile group: 'commons-collections', name: 'commons-collections', version: '3.2' compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.5' + compile group: 'opensymphony', name: 'sitemesh', version: '2.4.2' testCompile group: 'junit', name: 'junit', version: '4.+' } 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 new file mode 100644 index 00000000..eb04dde8 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java @@ -0,0 +1,24 @@ +package at.gv.egiz.pdfas.web.config; + +public class WebConfiguration { + + public static String getPublicURL() { + return null; + } + + public static String getLocalBKUURL() { + // TODO: Read URL from config + return "http://127.0.0.1:3495/http-security-layer-request"; + } + + public static String getOnlineBKUURL() { + // TODO: Read URL from config + return "http://abyss.iaik.tugraz.at/bkuonline/http-security-layer-request"; + } + + public static String getHandyBKUURL() { + // TODO: Read URL from config + return "http://127.0.0.1:3495/http-security-layer-request"; + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/package-info.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/package-info.java new file mode 100644 index 00000000..6334ff83 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.web.config; \ No newline at end of file diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsWebException.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsWebException.java new file mode 100644 index 00000000..3e734265 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsWebException.java @@ -0,0 +1,17 @@ +package at.gv.egiz.pdfas.web.exception; + +public class PdfAsWebException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -4632774270754873043L; + + public PdfAsWebException(String message) { + super(message); + } + + public PdfAsWebException(String message, Throwable e) { + super(message, e); + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/package-info.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/package-info.java new file mode 100644 index 00000000..206f5f40 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.web.exception; \ No newline at end of file diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java new file mode 100644 index 00000000..bcda2263 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java @@ -0,0 +1,75 @@ +package at.gv.egiz.pdfas.web.filter; + +import java.io.IOException; +import java.util.Enumeration; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.apache.http.HttpRequest; +import org.apache.log4j.BasicConfigurator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; + +/** + * Servlet Filter implementation class ExceptionCatchFilter + */ +public class ExceptionCatchFilter implements Filter { + + private static final Logger logger = LoggerFactory + .getLogger(ExceptionCatchFilter.class); + + /** + * Default constructor. + */ + public ExceptionCatchFilter() { + } + + /** + * @see Filter#destroy() + */ + public void destroy() { + } + + /** + * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + //try { + + if(request instanceof HttpServletRequest) { + logger.debug("Processing Parameters into Attributes"); + HttpServletRequest httpRequest = (HttpServletRequest)request; + Enumeration parameterNames = httpRequest.getParameterNames(); + while(parameterNames.hasMoreElements()) { + String name = parameterNames.nextElement(); + String value = httpRequest.getParameter(name); + request.setAttribute(name, value); + logger.info("Setting attribute: " + name + " - " + value); + } + } + + + chain.doFilter(request, response); + /*} catch(Throwable e) { + System.err.println("Unhandled Exception found!"); + e.printStackTrace(System.err); + logger.error("Unhandled Exception found!", e); + }*/ + } + + /** + * @see Filter#init(FilterConfig) + */ + public void init(FilterConfig fConfig) throws ServletException { + BasicConfigurator.configure(); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/HTMLFormater.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/HTMLFormater.java new file mode 100644 index 00000000..fe2c9271 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/HTMLFormater.java @@ -0,0 +1,13 @@ +package at.gv.egiz.pdfas.web.helper; + +public class HTMLFormater { + + public static String formatStackTrace(StackTraceElement[] elements) { + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < elements.length; i++) { + sb.append(elements[i].toString()); + sb.append("
"); + } + return sb.toString(); + } +} 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 154cfd01..daf18108 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 @@ -5,6 +5,9 @@ import java.io.IOException; import java.util.Iterator; import java.util.List; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -12,14 +15,29 @@ import javax.xml.bind.JAXBElement; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.lowagie.text.html.WebColors; + +import at.gv.egiz.pdfas.lib.api.ByteArrayDataSink; import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource; import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.DataSink; import at.gv.egiz.pdfas.lib.api.PdfAs; import at.gv.egiz.pdfas.lib.api.PdfAsFactory; +import at.gv.egiz.pdfas.lib.api.SignaturePosition; import at.gv.egiz.pdfas.lib.api.StatusRequest; +import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.api.sign.SignResult; +import at.gv.egiz.pdfas.lib.impl.PdfAsImpl; +import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl; import at.gv.egiz.pdfas.sigs.pades.PAdESSigner; +import at.gv.egiz.pdfas.sigs.pades.PAdESSignerKeystore; +import at.gv.egiz.pdfas.sigs.pkcs7detached.PKCS7DetachedSigner; +import at.gv.egiz.pdfas.web.config.WebConfiguration; +import at.gv.egiz.pdfas.web.exception.PdfAsWebException; import at.gv.egiz.sl.CreateCMSSignatureRequestType; import at.gv.egiz.sl.CreateCMSSignatureResponseType; import at.gv.egiz.sl.InfoboxAssocArrayPairType; @@ -27,6 +45,7 @@ import at.gv.egiz.sl.InfoboxReadRequestType; import at.gv.egiz.sl.InfoboxReadResponseType; import at.gv.egiz.sl.ObjectFactory; import at.gv.egiz.sl.util.BKUSLConnector; +import at.gv.egiz.sl.util.MOAConnector; import at.gv.egiz.sl.util.SLMarschaller; public class PdfAsHelper { @@ -34,32 +53,240 @@ public class PdfAsHelper { private static final String PDF_CONFIG = "PDF_CONFIG"; private static final String PDF_STATUS = "PDF_STATUS"; private static final String PDF_SL_CONNECTOR = "PDF_SL_CONNECTOR"; + private static final String PDF_SIGNER = "PDF_SIGNER"; + private static final String PDF_SL_INTERACTIVE = "PDF_SL_INTERACTIVE"; + private static final String PDF_SIGNED_DATA = "PDF_SIGNED_DATA"; + private static final String PDF_ERR_MESSAGE = "PDF_ERR_MESSAGE"; + private static final String PDF_ERR_THROWABLE = "PDF_ERR_THROWABLE"; + private static final String PDF_ERROR_PAGE = "/ErrorPage"; + private static final String PDF_PROVIDE_PAGE = "/ProvidePDF"; + private static final String PDF_PDFDATA_PAGE = "/PDFData"; + private static final String PDF_DATAURL_PAGE = "/DataURL"; + 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"; + + // For development only: + public static final String keyStoreFile = "/home/afitzek/devel/pdfas_neu/test.p12"; + public static final String keyStoreType = "PKCS12"; + public static final String keyStorePass = "123456"; + // public static final String keyAlias = "pdf"; + public static final String keyAlias = "ecc_test"; + public static final String keyPass = "123456"; + + private static final Logger logger = LoggerFactory + .getLogger(PdfAsHelper.class); private static PdfAs pdfAs; private static ObjectFactory of = new ObjectFactory(); static { + // TODO: read from config file + logger.debug("Creating PDF-AS"); pdfAs = PdfAsFactory.createPdfAs(new File("/home/afitzek/.pdfas")); + logger.debug("Creating PDF-AS done"); } - public static void startSignature(HttpServletRequest request, + private static void validatePdfSize(HttpServletRequest request, + HttpServletResponse response, byte[] pdfData) + throws PdfAsWebException { + // Try to check num-bytes + String pdfSizeString = PdfAsParameterExtractor.getNumBytes(request); + if (pdfSizeString != null) { + long pdfSize = -1; + try { + pdfSize = Long.parseLong(pdfSizeString); + } catch (NumberFormatException e) { + throw new PdfAsWebException( + PdfAsParameterExtractor.PARAM_NUM_BYTES + + " parameter has to be a positiv number!", e); + } + if (pdfSize <= 0) { + throw new PdfAsWebException( + "Invalid PDF Size! Has to bigger than zero!"); + } + + if (pdfData.length != pdfSize) { + throw new PdfAsWebException("Signature Data Size and " + + PdfAsParameterExtractor.PARAM_NUM_BYTES + + " missmatch!"); + } + } + } + + private static String buildPosString(HttpServletRequest request, + HttpServletResponse response) throws PdfAsWebException { + String posP = PdfAsParameterExtractor.getSigPosP(request); + String posX = PdfAsParameterExtractor.getSigPosX(request); + String posY = PdfAsParameterExtractor.getSigPosY(request); + String posW = PdfAsParameterExtractor.getSigPosW(request); + + if (posP == null && posW == null && posX == null && posY == null) { + return null; + } + + StringBuilder sb = new StringBuilder(); + + if (posX != null) { + try { + Float.parseFloat(posX); + } catch (NumberFormatException e) { + throw new PdfAsWebException( + PdfAsParameterExtractor.PARAM_SIG_POS_X + + " has invalid value!", e); + } + sb.append("x:" + posX.trim() + ";"); + } else { + sb.append("x:auto;"); + } + + if (posY != null) { + try { + Float.parseFloat(posY); + } catch (NumberFormatException e) { + throw new PdfAsWebException( + PdfAsParameterExtractor.PARAM_SIG_POS_Y + + " has invalid value!", e); + } + sb.append("y:" + posY.trim() + ";"); + } else { + sb.append("y:auto;"); + } + + if (posW != null) { + try { + Float.parseFloat(posW); + } catch (NumberFormatException e) { + throw new PdfAsWebException( + PdfAsParameterExtractor.PARAM_SIG_POS_W + + " has invalid value!", e); + } + sb.append("w:" + posW.trim() + ";"); + } else { + sb.append("w:auto;"); + } + + if (posP != null) { + if (!(posP.equals("auto") || posP.equals("new"))) { + throw new PdfAsWebException( + PdfAsParameterExtractor.PARAM_SIG_POS_P + + " has invalid value! (auto | new )"); + } + sb.append("p:" + posP.trim() + ";"); + } else { + sb.append("P:auto;"); + } + + return sb.toString(); + } + + public static void doSignature(HttpServletRequest request, + HttpServletResponse response, byte[] pdfData) throws Exception { + + } + + /** + * Create synchronous PDF Signature + * + * @param request + * The Web request + * @param response + * The Web response + * @param pdfData + * The pdf data + * @return The signed pdf data + * @throws Exception + */ + public static byte[] synchornousSignature(HttpServletRequest request, HttpServletResponse response, byte[] pdfData) throws Exception { + validatePdfSize(request, response, pdfData); + + Configuration config = pdfAs.getConfiguration(); + + // Generate Sign Parameter + SignParameter signParameter = PdfAsFactory.createSignParameter(config, + new ByteArrayDataSource(pdfData)); + + // Get Connector + String connector = PdfAsParameterExtractor.getConnector(request); + + if (!connector.equals("moa") && !connector.equals("jks")) { + throw new PdfAsWebException("Invalid connector (moa | jks)"); + } + + IPlainSigner signer; + if (connector.equals("moa")) { + signer = new PAdESSigner(new MOAConnector(config)); + } else { + // TODO: + // signer = new PAdESSignerKeystore(file, alias, kspassword, + // keypassword, type) + signer = new PKCS7DetachedSigner(keyStoreFile, keyAlias, + keyStorePass, keyPass, keyStoreType); + } + + signParameter.setPlainSigner(signer); + + // set Signature Profile (null use default ...) + signParameter.setSignatureProfileId(PdfAsParameterExtractor + .getSigType(request)); + + ByteArrayDataSink output = new ByteArrayDataSink(); + signParameter.setOutput(output); + + // set Signature Position + signParameter.setSignaturePosition(buildPosString(request, response)); + + pdfAs.sign(signParameter); + + return output.getData(); + } + + public static void startSignature(HttpServletRequest request, + HttpServletResponse response, ServletContext context, byte[] pdfData) + throws Exception { + + validatePdfSize(request, response, pdfData); HttpSession session = request.getSession(); Configuration config = pdfAs.getConfiguration(); session.setAttribute(PDF_CONFIG, config); - BKUSLConnector bkuSLConnector = new BKUSLConnector(config); + + // Generate Sign Parameter SignParameter signParameter = PdfAsFactory.createSignParameter(config, new ByteArrayDataSource(pdfData)); - signParameter.setPlainSigner(new PAdESSigner(bkuSLConnector)); - - session.setAttribute(PDF_SL_CONNECTOR, bkuSLConnector); + + // Get Connector + String connector = PdfAsParameterExtractor.getConnector(request); + + IPlainSigner signer; + if (connector.equals("bku") || connector.equals("onlinebku") || connector.equals("mobilebku")) { + BKUSLConnector conn = new BKUSLConnector(config); + signer = new PAdESSigner(conn); + session.setAttribute(PDF_SL_CONNECTOR, conn); + } else { + throw new PdfAsWebException("Invalid connector (bku | onlinebku | mobilebku | moa | jks)"); + } + + signParameter.setPlainSigner(signer); + session.setAttribute(PDF_SIGNER, signer); + session.setAttribute(PDF_SL_INTERACTIVE, connector); + + // set Signature Profile (null use default ...) + signParameter.setSignatureProfileId(PdfAsParameterExtractor + .getSigType(request)); + + ByteArrayDataSink dataSink = new ByteArrayDataSink(); + signParameter.setOutput(dataSink); + + // set Signature Position + signParameter.setSignaturePosition(buildPosString(request, response)); StatusRequest statusRequest = pdfAs.startSign(signParameter); session.setAttribute(PDF_STATUS, statusRequest); - PdfAsHelper.process(request, response); + PdfAsHelper.process(request, response, context); } private static byte[] getCertificate( @@ -69,36 +296,40 @@ public class PdfAsHelper { List pairs = infoboxReadResponseType .getAssocArrayData().getPair(); Iterator pairIterator = pairs.iterator(); - while(pairIterator.hasNext()) { + while (pairIterator.hasNext()) { InfoboxAssocArrayPairType pair = pairIterator.next(); - if(pair.getKey().equals("SecureSignatureKeypair")) { + if (pair.getKey().equals("SecureSignatureKeypair")) { return pair.getBase64Content(); } } } // SecureSignatureKeypair - + return data; } public static void injectCertificate(HttpServletRequest request, - HttpServletResponse response, - InfoboxReadResponseType infoboxReadResponseType) throws Exception { - + HttpServletResponse response, + InfoboxReadResponseType infoboxReadResponseType, + ServletContext context) throws Exception { + HttpSession session = request.getSession(); - StatusRequest statusRequest = (StatusRequest)session.getAttribute(PDF_STATUS); - + StatusRequest statusRequest = (StatusRequest) session + .getAttribute(PDF_STATUS); + statusRequest.setCertificate(getCertificate(infoboxReadResponseType)); statusRequest = pdfAs.process(statusRequest); session.setAttribute(PDF_STATUS, statusRequest); - - PdfAsHelper.process(request, response); + + PdfAsHelper.process(request, response, context); } public static void injectSignature(HttpServletRequest request, HttpServletResponse response, - CreateCMSSignatureResponseType createCMSSignatureResponseType) - throws Exception { + CreateCMSSignatureResponseType createCMSSignatureResponseType, + ServletContext context) throws Exception { + + logger.info("Got CMS Signature Response"); HttpSession session = request.getSession(); StatusRequest statusRequest = (StatusRequest) session @@ -109,58 +340,88 @@ public class PdfAsHelper { statusRequest = pdfAs.process(statusRequest); session.setAttribute(PDF_STATUS, statusRequest); - PdfAsHelper.process(request, response); + PdfAsHelper.process(request, response, context); } public static void process(HttpServletRequest request, - HttpServletResponse response) throws Exception { + HttpServletResponse response, ServletContext context) + throws Exception { HttpSession session = request.getSession(); StatusRequest statusRequest = (StatusRequest) session .getAttribute(PDF_STATUS); - BKUSLConnector bkuSLConnector = (BKUSLConnector) session - .getAttribute(PDF_SL_CONNECTOR); - Configuration config = (Configuration) session.getAttribute(PDF_CONFIG); - - if (statusRequest.needCertificate()) { - // build SL Request to read certificate - InfoboxReadRequestType readCertificateRequest = bkuSLConnector - .createInfoboxReadRequest(); - - JAXBElement readRequest = of - .createInfoboxReadRequest(readCertificateRequest); - - String url = request.getContextPath() + "/DataURL;jsessionid=" - + session.getId(); - String fullurl = request.getScheme() + "://" - + request.getServerName() + ":" + request.getServerPort() - + url; - String slRequest = SLMarschaller.marshalToString(readRequest); - String template = getTemplateSL(); - template = template.replace("##BKU##", - "http://127.0.0.1:3495/http-security-layer-request"); - template = template.replace("##XMLRequest##", - StringEscapeUtils.escapeHtml4(slRequest)); - template = template.replace("##DataURL##", fullurl); - response.getWriter().write(template); - response.getWriter().close(); - } else if (statusRequest.needSignature()) { - // build SL Request for cms signature - CreateCMSSignatureRequestType createCMSSignatureRequestType = - bkuSLConnector.createCMSRequest(statusRequest.getSignatureData(), - statusRequest.getSignatureDataByteRange()); - - String slRequest = SLMarschaller.marshalToString(of - .createCreateCMSSignatureRequest(createCMSSignatureRequestType)); - - response.setContentType("text/xml"); - response.getWriter().write(slRequest); - response.getWriter().close(); - - } else if (statusRequest.isReady()) { - // TODO: store pdf document redirect to Finish URL + IPlainSigner plainSigner = (IPlainSigner) session + .getAttribute(PDF_SIGNER); + + String connector = (String) session.getAttribute(PDF_SL_INTERACTIVE); + + if (connector.equals("bku") || connector.equals("onlinebku") || connector.equals("mobilebku")) { + BKUSLConnector bkuSLConnector = (BKUSLConnector) session + .getAttribute(PDF_SL_CONNECTOR); + + // TODO Handle logic for BKU interaction + + Configuration config = (Configuration) session + .getAttribute(PDF_CONFIG); + + if (statusRequest.needCertificate()) { + logger.info("Needing Certificate from BKU"); + // build SL Request to read certificate + InfoboxReadRequestType readCertificateRequest = bkuSLConnector + .createInfoboxReadRequest(); + + JAXBElement readRequest = of + .createInfoboxReadRequest(readCertificateRequest); + + String url = request.getContextPath() + "/DataURL;jsessionid=" + + session.getId(); + String fullurl = request.getScheme() + "://" + + request.getServerName() + ":" + + request.getServerPort() + url; + String slRequest = SLMarschaller.marshalToString(readRequest); + String template = getTemplateSL(); + template = template.replace("##BKU##", + generateBKUURL(connector)); + template = template.replace("##XMLRequest##", + StringEscapeUtils.escapeHtml4(slRequest)); + template = template.replace("##DataURL##", fullurl); + response.getWriter().write(template); + response.getWriter().close(); + } else if (statusRequest.needSignature()) { + logger.info("Needing Signature from BKU"); + // build SL Request for cms signature + CreateCMSSignatureRequestType createCMSSignatureRequestType = bkuSLConnector + .createCMSRequest(statusRequest.getSignatureData(), + statusRequest.getSignatureDataByteRange()); + + String slRequest = SLMarschaller + .marshalToString(of + .createCreateCMSSignatureRequest(createCMSSignatureRequestType)); + + response.setContentType("text/xml"); + response.getWriter().write(slRequest); + response.getWriter().close(); + + } else if (statusRequest.isReady()) { + // TODO: store pdf document redirect to Finish URL + logger.info("Document ready!"); + + SignResult result = pdfAs.finishSign(statusRequest); + DataSink output = result.getOutputDocument(); + if (output instanceof ByteArrayDataSink) { + ByteArrayDataSink byteDataSink = (ByteArrayDataSink) output; + PdfAsHelper.setSignedPdf(request, response, + byteDataSink.getData()); + PdfAsHelper.gotoProvidePdf(context, request, response); + } else { + // TODO: no signature data available! + } + + } else { + // TODO: invalid state + } } else { - // TODO: invalid state + // TODO Handle logic for } } @@ -169,5 +430,187 @@ public class PdfAsHelper { .toFile(PdfAsHelper.class.getResource("/template_sl.html"))); return xml; } + + public static String getErrorRedirectTemplateSL() throws IOException { + String xml = FileUtils.readFileToString(FileUtils + .toFile(PdfAsHelper.class.getResource("/template_error_redirect.html"))); + return xml; + } + + public static String getInvokeRedirectTemplateSL() throws IOException { + String xml = FileUtils.readFileToString(FileUtils + .toFile(PdfAsHelper.class.getResource("/template_invoke_redirect.html"))); + return xml; + } + + public static byte[] getSignedPdf(HttpServletRequest request, + HttpServletResponse response) { + HttpSession session = request.getSession(); + Object signedData = session.getAttribute(PDF_SIGNED_DATA); + if (signedData == null) { + return null; + } + + if (signedData instanceof byte[]) { + return (byte[]) signedData; + } + logger.warn("PDF_SIGNED_DATA in session is not a byte[] type!"); + return null; + } + + public static void setSignedPdf(HttpServletRequest request, + HttpServletResponse response, byte[] signedData) { + HttpSession session = request.getSession(); + session.setAttribute(PDF_SIGNED_DATA, signedData); + } + + public static void setSessionException(HttpServletRequest request, + HttpServletResponse response, String message, Throwable e) { + HttpSession session = request.getSession(); + session.setAttribute(PDF_ERR_MESSAGE, message); + session.setAttribute(PDF_ERR_THROWABLE, e); + } + + public static String getSessionErrMessage(HttpServletRequest request, + HttpServletResponse response) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(PDF_ERR_MESSAGE); + return obj == null ? null : obj.toString(); + } + + public static Throwable getSessionException(HttpServletRequest request, + HttpServletResponse response) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(PDF_ERR_THROWABLE); + if (obj == null) { + return null; + } + + if (obj instanceof Throwable) { + return (Throwable) obj; + } + logger.warn("PDF_ERR_THROWABLE in session is not a throwable type!"); + return null; + } + + public static void gotoError(ServletContext context, + HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + if (PdfAsHelper.getFromDataUrl(request)) { + response.sendRedirect(generateErrorURL(request, response)); + } else { + RequestDispatcher dispatcher = context + .getRequestDispatcher(PDF_ERROR_PAGE); + dispatcher.forward(request, response); + } + } + + public static void gotoProvidePdf(ServletContext context, + HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + if (PdfAsHelper.getFromDataUrl(request)) { + response.sendRedirect(generateProvideURL(request, response)); + } else { + RequestDispatcher dispatcher = context + .getRequestDispatcher(PDF_PROVIDE_PAGE); + dispatcher.forward(request, response); + } + } + + public static void setErrorURL(HttpServletRequest request, + HttpServletResponse response, String url) { + HttpSession session = request.getSession(); + session.setAttribute(PDF_ERR_URL, url); + } + + public static String getErrorURL(HttpServletRequest request, + HttpServletResponse response) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(PDF_ERR_URL); + return obj == null ? null : obj.toString(); + } + + public static void setInvokeURL(HttpServletRequest request, + HttpServletResponse response, String url) { + HttpSession session = request.getSession(); + session.setAttribute(PDF_INVOKE_URL, url); + logger.info("External Invoke URL: " + url); + } + + public static String getInvokeURL(HttpServletRequest request, + HttpServletResponse response) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(PDF_INVOKE_URL); + return obj == null ? null : obj.toString(); + } + private static String generateURL(HttpServletRequest request, + HttpServletResponse response, String Servlet) { + HttpSession session = request.getSession(); + String publicURL = WebConfiguration.getPublicURL(); + String dataURL = null; + if (publicURL != null) { + dataURL = publicURL + Servlet + ";jsessionid=" + session.getId(); + } else { + if ((request.getScheme().equals("http") && request.getServerPort() == 80) + || (request.getScheme().equals("https") && request + .getServerPort() == 443)) { + dataURL = request.getScheme() + "://" + request.getServerName() + + request.getContextPath() + Servlet + ";jsessionid=" + + session.getId(); + } else { + dataURL = request.getScheme() + "://" + request.getServerName() + + ":" + request.getServerPort() + + request.getContextPath() + Servlet + ";jsessionid=" + + session.getId(); + } + } + logger.info("Generated URL: " + dataURL); + return dataURL; + } + + public static String generateDataURL(HttpServletRequest request, + HttpServletResponse response) { + return generateURL(request, response, PDF_DATAURL_PAGE); + } + + public static String generateProvideURL(HttpServletRequest request, + HttpServletResponse response) { + return generateURL(request, response, PDF_PROVIDE_PAGE); + } + + public static String generateErrorURL(HttpServletRequest request, + HttpServletResponse response) { + return generateURL(request, response, PDF_ERROR_PAGE); + } + + public static String generatePdfURL(HttpServletRequest request, + HttpServletResponse response) { + return generateURL(request, response, PDF_PDFDATA_PAGE); + } + + public static String generateBKUURL(String connector) { + if(connector.equals("bku")) { + return WebConfiguration.getLocalBKUURL(); + } else if(connector.equals("onlinebku")) { + return WebConfiguration.getOnlineBKUURL(); + } else if(connector.equals("mobilebku")) { + return WebConfiguration.getHandyBKUURL(); + } + return WebConfiguration.getLocalBKUURL(); + } + + public static void setFromDataUrl(HttpServletRequest request) { + request.setAttribute(REQUEST_FROM_DU, (Boolean) true); + } + + public static boolean getFromDataUrl(HttpServletRequest request) { + Object obj = request.getAttribute(REQUEST_FROM_DU); + 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 new file mode 100644 index 00000000..5a79bb4a --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java @@ -0,0 +1,85 @@ +package at.gv.egiz.pdfas.web.helper; + +import javax.servlet.http.HttpServletRequest; + +public class PdfAsParameterExtractor { + + public static final String PARAM_CONNECTOR = "connector"; + public static final String PARAM_CONNECTOR_DEFAULT = "bku"; + + + public static final String PARAM_INVOKE_URL = "invoke-app-url"; + public static final String PARAM_INVOKE_URL_ERROR = "invoke-app-error-url"; + public static final String PARAM_LOCALE = "locale"; + public static final String PARAM_NUM_BYTES = "num-bytes"; + public static final String PARAM_PDF_URL = "pdf-url"; + public static final String PARAM_SIG_TYPE = "sig_type"; + public static final String PARAM_SIG_POS_P = "sig-pos-p"; + public static final String PARAM_SIG_POS_Y = "sig-pos-y"; + public static final String PARAM_SIG_POS_X = "sig-pos-x"; + public static final String PARAM_SIG_POS_W = "sig-pos-w"; + + public static String getConnector(HttpServletRequest request) { + String connector = (String)request.getAttribute(PARAM_CONNECTOR); + if(connector != null) { + return connector; + } + return PARAM_CONNECTOR_DEFAULT; + } + + public static String getInvokeURL(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_INVOKE_URL); + } + + public static String getInvokeErrorURL(HttpServletRequest request) { + String url = (String)request.getAttribute(PARAM_INVOKE_URL_ERROR); + if(url != null) { + //TODO validation! + } + return url; + } + + public static String getLocale(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_LOCALE); + } + + public static String getNumBytes(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_NUM_BYTES); + } + + public static String getPdfUrl(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_PDF_URL); + } + + public static String getSigType(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_SIG_TYPE); + } + + public static String getSigPosP(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_SIG_POS_P); + } + + public static String getSigPosY(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_SIG_POS_Y); + } + + public static String getSigPosX(HttpServletRequest request) { + return (String)request.getAttribute(PARAM_SIG_POS_X); + } + + 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 new file mode 100644 index 00000000..7c90dbc8 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/RemotePDFFetcher.java @@ -0,0 +1,30 @@ +package at.gv.egiz.pdfas.web.helper; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import at.gv.egiz.pdfas.common.utils.StreamUtils; +import at.gv.egiz.pdfas.web.exception.PdfAsWebException; + +public class RemotePDFFetcher { + + public static byte[] fetchPdfFile(String pdfURL) throws PdfAsWebException { + URL url; + try { + url = new URL(pdfURL); + } catch (MalformedURLException e) { + 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); + } catch (Exception e) { + throw new PdfAsWebException("Failed to fetch pdf document!", e); + } + } else { + throw new PdfAsWebException("Failed to fetch pdf document protocol " + url.getProtocol() + " is not supported"); + } + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java index a8dfb053..a0fe3e80 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java @@ -27,7 +27,6 @@ public class DataURLServlet extends HttpServlet { */ public DataURLServlet() { super(); - // TODO Auto-generated constructor stub } /** @@ -51,7 +50,7 @@ public class DataURLServlet extends HttpServlet { protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { - + PdfAsHelper.setFromDataUrl(request); String xmlResponse = request.getParameter("XMLResponse"); System.out.println(xmlResponse); @@ -59,10 +58,10 @@ public class DataURLServlet extends HttpServlet { JAXBElement jaxbObject = (JAXBElement) SLMarschaller.unmarshalFromString(xmlResponse); if(jaxbObject.getValue() instanceof InfoboxReadResponseType) { InfoboxReadResponseType infoboxReadResponseType = (InfoboxReadResponseType)jaxbObject.getValue(); - PdfAsHelper.injectCertificate(request, response, infoboxReadResponseType); + PdfAsHelper.injectCertificate(request, response, infoboxReadResponseType, getServletContext()); } else if(jaxbObject.getValue() instanceof CreateCMSSignatureResponseType) { CreateCMSSignatureResponseType createCMSSignatureResponseType = (CreateCMSSignatureResponseType)jaxbObject.getValue(); - PdfAsHelper.injectSignature(request, response, createCMSSignatureResponseType); + PdfAsHelper.injectSignature(request, response, createCMSSignatureResponseType, getServletContext()); } else if(jaxbObject.getValue() instanceof ErrorResponseType) { ErrorResponseType errorResponseType = (ErrorResponseType)jaxbObject.getValue(); // TODO: store error and redirect user diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java new file mode 100644 index 00000000..fceeed85 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java @@ -0,0 +1,101 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.io.PrintWriter; +import java.net.URLEncoder; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.swing.text.html.HTML; + +import org.apache.commons.lang3.StringEscapeUtils; + +import at.gv.egiz.pdfas.web.helper.HTMLFormater; +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; + +/** + * Servlet implementation class ErrorPage + */ +public class ErrorPage extends HttpServlet { + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public ErrorPage() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response); + } + + protected void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + if (PdfAsHelper.getFromDataUrl(request)) { + // redirect to here! + response.sendRedirect(PdfAsHelper.generateErrorURL(request, + response)); + return; + } else { + String errorURL = PdfAsHelper.getErrorURL(request, response); + Throwable e = PdfAsHelper + .getSessionException(request, response); + String message = PdfAsHelper.getSessionErrMessage(request, + response); + if (errorURL != null) { + String template = PdfAsHelper.getErrorRedirectTemplateSL(); + template = template.replace("##ERROR_URL##", + errorURL); + if (e != null) { + template = template.replace("##CAUSE##", + URLEncoder.encode(e.getMessage(), "UTF-8")); + } else { + template = template.replace("##CAUSE##", + ""); + } + if (message != null) { + template = template.replace("##ERROR##", URLEncoder.encode(message, "UTF-8")); + } else { + template = template.replace("##ERROR##", "Unbekannter Fehler"); + } + response.setContentType("text/html"); + response.getWriter().write(template); + response.getWriter().close(); + } else { + response.setContentType("text/html"); + PrintWriter pw = response.getWriter(); + + pw.write("Error Page:"); + if (message != null) { + pw.write("

" + message + "

"); + } + + if (e != null) { + pw.write("

" + + HTMLFormater.formatStackTrace(e.getStackTrace()) + + "

"); + } + pw.write(""); + pw.close(); + } + } + } +} 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 new file mode 100644 index 00000000..90c77320 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java @@ -0,0 +1,205 @@ +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; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.slf4j.Logger; +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.exception.PdfAsWebException; +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 + */ +public class ExternSignServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private static final String UPLOAD_PDF_DATA = "pdfFile"; + private static final String UPLOAD_DIRECTORY = "upload"; + private static final int THRESHOLD_SIZE = 1024 * 1024 * 3; // 3MB + private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB + private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB + + private static final Logger logger = LoggerFactory + .getLogger(ExternSignServlet.class); + + /** + * Default constructor. + */ + public ExternSignServlet() { + } + + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + System.out.println("Get signing request"); + logger.info("Get signing request"); + + String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); + PdfAsHelper.setErrorURL(request, response, errorUrl); + try { + // Mandatory Parameters on Get Request: + String invokeUrl = PdfAsParameterExtractor.getInvokeURL(request); + PdfAsHelper.setInvokeURL(request, response, invokeUrl); + + String pdfUrl = PdfAsParameterExtractor.getPdfUrl(request); + + if (pdfUrl == null) { + throw new PdfAsWebException( + "No PDF URL given! Use POST request to sign without PDF URL."); + } + + byte[] pdfData = RemotePDFFetcher.fetchPdfFile(pdfUrl); + doSignature(request, response, pdfData); + } catch (Exception e) { + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + System.out.println("Post signing request"); + logger.info("Post signing request"); + + String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); + PdfAsHelper.setErrorURL(request, response, errorUrl); + + try { + byte[] filecontent = null; + + // checks if the request actually contains upload file + if (!ServletFileUpload.isMultipartContent(request)) { + // No Uploaded data! + if (PdfAsParameterExtractor.getPdfUrl(request) != null) { + doGet(request, response); + return; + } else { + throw new PdfAsWebException("No Signature data defined!"); + } + } else { + // configures upload settings + DiskFileItemFactory factory = new DiskFileItemFactory(); + factory.setSizeThreshold(THRESHOLD_SIZE); + factory.setRepository(new File(System + .getProperty("java.io.tmpdir"))); + + ServletFileUpload upload = new ServletFileUpload(factory); + upload.setFileSizeMax(MAX_FILE_SIZE); + upload.setSizeMax(MAX_REQUEST_SIZE); + + // constructs the directory path to store upload file + String uploadPath = getServletContext().getRealPath("") + + File.separator + UPLOAD_DIRECTORY; + // creates the directory if it does not exist + File uploadDir = new File(uploadPath); + if (!uploadDir.exists()) { + uploadDir.mkdir(); + } + + List formItems = upload.parseRequest(request); + logger.debug(formItems.size() + " Items in form data"); + if (formItems.size() < 1) { + // No Uploaded data! + // Try do get + // No Uploaded data! + if (PdfAsParameterExtractor.getPdfUrl(request) != null) { + doGet(request, response); + return; + } else { + throw new PdfAsWebException( + "No Signature data defined!"); + } + } else { + for(int i = 0; i < formItems.size(); i++) { + Object obj = formItems.get(i); + if(obj instanceof FileItem) { + FileItem item = (FileItem) obj; + if(item.getFieldName().equals(UPLOAD_PDF_DATA)) { + filecontent = item.get(); + logger.debug("Found pdf Data!"); + } else { + request.setAttribute(item.getFieldName(), item.getString()); + logger.debug("Setting " + item.getFieldName() + " = " + item.getString()); + } + } else { + logger.info(obj.getClass().getName() + " - " + obj.toString()); + } + } + } + } + + if(filecontent == null) { + if (PdfAsParameterExtractor.getPdfUrl(request) != null) { + filecontent = RemotePDFFetcher.fetchPdfFile(PdfAsParameterExtractor.getPdfUrl(request)); + } + } + + if(filecontent == null) { + throw new PdfAsException("No Signature data available"); + } + + doSignature(request, response, filecontent); + } catch (Exception e) { + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } + + protected void doSignature(HttpServletRequest request, + HttpServletResponse response, byte[] pdfData) throws Exception { + // Get Connector + String connector = PdfAsParameterExtractor.getConnector(request); + + String invokeUrl = PdfAsParameterExtractor.getInvokeURL(request); + PdfAsHelper.setInvokeURL(request, response, invokeUrl); + + String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); + PdfAsHelper.setErrorURL(request, response, errorUrl); + + logger.debug("Starting signature creation with: " + connector); + + IPlainSigner signer; + if (connector.equals("bku") || connector.equals("onlinebku") || connector.equals("mobilebku")) { + // start asynchronous signature creation + PdfAsHelper.startSignature(request, response, getServletContext(), pdfData); + } else if (connector.equals("jks") || connector.equals("moa")) { + // start synchronous siganture creation + byte[] pdfSignedData = PdfAsHelper.synchornousSignature(request, + response, pdfData); + PdfAsHelper.setSignedPdf(request, response, pdfSignedData); + PdfAsHelper.gotoProvidePdf(getServletContext(), request, response); + return; + } else { + throw new PdfAsWebException("Invalid connector (bku | moa | jks)"); + } + + } + +} 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 new file mode 100644 index 00000000..6ce0e1c9 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java @@ -0,0 +1,62 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; + +/** + * Servlet implementation class PDFData + */ +public class PDFData extends HttpServlet { + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public PDFData() { + super(); + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.process(request, response); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.process(request, response); + } + + protected void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + byte[] signedData = PdfAsHelper.getSignedPdf(request, response); + + if (signedData != null) { + response.setContentType("application/pdf"); + OutputStream os = response.getOutputStream(); + os.write(signedData); + os.close(); + + // When data is collected destroy session! + request.getSession().invalidate(); + } else { + PdfAsHelper.setSessionException(request, response, + "No signed pdf document available.", null); + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java index 26f42840..e1387fce 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java @@ -1,37 +1,84 @@ package at.gv.egiz.pdfas.web.servlets; import java.io.IOException; +import java.io.PrintWriter; + import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; + /** * Servlet implementation class ProvidePDF */ public class ProvidePDFServlet extends HttpServlet { private static final long serialVersionUID = 1L; - - /** - * @see HttpServlet#HttpServlet() - */ - public ProvidePDFServlet() { - super(); - // TODO Auto-generated constructor stub - } /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + * @see HttpServlet#HttpServlet() + */ + public ProvidePDFServlet() { + super(); + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) */ - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // TODO Auto-generated method stub + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.process(request, response); } /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) */ - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // TODO Auto-generated method stub + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.process(request, response); } + protected void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + String invokeURL = PdfAsHelper.getInvokeURL(request, response); + + if (invokeURL == null) { + // Deliver to Browser directly! + response.setContentType("text/html"); + PrintWriter pw = response.getWriter(); + pw.write("PDF ready @: here"); + pw.close(); + + } else { + // Redirect Browser + String template = PdfAsHelper.getInvokeRedirectTemplateSL(); + template = template.replace("##INVOKE_URL##", invokeURL); + + byte[] signedData = PdfAsHelper.getSignedPdf(request, response); + if (signedData != null) { + template = template.replace("##PDFLENGTH##", + String.valueOf(signedData.length)); + } else { + throw new PdfAsException("No Signature data available"); + } + + template = template.replace("##PDFURL##", + PdfAsHelper.generatePdfURL(request, response)); + response.setContentType("text/html"); + response.getWriter().write(template); + response.getWriter().close(); + } + } catch (Exception e) { + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java deleted file mode 100644 index b0c9a56e..00000000 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java +++ /dev/null @@ -1,102 +0,0 @@ -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; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.fileupload.servlet.ServletFileUpload; - -import at.gv.egiz.pdfas.web.helper.PdfAsHelper; - -/** - * Servlet implementation class Sign - */ -public class SignServlet extends HttpServlet { - - private static final long serialVersionUID = 1L; - - private static final String UPLOAD_DIRECTORY = "upload"; - private static final int THRESHOLD_SIZE = 1024 * 1024 * 3; // 3MB - private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB - private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB - - /** - * Default constructor. - */ - public SignServlet() { - // TODO Auto-generated constructor stub - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - try { - doParameters(request, response); - } catch (Exception e) { - e.printStackTrace(); - } - } - - protected void doParameters(HttpServletRequest request, - HttpServletResponse response) throws Exception { - // checks if the request actually contains upload file - if (!ServletFileUpload.isMultipartContent(request)) { - PrintWriter writer = response.getWriter(); - writer.println("Request does not contain upload data"); - writer.flush(); - return; - } - - // configures upload settings - DiskFileItemFactory factory = new DiskFileItemFactory(); - factory.setSizeThreshold(THRESHOLD_SIZE); - factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); - - ServletFileUpload upload = new ServletFileUpload(factory); - upload.setFileSizeMax(MAX_FILE_SIZE); - upload.setSizeMax(MAX_REQUEST_SIZE); - - // constructs the directory path to store upload file - String uploadPath = getServletContext().getRealPath("") - + File.separator + UPLOAD_DIRECTORY; - // creates the directory if it does not exist - File uploadDir = new File(uploadPath); - if (!uploadDir.exists()) { - uploadDir.mkdir(); - } - - List formItems = upload.parseRequest(request); - byte[] filecontent = null; - if(formItems.size() != 1) { - // TODO: no file uploaded! - } else { - FileItem item = (FileItem) formItems.get(0); - filecontent = item.get(); - } - - doSignature(request, response, filecontent); - } - - protected void doSignature(HttpServletRequest request, - HttpServletResponse response, byte[] pdfData) { - try { - // TODO: read Parameters ... - PdfAsHelper.startSignature(request, response, pdfData); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - -} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/TestServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/TestServlet.java new file mode 100644 index 00000000..7e5ae044 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/TestServlet.java @@ -0,0 +1,43 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; + +/** + * Servlet implementation class TestServlet + */ +public class TestServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public TestServlet() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + PrintWriter pw = response.getWriter(); + pw.write(PdfAsHelper.generateDataURL(request, response)); + pw.close(); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // TODO Auto-generated method stub + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java index 119bd2cb..4418c30b 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java @@ -26,7 +26,6 @@ public class VerifyServlet extends HttpServlet { */ public VerifyServlet() { super(); - // TODO Auto-generated constructor stub } /** diff --git a/pdf-as-web/src/main/resources/template_error_redirect.html b/pdf-as-web/src/main/resources/template_error_redirect.html new file mode 100644 index 00000000..dd3f9d46 --- /dev/null +++ b/pdf-as-web/src/main/resources/template_error_redirect.html @@ -0,0 +1,56 @@ + + + + + + + + + +
+
+
+
+ +
+
+
+
+ + + diff --git a/pdf-as-web/src/main/resources/template_invoke_redirect.html b/pdf-as-web/src/main/resources/template_invoke_redirect.html new file mode 100644 index 00000000..0f98ffbb --- /dev/null +++ b/pdf-as-web/src/main/resources/template_invoke_redirect.html @@ -0,0 +1,56 @@ + + + + + + + + + +
+
+
+
+ + + +
+
+
+
+ + + diff --git a/pdf-as-web/src/main/webapp/WEB-INF/decorators.xml b/pdf-as-web/src/main/webapp/WEB-INF/decorators.xml new file mode 100644 index 00000000..6a6ed0a0 --- /dev/null +++ b/pdf-as-web/src/main/webapp/WEB-INF/decorators.xml @@ -0,0 +1,13 @@ + + + + /assets/* + + + + /* + /Sign + /ProvidePDF + /ErrorPage + + \ No newline at end of file diff --git a/pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp b/pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp new file mode 100644 index 00000000..1179d48c --- /dev/null +++ b/pdf-as-web/src/main/webapp/WEB-INF/decorators/default_layout.jsp @@ -0,0 +1,41 @@ + +<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" + prefix="decorator"%> +<%@page contentType="text/html; charset=UTF-8"%> + + + + + + + + + + <decorator:title></decorator:title> + + + + + + + +
+
+

PDF-Signatur

+
+ +
+
+ +
+
+ + + +
+ + + \ No newline at end of file diff --git a/pdf-as-web/src/main/webapp/WEB-INF/sitemesh.xml b/pdf-as-web/src/main/webapp/WEB-INF/sitemesh.xml new file mode 100644 index 00000000..d8dfb3c9 --- /dev/null +++ b/pdf-as-web/src/main/webapp/WEB-INF/sitemesh.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pdf-as-web/src/main/webapp/WEB-INF/web.xml b/pdf-as-web/src/main/webapp/WEB-INF/web.xml index 44298afe..81fa6dad 100644 --- a/pdf-as-web/src/main/webapp/WEB-INF/web.xml +++ b/pdf-as-web/src/main/webapp/WEB-INF/web.xml @@ -9,36 +9,32 @@ PDF-AS-WEB Application + + ExceptionCatchFilter + ExceptionCatchFilter + + at.gv.egiz.pdfas.web.filter.ExceptionCatchFilter + + + sitemesh + com.opensymphony.sitemesh.webapp.SiteMeshFilter + - - - - + + sitemesh + /* + + + ExceptionCatchFilter + /* + SignServlet The Sign Servlet allows Users to Sign PDF Documents ... - at.gv.egiz.pdfas.web.servlets.SignServlet + at.gv.egiz.pdfas.web.servlets.ExternSignServlet 5 @@ -59,6 +55,24 @@ at.gv.egiz.pdfas.web.servlets.VerifyServlet + + PDFData + PDFData + + at.gv.egiz.pdfas.web.servlets.PDFData + + + ErrorPage + ErrorPage + + at.gv.egiz.pdfas.web.servlets.ErrorPage + + + TestServlet + TestServlet + + at.gv.egiz.pdfas.web.servlets.TestServlet +