Skip to content

Commit

Permalink
major refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
celuchmarek committed Nov 6, 2023
1 parent e456ed6 commit 8ed48e5
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 140 deletions.
36 changes: 23 additions & 13 deletions src/main/java/digital/slovensko/autogram/core/SigningJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.File;

import digital.slovensko.autogram.core.eforms.EFormUtils;
import digital.slovensko.autogram.core.eforms.XDCBuilder;
import digital.slovensko.autogram.core.eforms.XDCValidator;
import digital.slovensko.autogram.core.errors.AutogramException;
Expand All @@ -10,7 +11,6 @@
import eu.europa.esig.dss.asic.xades.signature.ASiCWithXAdESService;
import eu.europa.esig.dss.cades.signature.CAdESService;
import eu.europa.esig.dss.enumerations.SignatureLevel;
import eu.europa.esig.dss.model.CommonDocument;
import eu.europa.esig.dss.model.DSSDocument;
import eu.europa.esig.dss.model.FileDocument;
import eu.europa.esig.dss.pades.signature.PAdESService;
Expand All @@ -21,16 +21,16 @@

public class SigningJob {
private final Responder responder;
private final CommonDocument document;
private final DSSDocument document;
private final SigningParameters parameters;

public SigningJob(CommonDocument document, SigningParameters parameters, Responder responder) {
private SigningJob(DSSDocument document, SigningParameters parameters, Responder responder) {
this.document = document;
this.parameters = parameters;
this.responder = responder;
}

public CommonDocument getDocument() {
public DSSDocument getDocument() {
return this.document;
}

Expand Down Expand Up @@ -77,12 +77,6 @@ private DSSDocument signDocumentAsCAdeS(SigningKey key) {
}

private DSSDocument signDocumentAsAsiCWithXAdeS(SigningKey key) {
DSSDocument doc = getDocument();
if (getParameters().shouldCreateDatacontainer() && !(isXDC(doc.getMimeType()) || isAsice(doc.getMimeType()))) {
doc = XDCBuilder.transform(getParameters(), doc);
doc.setMimeType(AutogramMimeType.XML_DATACONTAINER);
}

var commonCertificateVerifier = new CommonCertificateVerifier();
var service = new ASiCWithXAdESService(commonCertificateVerifier);
var signatureParameters = getParameters().getASiCWithXAdESSignatureParameters();
Expand All @@ -91,10 +85,10 @@ private DSSDocument signDocumentAsAsiCWithXAdeS(SigningKey key) {
signatureParameters.setCertificateChain(key.getCertificateChain());
signatureParameters.setSignWithExpiredCertificate(true);

var dataToSign = service.getDataToSign(doc, signatureParameters);
var dataToSign = service.getDataToSign(getDocument(), signatureParameters);
var signatureValue = key.sign(dataToSign, getParameters().getDigestAlgorithm());

return service.signDocument(doc, signatureParameters, signatureValue);
return service.signDocument(getDocument(), signatureParameters, signatureValue);
}

private DSSDocument signDocumentAsXAdeS(SigningKey key) {
Expand Down Expand Up @@ -148,12 +142,28 @@ private DSSDocument signDocumentAsPAdeS(SigningKey key) {
public static FileDocument createDSSFileDocumentFromFile(File file) {
var fileDocument = new FileDocument(file);

if (isXML(fileDocument.getMimeType()) && XDCValidator.isXDCContent(fileDocument))
if (isXDC(fileDocument.getMimeType()) || isXML(fileDocument.getMimeType()) && XDCValidator.isXDCContent(fileDocument))
fileDocument.setMimeType(AutogramMimeType.XML_DATACONTAINER);

return fileDocument;
}

private static SigningJob build(DSSDocument document, SigningParameters params, Responder responder) {
if (params.shouldCreateXdc()) {
var mimeType = document.getMimeType();
if (!isXDC(mimeType) && !isAsice(mimeType)) {
document = XDCBuilder.transform(params, document.getName(), EFormUtils.getXmlFromDocument(document));
document.setMimeType(AutogramMimeType.XML_DATACONTAINER);
}
}

return new SigningJob(document, params, responder);
}

public static SigningJob buildFromRequest(DSSDocument document, SigningParameters params, Responder responder) {
return build(document, params, responder);
}

public static SigningJob buildFromFile(File file, Responder responder, boolean checkPDFACompliance, SignatureLevel signatureType, boolean isEn319132) {
var document = createDSSFileDocumentFromFile(file);
var parameters = getParametersForFile(document, checkPDFACompliance, signatureType, isEn319132);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import digital.slovensko.autogram.core.errors.AutogramException;
import digital.slovensko.autogram.core.errors.SigningParametersException;
import digital.slovensko.autogram.core.errors.TransformationParsingErrorException;
import digital.slovensko.autogram.util.AsicContainerUtils;
import digital.slovensko.autogram.core.eforms.EFormResources;
import digital.slovensko.autogram.core.eforms.EFormUtils;
import digital.slovensko.autogram.core.eforms.XDCValidator;
Expand Down Expand Up @@ -40,12 +41,14 @@ public class SigningParameters {
private final boolean checkPDFACompliance;
private final int visualizationWidth;
private final boolean autoLoadEform;
private final String transformationOutputMimeTypeString;

private SigningParameters(SignatureLevel level, ASiCContainerType container,
String containerXmlns, SignaturePackaging packaging, DigestAlgorithm digestAlgorithm,
Boolean en319132, String infoCanonicalization, String propertiesCanonicalization,
String keyInfoCanonicalization, String schema, String transformation, String identifier,
boolean checkPDFACompliance, int preferredPreviewWidth, boolean autoLoadEform) {
boolean checkPDFACompliance, int preferredPreviewWidth, boolean autoLoadEform,
String transformationOutputMimeTypeString) {
this.level = level;
this.asicContainer = container;
this.containerXmlns = containerXmlns;
Expand All @@ -61,6 +64,7 @@ private SigningParameters(SignatureLevel level, ASiCContainerType container,
this.checkPDFACompliance = checkPDFACompliance;
this.visualizationWidth = preferredPreviewWidth;
this.autoLoadEform = autoLoadEform;
this.transformationOutputMimeTypeString = transformationOutputMimeTypeString;
}

public ASiCWithXAdESSignatureParameters getASiCWithXAdESSignatureParameters() {
Expand Down Expand Up @@ -181,7 +185,8 @@ public static SigningParameters buildFromRequest(SignatureLevel level, ASiCConta
String containerXmlns, SignaturePackaging packaging, DigestAlgorithm digestAlgorithm,
Boolean en319132, String infoCanonicalization, String propertiesCanonicalization,
String keyInfoCanonicalization, String schema, String transformation, String identifier,
boolean checkPDFACompliance, int preferredPreviewWidth, boolean autoLoadEform, DSSDocument document) throws AutogramException {
boolean checkPDFACompliance, int preferredPreviewWidth, boolean autoLoadEform, DSSDocument document)
throws AutogramException {

return buildParameters(level, container, containerXmlns, packaging, digestAlgorithm, en319132,
infoCanonicalization, propertiesCanonicalization, keyInfoCanonicalization, schema, transformation,
Expand All @@ -203,9 +208,13 @@ private static SigningParameters buildParameters(SignatureLevel level, ASiCConta
if (document.getMimeType() == null)
throw new SigningParametersException("Dokument nemá definovaný MIME type", "Dokument poskytnutý na podpis nemá definovaný MIME type");

var extractedDocument = document;
var mimeType = document.getMimeType();
if (isAsice(mimeType))
extractedDocument = AsicContainerUtils.getOriginalDocument(document);

if (autoLoadEform && (isAsice(mimeType) || isXML(mimeType) || isXDC(mimeType))) {
var eformAttributes = EFormResources.tryToLoadEFormAttributes(document, propertiesCanonicalization);
var eformAttributes = EFormResources.tryToLoadEFormAttributes(extractedDocument, propertiesCanonicalization);

if (eformAttributes != null) {
schema = eformAttributes.schema();
Expand All @@ -216,6 +225,10 @@ private static SigningParameters buildParameters(SignatureLevel level, ASiCConta
}
}

var transformationOutputMimeTypeString = EFormUtils.extractTransformationOutputMimeTypeString(transformation);
if (!List.of("TXT", "HTML").contains(transformationOutputMimeTypeString))
throw new TransformationParsingErrorException("Unsupported transformation output method: " + mimeType);

if (containerXmlns != null && containerXmlns.contains("xmldatacontainer")) {
if (schema == null)
throw new SigningParametersException("Chýba XSD schéma", "XSD Schéma je povinný atribút pre XML Datacontainer");
Expand All @@ -229,13 +242,17 @@ private static SigningParameters buildParameters(SignatureLevel level, ASiCConta
if (digestAlgorithm == null)
digestAlgorithm = DigestAlgorithm.SHA256;

if (isAsice(mimeType) || isXML(mimeType) || isXDC(mimeType))
XDCValidator.validateXml(schema, transformation, EFormUtils.getXmlDocument(document), propertiesCanonicalization, digestAlgorithm);
if (isXML(extractedDocument.getMimeType()) || isXDC(extractedDocument.getMimeType()))
XDCValidator.validateXml(schema, transformation, extractedDocument, propertiesCanonicalization, digestAlgorithm);

else
throw new SigningParametersException("Nesprávny typ dokumentu", "Zadaný dokument nemožno podpísať ako elektronický formulár v XML Datacontaineri");
}

return new SigningParameters(level, container, containerXmlns, packaging, digestAlgorithm, en319132,
infoCanonicalization, propertiesCanonicalization, keyInfoCanonicalization, schema, transformation,
identifier, checkPDFACompliance, preferredPreviewWidth, autoLoadEform);
identifier, checkPDFACompliance, preferredPreviewWidth, autoLoadEform,
transformationOutputMimeTypeString);
}

public static SigningParameters buildForPDF(String filename, DSSDocument document, boolean checkPDFACompliance, boolean signAsEn319132) throws AutogramException {
Expand Down Expand Up @@ -265,10 +282,6 @@ public String getIdentifier() {
return identifier;
}

public boolean shouldCreateDatacontainer() {
return getContainerXmlns() != null && getContainerXmlns().contains("xmldatacontainer");
}

public boolean getCheckPDFACompliance() {
return checkPDFACompliance;
}
Expand All @@ -281,11 +294,11 @@ public boolean getAutoLoadEform() {
return autoLoadEform;
}

public String extractTransformationOutputMimeTypeString() throws TransformationParsingErrorException {
var mimeType = EFormUtils.extractTransformationOutputMimeTypeString(transformation);
if (!List.of("TXT", "HTML").contains(mimeType))
throw new TransformationParsingErrorException("Unsupported transformation output method: " + mimeType);
public String getTransformationOutputMimeTypeString() {
return transformationOutputMimeTypeString;
}

return mimeType;
public boolean shouldCreateXdc() {
return containerXmlns != null && containerXmlns.contains("xmldatacontainer");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import digital.slovensko.autogram.core.errors.AutogramException;
import digital.slovensko.autogram.core.errors.XMLValidationException;
import digital.slovensko.autogram.util.AsicContainerUtils;

import static digital.slovensko.autogram.core.eforms.EFormUtils.*;
import static digital.slovensko.autogram.core.AutogramMimeType.*;
Expand All @@ -28,9 +27,6 @@ public class EFormResources {
private final String xsltDigest;

public static EFormAttributes tryToLoadEFormAttributes(DSSDocument document, String propertiesCanonicalization) throws AutogramException {
if (isAsice(document.getMimeType()))
document = AsicContainerUtils.getOriginalDocument(document);

if (!isXDC(document.getMimeType()) && !isXML(document.getMimeType()))
return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@
import org.xml.sax.SAXException;

import digital.slovensko.autogram.core.errors.XMLValidationException;
import digital.slovensko.autogram.core.errors.MultipleOriginalDocumentsFoundException;
import digital.slovensko.autogram.core.errors.OriginalDocumentNotFoundException;
import digital.slovensko.autogram.core.errors.TransformationException;
import digital.slovensko.autogram.core.errors.TransformationParsingErrorException;
import digital.slovensko.autogram.core.errors.UnrecognizedException;
import digital.slovensko.autogram.util.AsicContainerUtils;
import digital.slovensko.autogram.util.XMLUtils;
import eu.europa.esig.dss.enumerations.DigestAlgorithm;
import eu.europa.esig.dss.model.DSSDocument;
Expand Down Expand Up @@ -196,29 +193,6 @@ public static Document getEformXmlFromXdcDocument(DSSDocument document) throws X
return responseDocument;
}

public static String transformElementToString(Node element) throws XMLValidationException {
try {
var document = XMLUtils.getSecureDocumentBuilder().newDocument();
Node node;
try {
node = document.importNode(element, true);
} catch (DOMException e) {
node = document.importNode(element.getFirstChild(), true);
}

document.appendChild(node);

var transformer = XMLUtils.getSecureTransformerFactory().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
var writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));

return writer.toString();
} catch (Exception e) {
throw new XMLValidationException("Zlyhala validácia XML Datacontainera", "Nepodarilo sa načítať XML dokument", e);
}
}

public static String transform(DSSDocument documentToDisplay, String transformation) throws TransformationException {
try {
var parsedDocument = getXmlFromDocument(documentToDisplay);
Expand All @@ -243,18 +217,4 @@ public static String transform(DSSDocument documentToDisplay, String transformat
throw new TransformationException("Zlyhala transformácia podľa XSLT", "Nepodarilo sa transformovať XML dokument podľa XSLT transformácie", e);
}
}

public static DSSDocument getXmlDocument(DSSDocument document)
throws XMLValidationException, OriginalDocumentNotFoundException,
MultipleOriginalDocumentsFoundException {
if (isAsice(document.getMimeType())) {
var originalDocument = AsicContainerUtils.getOriginalDocument(document);
if (!isXDC(originalDocument.getMimeType()))
return null;

return originalDocument;
}

return document;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,32 @@

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public abstract class XDCBuilder {
private static final Charset ENCODING = StandardCharsets.UTF_8;

public static DSSDocument transform(SigningParameters params, DSSDocument dssDocument) {
public static DSSDocument transform(SigningParameters params, String filename, Document parsedDocument) {
var identifier = params.getIdentifier();
var lastSlashIndex = identifier.lastIndexOf("/");
if (lastSlashIndex == -1)
throw new RuntimeException("Identifier contains no slash: " + identifier);

var identifierVersion = identifier.substring(lastSlashIndex + 1);
try {
var xmlByteArrayInput = dssDocument.openStream().readAllBytes();
var parsedDocument = parseDOMDocument(new String(xmlByteArrayInput, ENCODING));
var transformedDocument = transformDocument(parsedDocument, params.getContainerXmlns(), identifier,
identifierVersion,
params.getSchema(), params.getTransformation(), params.getPropertiesCanonicalization(),
params.getDigestAlgorithm(), params.extractTransformationOutputMimeTypeString());
params.getDigestAlgorithm(), params.getTransformationOutputMimeTypeString());
var content = getDocumentContent(transformedDocument).getBytes(ENCODING);

return new InMemoryDocument(content, dssDocument.getName());
return new InMemoryDocument(content, filename);

} catch (TransformationException e) {
throw e;
Expand All @@ -53,12 +46,6 @@ public static DSSDocument transform(SigningParameters params, DSSDocument dssDoc
}
}

private static Document parseDOMDocument(String xmlContent)
throws ParserConfigurationException, IOException, SAXException {
var source = new InputSource(new StringReader(xmlContent));
return XMLUtils.getSecureDocumentBuilder().parse(source);
}

private static Document transformDocument(Document document, String containerXmlns, String identifierUri,
String identifierVersion, String xsdSchema, String xsltSchema, String canonicalizationMethod,
DigestAlgorithm digestAlgorithm, String mediaDestinationTypeDescription) {
Expand Down
Loading

0 comments on commit 8ed48e5

Please sign in to comment.