package eu.europa.esig.dss.xades.requirements;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import eu.europa.esig.dss.DSSDocument;
import eu.europa.esig.dss.DSSUtils;
import eu.europa.esig.dss.utils.Utils;
import eu.europa.esig.dss.x509.CertificateToken;
public abstract class AbstractRequirementChecks {
private static DocumentBuilderFactory dbf;
private static XPath xpath;
protected Document document;
@BeforeClass
public static void initClass() {
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
XPathFactory f = XPathFactory.newInstance();
xpath = f.newXPath();
xpath.setNamespaceContext(new XAdESNamespaceContext());
}
@Before
public void init() throws Exception {
DSSDocument signedDocument = getSignedDocument();
signedDocument.save("target/requirement-check.xml");
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
document = documentBuilder.parse(signedDocument.openStream());
}
protected abstract DSSDocument getSignedDocument() throws Exception;
/**
* ds:KeyInfo/X509Data/X509Certificate shall be present in B/T/LT/LTA
*/
@Test
public void checkX509CertificatePresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//ds:KeyInfo/ds:X509Data/ds:X509Certificate");
NodeList nodeList = (NodeList) exp.evaluate(document, XPathConstants.NODESET);
assertNotNull(nodeList);
int length = nodeList.getLength();
assertTrue(length > 0);
for (int i = 0; i < length; i++) {
Node node = nodeList.item(i);
String certificateBase64 = node.getTextContent();
byte[] decodeCertificate = Utils.fromBase64(certificateBase64);
CertificateToken certificateToken = DSSUtils.loadCertificate(decodeCertificate);
assertNotNull(certificateToken);
}
}
/**
* ds:SignedInfo/ds:CanonicalizationMethod shall be present in B/T/LT/LTA
*/
@Test
public void checkSignedInfoCanonicalizationMethodPresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//ds:SignedInfo/ds:CanonicalizationMethod");
Node node = (Node) exp.evaluate(document, XPathConstants.NODE);
assertNotNull(node);
NamedNodeMap attributes = node.getAttributes();
Node algoNode = attributes.getNamedItem("Algorithm");
assertTrue(Utils.isStringNotEmpty(algoNode.getTextContent()));
}
/**
* ds:Reference shall be present in B/T/LT/LTA
*/
@Test
public void checkReferencesPresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//ds:Reference");
NodeList nodeList = (NodeList) exp.evaluate(document, XPathConstants.NODESET);
assertNotNull(nodeList);
int length = nodeList.getLength();
assertTrue(length >= 2);
}
/**
* SigningTime shall be present in B/T/LT/LTA
*/
@Test
public void checkSigningTimePresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//xades:SignedProperties/xades:SignedSignatureProperties/xades:SigningTime");
Node node = (Node) exp.evaluate(document, XPathConstants.NODE);
assertNotNull(node);
}
/**
* SigingCertificate shall be present in B/T/LT/LTA
*/
@Test
public void checkSigningCertificatePresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//xades:SignedProperties/xades:SignedSignatureProperties/xades:SigningCertificateV2");
Node node = (Node) exp.evaluate(document, XPathConstants.NODE);
assertNotNull(node);
}
/**
* DataObjectFormat with attribute ObjectReference shall be present in B/T/LT/LTA
*/
@Test
public void checkDataObjectFormatPresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//xades:SignedProperties/xades:SignedDataObjectProperties/xades:DataObjectFormat");
Node node = (Node) exp.evaluate(document, XPathConstants.NODE);
assertNotNull(node);
NamedNodeMap attributes = node.getAttributes();
Node objectReferenceAttribute = attributes.getNamedItem("ObjectReference");
assertTrue(Utils.isStringNotEmpty(objectReferenceAttribute.getTextContent()));
}
/**
* DataObjectFormat/MimeType shall be present in B/T/LT/LTA
*/
@Test
public void checkDataObjectFormatMimeTypePresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//xades:SignedProperties/xades:SignedDataObjectProperties/xades:DataObjectFormat/xades:MimeType");
Node node = (Node) exp.evaluate(document, XPathConstants.NODE);
assertNotNull(node);
assertTrue(Utils.isStringNotEmpty(node.getTextContent()));
}
/**
* SignatureTimeStamp shall be present in T/LT/LTA
*/
@Test
public void checkSignatureTimeStampPresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//xades:UnsignedProperties/xades:UnsignedSignatureProperties/xades:SignatureTimeStamp");
Node node = (Node) exp.evaluate(document, XPathConstants.NODE);
assertNotNull(node);
}
/**
* ArchiveTimeStamp shall be present in LTA
*/
@Test
public void checkArchiveTimeStampPresent() throws XPathExpressionException {
XPathExpression exp = xpath.compile("//xades:UnsignedProperties/xades:UnsignedSignatureProperties/xades141:ArchiveTimeStamp");
Node node = (Node) exp.evaluate(document, XPathConstants.NODE);
assertNotNull(node);
}
}