diff options
author | Thomas <> | 2023-01-11 23:23:30 +0100 |
---|---|---|
committer | Thomas <> | 2023-01-11 23:23:30 +0100 |
commit | 42e68c8f3e53b34663d2fe9c434b0b034ff9ddf0 (patch) | |
tree | de9aceb59655ff02fcbc4100f07fe33d035f34f1 /pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets | |
parent | 989f7685e730255a08c32e7a10c090f2ffc22d26 (diff) | |
download | pdf-as-4-42e68c8f3e53b34663d2fe9c434b0b034ff9ddf0.tar.gz pdf-as-4-42e68c8f3e53b34663d2fe9c434b0b034ff9ddf0.tar.bz2 pdf-as-4-42e68c8f3e53b34663d2fe9c434b0b034ff9ddf0.zip |
feat(web): add bulk-light functionality into PDF-AS-Web
Diffstat (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets')
6 files changed, 517 insertions, 295 deletions
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 674d3351..898e44e2 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 @@ -23,6 +23,25 @@ ******************************************************************************/ package at.gv.egiz.pdfas.web.servlets; +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +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.api.processing.CoreSignParams; +import at.gv.egiz.pdfas.api.processing.DocumentToSign; +import at.gv.egiz.pdfas.api.processing.PdfasSignRequest; +import at.gv.egiz.pdfas.api.processing.PdfasSignResponse; +import at.gv.egiz.pdfas.api.ws.PDFASSignParameters.Connector; import at.gv.egiz.pdfas.common.exceptions.PDFASError; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsValidationException; @@ -43,24 +62,12 @@ import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status; import at.gv.egiz.pdfas.web.stats.StatisticFrontend; -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 javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; +import lombok.extern.slf4j.Slf4j; /** * Servlet implementation class Sign */ +@Slf4j public class ExternSignServlet extends HttpServlet { private static final long serialVersionUID = 1L; @@ -69,9 +76,6 @@ public class ExternSignServlet extends HttpServlet { private static final String UPLOAD_PDF_DATA = "pdf-file"; private static final String UPLOAD_DIRECTORY = "upload"; - - private static final Logger logger = LoggerFactory - .getLogger(ExternSignServlet.class); /** * Default constructor. @@ -81,7 +85,7 @@ public class ExternSignServlet extends HttpServlet { String webconfig = System.getProperty(PDF_AS_WEB_CONF); if(webconfig == null) { - logger.error("No web configuration provided! Please specify: " + PDF_AS_WEB_CONF); + log.error("No web configuration provided! Please specify: " + PDF_AS_WEB_CONF); throw new RuntimeException("No web configuration provided! Please specify: " + PDF_AS_WEB_CONF); } @@ -92,7 +96,7 @@ public class ExternSignServlet extends HttpServlet { PdfAsFactory.validateConfiguration((ISettings)PdfAsHelper.getPdfAsConfig()); } catch (PdfAsSettingsValidationException e) { // TODO Auto-generated catch block - logger.error(e.getLocalizedMessage(),e.getCause()); + log.error(e.getLocalizedMessage(),e.getCause()); //e.printStackTrace(); } } @@ -100,9 +104,10 @@ public class ExternSignServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - //PdfAsHelper.regenerateSession(request); + // invalidate existing http sessions at first + request.getSession().invalidate(); - logger.debug("Get signing request"); + log.debug("Get signing request"); String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); PdfAsHelper.setErrorURL(request, response, errorUrl); @@ -131,7 +136,7 @@ public class ExternSignServlet extends HttpServlet { byte[] pdfData = RemotePDFFetcher.fetchPdfFile(pdfUrl); doSignature(request, response, pdfData, statisticEvent); } catch (Exception e) { - logger.error("Signature failed", e); + log.error("Signature failed", e); statisticEvent.setStatus(Status.ERROR); statisticEvent.setException(e); if(e instanceof PDFASError) { @@ -154,10 +159,11 @@ public class ExternSignServlet extends HttpServlet { */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - - //PdfAsHelper.regenerateSession(request); - - logger.debug("Post signing request"); + + // invalidate existing http sessions at first + request.getSession().invalidate(); + + log.debug("Post signing request"); String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); PdfAsHelper.setErrorURL(request, response, errorUrl); @@ -202,7 +208,7 @@ public class ExternSignServlet extends HttpServlet { } List<?> formItems = upload.parseRequest(request); - logger.debug(formItems.size() + " Items in form data"); + log.debug(formItems.size() + " Items in form data"); if (formItems.size() < 1) { // No Uploaded data! // Try do get @@ -224,30 +230,30 @@ public class ExternSignServlet extends HttpServlet { try { File f = new File(item.getName()); String name = f.getName(); - logger.debug("Got upload: " + item.getName()); + log.debug("Got upload: " + item.getName()); if(name != null) { if(!(name.endsWith(".pdf") || name.endsWith(".PDF"))) { name += ".pdf"; } - logger.debug("Setting Filename in session: " + name); + log.debug("Setting Filename in session: " + name); PdfAsHelper.setPDFFileName(request, name); } } catch(Throwable e) { - logger.warn("In resolving filename", e); + log.warn("In resolving filename", e); } if(filecontent.length < 10) { filecontent = null; } else { - logger.debug("Found pdf Data! Size: " + filecontent.length); + log.debug("Found pdf Data! Size: " + filecontent.length); } } else { request.setAttribute(item.getFieldName(), item.getString()); - logger.debug("Setting " + item.getFieldName() + " = " + item.getString()); + log.debug("Setting " + item.getFieldName() + " = " + item.getString()); } } else { - logger.debug(obj.getClass().getName() + " - " + obj.toString()); + log.debug(obj.getClass().getName() + " - " + obj.toString()); } } } @@ -282,7 +288,7 @@ public class ExternSignServlet extends HttpServlet { doSignature(request, response, filecontent, statisticEvent); } catch (Exception e) { - logger.error("Signature failed", e); + log.error("Signature failed", e); statisticEvent.setStatus(Status.ERROR); statisticEvent.setException(e); if(e instanceof PDFASError) { @@ -351,24 +357,48 @@ public class ExternSignServlet extends HttpServlet { } } catch(Exception e) { - logger.error(e.getLocalizedMessage()); + log.error(e.getLocalizedMessage()); } String filename = PdfAsParameterExtractor.getFilename(request); if(filename != null) { - logger.debug("Setting Filename in session: " + filename); + log.debug("Setting Filename in session: " + filename); PdfAsHelper.setPDFFileName(request, filename); } String pdfDataHash = DigestHelper.getHexEncodedHash(pdfData); PdfAsHelper.setSignatureDataHash(request, pdfDataHash); - logger.debug("Storing signatures data hash: " + pdfDataHash); + log.debug("Storing signatures data hash: " + pdfDataHash); Map<String, String> dynamicSignatureBlockArguments = PdfAsParameterExtractor.getDynamicSignatureBlockParameters(request); - logger.debug("Starting signature creation with: " + connector); + log.debug("Starting signature creation with: " + connector); + + // prepare internal process data-structure + PdfasSignRequest data = new PdfasSignRequest(); + + CoreSignParams coreParams = new CoreSignParams(); + coreParams.setSignatureBlockParameters(dynamicSignatureBlockArguments); + coreParams.setConnector(Connector.fromString(connector)); + coreParams.setKeyIdentifier(PdfAsParameterExtractor.getKeyIdentifier(request)); + coreParams.setOverrides(PdfAsParameterExtractor.getOverwriteMap(request)); + coreParams.setPreprocessor(PdfAsParameterExtractor.getPreProcessorMap(request)); + coreParams.setInvokeErrorUrl(errorUrl); + coreParams.setInvokeTarget(invokeTarget); + coreParams.setInvokeUrl(invokeUrl); + coreParams.setTransactionId(transactionId); + data.setCoreParams(coreParams); + + DocumentToSign document = new DocumentToSign(); + document.setInputData(pdfData); + document.setPosition(PdfAsHelper.buildPosString(request, response)); + document.setProfile(PdfAsParameterExtractor.getSigType(request)); + document.setQrCodeContent(qrcodeContent); + document.setFileName(PdfAsHelper.getPDFFileName(request)); + data.addDocumentToSign(document); + //IPlainSigner signer; if (connector.equals("bku") || connector.equals("onlinebku") || connector.equals("mobilebku") @@ -397,13 +427,12 @@ public class ExternSignServlet extends HttpServlet { } PdfAsHelper.setStatisticEvent(request, response, statisticEvent); + + // sign document + PdfAsHelper.startSignature(request, response, getServletContext(), connector, data); - - PdfAsHelper.startSignature(request, response, getServletContext(), pdfData, connector, - PdfAsHelper.buildPosString(request, response), transactionId, PdfAsParameterExtractor - .getSigType(request), PdfAsParameterExtractor.getPreProcessorMap(request), - PdfAsParameterExtractor.getOverwriteMap(request), dynamicSignatureBlockArguments); return; + } else if (connector.equals("jks") || connector.equals("moa")) { // start synchronous siganture creation @@ -434,10 +463,13 @@ public class ExternSignServlet extends HttpServlet { } } - byte[] pdfSignedData = PdfAsHelper.synchronousSignature(request, - response, pdfData, dynamicSignatureBlockArguments); - PdfAsHelper.setSignedPdf(request, response, pdfSignedData); + // sign document + PdfasSignResponse pdfSignedData = PdfAsHelper.synchronousServerSignature(data); + // inject response + PdfAsHelper.setPdfSigningResponse(request, pdfSignedData); + + // set statistic entry statisticEvent.setStatus(Status.OK); statisticEvent.setEndNow(); statisticEvent.setTimestampNow(); @@ -446,8 +478,10 @@ public class ExternSignServlet extends HttpServlet { 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/JSONAPIServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java index 641c09e7..d5ef2079 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java @@ -1,7 +1,28 @@ package at.gv.egiz.pdfas.web.servlets; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.api.processing.CoreSignParams; +import at.gv.egiz.pdfas.api.processing.DocumentToSign; +import at.gv.egiz.pdfas.api.processing.PdfasSignRequest; +import at.gv.egiz.pdfas.api.processing.PdfasSignResponse; import at.gv.egiz.pdfas.api.ws.PDFASSignParameters; -import at.gv.egiz.pdfas.api.ws.PDFASSignResponse; +import at.gv.egiz.pdfas.api.ws.PDFASSignParameters.Connector; import at.gv.egiz.pdfas.common.exceptions.PDFASError; import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; @@ -13,27 +34,13 @@ import at.gv.egiz.pdfas.web.helper.JSONStartResponse; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.pdfas.web.stats.StatisticEvent; import at.gv.egiz.pdfas.web.stats.StatisticFrontend; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.IOUtils; -import org.json.JSONArray; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; /** * Created by Andreas Fitzek on 6/23/16. */ public class JSONAPIServlet extends HttpServlet { + private static final long serialVersionUID = -2319338922500393376L; private static final String JSON_PROFILE = "profile"; private static final String JSON_POSITION = "position"; private static final String JSON_CONNECTOR = "connector"; @@ -151,17 +158,39 @@ public class JSONAPIServlet extends HttpServlet { }catch(Exception e){ e.printStackTrace(); } + + + PdfasSignRequest data = new PdfasSignRequest(); + + data.setRequestID(requestID); + + CoreSignParams coreParams = new CoreSignParams(); + coreParams.setSignatureBlockParameters(signatureBlockParametersMap); + coreParams.setConnector(Connector.fromString(connector)); + data.setCoreParams(coreParams); + + DocumentToSign document = new DocumentToSign(); + document.setInputData(inputDocument); + document.setPosition(position); + document.setProfile(profile); + data.addDocumentToSign(document); + + + if (PDFASSignParameters.Connector.MOA.equals(connectorEnum) || PDFASSignParameters.Connector.JKS.equals(connectorEnum)) { // Plain server based signatures!! - PDFASSignResponse pdfasSignResponse = PdfAsHelper.synchronousServerSignature( - inputDocument, parameters, signatureBlockParametersMap); - + + + //TODO: update implementation to support more than one file!!!! + + PdfasSignResponse pdfasSignResponse = PdfAsHelper.synchronousServerSignature(data); + VerifyResult verifyResult = null; List<VerifyResult> verResults = PdfAsHelper .synchronousVerify( - pdfasSignResponse.getSignedPDF(), + pdfasSignResponse.getSignedPdfs().get(0).getOutputData(), -1, VerifyParameter.SignatureVerificationLevel.INTEGRITY_ONLY_VERIFICATION, null); @@ -187,7 +216,7 @@ public class JSONAPIServlet extends HttpServlet { statisticEvent.setLogged(true); } - jsonResponse.put(JSON_OUTPUT, Base64.encodeBase64String(pdfasSignResponse.getSignedPDF())); + jsonResponse.put(JSON_OUTPUT, Base64.encodeBase64String(pdfasSignResponse.getSignedPdfs().get(0).getOutputData())); jsonResponse.put(JSON_OUTPUT_SIG, verifyResult.getValueCheckCode().getCode()); jsonResponse.put(JSON_OUTPUT_CER, verifyResult.getCertificateCheck().getCode()); @@ -234,13 +263,8 @@ public class JSONAPIServlet extends HttpServlet { } } - PdfAsHelper.startSignatureJson(request, response, getServletContext(), - inputDocument, connectorEnum.toString(), - position, - null, - profile, null, - null); + connectorEnum.toString(), data); JSONStartResponse jsonStartResponse = PdfAsHelper.startJsonProcess(request, response, getServletContext()); 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 401d3e68..bf45745d 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 @@ -3,19 +3,19 @@ * 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 @@ -23,147 +23,262 @@ ******************************************************************************/ package at.gv.egiz.pdfas.web.servlets; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; 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.config.WebConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import at.gv.egiz.pdfas.api.processing.SignedDocument; import at.gv.egiz.pdfas.api.ws.PDFASVerificationResponse; +import at.gv.egiz.pdfas.web.config.WebConfiguration; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor; import at.gv.egiz.pdfas.web.stats.StatisticEvent; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status; import at.gv.egiz.pdfas.web.stats.StatisticFrontend; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.OutputStream; +import lombok.extern.slf4j.Slf4j; /** * Servlet implementation class PDFData */ +@Slf4j public class PDFData extends HttpServlet { - private static final long serialVersionUID = 1L; - - private static final Logger logger = LoggerFactory.getLogger(PDFData.class); - - /** - * @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); - - StatisticEvent statisticEvent = PdfAsHelper.getStatisticEvent(request, - response); - - String plainPDFDigest = PdfAsParameterExtractor.getOrigDigest(request); - - if (signedData != null) { - - if(WebConfiguration.isKeepSignedDocument()) { - if(PdfAsHelper.isSignedDataExpired(request, response)) { - logger.info("Destroying expired signed data in session"); - request.getSession().invalidate(); - PdfAsHelper.setSessionException(request, response, - "No signed pdf document available.", null); - PdfAsHelper.gotoError(getServletContext(), request, response); - return; - } - } - - if (plainPDFDigest != null) { - String signatureDataHash = PdfAsHelper - .getSignatureDataHash(request); - if (!plainPDFDigest.equalsIgnoreCase(signatureDataHash)) { - logger.warn("Digest Hash mismatch!"); - logger.warn("Requested digest: " + plainPDFDigest); - logger.warn("Saved digest: " + signatureDataHash); - - PdfAsHelper.setSessionException(request, response, - "Signature Data digest do not match!", null); - PdfAsHelper.gotoError(getServletContext(), request, - response); - return; - } - } - response.setHeader("Content-Disposition", "inline;filename=" - + PdfAsHelper.getPDFFileName(request)); - String pdfCert = PdfAsHelper.getSignerCertificate(request); - if (pdfCert != null) { - response.setHeader("Signer-Certificate", pdfCert); - } - - if (statisticEvent != null) { - if (!statisticEvent.isLogged()) { - statisticEvent.setStatus(Status.OK); - - statisticEvent.setEndNow(); - statisticEvent.setTimestampNow(); - StatisticFrontend.getInstance().storeEvent(statisticEvent); - statisticEvent.setLogged(true); - } - } - - PDFASVerificationResponse resp = PdfAsHelper - .getPDFASVerificationResponse(request); - if (resp != null) { - response.setHeader("CertificateCheckCode", - String.valueOf(resp.getCertificateCode())); - response.setHeader("ValueCheckCode", - String.valueOf(resp.getValueCode())); - } - response.setContentType("application/pdf"); - OutputStream os = response.getOutputStream(); - os.write(signedData); - os.close(); - - // When data is collected destroy session! - if(!WebConfiguration.isKeepSignedDocument()) { - logger.debug("Destroying signed data in session : {}", request.getSession().getId()); - request.getSession().invalidate(); - } else { - logger.debug("Keeping signed data in session : {}", request.getSession().getId()); - } - } else { - logger.info("No signed pdf document available."); - PdfAsHelper.setSessionException(request, response, - "No signed pdf document available.", null); - PdfAsHelper.gotoError(getServletContext(), request, response); - } - } + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public PDFData() { + super(); + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.process(request, response); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.process(request, response); + } + + protected void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + if (PdfAsHelper.getPdfSigningResponse(request).getSignedPdfs().isEmpty()) { + log.info("No signed pdf document available."); + PdfAsHelper.setSessionException(request, response, + "No signed pdf document available.", null); + PdfAsHelper.gotoError(getServletContext(), request, response); + + } else if (PdfAsHelper.getPdfSigningResponse(request).getSignedPdfs().size() == 1) { + buildSingleFileResult(request, response, + PdfAsHelper.getPdfSigningResponse(request).getSignedPdfs().get(0)); + + } else { + buildMultipleFileResult(request, response, PdfAsHelper.getPdfSigningResponse(request).getSignedPdfs()); + + } + + } + + private void buildMultipleFileResult(HttpServletRequest request, HttpServletResponse response, + List<SignedDocument> signedPdfs) throws IOException, ServletException { + + final StatisticEvent statisticEvent = PdfAsHelper.getStatisticEvent(request,response); + + // check if some files are expired + if (WebConfiguration.isKeepSignedDocument()) { + if (signedPdfs.stream() + .filter(el -> isSignedDataExpired(el)) + .findFirst().isPresent()) { + log.info("Destroying expired signed data in session"); + request.getSession().invalidate(); + PdfAsHelper.setSessionException(request, response, + "No signed pdf document available.", null); + PdfAsHelper.gotoError(getServletContext(), request, response); + return; + } + } + + // package files into ZIP + byte[] zippedFiles = packageSignedPdfsIntoZip(signedPdfs); + + // write static log + if (statisticEvent != null) { + if (!statisticEvent.isLogged()) { + statisticEvent.setStatus(Status.OK); + statisticEvent.setEndNow(); + statisticEvent.setTimestampNow(); + StatisticFrontend.getInstance().storeEvent(statisticEvent); + statisticEvent.setLogged(true); + } + } + + // build response + response.setHeader("Content-Disposition", "inline;filename=multiple_documents.zip"); + response.setContentType("application/zip"); + final OutputStream os = response.getOutputStream(); + + os.write(zippedFiles); + os.close(); + + // When data is collected destroy session! + if (!WebConfiguration.isKeepSignedDocument()) { + log.debug("Destroying signed data in session : {}", request.getSession().getId()); + request.getSession().invalidate(); + } else { + log.debug("Keeping signed data in session : {}", request.getSession().getId()); + } + + } + + private byte[] packageSignedPdfsIntoZip(List<SignedDocument> signedPdfs) throws IOException { + ByteArrayOutputStream baOut = new ByteArrayOutputStream(); + + try { + ZipOutputStream zos = new ZipOutputStream(baOut); + zos.setLevel(Deflater.BEST_COMPRESSION); + zos.setMethod(Deflater.DEFLATED); + + Iterator<SignedDocument> it = signedPdfs.iterator(); + while (it.hasNext()) { + SignedDocument entry = it.next(); + if (entry.getOutputData() != null) { + log.debug("Compressing file {}.", entry.getFileName()); + ZipEntry oze = new ZipEntry(entry.getFileName()); + zos.putNextEntry(oze); + zos.write(entry.getOutputData()); + zos.closeEntry(); + + } else { + log.warn("Ignore entry with name: {} because it's empty", entry.getFileName()); + + } + } + zos.closeEntry(); + zos.finish(); + zos.close(); + + return baOut.toByteArray(); + + } finally { + baOut.close(); + + } + + } + + private void buildSingleFileResult(HttpServletRequest request, HttpServletResponse response, SignedDocument signedFile) throws ServletException, IOException { + final byte[] signedData = signedFile.getOutputData(); + + final StatisticEvent statisticEvent = PdfAsHelper.getStatisticEvent(request, + response); + + final String plainPDFDigest = PdfAsParameterExtractor.getOrigDigest(request); + + if (signedData != null) { + + if (WebConfiguration.isKeepSignedDocument()) { + if (isSignedDataExpired(signedFile)) { + log.info("Destroying expired signed data in session"); + request.getSession().invalidate(); + PdfAsHelper.setSessionException(request, response, + "No signed pdf document available.", null); + PdfAsHelper.gotoError(getServletContext(), request, response); + return; + } + } + + if (plainPDFDigest != null) { + final String signatureDataHash = PdfAsHelper + .getSignatureDataHash(request); + if (!plainPDFDigest.equalsIgnoreCase(signatureDataHash)) { + log.warn("Digest Hash mismatch!"); + log.warn("Requested digest: " + plainPDFDigest); + log.warn("Saved digest: " + signatureDataHash); + + PdfAsHelper.setSessionException(request, response, + "Signature Data digest do not match!", null); + PdfAsHelper.gotoError(getServletContext(), request, + response); + return; + } + } + response.setHeader("Content-Disposition", "inline;filename=" + + PdfAsHelper.getPDFFileName(request)); + final String pdfCert = signedFile.getSignerCertificate(); + if (pdfCert != null) { + response.setHeader("Signer-Certificate", pdfCert); + } + + if (statisticEvent != null) { + if (!statisticEvent.isLogged()) { + statisticEvent.setStatus(Status.OK); + + statisticEvent.setEndNow(); + statisticEvent.setTimestampNow(); + StatisticFrontend.getInstance().storeEvent(statisticEvent); + statisticEvent.setLogged(true); + } + } + + final PDFASVerificationResponse resp = signedFile.getVerificationResponse(); + if (resp != null) { + response.setHeader("CertificateCheckCode", + String.valueOf(resp.getCertificateCode())); + response.setHeader("ValueCheckCode", + String.valueOf(resp.getValueCode())); + } + response.setContentType("application/pdf"); + final OutputStream os = response.getOutputStream(); + os.write(signedData); + os.close(); + + // When data is collected destroy session! + if (!WebConfiguration.isKeepSignedDocument()) { + log.debug("Destroying signed data in session : {}", request.getSession().getId()); + request.getSession().invalidate(); + } else { + log.debug("Keeping signed data in session : {}", request.getSession().getId()); + } + } else { + log.info("No signed pdf document available."); + PdfAsHelper.setSessionException(request, response, + "No signed pdf document available.", null); + PdfAsHelper.gotoError(getServletContext(), request, response); + + } + + } + + private static boolean isSignedDataExpired(SignedDocument signedFile) { + final long now = System.currentTimeMillis(); + final long validUntil = signedFile.getSigningTimestamp() + 300000; + + log.debug("Checking signed data valid until {} now is {}", validUntil, now); + return validUntil < now; + + } + } 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 7262586d..47469eb2 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 @@ -26,32 +26,31 @@ package at.gv.egiz.pdfas.web.servlets; import java.io.IOException; import java.net.URL; import java.net.URLEncoder; +import java.util.List; import javax.servlet.RequestDispatcher; 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 org.codehaus.stax2.io.EscapingWriterFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import at.gv.egiz.pdfas.api.processing.SignedDocument; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.web.config.WebConfiguration; +import at.gv.egiz.pdfas.web.exception.PdfAsStoreException; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.pdfas.web.helper.UrlParameterExtractor; +import at.gv.egiz.pdfas.web.store.RequestStore; +import lombok.extern.slf4j.Slf4j; /** * Servlet implementation class ProvidePDF */ +@Slf4j public class ProvidePDFServlet extends HttpServlet { private static final long serialVersionUID = 1L; - - private static final Logger logger = LoggerFactory - .getLogger(ProvidePDFServlet.class); private static final String PDF_DATA_URL = "##PDFDATAURL##"; @@ -88,7 +87,7 @@ public class ProvidePDFServlet extends HttpServlet { if (invokeURL == null || !WebConfiguration.isProvidePdfURLinWhitelist(invokeURL)) { if(invokeURL != null) { - logger.warn(invokeURL + " is not allowed by whitelist"); + log.warn(invokeURL + " is not allowed by whitelist"); } if (PdfAsHelper.getResponseMode(request, response).equals(PdfAsHelper.PDF_RESPONSE_MODES.htmlform)) { @@ -100,60 +99,126 @@ public class ProvidePDFServlet extends HttpServlet { response.getWriter().close(); } else { - logger.debug("PDFResult directMode: Forward to PDFData Servlet directly"); + log.debug("PDFResult directMode: Forward to PDFData Servlet directly"); RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/PDFData"); dispatcher.forward(request, response); } - } else { - // Redirect Browser - String template = PdfAsHelper.getInvokeRedirectTemplateSL(); - - URL url = new URL(invokeURL); - int p=url.getPort(); - //no port, but http or https --> use default port - if((url.getProtocol().equalsIgnoreCase("https") || url.getProtocol().equalsIgnoreCase("http")) && p == -1){ - p=url.getDefaultPort(); - } - String invokeUrlProcessed = url.getProtocol() + "://" + // "http" + ":// - url.getHost() + // "myhost" - ":" + // ":" - p + // "8080" - url.getPath(); - - template = template.replace("##INVOKE_URL##", invokeUrlProcessed); - - String extraParams = UrlParameterExtractor.buildParameterFormString(url); - template = template.replace("##ADD_PARAMS##", extraParams); - - 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"); - } - - String target = PdfAsHelper.getInvokeTarget(request, response); - - if(target == null) { - target = "_self"; - } - - template = template.replace("##TARGET##", StringEscapeUtils.escapeHtml4(target)); - - template = template.replace("##PDFURL##", - URLEncoder.encode(PdfAsHelper.generatePdfURL(request, response), - "UTF-8")); - response.setContentType("text/html"); - response.getWriter().write(template); - response.getWriter().close(); + } else { + List<SignedDocument> signedPdfs = PdfAsHelper.getPdfSigningResponse(request).getSignedPdfs(); + + if (signedPdfs.isEmpty()) { + log.info("No signed pdf document available."); + PdfAsHelper.setSessionException(request, response, + "No signed pdf document available.", null); + PdfAsHelper.gotoError(getServletContext(), request, response); + + } else if (signedPdfs.size() == 1) { + provideSingleFile(request, response, signedPdfs.get(0), invokeURL); + + + } else { + provideTokenToGetMultipleFiles(request, response, invokeURL); + + } } + } catch (Exception e) { - PdfAsHelper.setSessionException(request, response, e.getMessage(), - e); + PdfAsHelper.setSessionException(request, response, e.getMessage(), e); PdfAsHelper.gotoError(getServletContext(), request, response); + } } + + private void provideTokenToGetMultipleFiles(HttpServletRequest request, HttpServletResponse response, + String invokeURL) throws IOException, PdfAsStoreException { + + String template = PdfAsHelper.getInvokeRedirectTemplateMoreFiles(); + + URL url = new URL(invokeURL); + int p=url.getPort(); + //no port, but http or https --> use default port + if((url.getProtocol().equalsIgnoreCase("https") || url.getProtocol().equalsIgnoreCase("http")) && p == -1){ + p=url.getDefaultPort(); + } + String invokeUrlProcessed = url.getProtocol() + "://" + // "http" + ":// + url.getHost() + // "myhost" + ":" + // ":" + p + // "8080" + url.getPath(); + + template = template.replace("##INVOKE_URL##", invokeUrlProcessed); + + String extraParams = UrlParameterExtractor.buildParameterFormString(url); + template = template.replace("##ADD_PARAMS##", extraParams); + + + String target = PdfAsHelper.getInvokeTarget(request, response); + if(target == null) { + target = "_self"; + + } + template = template.replace("##TARGET##", StringEscapeUtils.escapeHtml4(target)); + + String accessToken = RequestStore.getInstance().createNewResponseEntry(PdfAsHelper.getPdfSigningResponse(request)); + template = template.replace("##RESPONSETOKEN##", accessToken); + + response.setContentType("text/html"); + response.getWriter().write(template); + response.getWriter().close(); + + + + + + } + + private void provideSingleFile(HttpServletRequest request, HttpServletResponse response, SignedDocument signedDocument, String invokeURL) throws IOException, PdfAsException { + // Redirect Browser + String template = PdfAsHelper.getInvokeRedirectTemplateSL(); + + URL url = new URL(invokeURL); + int p=url.getPort(); + //no port, but http or https --> use default port + if((url.getProtocol().equalsIgnoreCase("https") || url.getProtocol().equalsIgnoreCase("http")) && p == -1){ + p=url.getDefaultPort(); + } + String invokeUrlProcessed = url.getProtocol() + "://" + // "http" + ":// + url.getHost() + // "myhost" + ":" + // ":" + p + // "8080" + url.getPath(); + + template = template.replace("##INVOKE_URL##", invokeUrlProcessed); + + String extraParams = UrlParameterExtractor.buildParameterFormString(url); + template = template.replace("##ADD_PARAMS##", extraParams); + + + //TODO: implement use-case if result contains more than one file + byte[] signedData = PdfAsHelper.getPdfSigningResponse(request).getSignedPdfs().get(0).getOutputData(); + if (signedData != null) { + template = template.replace("##PDFLENGTH##", + String.valueOf(signedData.length)); + } else { + throw new PdfAsException("No Signature data available"); + } + + String target = PdfAsHelper.getInvokeTarget(request, response); + + if(target == null) { + target = "_self"; + } + + template = template.replace("##TARGET##", StringEscapeUtils.escapeHtml4(target)); + + template = template.replace("##PDFURL##", + URLEncoder.encode(PdfAsHelper.generatePdfURL(request, response), + "UTF-8")); + response.setContentType("text/html"); + response.getWriter().write(template); + response.getWriter().close(); + + } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java index 664dd9b3..d7a3d3c6 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java @@ -24,18 +24,14 @@ package at.gv.egiz.pdfas.web.servlets; import java.io.IOException; -import java.util.Map; import javax.servlet.ServletException; 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.api.processing.PdfasSignRequest; import at.gv.egiz.pdfas.api.ws.PDFASSignParameters.Connector; -import at.gv.egiz.pdfas.api.ws.PDFASSignRequest; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel; import at.gv.egiz.pdfas.web.config.WebConfiguration; @@ -45,15 +41,14 @@ import at.gv.egiz.pdfas.web.helper.DigestHelper; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.pdfas.web.stats.StatisticEvent; import at.gv.egiz.pdfas.web.store.RequestStore; +import lombok.extern.slf4j.Slf4j; +@Slf4j public class UIEntryPointServlet extends HttpServlet { private static final long serialVersionUID = 1L; public static final String REQUEST_ID_PARAM = "reqId"; - private static final Logger logger = LoggerFactory - .getLogger(UIEntryPointServlet.class); - public UIEntryPointServlet() { } @@ -72,13 +67,16 @@ public class UIEntryPointServlet extends HttpServlet { protected void doProcess(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { + // invalidate existing http sessions at first + req.getSession().invalidate(); + String storeId = req.getParameter(REQUEST_ID_PARAM); if (storeId == null) { throw new PdfAsStoreException("Wrong Parameters"); } - PDFASSignRequest pdfAsRequest = RequestStore.getInstance() + PdfasSignRequest pdfAsRequest = RequestStore.getInstance() .fetchStoreEntry(storeId); if (pdfAsRequest == null) { @@ -91,16 +89,15 @@ public class UIEntryPointServlet extends HttpServlet { PdfAsHelper.setStatisticEvent(req, resp, statisticEvent); - Connector connector = pdfAsRequest.getParameters().getConnector(); + Connector connector = pdfAsRequest.getCoreParams().getConnector(); - String invokeUrl = pdfAsRequest.getParameters().getInvokeURL(); + String invokeUrl = pdfAsRequest.getCoreParams().getInvokeUrl(); PdfAsHelper.setInvokeURL(req, resp, invokeUrl); - String invokeTarget = pdfAsRequest.getParameters() - .getInvokeTarget(); + String invokeTarget = pdfAsRequest.getCoreParams().getInvokeTarget(); PdfAsHelper.setInvokeTarget(req, resp, invokeTarget); - String errorUrl = pdfAsRequest.getParameters().getInvokeErrorURL(); + String errorUrl = pdfAsRequest.getCoreParams().getInvokeErrorUrl(); PdfAsHelper.setErrorURL(req, resp, errorUrl); SignatureVerificationLevel lvl = SignatureVerificationLevel.INTEGRITY_ONLY_VERIFICATION; @@ -116,17 +113,16 @@ public class UIEntryPointServlet extends HttpServlet { } PdfAsHelper.setVerificationLevel(req, lvl); - if (pdfAsRequest.getInputData() == null) { + if (pdfAsRequest.hasNext() && pdfAsRequest.getInput().get(0).getInputData() == null) { throw new PdfAsException("No Signature data available"); } - String pdfDataHash = DigestHelper.getHexEncodedHash(pdfAsRequest - .getInputData()); + String pdfDataHash = DigestHelper.getHexEncodedHash(pdfAsRequest.getInput().get(0).getInputData()); PdfAsHelper.setSignatureDataHash(req, pdfDataHash); - logger.debug("Storing signatures data hash: " + pdfDataHash); + log.debug("Storing signatures data hash: " + pdfDataHash); - logger.debug("Starting signature creation with: " + connector); + log.debug("Starting signature creation with: " + connector); // IPlainSigner signer; if (connector.equals(Connector.BKU) @@ -163,26 +159,8 @@ public class UIEntryPointServlet extends HttpServlet { } } - Map<String, String> map = null; - if (pdfAsRequest.getParameters().getPreprocessor() != null) { - map = pdfAsRequest.getParameters().getPreprocessor() - .getMap(); - } + PdfAsHelper.startSignature(req, resp, getServletContext(), connector.toString(), pdfAsRequest); - Map<String, String> overwrite = null; - if (pdfAsRequest.getParameters().getOverrides() != null) { - overwrite = pdfAsRequest.getParameters().getOverrides() - .getMap(); - } - //TODO alex - Map<String, String> dynamicSignatureBlockArguments = pdfAsRequest.getSignatureBlockParameters(); - - PdfAsHelper.startSignature(req, resp, getServletContext(), - pdfAsRequest.getInputData(), connector.toString(), - pdfAsRequest.getParameters().getPosition(), - pdfAsRequest.getParameters().getTransactionId(), - pdfAsRequest.getParameters().getProfile(), map, - overwrite, dynamicSignatureBlockArguments); } else { throw new PdfAsWebException("Invalid connector (" + Connector.BKU + " | " + Connector.ONLINEBKU + " | " @@ -190,7 +168,7 @@ public class UIEntryPointServlet extends HttpServlet { } } catch (Throwable e) { - logger.warn("Failed to process Request: ", e); + log.warn("Failed to process Request: ", e); PdfAsHelper.setSessionException(req, resp, e.getMessage(), e); PdfAsHelper.gotoError(getServletContext(), req, resp); } 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 bc5f2e2d..003a4a73 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 @@ -50,10 +50,10 @@ import at.gv.egiz.pdfas.web.helper.RemotePDFFetcher; import at.gv.egiz.pdfas.web.helper.VerifyEncoder; import at.gv.egiz.pdfas.web.helper.VerifyResultEncoder; import at.gv.egiz.pdfas.web.stats.StatisticEvent; -import at.gv.egiz.pdfas.web.stats.StatisticFrontend; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status; +import at.gv.egiz.pdfas.web.stats.StatisticFrontend; /** * Servlet implementation class VerifyServlet @@ -84,6 +84,9 @@ public class VerifyServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // invalidate existing http sessions at first + request.getSession().invalidate(); + logger.info("Get verify request"); String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); @@ -138,6 +141,9 @@ public class VerifyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // invalidate existing http sessions at first + request.getSession().invalidate(); + logger.info("Post verify request"); String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); |