diff options
author | emusic <emina.music@egiz.gv.at> | 2018-11-22 13:14:28 +0100 |
---|---|---|
committer | emusic <emina.music@egiz.gv.at> | 2018-11-22 13:14:28 +0100 |
commit | f76f559c8c1437a152a4f51b441e4cebe25430f1 (patch) | |
tree | 8930f89863cdc7e564f6a97ac777c133384a8730 /pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets | |
parent | cd6ff625d48a63e024b05ed1a253be3551e41599 (diff) | |
parent | c87c82009fb07e285d6c9acfd4686efc2cbf21c9 (diff) | |
download | pdf-as-4-f76f559c8c1437a152a4f51b441e4cebe25430f1.tar.gz pdf-as-4-f76f559c8c1437a152a4f51b441e4cebe25430f1.tar.bz2 pdf-as-4-f76f559c8c1437a152a4f51b441e4cebe25430f1.zip |
Merge branch 'SL20_development'
# Conflicts:
# build.gradle
# pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/Main.java
# pdf-as-lib/src/configuration/cfg/advancedconfig.properties
# pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java
# pdf-as-lib/src/main/resources/config/config.zip
# pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
# pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java
Diffstat (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets')
7 files changed, 363 insertions, 6 deletions
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 45861953..50c3b063 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 @@ -93,11 +93,11 @@ public class DataURLServlet extends HttpServlet { if(jaxbObject.getValue() instanceof InfoboxReadResponseType) { InfoboxReadResponseType infoboxReadResponseType = (InfoboxReadResponseType)jaxbObject.getValue(); logger.info("Got InfoboxReadResponseType"); - PdfAsHelper.injectCertificate(request, response, infoboxReadResponseType, getServletContext()); + PdfAsHelper.injectCertificate(request, response, PdfAsHelper.getCertificate(infoboxReadResponseType), getServletContext()); } else if(jaxbObject.getValue() instanceof CreateCMSSignatureResponseType) { CreateCMSSignatureResponseType createCMSSignatureResponseType = (CreateCMSSignatureResponseType)jaxbObject.getValue(); logger.info("Got CreateCMSSignatureResponseType"); - PdfAsHelper.injectSignature(request, response, createCMSSignatureResponseType, getServletContext()); + PdfAsHelper.injectSignature(request, response, createCMSSignatureResponseType.getCMSSignature(), getServletContext()); } else if(jaxbObject.getValue() instanceof ErrorResponseType) { ErrorResponseType errorResponseType = (ErrorResponseType)jaxbObject.getValue(); logger.warn("SecurityLayer: " + errorResponseType.getErrorCode() + " " + errorResponseType.getInfo()); 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 3cea5247..1d2ab14e 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 @@ -354,7 +354,8 @@ public class ExternSignServlet extends HttpServlet { logger.debug("Starting signature creation with: " + connector); //IPlainSigner signer; - if (connector.equals("bku") || connector.equals("onlinebku") || connector.equals("mobilebku")) { + if (connector.equals("bku") || connector.equals("onlinebku") || connector.equals("mobilebku") + || connector.equals("sl20")) { // start asynchronous signature creation if(connector.equals("bku")) { @@ -372,6 +373,11 @@ public class ExternSignServlet extends HttpServlet { throw new PdfAsWebException("Invalid connector bku is not supported"); } } + if (connector.equals("sl20")) { + if(WebConfiguration.getSecurityLayer20URL() == null) { + throw new PdfAsWebException("Invalid connector bku is not supported"); + } + } PdfAsHelper.setStatisticEvent(request, response, statisticEvent); 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 0cee185a..13d874e8 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 @@ -119,7 +119,9 @@ public class JSONAPIServlet extends HttpServlet { connectorEnum = PDFASSignParameters.Connector.MOBILEBKU; } else if(PDFASSignParameters.Connector.ONLINEBKU.equalsName(connector)) { connectorEnum = PDFASSignParameters.Connector.ONLINEBKU; - } + } else if(PDFASSignParameters.Connector.SECLAYER20.equalsName(connector)) { + connectorEnum = PDFASSignParameters.Connector.SECLAYER20; + } if(connectorEnum == null) { throw new ServletException( @@ -212,6 +214,13 @@ public class JSONAPIServlet extends HttpServlet { "Invalid connector mobilebku is not supported"); } } + + if (PDFASSignParameters.Connector.SECLAYER20.equals(connectorEnum)) { + if (WebConfiguration.getSecurityLayer20URL() == null) { + throw new PdfAsWebException( + "Invalid connector mobilebku is not supported"); + } + } PdfAsHelper.startSignatureJson(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 2cf2f8ff..ec7e7f2b 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 @@ -23,8 +23,18 @@ ******************************************************************************/ package at.gv.egiz.pdfas.web.servlets; -import at.gv.egiz.pdfas.api.ws.PDFASVerificationResponse; +import java.io.*; + +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.ws.PDFASVerificationResponse; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor; import at.gv.egiz.pdfas.web.stats.StatisticEvent; diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFURLData.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFURLData.java new file mode 100644 index 00000000..d4112cad --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFURLData.java @@ -0,0 +1,87 @@ +package at.gv.egiz.pdfas.web.servlets; + +import at.gv.egiz.pdfas.common.exceptions.PDFIOException; +import at.gv.egiz.pdfas.common.utils.PDFUtils; +import at.gv.egiz.pdfas.lib.api.StatusRequest; +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 javax.servlet.http.HttpSession; +import java.io.IOException; +import java.io.OutputStream; + +public class PDFURLData extends HttpServlet { + + private static final long serialVersionUID = 1L; + private static final String PDF_STATUS = "PDF_STATUS"; + + + private static final Logger logger = LoggerFactory.getLogger(PDFData.class); + + /** + * @see HttpServlet#HttpServlet() + */ + public PDFURLData() { + super(); + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + this.process(request, response); + } catch (PDFIOException e) { + response.sendError(500, "file cannot be transfered"); + } + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + this.process(request, response); + } catch (PDFIOException e) { + response.sendError(500, "internal server error"); } + } + + protected void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException, PDFIOException { + + HttpSession session = request.getSession(); + StatusRequest statusRequest = (StatusRequest) session + .getAttribute(PDF_STATUS); + + if(statusRequest!=null) + { + byte[] nonSignedData = statusRequest.getSignatureData(); + + if (nonSignedData != null) { + + byte[] blackoutnonSignedData = PDFUtils.blackOutSignature(nonSignedData, statusRequest.getSignatureDataByteRange()); + + response.setContentType("application/pdf"); + OutputStream os = response.getOutputStream(); + os.write(blackoutnonSignedData); + os.close(); + logger.debug("pdf file transfer finished"); + + } else { + logger.info("no pdf document is found"); + response.sendError(500, "no signed data found"); + } + } else { + logger.info("no session found"); + response.sendError(500, "no signed data found"); + } + } +}
\ No newline at end of file diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SLDataURLServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SLDataURLServlet.java new file mode 100644 index 00000000..31f5a2ef --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SLDataURLServlet.java @@ -0,0 +1,236 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.jose4j.base64url.Base64Url; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; + +import at.gv.egiz.pdfas.lib.util.StreamUtils; +import at.gv.egiz.pdfas.web.config.WebConfiguration; +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; +import at.gv.egiz.pdfas.web.sl20.JsonSecurityUtils; +import at.gv.egiz.pdfas.web.sl20.X509Utils; +import at.gv.egiz.sl20.data.VerificationResult; +import at.gv.egiz.sl20.exceptions.SL20Exception; +import at.gv.egiz.sl20.exceptions.SL20SecurityException; +import at.gv.egiz.sl20.exceptions.SLCommandoParserException; +import at.gv.egiz.sl20.utils.SL20Constants; +import at.gv.egiz.sl20.utils.SL20JSONExtractorUtils; + +@MultipartConfig +public class SLDataURLServlet extends HttpServlet { + + private static final Logger logger = LoggerFactory + .getLogger(SLDataURLServlet.class); + + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public SLDataURLServlet() { + 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 { + + JsonObject sl20ReqObj = null; + try { + if(!PdfAsHelper.checkDataUrlAccess(request)) { + throw new Exception("No valid dataURL access"); + } + + PdfAsHelper.setFromDataUrl(request); + + String sl20Result = request.getParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM); + if (StringUtils.isEmpty(sl20Result)) { + //Workaround for SIC Handy-Signature, because it sends result in InputStream + String isReqInput = StreamUtils.readStream(request.getInputStream(), "UTF-8"); + if (StringUtils.isNotEmpty(isReqInput)) { + logger.info("Use SIC Handy-Signature work-around!"); + sl20Result = isReqInput.substring("slcommand=".length()); + + } else { + logger.info("NO SL2.0 commando or result FOUND."); + throw new SL20Exception("sl20.04", null); + } + + } + + logger.trace("Received SL2.0 command: " + sl20Result); + + //parse SL2.0 command/result into JSON + try { + JsonParser jsonParser = new JsonParser(); + JsonElement sl20Req = jsonParser.parse(Base64Url.decodeToUtf8String(sl20Result)); + sl20ReqObj = sl20Req.getAsJsonObject(); + + } catch (JsonSyntaxException e) { + logger.warn("SL2.0 command or result is NOT valid JSON.", e); + logger.debug("SL2.0 msg: " + sl20Result); + throw new SL20Exception("sl20.02", e); + + } + + //extract transactionId + String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); + if (StringUtils.isNotEmpty(transactionId)) + request.setAttribute(PdfAsHelper.PDF_SESSION_PREFIX + SL20Constants.SL20_TRANSACTIONID, transactionId); + + + //validate reqId with inResponseTo + String sl20ReqId = (String) request.getSession(false).getAttribute(PdfAsHelper.PDF_SESSION_PREFIX + SL20Constants.SL20_REQID); + String inRespTo = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true); + if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { + logger.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + } + + JsonSecurityUtils joseTools = JsonSecurityUtils.getInstance(); + if (!joseTools.isInitialized()) + joseTools = null; + + //validate signature + VerificationResult payLoadContainer = SL20JSONExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, + WebConfiguration.isSL20SigningRequired()); + + if ( (payLoadContainer.isValidSigned() == null || !payLoadContainer.isValidSigned())) { + if (WebConfiguration.isSL20SigningRequired()) { + logger.info("SL20 result from VDA was not valid signed"); + throw new SL20SecurityException("Signature on SL20 result NOT valid."); + + } else { + logger.warn("SL20 result from VDA is NOT valid signed, but signatures-verification is DISABLED by configuration!"); + + } + } + + //extract payloaf + JsonObject payLoad = payLoadContainer.getPayload(); + + logger.trace("SL2.0 payLoad on DataURL: " + payLoad.toString()); + + //check response type + if (SL20JSONExtractorUtils.getStringValue( + payLoad, SL20Constants.SL20_COMMAND_CONTAINER_NAME, true) + .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_GETCERTIFICATE)) { + logger.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_GETCERTIFICATE + " result .... "); + + JsonElement getCertificateResult = SL20JSONExtractorUtils.extractSL20Result( + payLoad, joseTools, + WebConfiguration.isSL20EncryptionRequired()); + + //extract certificates + List<String> certsB64 = SL20JSONExtractorUtils.getListOfStringElements(getCertificateResult.getAsJsonObject(), + SL20Constants.SL20_COMMAND_PARAM_GETCERTIFICATE_RESULT_CERTIFICATE, + true); + + if (certsB64.isEmpty()) { + logger.warn("SL20 'getCertificate' result contains NO certificate"); + throw new SLCommandoParserException(); + + } else if (certsB64.size() == 1) { + logger.debug("SL20 'getCertificate' result contains only one certificate"); + PdfAsHelper.injectCertificate(request, response, Base64.getDecoder().decode(certsB64.get(0)), getServletContext()); + + } else { + logger.debug("SL20 'getCertificate' result contains more than one certificate. Certificates must be sorted ... "); + List<X509Certificate> certs = new ArrayList<X509Certificate>(); + for (String certB64 : certsB64) + certs.add(new iaik.x509.X509Certificate(Base64.getDecoder().decode(certB64))); + + List<X509Certificate> sortedCerts = X509Utils.sortCertificates(certs); + logger.debug("Sorting of certificate completed. Select end-user certificate ... "); + PdfAsHelper.injectCertificate(request, response, sortedCerts.get(0).getEncoded(), getServletContext()); + + } + + } else if (SL20JSONExtractorUtils.getStringValue( + payLoad, SL20Constants.SL20_COMMAND_CONTAINER_NAME, true) + .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_CREATE_SIG_CADES)) { + logger.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_CREATE_SIG_CADES + " result .... "); + + JsonElement getCertificateResult = SL20JSONExtractorUtils.extractSL20Result( + payLoad, joseTools, + WebConfiguration.isSL20EncryptionRequired()); + + //extract CAdES signature + String cadesSigB64 = SL20JSONExtractorUtils.getStringValue( + getCertificateResult.getAsJsonObject(), + SL20Constants.SL20_COMMAND_PARAM_CREATE_SIG_CADES_RESULT_SIGNATURE, + true); + + if (StringUtils.isEmpty(cadesSigB64)) { + logger.warn("SL20 'createCAdES' result contains NO signature"); + throw new SLCommandoParserException(); + } + + PdfAsHelper.injectSignature(request, response, Base64.getDecoder().decode(cadesSigB64), getServletContext()); + + } else { + logger.info("SL20 response is NOT a " + SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID + " result"); + throw new SLCommandoParserException(); + + } + + } catch (Exception e) { + logger.warn("Error in DataURL Servlet. " , e); + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + + if (PdfAsHelper.getFromDataUrl(request)) { + String errorUrl = PdfAsHelper.generateErrorURL(request, response); + try { + String transactionId = null; + if (sl20ReqObj != null) + transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); + + PdfAsHelper.buildSL20RedirectResponse(request, response, transactionId, errorUrl); + + } catch (SL20Exception e1) { + logger.error("SL20 error-handling FAILED", e); + response.sendError(500, "Internal Server Error."); + + } + + } else + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } +} 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 e8ac3658..73f8299c 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 @@ -131,7 +131,8 @@ public class UIEntryPointServlet extends HttpServlet { // IPlainSigner signer; if (connector.equals(Connector.BKU) || connector.equals(Connector.ONLINEBKU) - || connector.equals(Connector.MOBILEBKU)) { + || connector.equals(Connector.MOBILEBKU) + || connector.equals(Connector.SECLAYER20)) { // start asynchronous signature creation if (connector.equals(Connector.BKU)) { @@ -154,6 +155,14 @@ public class UIEntryPointServlet extends HttpServlet { "Invalid connector mobilebku is not supported"); } } + + if (connector.equals(Connector.SECLAYER20)) { + if (WebConfiguration.getSecurityLayer20URL() == null) { + throw new PdfAsWebException( + "Invalid connector mobilebku is not supported"); + } + } + Map<String, String> map = null; if (pdfAsRequest.getParameters().getPreprocessor() != null) { map = pdfAsRequest.getParameters().getPreprocessor() |