diff --git a/itext.tests/itext.sign.tests/itext/signatures/testutils/report/xml/XmlReportTestTool.cs b/itext.tests/itext.sign.tests/itext/signatures/testutils/report/xml/XmlReportTestTool.cs
new file mode 100644
index 0000000000..1e0ca74f40
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/testutils/report/xml/XmlReportTestTool.cs
@@ -0,0 +1,133 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
+using iText.Signatures.Validation.Report.Xml;
+
+namespace iText.Signatures.Testutils.Report.Xml {
+ public class XmlReportTestTool {
+ private static readonly String XSDROOT = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
+ .CurrentContext.TestDirectory) + "/resources/itext/signatures/validation/report/xml/";
+
+ private readonly XmlDocument xml;
+
+ private readonly String report;
+ private XPathNavigator navigator;
+ private XmlNamespaceManager manager;
+
+ public XmlReportTestTool(String report) {
+ this.report = report;
+ xml = new XmlDocument();
+ xml.LoadXml(report);
+
+ navigator = xml.CreateNavigator();
+ manager = new XmlNamespaceManager(navigator.NameTable);
+ manager.AddNamespace("r", XmlReportGenerator.DOC_NS);
+ manager.AddNamespace("ds", XmlReportGenerator.DS_NS);
+ manager.AddNamespace("xs", XmlReportGenerator.XS_NS);
+ manager.AddNamespace("xsi", XmlReportGenerator.XSI_NS);
+ }
+
+ public virtual XmlElement GetDocumentNode() {
+ return xml.DocumentElement;
+ }
+
+ public virtual int CountElements(String xPathQuery) {
+ return xml.SelectNodes(xPathQuery, manager).Count;
+ }
+
+ public virtual String GetElementContent(String xPathQuery) {
+ return xml.SelectSingleNode(xPathQuery, manager).InnerText;
+ }
+
+ public virtual XmlNodeList ExecuteXpathAsNodeList(String xPathQuery) {
+ return xml.SelectNodes(xPathQuery, manager);
+ }
+
+ public virtual XmlNode ExecuteXpathAsNode(String xPathQuery) {
+ return xml.SelectSingleNode(xPathQuery, manager);
+ }
+
+ public virtual String ExecuteXpathAsString(String xPathQuery) {
+ return (String)navigator.Evaluate(xPathQuery, manager);
+ }
+
+ public virtual double? ExecuteXpathAsNumber(String xPathQuery) {
+ return (double?)navigator.Evaluate(xPathQuery, manager);
+ }
+
+ public virtual bool? ExecuteXpathAsBoolean(String xPathQuery) {
+ return (bool?)navigator.Evaluate(xPathQuery, manager);
+ }
+
+ public virtual String ValidateXMLSchema() {
+ List files = new List();
+ files.AddAll(new[] {
+ XSDROOT + "xml.xsd",
+ XSDROOT + "XMLSchema.xsd",
+ XSDROOT + "XAdES.xsd",
+ XSDROOT + "ts_119612v020201_201601xsd.xsd",
+ XSDROOT + "1910202xmlSchema.xsd",
+ XSDROOT + "xmldsig-core-schema.xsd"
+ });
+
+ var schemas = files.Select(f => XmlSchema.Read(XmlReader.Create(f,
+ new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse }), (s, e) => {
+ }));
+
+ XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();
+ foreach (var s in schemas) {
+ xmlSchemaSet.Add(s);
+ }
+
+ XmlReaderSettings validationSettings = new XmlReaderSettings();
+ validationSettings.ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints | XmlSchemaValidationFlags.ReportValidationWarnings | XmlSchemaValidationFlags.AllowXmlAttributes;
+ validationSettings.ValidationType = ValidationType.Schema;
+ validationSettings.Schemas.Add(xmlSchemaSet);
+ validationSettings.Schemas.Compile();
+ StringBuilder log = new StringBuilder();
+
+ validationSettings.ValidationEventHandler += (s, e) => {
+ log.Append("***\n");
+ log.Append("\tPosition:").Append(e.Exception.LineNumber).Append(':').Append(e.Exception.LinePosition).Append('\n');
+ log.Append("\tSeverity:").Append(e.Severity).Append('\n');
+ log.Append("\tMessage :").Append(e.Message).Append('\n');
+ };
+
+ XmlReader reader = XmlReader.Create(new StringReader(report), validationSettings);
+ while (reader.Read()) {}
+
+ String message = log.ToString();
+ if (String.IsNullOrEmpty(message)) {
+ return null;
+ }
+ return message;
+ }
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/AbstractCollectableObjectTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/AbstractCollectableObjectTest.cs
new file mode 100644
index 0000000000..ae556823a1
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/AbstractCollectableObjectTest.cs
@@ -0,0 +1,61 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+namespace iText.Signatures.Validation.Report.Xml {
+ public abstract class AbstractCollectableObjectTest : AbstractIdentifiableObjectTest {
+ private AbstractCollectableObjectTest.MockCollectableObjectVisitor mockVisitor;
+
+ [NUnit.Framework.SetUp]
+ public virtual void SetUpParent() {
+ mockVisitor = new AbstractCollectableObjectTest.MockCollectableObjectVisitor();
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestVisitorUsage() {
+ AbstractCollectableObject sut = GetCollectableObjectUnderTest();
+ sut.Accept(mockVisitor);
+ NUnit.Framework.Assert.AreEqual(1, mockVisitor.calls);
+ }
+
+//\cond DO_NOT_DOCUMENT
+ internal override AbstractIdentifiableObject GetIdentifiableObjectUnderTest() {
+ return GetCollectableObjectUnderTest();
+ }
+//\endcond
+
+//\cond DO_NOT_DOCUMENT
+ internal abstract AbstractCollectableObject GetCollectableObjectUnderTest();
+//\endcond
+
+ private class MockCollectableObjectVisitor : CollectableObjectVisitor {
+ public int calls;
+
+ public virtual void Visit(CertificateWrapper certificateWrapper) {
+ calls++;
+ }
+
+ public virtual void Visit(POEValidationReport poeValidationReport) {
+ calls++;
+ }
+ }
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/AbstractIdentifiableObjectTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/AbstractIdentifiableObjectTest.cs
new file mode 100644
index 0000000000..68d2355456
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/AbstractIdentifiableObjectTest.cs
@@ -0,0 +1,103 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Test;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ public abstract class AbstractIdentifiableObjectTest : ExtendedITextTest {
+ [NUnit.Framework.Test]
+ public virtual void TestIdentifiersAreUnique() {
+ AbstractIdentifiableObject sut1 = new AbstractIdentifiableObjectTest.TestIdentifiableObject("A");
+ AbstractIdentifiableObject sut2 = new AbstractIdentifiableObjectTest.TestIdentifiableObject("A");
+ NUnit.Framework.Assert.AreNotEqual(sut1.GetIdentifier().GetId(), sut2.GetIdentifier().GetId());
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestEqualsForEqualIdentity() {
+ AbstractIdentifiableObject sut1 = GetIdentifiableObjectUnderTest();
+ AbstractIdentifiableObject sut2 = sut1;
+ // Equals is being tested here.
+ NUnit.Framework.Assert.IsTrue(sut1.Equals(sut2));
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestEqualsForNull() {
+ AbstractIdentifiableObject sut = GetIdentifiableObjectUnderTest();
+ // Equals is being tested here.
+ NUnit.Framework.Assert.IsFalse(sut.Equals(null));
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestEqualsForSomeObject() {
+ AbstractIdentifiableObject sut = GetIdentifiableObjectUnderTest();
+ // Equals is being tested here.
+ NUnit.Framework.Assert.IsFalse(sut.Equals("Test"));
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestEqualsForEqualInstances() {
+ PerformTestEqualsForEqualInstances();
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestHashForEqualInstances() {
+ PerformTestHashForEqualInstances();
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestEqualsForDifferentInstances() {
+ PerformTestEqualsForDifferentInstances();
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestHashForDifferentInstances() {
+ PerformTestHashForDifferentInstances();
+ }
+
+ protected internal abstract void PerformTestHashForEqualInstances();
+
+ protected internal abstract void PerformTestEqualsForEqualInstances();
+
+ protected internal abstract void PerformTestEqualsForDifferentInstances();
+
+ protected internal abstract void PerformTestHashForDifferentInstances();
+
+//\cond DO_NOT_DOCUMENT
+ internal abstract AbstractIdentifiableObject GetIdentifiableObjectUnderTest();
+//\endcond
+
+ private class TestIdentifiableObject : AbstractIdentifiableObject {
+ protected internal TestIdentifiableObject(String prefix)
+ : base(prefix) {
+ }
+
+ public override bool Equals(Object o) {
+ return false;
+ }
+
+ public override int GetHashCode() {
+ return 0;
+ }
+ }
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/CertificateWrapperTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/CertificateWrapperTest.cs
new file mode 100644
index 0000000000..2d2d1a30f4
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/CertificateWrapperTest.cs
@@ -0,0 +1,94 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Bouncycastleconnector;
+using iText.Commons.Bouncycastle;
+using iText.Commons.Bouncycastle.Cert;
+using iText.Commons.Utils;
+using iText.Signatures.Testutils;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ [NUnit.Framework.Category("BouncyCastleUnitTest")]
+ public class CertificateWrapperTest : AbstractCollectableObjectTest {
+ private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
+
+ private static readonly String CERTS_SRC = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
+ .CurrentContext.TestDirectory) + "/resources/itext/signatures/certs/";
+
+ private static IX509Certificate cert1;
+
+ private static IX509Certificate cert2;
+
+ [NUnit.Framework.OneTimeSetUp]
+ public static void SetUpFixture() {
+ cert1 = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "root.pem")[0];
+ cert2 = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertDsa01.pem")[0];
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestEqualInstancesHaveUniqueIds() {
+ CertificateWrapper sut1 = new CertificateWrapper(cert1);
+ CertificateWrapper sut2 = new CertificateWrapper(cert1);
+ NUnit.Framework.Assert.AreNotEqual(sut1.GetIdentifier().GetId(), sut2.GetIdentifier().GetId());
+ }
+
+ protected internal override void PerformTestHashForEqualInstances() {
+ CertificateWrapper sut1 = new CertificateWrapper(cert1);
+ CertificateWrapper sut2 = new CertificateWrapper(cert1);
+ NUnit.Framework.Assert.AreEqual(sut1.GetHashCode(), sut2.GetHashCode());
+ }
+
+ protected internal override void PerformTestEqualsForEqualInstances() {
+ CertificateWrapper sut1 = new CertificateWrapper(cert1);
+ CertificateWrapper sut2 = new CertificateWrapper(cert1);
+ NUnit.Framework.Assert.AreEqual(sut1, sut2);
+ }
+
+ protected internal override void PerformTestEqualsForDifferentInstances() {
+ CertificateWrapper sut1 = new CertificateWrapper(cert1);
+ CertificateWrapper sut2 = new CertificateWrapper(cert2);
+ NUnit.Framework.Assert.AreNotEqual(sut1, sut2);
+ }
+
+ protected internal override void PerformTestHashForDifferentInstances() {
+ CertificateWrapper sut1 = new CertificateWrapper(cert1);
+ CertificateWrapper sut2 = new CertificateWrapper(cert2);
+ NUnit.Framework.Assert.AreNotEqual(sut1.GetHashCode(), sut2.GetHashCode());
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestGetBase64ASN1Structure() {
+ CertificateWrapper sut = new CertificateWrapper(cert1);
+ IX509Certificate sutCert = FACTORY.CreateX509Certificate(Convert.FromBase64String(sut.GetBase64ASN1Structure
+ ()));
+ IX509Certificate origCert = FACTORY.CreateX509Certificate(cert1.GetEncoded());
+ NUnit.Framework.Assert.AreEqual(origCert, sutCert);
+ }
+
+//\cond DO_NOT_DOCUMENT
+ internal override AbstractCollectableObject GetCollectableObjectUnderTest() {
+ return new CertificateWrapper(cert1);
+ }
+//\endcond
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/PadesValidationReportTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/PadesValidationReportTest.cs
new file mode 100644
index 0000000000..18a53ba5ae
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/PadesValidationReportTest.cs
@@ -0,0 +1,74 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Commons.Utils;
+using iText.Signatures.Cms;
+using iText.Signatures.Testutils;
+using iText.Test;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ [NUnit.Framework.Category("BouncyCastleUnitTest")]
+ public class PadesValidationReportTest : ExtendedITextTest {
+ private static CMSContainer signature;
+
+ private readonly ValidationObjects validationObjects = new ValidationObjects();
+
+ [NUnit.Framework.OneTimeSetUp]
+ public static void SetupFixture() {
+ signature = new CMSContainer(Convert.FromBase64String(XmlReportTestHelper.SIGNATURE1_BASE64));
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestCreation() {
+ PadesValidationReport sut = new PadesValidationReport(validationObjects);
+ NUnit.Framework.Assert.IsNotNull(sut);
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestAddSignatureValidationReport() {
+ PadesValidationReport sut = new PadesValidationReport(validationObjects);
+ SignatureValidationReport signatureValidationReport = new SignatureValidationReport(validationObjects, signature
+ , "signatureName", TimeTestUtil.TEST_DATE_TIME);
+ sut.AddSignatureValidationReport(signatureValidationReport);
+ // Collection should be returned
+ NUnit.Framework.Assert.IsNotNull(sut.GetSignatureValidationReports());
+ // Collection should contain at least one element
+ NUnit.Framework.Assert.IsFalse(sut.GetSignatureValidationReports().IsEmpty());
+ // The added signature validation report should be in the collection
+ NUnit.Framework.Assert.IsTrue(sut.GetSignatureValidationReports().Contains(signatureValidationReport));
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestAddMultipleSignatureValidationReports() {
+ PadesValidationReport sut = new PadesValidationReport(validationObjects);
+ SignatureValidationReport signatureValidationReport1 = new SignatureValidationReport(validationObjects, signature
+ , "signatureName", TimeTestUtil.TEST_DATE_TIME);
+ SignatureValidationReport signatureValidationReport2 = new SignatureValidationReport(validationObjects, signature
+ , "signatureName", TimeTestUtil.TEST_DATE_TIME);
+ sut.AddSignatureValidationReport(signatureValidationReport1);
+ sut.AddSignatureValidationReport(signatureValidationReport2);
+ NUnit.Framework.Assert.IsTrue(sut.GetSignatureValidationReports().Contains(signatureValidationReport1));
+ NUnit.Framework.Assert.IsTrue(sut.GetSignatureValidationReports().Contains(signatureValidationReport2));
+ }
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureIdentifierTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureIdentifierTest.cs
new file mode 100644
index 0000000000..2f5e97167a
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureIdentifierTest.cs
@@ -0,0 +1,63 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using iText.Signatures.Cms;
+using iText.Signatures.Testutils;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ public class SignatureIdentifierTest : AbstractIdentifiableObjectTest {
+ protected internal override void PerformTestHashForEqualInstances() {
+ AbstractIdentifiableObject sut1 = GetIdentifiableObjectUnderTest();
+ AbstractIdentifiableObject sut2 = GetIdentifiableObjectUnderTest();
+ // CMS Containers have not equal hashes.
+ NUnit.Framework.Assert.AreNotEqual(sut1.GetHashCode(), sut2.GetHashCode());
+ }
+
+ protected internal override void PerformTestEqualsForEqualInstances() {
+ AbstractIdentifiableObject sut1 = GetIdentifiableObjectUnderTest();
+ AbstractIdentifiableObject sut2 = GetIdentifiableObjectUnderTest();
+ // CMS Containers are not equal.
+ NUnit.Framework.Assert.AreNotEqual(sut1, sut2);
+ }
+
+ protected internal override void PerformTestEqualsForDifferentInstances() {
+ AbstractIdentifiableObject sut1 = GetIdentifiableObjectUnderTest();
+ AbstractIdentifiableObject sut2 = new SignatureIdentifier(new ValidationObjects(), new CMSContainer(), "other test"
+ , TimeTestUtil.TEST_DATE_TIME);
+ NUnit.Framework.Assert.AreNotEqual(sut1, sut2);
+ }
+
+ protected internal override void PerformTestHashForDifferentInstances() {
+ AbstractIdentifiableObject sut1 = GetIdentifiableObjectUnderTest();
+ AbstractIdentifiableObject sut2 = new SignatureIdentifier(new ValidationObjects(), new CMSContainer(), "other test"
+ , TimeTestUtil.TEST_DATE_TIME);
+ NUnit.Framework.Assert.AreNotEqual(sut1.GetHashCode(), sut2.GetHashCode());
+ }
+
+//\cond DO_NOT_DOCUMENT
+ internal override AbstractIdentifiableObject GetIdentifiableObjectUnderTest() {
+ return new SignatureIdentifier(new ValidationObjects(), new CMSContainer(), "test", TimeTestUtil.TEST_DATE_TIME
+ );
+ }
+//\endcond
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureValidationReportTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureValidationReportTest.cs
new file mode 100644
index 0000000000..e0ea6db78a
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureValidationReportTest.cs
@@ -0,0 +1,98 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Commons.Utils;
+using iText.Signatures.Cms;
+using iText.Signatures.Testutils;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ [NUnit.Framework.Category("BouncyCastleIntegrationTest")]
+ public class SignatureValidationReportTest : AbstractIdentifiableObjectTest {
+ private static CMSContainer signature1;
+
+ private static CMSContainer signature2;
+
+ private readonly ValidationObjects validationObjects = new ValidationObjects();
+
+ [NUnit.Framework.OneTimeSetUp]
+ public static void SetupFixture() {
+ signature1 = new CMSContainer(Convert.FromBase64String(XmlReportTestHelper.SIGNATURE1_BASE64));
+ signature2 = new CMSContainer(Convert.FromBase64String(XmlReportTestHelper.SIGNATURE2_BASE64));
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestCreation() {
+ SignatureValidationReport sut = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ NUnit.Framework.Assert.IsNotNull(sut);
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestSetSignatureValidationStatus() {
+ SignatureValidationReport sut = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ SignatureValidationStatus status = new SignatureValidationStatus();
+ sut.SetSignatureValidationStatus(status);
+ NUnit.Framework.Assert.AreEqual(status, sut.GetSignatureValidationStatus());
+ }
+
+ protected internal override void PerformTestHashForEqualInstances() {
+ SignatureValidationReport sut1 = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ SignatureValidationReport sut2 = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ NUnit.Framework.Assert.AreEqual(sut1.GetHashCode(), sut2.GetHashCode());
+ }
+
+ protected internal override void PerformTestEqualsForEqualInstances() {
+ SignatureValidationReport sut1 = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ SignatureValidationReport sut2 = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ NUnit.Framework.Assert.AreEqual(sut1, sut2);
+ }
+
+ protected internal override void PerformTestEqualsForDifferentInstances() {
+ SignatureValidationReport sut1 = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ SignatureValidationReport sut2 = new SignatureValidationReport(validationObjects, signature2, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ NUnit.Framework.Assert.AreNotEqual(sut1, sut2);
+ }
+
+ protected internal override void PerformTestHashForDifferentInstances() {
+ SignatureValidationReport sut1 = new SignatureValidationReport(validationObjects, signature1, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ SignatureValidationReport sut2 = new SignatureValidationReport(validationObjects, signature2, "signatureName"
+ , TimeTestUtil.TEST_DATE_TIME);
+ NUnit.Framework.Assert.AreNotEqual(sut1.GetHashCode(), sut2.GetHashCode());
+ }
+
+//\cond DO_NOT_DOCUMENT
+ internal override AbstractIdentifiableObject GetIdentifiableObjectUnderTest() {
+ return new SignatureValidationReport(validationObjects, signature1, "signatureName", TimeTestUtil.TEST_DATE_TIME
+ );
+ }
+//\endcond
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureValidationStatusTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureValidationStatusTest.cs
new file mode 100644
index 0000000000..5e0b51cc48
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/SignatureValidationStatusTest.cs
@@ -0,0 +1,53 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using iText.Test;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ [NUnit.Framework.Category("UnitTest")]
+ public class SignatureValidationStatusTest : ExtendedITextTest {
+ [NUnit.Framework.Test]
+ public virtual void TestCreation() {
+ SignatureValidationStatus sut = new SignatureValidationStatus();
+ NUnit.Framework.Assert.IsNotNull(sut);
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestSetMainIndication() {
+ SignatureValidationStatus sut = new SignatureValidationStatus();
+ sut.SetMainIndication(SignatureValidationStatus.MainIndication.TOTAL_PASSED);
+ NUnit.Framework.Assert.AreEqual(SignatureValidationStatus.MainIndication.TOTAL_PASSED, sut.GetMainIndication
+ ());
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void TestUpdateMainIndication() {
+ SignatureValidationStatus sut = new SignatureValidationStatus();
+ sut.SetMainIndication(SignatureValidationStatus.MainIndication.TOTAL_PASSED);
+ NUnit.Framework.Assert.AreEqual(SignatureValidationStatus.MainIndication.TOTAL_PASSED, sut.GetMainIndication
+ ());
+ sut.SetMainIndication(SignatureValidationStatus.MainIndication.INDETERMINATE);
+ NUnit.Framework.Assert.AreEqual(SignatureValidationStatus.MainIndication.INDETERMINATE, sut.GetMainIndication
+ ());
+ }
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/XmlReportGeneratorTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/XmlReportGeneratorTest.cs
new file mode 100644
index 0000000000..fc6aaa3d7f
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/XmlReportGeneratorTest.cs
@@ -0,0 +1,93 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using iText.Bouncycastleconnector;
+using iText.Commons.Bouncycastle;
+using iText.Commons.Utils;
+using iText.Kernel.Pdf;
+using iText.Signatures;
+using iText.Signatures.Cms;
+using iText.Signatures.Testutils.Report.Xml;
+using iText.Signatures.Validation;
+using iText.Test;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ [NUnit.Framework.Category("BouncyCastleIntegrationTest")]
+ internal class XmlReportGeneratorTest : ExtendedITextTest {
+ private static readonly String SOURCE_FOLDER = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
+ .CurrentContext.TestDirectory) + "/resources/itext/signatures/validation/SignatureValidatorTest/";
+
+ private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
+
+ private ValidatorChainBuilder builder;
+
+ [NUnit.Framework.OneTimeSetUp]
+ public static void Before() {
+ }
+
+ [NUnit.Framework.SetUp]
+ public virtual void SetUp() {
+ builder = new ValidatorChainBuilder();
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void BaseXmlReportGenerationTest() {
+ using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "docWithMultipleSignaturesAndTimeStamp.pdf"
+ ))) {
+ AdESReportAggregator reportAggregator = new DefaultAdESReportAggregator();
+ builder.WithAdESReportAggregator(reportAggregator).BuildSignatureValidator(document).ValidateSignatures();
+ XmlReportGenerator reportGenerator = new XmlReportGenerator(new XmlReportOptions());
+ StringWriter stringWriter = new StringWriter();
+ reportGenerator.Generate(reportAggregator.GetReport(), stringWriter);
+ XmlReportTestTool testTool = new XmlReportTestTool(stringWriter.ToString());
+ NUnit.Framework.Assert.AreEqual("ValidationReport", testTool.GetDocumentNode().Name);
+ // There are 5 signatures, but 3 are timestamps
+ NUnit.Framework.Assert.AreEqual(2, testTool.CountElements("//r:SignatureValidationReport"));
+ XmlNodeList signatureValueNodes = testTool.ExecuteXpathAsNodeList("//r:SignatureValidationReport//ds:SignatureValue"
+ );
+ IList b64ReportedSignatures = new List(signatureValueNodes.Count);
+ for (int i = 0; i < signatureValueNodes.Count; i++) {
+ b64ReportedSignatures.Add(signatureValueNodes.Item(i).InnerText);
+ }
+ SignatureUtil sigUtil = new SignatureUtil(document);
+ foreach (String sigName in sigUtil.GetSignatureNames()) {
+ PdfSignature signature = sigUtil.GetSignature(sigName);
+ if (!PdfName.ETSI_RFC3161.Equals(signature.GetSubFilter())) {
+ CMSContainer cms = new CMSContainer(sigUtil.GetSignature(sigName).GetContents().GetValueBytes());
+ String b64signature = Convert.ToBase64String(cms.GetSignerInfo().GetSignatureData());
+ NUnit.Framework.Assert.IsTrue(b64ReportedSignatures.Contains(b64signature));
+ }
+ }
+ // For each reported signature the certificate is added to the validation objects
+ NUnit.Framework.Assert.IsTrue(testTool.CountElements("//r:ValidationObject[r:ObjectType=\"urn:etsi:019102:validationObject:certificate\"]"
+ ) >= 2);
+ NUnit.Framework.Assert.IsNull(testTool.ValidateXMLSchema());
+ }
+ }
+ }
+//\endcond
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/XmlReportTestHelper.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/XmlReportTestHelper.cs
new file mode 100644
index 0000000000..477f2a1fa3
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/validation/report/xml/XmlReportTestHelper.cs
@@ -0,0 +1,106 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ public class XmlReportTestHelper {
+ public const String SIGNATURE1_BASE64 = "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" + "AzELBgkqhkiG9w0BBwEwgdcGCyqGSIb3DQEJEAIvMYHHMIHEMIHBMIG+MAsGCWCGSAFlAwQCAwRA"
+ + "AkAgKLsU9tnszC7NHib9or5LV4PpvNPC47JHsVOAg7yosOar3GdSaJmTVDHsMgBkmQeuJZS0zodG" + "Rr997DnM9DBtMGWkYzBhMQswCQYDVQQGEwJCWTEOMAwGA1UEBwwFTWluc2sxDjAMBgNVBAoMBWlU"
+ + "ZXh0MQ0wCwYDVQQLDAR0ZXN0MSMwIQYDVQQDDBppVGV4dFRlc3RJbnRlcm1lZGlhdGVSc2EwMQIE" + "XGwsIjCCARMGCSqGSIb3DQEJBDGCAQQEggEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAL"
+ + "BgkqhkiG9w0BAQ0EggEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
+
+ public const String SIGNATURE2_BASE64 = "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" + "wpYmYmEvttxL6/8G14vWgq5wbF0=";
+ }
+}
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/1910202xmlSchema.xsd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/1910202xmlSchema.xsd
new file mode 100644
index 0000000000..9f63146e7c
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/1910202xmlSchema.xsd
@@ -0,0 +1,626 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XAdES.xsd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XAdES.xsd
new file mode 100644
index 0000000000..edce1e3984
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XAdES.xsd
@@ -0,0 +1,467 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XMLSchema.dtd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XMLSchema.dtd
new file mode 100644
index 0000000000..64aa2d9701
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XMLSchema.dtd
@@ -0,0 +1,513 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%xs-datatypes;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XMLSchema.xsd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XMLSchema.xsd
new file mode 100644
index 0000000000..12c2209110
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/XMLSchema.xsd
@@ -0,0 +1,2534 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]>
+
+
+
+ Part 1 version: Id: structures.xsd,v 1.2 2004/01/15 11:34:25 ht Exp
+ Part 2 version: Id: datatypes.xsd,v 1.3 2004/01/23 18:11:13 ht Exp
+
+
+
+
+
+ The schema corresponding to this document is normative,
+ with respect to the syntactic constraints it expresses in the
+ XML Schema language. The documentation (within <documentation> elements)
+ below, is not normative, but rather highlights important aspects of
+ the W3C Recommendation of which this is a part
+
+
+
+
+ The simpleType element and all of its members are defined
+ towards the end of this schema document
+
+
+
+
+
+ Get access to the xml: attribute groups for xml:lang
+ as declared on 'schema' and 'documentation' below
+
+
+
+
+
+
+
+ This type is extended by almost all schema types
+ to allow attributes from other namespaces to be
+ added to user schemas.
+
+
+
+
+
+
+
+
+
+
+
+
+ This type is extended by all types which allow annotation
+ other than <schema> itself
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This group is for the
+ elements which occur freely at the top level of schemas.
+ All of their types are based on the "annotated" type by extension.
+
+
+
+
+
+
+
+
+
+
+
+
+ This group is for the
+ elements which can self-redefine (see <redefine> below).
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ #all or (possibly empty) subset of {extension, restriction}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ #all or (possibly empty) subset of {extension, restriction, list, union}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ for maxOccurs
+
+
+
+
+
+
+
+
+
+
+
+ for all particles
+
+
+
+
+
+
+ for element, group and attributeGroup,
+ which both define and reference
+
+
+
+
+
+
+
+ 'complexType' uses this
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This branch is short for
+ <complexContent>
+ <restriction base="xs:anyType">
+ ...
+ </restriction>
+ </complexContent>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Will be restricted to required or forbidden
+
+
+
+
+
+ Not allowed if simpleContent child is chosen.
+ May be overriden by setting on complexContent child.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This choice is added simply to
+ make this a valid restriction per the REC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides any setting on complexType parent.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This choice is added simply to
+ make this a valid restriction per the REC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No typeDefParticle group reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ #all or (possibly empty) subset of {substitution, extension,
+ restriction}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The element element can be used either
+ at the top level to define an element-type binding globally,
+ or within a content model to either reference a globally-defined
+ element or type or declare an element-type binding locally.
+ The ref form is not allowed at the top level.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ group type for explicit groups, named top-level groups and
+ group references
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ group type for the three kinds of group
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This choice with min/max is here to
+ avoid a pblm with the Elt:All/Choice/Seq
+ Particle derivation constraint
+
+
+
+
+
+
+
+
+
+ restricted max/min
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Only elements allowed inside
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ simple type for the value of the 'namespace' attr of
+ 'any' and 'anyAttribute'
+
+
+
+ Value is
+ ##any - - any non-conflicting WFXML/attribute at all
+
+ ##other - - any non-conflicting WFXML/attribute from
+ namespace other than targetNS
+
+ ##local - - any unqualified non-conflicting WFXML/attribute
+
+ one or - - any non-conflicting WFXML/attribute from
+ more URI the listed namespaces
+ references
+ (space separated)
+
+ ##targetNamespace or ##local may appear in the above list, to
+ refer to the targetNamespace of the enclosing
+ schema or an absent targetNamespace respectively
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A subset of XPath expressions for use
+in selectors
+ A utility type, not for public
+use
+
+
+
+ The following pattern is intended to allow XPath
+ expressions per the following EBNF:
+ Selector ::= Path ( '|' Path )*
+ Path ::= ('.//')? Step ( '/' Step )*
+ Step ::= '.' | NameTest
+ NameTest ::= QName | '*' | NCName ':' '*'
+ child:: is also allowed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A subset of XPath expressions for use
+in fields
+ A utility type, not for public
+use
+
+
+
+ The following pattern is intended to allow XPath
+ expressions per the same EBNF as for selector,
+ with the following change:
+ Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The three kinds of identity constraints, all with
+ type of or derived from 'keybase'.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ A public identifier, per ISO 8879
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ notations for use within XML Schema schemas
+
+
+
+
+
+
+
+
+ Not the real urType, but as close an approximation as we can
+ get in the XML representation
+
+
+
+
+
+
+
+
+
+ First the built-in primitive datatypes. These definitions are for
+ information only, the real built-in definitions are magic.
+
+
+
+ For each built-in datatype in this schema (both primitive and
+ derived) can be uniquely addressed via a URI constructed
+ as follows:
+ 1) the base URI is the URI of the XML Schema namespace
+ 2) the fragment identifier is the name of the datatype
+
+ For example, to address the int datatype, the URI is:
+
+ http://www.w3.org/2001/XMLSchema#int
+
+ Additionally, each facet definition element can be uniquely
+ addressed via a URI constructed as follows:
+ 1) the base URI is the URI of the XML Schema namespace
+ 2) the fragment identifier is the name of the facet
+
+ For example, to address the maxInclusive facet, the URI is:
+
+ http://www.w3.org/2001/XMLSchema#maxInclusive
+
+ Additionally, each facet usage in a built-in datatype definition
+ can be uniquely addressed via a URI constructed as follows:
+ 1) the base URI is the URI of the XML Schema namespace
+ 2) the fragment identifier is the name of the datatype, followed
+ by a period (".") followed by the name of the facet
+
+ For example, to address the usage of the maxInclusive facet in
+ the definition of int, the URI is:
+
+ http://www.w3.org/2001/XMLSchema#int.maxInclusive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NOTATION cannot be used directly in a schema; rather a type
+ must be derived from it by specifying at least one enumeration
+ facet whose value is the name of a NOTATION declared in the
+ schema.
+
+
+
+
+
+
+
+
+
+ Now the derived primitive types
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern specifies the content of section 2.12 of XML 1.0e2
+ and RFC 3066 (Revised version of RFC 1766).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern matches production 7 from the XML spec
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern matches production 5 from the XML spec
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern matches production 4 from the Namespaces in XML spec
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #all or (possibly empty) subset of {restriction, union, list}
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Can be restricted to required or forbidden
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Required at the top level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Forbidden when nested
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ We should use a substitution group for facets, but
+ that's ruled out because it would allow users to
+ add their own, which we're not ready for yet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ base attribute and simpleType child are mutually
+ exclusive, but one or other is required
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ itemType attribute and simpleType child are mutually
+ exclusive, but one or other is required
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ memberTypes attribute must be non-empty or there must be
+ at least one simpleType child
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/datatypes.dtd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/datatypes.dtd
new file mode 100644
index 0000000000..8e48553bee
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/datatypes.dtd
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/ts_119612v020201_201601xsd.xsd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/ts_119612v020201_201601xsd.xsd
new file mode 100644
index 0000000000..ca8192b338
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/ts_119612v020201_201601xsd.xsd
@@ -0,0 +1,457 @@
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.1.4 Language support
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.1.4 Language support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.5 Scheme operator address
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.5.1 Scheme operator postal address
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.5.2 Scheme operator electronic address
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.17 Scheme extensions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.1.4 Language support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.18 Trust Service Provider List
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3 Scheme information
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.3 TSL type
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.4 Scheme operator name
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.6 Scheme name
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.7 Scheme information URI
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.9 Scheme type/community/rules
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.10 Scheme territory
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.11 TSL policy/legal notice
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.15 Next update
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.13 Pointers to other TSLs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pecified in TS 119 612 v2.1.1 clause 5.3.13 Pointers to other TSLs item b) from Format
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.13 Pointers to other TSLs item c) from Format
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.16 Distribution points
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.3.18 Trust Service Provider List
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.4 TSP information
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.4.6 TSP Services (list of services)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5 Service information
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5.4 Service current status
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5.7 Service supply points
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5.1 Service type identifier
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5.3 Service digital identity
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5.10 Service history
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.6 Service history instance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5.9.4 expiredCertsRevocationInfo Extension
+
+
+ Specified in TS 119 612 v2.1.1 clause 5.5.9.1 additionalServiceInformation Extension
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/xml.xsd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/xml.xsd
new file mode 100644
index 0000000000..d662b4236c
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/xml.xsd
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+
+
+
+
+ This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang or xml:space attributes
+ on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ <schema . . .>
+ . . .
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ <type . . .>
+ . . .
+ <attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes
+
+
+
+ In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2001/03/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself. In other words, if the XML Schema namespace changes, the version
+ of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2001/03/xml.xsd will not change.
+
+
+
+
+
+ In due course, we should install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values . . .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.
+
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/xmldsig-core-schema.xsd b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/xmldsig-core-schema.xsd
new file mode 100644
index 0000000000..df126b30e6
--- /dev/null
+++ b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/report/xml/xmldsig-core-schema.xsd
@@ -0,0 +1,318 @@
+
+
+
+
+
+ ]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/itext.tests/itext.svg.tests/itext/svg/css/SvgStyleResolverIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/css/SvgStyleResolverIntegrationTest.cs
index 1b6895900d..ffb059b433 100644
--- a/itext.tests/itext.svg.tests/itext/svg/css/SvgStyleResolverIntegrationTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/css/SvgStyleResolverIntegrationTest.cs
@@ -199,5 +199,15 @@ public virtual void RelativeStyleInheritanceTest() {
public virtual void TextTagNoFontSizeTest() {
ConvertAndCompare(sourceFolder, destinationFolder, "textTagNoFontSize");
}
+
+ [NUnit.Framework.Test]
+ public virtual void ChartWithText1Test() {
+ ConvertAndCompare(sourceFolder, destinationFolder, "chartWithText1");
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void ChartWithText2Test() {
+ ConvertAndCompare(sourceFolder, destinationFolder, "chartWithText2");
+ }
}
}
diff --git a/itext.tests/itext.svg.tests/itext/svg/css/XLinkTest.cs b/itext.tests/itext.svg.tests/itext/svg/css/XLinkTest.cs
index 77054781a5..e5530ec464 100644
--- a/itext.tests/itext.svg.tests/itext/svg/css/XLinkTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/css/XLinkTest.cs
@@ -22,8 +22,11 @@ You should have received a copy of the GNU Affero General Public License
*/
using System;
using System.Collections.Generic;
+using iText.IO.Source;
+using iText.Kernel.Pdf;
using iText.StyledXmlParser.Node.Impl.Jsoup.Node;
using iText.Svg;
+using iText.Svg.Converter;
using iText.Svg.Css.Impl;
using iText.Svg.Processors.Impl;
using iText.Test;
@@ -68,5 +71,22 @@ public virtual void SvgCssResolveDataXlinkTest() {
attr = sr.ResolveStyles(node, new SvgCssContext());
NUnit.Framework.Assert.AreEqual(value3, attr.Get("xlink:href"));
}
+
+ [NUnit.Framework.Test]
+ [LogMessage(iText.StyledXmlParser.Logs.StyledXmlParserLogMessageConstant.UNABLE_TO_RETRIEVE_IMAGE_WITH_GIVEN_BASE_URI
+ )]
+ public virtual void SvgCssResolveMalformedXlink2Test() {
+ PdfWriter writer = new PdfWriter(new ByteArrayOutputStream());
+ PdfDocument pdfDoc = new PdfDocument(writer);
+ pdfDoc.AddNewPage();
+ String svg = "\n" + "\n" + "";
+ int pagenr = 1;
+ // Does not throw
+ SvgConverter.DrawOnDocument(svg, pdfDoc, pagenr);
+ pdfDoc.Close();
+ }
}
}
diff --git a/itext.tests/itext.svg.tests/itext/svg/jfreesvg/JFreeSvgTest.cs b/itext.tests/itext.svg.tests/itext/svg/jfreesvg/JFreeSvgTest.cs
index 7864aa7815..9e21839dce 100644
--- a/itext.tests/itext.svg.tests/itext/svg/jfreesvg/JFreeSvgTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/jfreesvg/JFreeSvgTest.cs
@@ -41,14 +41,12 @@ public static void BeforeClass() {
//Do not make changes in svg file because it was generated by JFreeSVG
[NUnit.Framework.Test]
public virtual void UsingJFreeSvgFromStringTest() {
- //TODO: update cmp-file when DEVSIX-2246 will be fixed
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "rectangleFromStringTest");
}
//Do not make changes in svg file because it was generated by JFreeSVG
[NUnit.Framework.Test]
public virtual void UsingJFreeSvgFromFileTest() {
- //TODO: update cmp-file when DEVSIX-2246 will be fixed
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "rectangleFromFileTest");
}
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/FillTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/FillTest.cs
index e93f382c70..305a7cee0f 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/FillTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/FillTest.cs
@@ -22,7 +22,9 @@ You should have received a copy of the GNU Affero General Public License
*/
using System;
using iText.Svg.Exceptions;
+using iText.Svg.Logs;
using iText.Test;
+using iText.Test.Attributes;
namespace iText.Svg.Renderers {
[NUnit.Framework.Category("IntegrationTest")]
@@ -58,7 +60,6 @@ public virtual void EoFillTest() {
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "eofill");
}
- /* This test should fail when DEVSIX-2251 is resolved*/
[NUnit.Framework.Test]
public virtual void EoFillTest01() {
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "eofill01");
@@ -84,7 +85,6 @@ public virtual void EoFillStrokeTest() {
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "eofillstroke");
}
- /* This test should fail when DEVSIX-2251 is resolved*/
[NUnit.Framework.Test]
public virtual void NonZeroFillTest() {
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "nonzerofill");
@@ -116,5 +116,12 @@ public virtual void InvalidUrlFillTest() {
//TODO update cmp file after DEVSIX-3365 will be fixed
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "invalidUrlFillTest");
}
+
+ [NUnit.Framework.Test]
+ [LogMessage(SvgLogMessageConstant.UNMAPPED_TAG, Count = 4)]
+ public virtual void TextFillFallbackTest() {
+ //TODO update cmp file after DEVSIX-2915 will be fixed
+ ConvertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "textFillFallbackTest");
+ }
}
}
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs
index 5e9f0b14d9..e69c69bf2b 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs
@@ -58,6 +58,12 @@ public virtual void StrokeWithDashesTest() {
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "strokeWithDashes");
}
+ [NUnit.Framework.Test]
+ public virtual void OverrideStrokeWidthTest() {
+ //TODO: update cmp-file after DEVSIX-2247 - SVG: Attributes override style declarations in style tags
+ ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "overrideStrokeWidth");
+ }
+
[NUnit.Framework.Test]
public virtual void AdvancedStrokeTest() {
//TODO: update cmp-file after DEVSIX-2258
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.cs
index 7d8230bbf6..4bb6fff9b6 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ClipPathSvgNodeRendererIntegrationTest.cs
@@ -101,6 +101,7 @@ public virtual void ClipPathCss() {
[NUnit.Framework.Test]
public virtual void ClipPathCssProperty() {
+ //TODO: update after DEVSIX-2828
properties = new SvgConverterProperties().SetBaseUri(sourceFolder);
ConvertAndCompareSinglePage(sourceFolder, destinationFolder, "clipPathCssProperty", properties);
}
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ImageSvgNodeRendererIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ImageSvgNodeRendererIntegrationTest.cs
index 826548af5d..74dbb5d2bd 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ImageSvgNodeRendererIntegrationTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/ImageSvgNodeRendererIntegrationTest.cs
@@ -115,7 +115,7 @@ public virtual void DifferentDimensionsTest() {
[NUnit.Framework.Test]
public virtual void ImageWithTransparencyTest() {
- //TODO: update cmp_ when DEVSIX-2250, DEVSIX-2258 fixed
+ //TODO: update cmp_ when DEVSIX-2258 fixed
ConvertAndCompareSinglePage(sourceFolder, destinationFolder, "imageWithTransparency", properties);
}
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs
index 77e508cd73..be6de9b313 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs
@@ -258,6 +258,11 @@ public virtual void MarkerOverflowVisibleNestedSvgViewBoxesTest() {
ConvertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOverflowVisibleNestedSvgViewBoxes");
}
+ [NUnit.Framework.Test]
+ public virtual void SquareInNotSquareViewBoxTest() {
+ ConvertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "squareInNotSquareViewBox");
+ }
+
[NUnit.Framework.Test]
public virtual void MarkerOverflowVisibleNestedSvgViewBoxes2Test() {
ConvertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOverflowVisibleNestedSvgViewBoxes2");
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathParsingIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathParsingIntegrationTest.cs
index 854cf71b1f..6543b20523 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathParsingIntegrationTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathParsingIntegrationTest.cs
@@ -85,21 +85,16 @@ public virtual void InvalidOperatorCSensTest() {
[NUnit.Framework.Test]
public virtual void MoreThanOneHParam() {
- // TODO DEVSIX-2331 Update the cmp after the issue is resolved
- // UPD: Seems to be fixed now, but leaving the remark and issue open because the scope of the issue might be bigger than
- // this test
ConvertAndCompare(sourceFolder, destinationFolder, "moreThanOneHParam");
}
[NUnit.Framework.Test]
public virtual void NegativeAfterPositiveHandlingTest01() {
- //TODO update after DEVSIX-2331 - several (negative) line operators
ConvertAndCompare(sourceFolder, destinationFolder, "negativeAfterPositiveHandling");
}
[NUnit.Framework.Test]
public virtual void NegativeAfterPositiveHandlingTest02() {
- //TODO update after DEVSIX-2333 (negative viewbox) fix
ConvertAndCompare(sourceFolder, destinationFolder, "negativeAfterPositiveHandlingExtendedViewbox");
}
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathSvgNodeRendererTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathSvgNodeRendererTest.cs
index dfabf37023..4d4d7415e4 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathSvgNodeRendererTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PathSvgNodeRendererTest.cs
@@ -260,7 +260,6 @@ public virtual void InvalidOperatorTest() {
, "invalidOperatorTest01"));
}
- //TODO DEVSIX-2242. This test should fail when the ticket is resolved
[NUnit.Framework.Test]
public virtual void PathLOperatorMultipleCoordinates() {
ConvertAndCompare(sourceFolder, destinationFolder, "pathLOperatorMultipleCoordinates");
diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.cs
index 2aa2eba3f7..f43dc6d304 100644
--- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.cs
+++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/PreserveAspectRatioSvgNodeRendererIntegrationTest.cs
@@ -58,7 +58,6 @@ public virtual void ViewBoxWithoutSetPreserveAspectRatioTest() {
[LogMessage(iText.StyledXmlParser.Logs.StyledXmlParserLogMessageConstant.INVALID_CSS_PROPERTY_DECLARATION,
Count = 19)]
public virtual void DifferentAspectRatiosTest() {
- //TODO: update cmp_ when DEVSIX-2250 fixed
ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "differentAspectRatios");
}
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/chartWithText1.svg b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/chartWithText1.svg
new file mode 100644
index 0000000000..8af3250682
--- /dev/null
+++ b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/chartWithText1.svg
@@ -0,0 +1,457 @@
+
\ No newline at end of file
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/chartWithText2.svg b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/chartWithText2.svg
new file mode 100644
index 0000000000..de7cbb85d4
--- /dev/null
+++ b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/chartWithText2.svg
@@ -0,0 +1,114 @@
+
\ No newline at end of file
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/cmp_chartWithText1.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/cmp_chartWithText1.pdf
new file mode 100644
index 0000000000..7d506a727b
Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/cmp_chartWithText1.pdf differ
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/cmp_chartWithText2.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/cmp_chartWithText2.pdf
new file mode 100644
index 0000000000..e8265d05f3
Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/css/SvgStyleResolver/cmp_chartWithText2.pdf differ
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/FillTest/cmp_textFillFallbackTest.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/FillTest/cmp_textFillFallbackTest.pdf
new file mode 100644
index 0000000000..d4b0217dfb
Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/FillTest/cmp_textFillFallbackTest.pdf differ
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/FillTest/textFillFallbackTest.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/FillTest/textFillFallbackTest.svg
new file mode 100644
index 0000000000..e52d0c59e2
--- /dev/null
+++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/FillTest/textFillFallbackTest.svg
@@ -0,0 +1,49 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_squareInNotSquareViewBox.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_squareInNotSquareViewBox.pdf
new file mode 100644
index 0000000000..aa3d66d8ae
Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_squareInNotSquareViewBox.pdf differ
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/squareInNotSquareViewBox.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/squareInNotSquareViewBox.svg
new file mode 100644
index 0000000000..7e4f96e110
--- /dev/null
+++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/squareInNotSquareViewBox.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_overrideStrokeWidth.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_overrideStrokeWidth.pdf
new file mode 100644
index 0000000000..60049b8172
Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_overrideStrokeWidth.pdf differ
diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/overrideStrokeWidth.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/overrideStrokeWidth.svg
new file mode 100644
index 0000000000..9b1911ef42
--- /dev/null
+++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/overrideStrokeWidth.svg
@@ -0,0 +1,17 @@
+
+
+
\ No newline at end of file
diff --git a/itext/itext.sign/itext/signatures/PdfPKCS7.cs b/itext/itext.sign/itext/signatures/PdfPKCS7.cs
index 8137d9383c..7faf3d1fec 100644
--- a/itext/itext.sign/itext/signatures/PdfPKCS7.cs
+++ b/itext/itext.sign/itext/signatures/PdfPKCS7.cs
@@ -1234,6 +1234,9 @@ public virtual IX509Certificate[] GetCertificates() {
/// array
///
public virtual IX509Certificate[] GetTimestampCertificates() {
+ if (timestampCerts == null) {
+ return new IX509Certificate[0];
+ }
return timestampCerts.ToArray(new IX509Certificate[0]);
}
diff --git a/itext/itext.sign/itext/signatures/validation/SignatureValidator.cs b/itext/itext.sign/itext/signatures/validation/SignatureValidator.cs
index 199f9f763b..882b3ffd7a 100644
--- a/itext/itext.sign/itext/signatures/validation/SignatureValidator.cs
+++ b/itext/itext.sign/itext/signatures/validation/SignatureValidator.cs
@@ -23,6 +23,7 @@ You should have received a copy of the GNU Affero General Public License
using System;
using System.Collections.Generic;
using System.IO;
+using System.Text;
using iText.Bouncycastleconnector;
using iText.Commons.Actions.Contexts;
using iText.Commons.Bouncycastle;
@@ -110,6 +111,8 @@ public class SignatureValidator {
private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory
();
+ private readonly ValidatorChainBuilder builder;
+
private ValidationContext validationContext = new ValidationContext(ValidatorContext.SIGNATURE_VALIDATOR,
CertificateSource.SIGNER_CERT, TimeBasedContext.PRESENT);
@@ -148,6 +151,7 @@ public class SignatureValidator {
///
protected internal SignatureValidator(PdfDocument originalDocument, ValidatorChainBuilder builder) {
this.originalDocument = originalDocument;
+ this.builder = builder;
this.certificateRetriever = builder.GetCertificateRetriever();
this.properties = builder.GetProperties();
this.certificateChainValidator = builder.GetCertificateChainValidator();
@@ -234,6 +238,7 @@ internal virtual ValidationReport ValidateLatestSignature(PdfDocument document)
// We only retrieve not signed revocation data at the very beginning of signature processing.
RetrieveNotSignedRevocationInfoFromSignatureContainer(pkcs7, validationContext);
if (StopValidation(validationReport, validationContext)) {
+ ReportResult(validationReport);
return validationReport;
}
IList certificatesFromDss = GetCertificatesFromDss(validationReport, document);
@@ -245,6 +250,7 @@ internal virtual ValidationReport ValidateLatestSignature(PdfDocument document)
if (UpdateLastKnownPoE(validationReport, pkcs7.GetTimeStampTokenInfo())) {
UpdateValidationClients(pkcs7, validationReport, validationContext, document);
}
+ ReportResult(validationReport);
return validationReport;
}
bool isPoEUpdated = false;
@@ -260,6 +266,7 @@ internal virtual ValidationReport ValidateLatestSignature(PdfDocument document)
}
validationReport.Merge(tsValidationReport);
if (StopValidation(tsValidationReport, validationContext)) {
+ ReportResult(validationReport);
return validationReport;
}
}
@@ -281,10 +288,25 @@ internal virtual ValidationReport ValidateLatestSignature(PdfDocument document)
RetrieveSignedRevocationInfoFromSignatureContainer(timestampSignatureContainer, validationContext);
UpdateValidationClients(pkcs7, validationReport, validationContext, document);
}
+ ReportResult(validationReport);
return validationReport.Merge(signatureReport);
}
//\endcond
+ private void ReportResult(ValidationReport validationReport) {
+ if (validationReport.GetValidationResult() == ValidationReport.ValidationResult.VALID) {
+ builder.GetAdESReportAggregator().ReportSignatureValidationSuccess();
+ return;
+ }
+ StringBuilder reason = new StringBuilder("[");
+ foreach (ReportItem reportItem in validationReport.GetFailures()) {
+ reason.Append(reportItem).Append("\n");
+ }
+ reason.Append("]");
+ builder.GetAdESReportAggregator().ReportSignatureValidationFailure(validationReport.GetValidationResult()
+ == ValidationReport.ValidationResult.INDETERMINATE, reason.ToString());
+ }
+
private ValidationReport Validate(String signatureName) {
ValidationReport validationReport = new ValidationReport();
bool validateSingleSignature = signatureName != null;
@@ -349,6 +371,14 @@ private PdfPKCS7 MathematicallyVerifySignature(ValidationReport validationReport
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData(latestSignatureName);
validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(VALIDATING_SIGNATURE_NAME
, latestSignatureName), ReportItem.ReportItemStatus.INFO));
+ if (pkcs7.IsTsp()) {
+ builder.GetAdESReportAggregator().ProofOfExistenceFound(signatureUtil.GetSignature(latestSignatureName).GetContents
+ ().GetValueBytes(), true);
+ }
+ else {
+ builder.GetAdESReportAggregator().StartSignatureValidation(signatureUtil.GetSignature(latestSignatureName)
+ .GetContents().GetValueBytes(), latestSignatureName, lastKnownPoE);
+ }
if (!signatureUtil.SignatureCoversWholeDocument(latestSignatureName)) {
validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(DOCUMENT_IS_NOT_COVERED
, latestSignatureName), ReportItem.ReportItemStatus.INVALID));
diff --git a/itext/itext.sign/itext/signatures/validation/ValidatorChainBuilder.cs b/itext/itext.sign/itext/signatures/validation/ValidatorChainBuilder.cs
index cbd6fef9c4..c01836f193 100644
--- a/itext/itext.sign/itext/signatures/validation/ValidatorChainBuilder.cs
+++ b/itext/itext.sign/itext/signatures/validation/ValidatorChainBuilder.cs
@@ -25,6 +25,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Cert;
using iText.Kernel.Pdf;
using iText.Signatures;
+using iText.Signatures.Validation.Report.Xml;
namespace iText.Signatures.Validation {
/// A builder class to construct all necessary parts of a validation chain.
@@ -51,6 +52,8 @@ public class ValidatorChainBuilder {
private ICollection knownCertificates;
+ private AdESReportAggregator adESReportAggregator = new NullAdESReportAggregator();
+
///
/// Create a new
///
@@ -260,6 +263,23 @@ public virtual ValidatorChainBuilder WithTrustedCertificates(ICollectionUse this AdES report aggregator to enable AdES compliant report generation.
+ ///
+ /// Use this AdES report aggregator to enable AdES compliant report generation.
+ ///
+ /// Generated
+ ///
+ /// report could be provided to
+ /// .
+ ///
+ /// the report aggregator to use
+ /// the current ValidatorChainBuilder
+ public virtual ValidatorChainBuilder WithAdESReportAggregator(AdESReportAggregator adESReportAggregator) {
+ this.adESReportAggregator = adESReportAggregator;
+ return this;
+ }
+
///
/// Retrieves the explicitly added or automatically created
///
@@ -294,6 +314,27 @@ public virtual SignatureValidationProperties GetProperties() {
return properties;
}
+ ///
+ /// Retrieves the explicitly added or automatically created
+ ///
+ /// instance.
+ ///
+ ///
+ /// Retrieves the explicitly added or automatically created
+ ///
+ /// instance.
+ /// Default is the
+ /// .
+ ///
+ ///
+ /// the explicitly added or automatically created
+ ///
+ /// instance.
+ ///
+ public virtual AdESReportAggregator GetAdESReportAggregator() {
+ return adESReportAggregator;
+ }
+
//\cond DO_NOT_DOCUMENT
///
/// Retrieves the explicitly added or automatically created
diff --git a/itext/itext.sign/itext/signatures/validation/report/ValidationReport.cs b/itext/itext.sign/itext/signatures/validation/report/ValidationReport.cs
index e69dd4c816..319a9f1489 100644
--- a/itext/itext.sign/itext/signatures/validation/report/ValidationReport.cs
+++ b/itext/itext.sign/itext/signatures/validation/report/ValidationReport.cs
@@ -38,7 +38,7 @@ public class ValidationReport {
public ValidationReport() {
}
- // Empty constructor.
+ // Declaring default constructor explicitly to avoid removing it unintentionally.
/// Get the result of a validation process.
///
///
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/AbstractCollectableObject.cs b/itext/itext.sign/itext/signatures/validation/report/xml/AbstractCollectableObject.cs
new file mode 100644
index 0000000000..57b4b4fad2
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/AbstractCollectableObject.cs
@@ -0,0 +1,35 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal abstract class AbstractCollectableObject : AbstractIdentifiableObject, CollectableObject {
+ protected internal AbstractCollectableObject(String prefix)
+ : base(prefix) {
+ }
+
+ public abstract void Accept(CollectableObjectVisitor arg1);
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/AbstractIdentifiableObject.cs b/itext/itext.sign/itext/signatures/validation/report/xml/AbstractIdentifiableObject.cs
new file mode 100644
index 0000000000..48df245832
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/AbstractIdentifiableObject.cs
@@ -0,0 +1,43 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal abstract class AbstractIdentifiableObject : IdentifiableObject {
+ private readonly Identifier id;
+
+ protected internal AbstractIdentifiableObject(String prefix) {
+ id = new Identifier(prefix + "-" + Guid.NewGuid().ToString());
+ }
+
+ public virtual Identifier GetIdentifier() {
+ return id;
+ }
+
+ public abstract override bool Equals(Object o);
+
+ public abstract override int GetHashCode();
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/AdESReportAggregator.cs b/itext/itext.sign/itext/signatures/validation/report/xml/AdESReportAggregator.cs
new file mode 100644
index 0000000000..01bc8cde0c
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/AdESReportAggregator.cs
@@ -0,0 +1,110 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ /// The interface for AdES reports aggregator implementations.
+ public interface AdESReportAggregator {
+ /// Called at the start of a signature validation
+ /// signature container as a byte[]
+ /// signature name
+ /// the signing date
+ void StartSignatureValidation(byte[] signature, String name, DateTime signingDate);
+
+ /// Called when a timestamp is encountered
+ /// timestamp container as a byte[]
+ /// true when the timestamp is document level, false for a signature timestamp
+ void ProofOfExistenceFound(byte[] timeStampSignature, bool document);
+
+ /// Called after a successful validation of the current signature
+ void ReportSignatureValidationSuccess();
+
+ /// Called after signature validation failed for the current signature
+ ///
+ ///
+ ///
+ /// when validation is neither valid nor invalid,
+ ///
+ /// when it is invalid
+ ///
+ /// the failure reason
+ void ReportSignatureValidationFailure(bool isInconclusive, String reason);
+
+ // code for future use commented out for code coverage
+ // /**
+ // * Called after certificate chain validation success for the current signature
+ // *
+ // * @param certificate the certificate that was tested
+ // */
+ // void reportCertificateChainValidationSuccess(X509Certificate certificate);
+ //
+ // /**
+ // * Called after certificate chain validation failed for the current signature
+ // *
+ // * @param certificate the validated certificate
+ // * @param isInconclusive false when validation is neither valid or invalid
+ // * @param reason the failure reason
+ // */
+ // void reportCertificateChainValidationFailure(X509Certificate certificate, boolean isInconclusive, String reason);
+ //
+ // /**
+ // * Called after crl validation success for the current signature
+ // *
+ // * @param certificate the validated certificate
+ // * @param crl the crl being tested
+ // */
+ // void reportCRLValidationSuccess(X509Certificate certificate, CRL crl);
+ //
+ // /**
+ // * Called after crl validation failed for the current signature
+ // *
+ // * @param certificate the validated certificate
+ // * @param crl the crl being tested
+ // * @param isInconclusive false when validation is neither valid or invalid
+ // * @param reason the failure reason
+ // */
+ // void reportCRLValidationFailure(X509Certificate certificate, CRL crl, boolean isInconclusive, String reason);
+ //
+ // /**
+ // * Called after ocsp validation success for the current signature
+ // *
+ // * @param certificate the validated certificate
+ // * @param ocsp the
+ // */
+ // void reportOCSPValidationSuccess(X509Certificate certificate, IBasicOCSPResp ocsp);
+ //
+ // /**
+ // * Called after ocsp validation failed for the current signature
+ // *
+ // * @param certificate the validated certificate
+ // * @param ocsp the
+ // * @param isInconclusive false when validation is neither valid or invalid
+ // * @param reason the failure reason
+ // */
+ // void reportOCSPValidationFailure(X509Certificate certificate, IBasicOCSPResp ocsp, boolean isInconclusive,
+ // String reason);
+ /// Retrieves the generated report
+ /// the generated report
+ PadesValidationReport GetReport();
+ }
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/CertificateWrapper.cs b/itext/itext.sign/itext/signatures/validation/report/xml/CertificateWrapper.cs
new file mode 100644
index 0000000000..43c422d3d3
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/CertificateWrapper.cs
@@ -0,0 +1,68 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using Org.BouncyCastle.Security.Certificates;
+using iText.Commons.Bouncycastle.Cert;
+using iText.Commons.Utils;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class CertificateWrapper : AbstractCollectableObject {
+ private readonly IX509Certificate certificate;
+
+ public CertificateWrapper(IX509Certificate signingCertificate)
+ : base("C") {
+ this.certificate = signingCertificate;
+ }
+
+ public override void Accept(CollectableObjectVisitor visitor) {
+ visitor.Visit(this);
+ }
+
+ public override bool Equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || GetType() != o.GetType()) {
+ return false;
+ }
+ iText.Signatures.Validation.Report.Xml.CertificateWrapper that = (iText.Signatures.Validation.Report.Xml.CertificateWrapper
+ )o;
+ return certificate.Equals(that.certificate);
+ }
+
+ public override int GetHashCode() {
+ return JavaUtil.ArraysHashCode(certificate);
+ }
+
+ public virtual String GetBase64ASN1Structure() {
+ try {
+ return Convert.ToBase64String(certificate.GetEncoded());
+ }
+ catch (CertificateEncodingException e) {
+ throw new Exception("Error encoding certificate.", e);
+ }
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/CollectableObject.cs b/itext/itext.sign/itext/signatures/validation/report/xml/CollectableObject.cs
new file mode 100644
index 0000000000..138c88abb2
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/CollectableObject.cs
@@ -0,0 +1,29 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal interface CollectableObject : IdentifiableObject {
+ void Accept(CollectableObjectVisitor visitor);
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/CollectableObjectVisitor.cs b/itext/itext.sign/itext/signatures/validation/report/xml/CollectableObjectVisitor.cs
new file mode 100644
index 0000000000..093728a1f2
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/CollectableObjectVisitor.cs
@@ -0,0 +1,31 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal interface CollectableObjectVisitor {
+ void Visit(CertificateWrapper certificateWrapper);
+
+ void Visit(POEValidationReport poeValidationReport);
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/DefaultAdESReportAggregator.cs b/itext/itext.sign/itext/signatures/validation/report/xml/DefaultAdESReportAggregator.cs
new file mode 100644
index 0000000000..e9e2dfe228
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/DefaultAdESReportAggregator.cs
@@ -0,0 +1,132 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.Logging;
+using iText.Commons;
+using iText.Signatures.Cms;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ /// Use this implementation when an xml report has to be created
+ public class DefaultAdESReportAggregator : AdESReportAggregator {
+ private static readonly ILogger LOGGER = ITextLogManager.GetLogger(typeof(iText.Signatures.Validation.Report.Xml.DefaultAdESReportAggregator
+ ));
+
+ private readonly ValidationObjects validationObjects = new ValidationObjects();
+
+ private readonly PadesValidationReport report;
+
+ private readonly Stack validationReportStack = new Stack();
+
+ /// Instantiates a new DefaultAdESReportAggregator instance
+ public DefaultAdESReportAggregator() {
+ report = new PadesValidationReport(validationObjects);
+ }
+
+ // Declaring default constructor explicitly to avoid removing it unintentionally
+ public virtual void StartSignatureValidation(byte[] signature, String name, DateTime signingDate) {
+ try {
+ SignatureValidationReport currentSignatureValidationReport = new SignatureValidationReport(validationObjects
+ , new CMSContainer(signature), name, signingDate);
+ validationReportStack.Push(currentSignatureValidationReport);
+ report.AddSignatureValidationReport(currentSignatureValidationReport);
+ }
+ catch (Exception e) {
+ // catching generic Exception here for portability
+ LOGGER.LogError(e, "Unable to parse signature container.");
+ throw new ArgumentException("Signature is not parsable", e);
+ }
+ }
+
+ public virtual void ProofOfExistenceFound(byte[] timeStampSignature, bool document) {
+ try {
+ POEValidationReport currentValidationReport = new POEValidationReport(validationObjects, new CMSContainer(
+ timeStampSignature), document);
+ validationReportStack.Push(currentValidationReport);
+ validationObjects.AddObject(currentValidationReport);
+ }
+ catch (Exception e) {
+ // catching generic Exception here for portability
+ LOGGER.LogError(e, "Unable to parse timestamp signature container.");
+ throw new ArgumentException("Timestamp signature is not parsable", e);
+ }
+ }
+
+ public virtual void ReportSignatureValidationSuccess() {
+ SignatureValidationStatus status = new SignatureValidationStatus();
+ status.SetMainIndication(SignatureValidationStatus.MainIndication.TOTAL_PASSED);
+ SubValidationReport currentValidationReport = validationReportStack.Pop();
+ currentValidationReport.SetSignatureValidationStatus(status);
+ }
+
+ public virtual void ReportSignatureValidationFailure(bool isInconclusive, String reason) {
+ SignatureValidationStatus status = new SignatureValidationStatus();
+ if (isInconclusive) {
+ status.SetMainIndication(SignatureValidationStatus.MainIndication.INDETERMINATE);
+ }
+ else {
+ status.SetMainIndication(SignatureValidationStatus.MainIndication.TOTAL_FAILED);
+ }
+ status.AddMessage(reason, SignatureValidationStatus.MessageType.ERROR);
+ SubValidationReport currentValidationReport = validationReportStack.Pop();
+ currentValidationReport.SetSignatureValidationStatus(status);
+ }
+
+ // code for future use commented out for code coverage
+ // @Override
+ // public void reportCertificateChainValidationSuccess(X509Certificate certificate) {
+ // //will be completed later
+ // }
+ //
+ // @Override
+ // public void reportCertificateChainValidationFailure(X509Certificate certificate, boolean isInconclusive,
+ // String reason) {
+ // //will be completed later
+ // }
+ //
+ // @Override
+ // public void reportCRLValidationSuccess(X509Certificate certificate, CRL crl) {
+ // //will be completed later
+ // }
+ //
+ // @Override
+ // public void reportCRLValidationFailure(X509Certificate certificate, CRL crl, boolean isInconclusive,
+ // String reason) {
+ // //will be completed later
+ // }
+ //
+ // @Override
+ // public void reportOCSPValidationSuccess(X509Certificate certificate, IBasicOCSPResp ocsp) {
+ // //will be completed later
+ // }
+ //
+ // @Override
+ // public void reportOCSPValidationFailure(X509Certificate certificate, IBasicOCSPResp ocsp, boolean isInconclusive,
+ // String reason) {
+ // //will be completed later
+ // }
+ public virtual PadesValidationReport GetReport() {
+ return report;
+ }
+ }
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/IdentifiableObject.cs b/itext/itext.sign/itext/signatures/validation/report/xml/IdentifiableObject.cs
new file mode 100644
index 0000000000..a3c6bf02fc
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/IdentifiableObject.cs
@@ -0,0 +1,30 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ /// Implementations must override hashvalue and equals, the hashvalue must be stable
+ internal interface IdentifiableObject {
+ Identifier GetIdentifier();
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/Identifier.cs b/itext/itext.sign/itext/signatures/validation/report/xml/Identifier.cs
new file mode 100644
index 0000000000..be93073499
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/Identifier.cs
@@ -0,0 +1,43 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class Identifier {
+ private readonly String id;
+
+ public Identifier(String id) {
+ this.id = id;
+ }
+
+ public virtual String GetId() {
+ return id;
+ }
+
+ public override String ToString() {
+ return id;
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/NullAdESReportAggregator.cs b/itext/itext.sign/itext/signatures/validation/report/xml/NullAdESReportAggregator.cs
new file mode 100644
index 0000000000..b7d3805f42
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/NullAdESReportAggregator.cs
@@ -0,0 +1,87 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ /// Use this implementation when no xml report has to be created
+ public class NullAdESReportAggregator : AdESReportAggregator {
+ /// Creates a new instance of NullAdESReportAggregator.
+ public NullAdESReportAggregator() {
+ }
+
+ // Declaring default constructor explicitly to avoid removing it unintentionally
+ public virtual void StartSignatureValidation(byte[] signature, String name, DateTime signingDate) {
+ }
+
+ // No action required
+ public virtual void ProofOfExistenceFound(byte[] timeStampSignature, bool document) {
+ }
+
+ // No action required
+ public virtual void ReportSignatureValidationSuccess() {
+ }
+
+ // No action required
+ public virtual void ReportSignatureValidationFailure(bool isInconclusive, String reason) {
+ }
+
+ // No action required
+ // code for future use commented out for code coverage
+ // @Override
+ // public void reportCertificateChainValidationSuccess(X509Certificate certificate) {
+ // // No action required
+ // }
+ //
+ // @Override
+ // public void reportCertificateChainValidationFailure(X509Certificate certificate, boolean isInconclusive,
+ // String reason) {
+ // // No action required
+ // }
+ //
+ // @Override
+ // public void reportCRLValidationSuccess(X509Certificate certificate, CRL crl) {
+ // // No action required
+ // }
+ //
+ // @Override
+ // public void reportCRLValidationFailure(X509Certificate certificate, CRL crl, boolean isInconclusive,
+ // String reason) {
+ // // No action required
+ // }
+ //
+ // @Override
+ // public void reportOCSPValidationSuccess(X509Certificate certificate, IBasicOCSPResp ocsp) {
+ // // No action required
+ // }
+ //
+ // @Override
+ // public void reportOCSPValidationFailure(X509Certificate certificate, IBasicOCSPResp ocsp, boolean isInconclusive,
+ // String reason) {
+ // // No action required
+ // }
+ public virtual PadesValidationReport GetReport() {
+ throw new NotSupportedException("Use another implementation of AdESReportAggregator to create an actual report"
+ );
+ }
+ }
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/POEValidationReport.cs b/itext/itext.sign/itext/signatures/validation/report/xml/POEValidationReport.cs
new file mode 100644
index 0000000000..205313aad8
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/POEValidationReport.cs
@@ -0,0 +1,61 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Signatures.Cms;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class POEValidationReport : AbstractCollectableObject, SubValidationReport {
+ public POEValidationReport(ValidationObjects validationObjects, CMSContainer cmsContainer, bool document)
+ : base("T") {
+ }
+
+ // Will be completed later
+ public virtual void SetSignatureValidationStatus(SignatureValidationStatus status) {
+ }
+
+ // Will be completed later
+ public override void Accept(CollectableObjectVisitor visitor) {
+ visitor.Visit(this);
+ }
+
+ public override bool Equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || GetType() != o.GetType()) {
+ return false;
+ }
+ iText.Signatures.Validation.Report.Xml.POEValidationReport that = (iText.Signatures.Validation.Report.Xml.POEValidationReport
+ )o;
+ // Will be completed later
+ return true;
+ }
+
+ public override int GetHashCode() {
+ // Will be completed later
+ return 0;
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/PadesValidationReport.cs b/itext/itext.sign/itext/signatures/validation/report/xml/PadesValidationReport.cs
new file mode 100644
index 0000000000..e94765272a
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/PadesValidationReport.cs
@@ -0,0 +1,57 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System.Collections.Generic;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ /// This class holds all parts needed to create an xml AdES report.
+ public class PadesValidationReport {
+ private readonly ICollection signatureValidationReports = new List();
+
+ private readonly ValidationObjects validationObjects;
+
+//\cond DO_NOT_DOCUMENT
+ internal PadesValidationReport(ValidationObjects validationObjects) {
+ this.validationObjects = validationObjects;
+ }
+//\endcond
+
+//\cond DO_NOT_DOCUMENT
+ internal virtual void AddSignatureValidationReport(SignatureValidationReport signatureValidationReport) {
+ signatureValidationReports.Add(signatureValidationReport);
+ }
+//\endcond
+
+//\cond DO_NOT_DOCUMENT
+ internal virtual ICollection GetSignatureValidationReports() {
+ return signatureValidationReports;
+ }
+//\endcond
+
+//\cond DO_NOT_DOCUMENT
+ internal virtual ICollection GetValidationObjects() {
+ return validationObjects.GetObjects();
+ }
+//\endcond
+ }
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/SignatureIdentifier.cs b/itext/itext.sign/itext/signatures/validation/report/xml/SignatureIdentifier.cs
new file mode 100644
index 0000000000..d63d8076c4
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/SignatureIdentifier.cs
@@ -0,0 +1,110 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.IO;
+using iText.Commons.Bouncycastle.Security;
+using iText.Commons.Digest;
+using iText.Commons.Utils;
+using iText.Kernel.Crypto;
+using iText.Signatures;
+using iText.Signatures.Cms;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class SignatureIdentifier : AbstractIdentifiableObject {
+ private readonly CMSContainer signature;
+
+ private readonly String signatureName;
+
+ private readonly DateTime signingDate;
+
+ private readonly CertificateWrapper signingCertificate;
+
+ public SignatureIdentifier(ValidationObjects signatureValidationObjects, CMSContainer signature, String signatureName
+ , DateTime signingDate)
+ : base("S") {
+ this.signature = signature;
+ this.signatureName = signatureName;
+ this.signingDate = signingDate;
+ this.signingCertificate = signatureValidationObjects.AddObject(new CertificateWrapper(signature.GetSignerInfo
+ ().GetSigningCertificate()));
+ }
+
+ public virtual String GetDigestMethodAlgorithm() {
+ return "http://www.w3.org/2001/04/xmlenc#sha256";
+ }
+
+ public virtual String GetDigestValue() {
+ try {
+ using (MemoryStream bos = new MemoryStream()) {
+ using (BinaryWriter dos = new BinaryWriter(bos)) {
+ dos.Write(DateTimeUtil.GetRelativeTime(signingDate));
+ dos.Write(signingCertificate.GetIdentifier().GetId());
+ dos.Write(signature.GetSignerInfo().GetSignatureData());
+ dos.Write(signatureName);
+ dos.Flush();
+ bos.Flush();
+ IMessageDigest digest = new BouncyCastleDigest().GetMessageDigest(DigestAlgorithms.SHA256);
+ return Convert.ToBase64String(digest.Digest(bos.ToArray()));
+ }
+ }
+ }
+ catch (AbstractGeneralSecurityException e) {
+ throw new Exception("Error creating signature id digest.", e);
+ }
+ catch (System.IO.IOException e) {
+ throw new Exception("Error creating output stream.", e);
+ }
+ }
+
+ public virtual String GetBase64SignatureValue() {
+ return Convert.ToBase64String(signature.GetSignerInfo().GetSignatureData());
+ }
+
+ public virtual bool IsHashOnly() {
+ return false;
+ }
+
+ public virtual bool IsDocHashOnly() {
+ return false;
+ }
+
+ public override bool Equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || GetType() != o.GetType()) {
+ return false;
+ }
+ iText.Signatures.Validation.Report.Xml.SignatureIdentifier that = (iText.Signatures.Validation.Report.Xml.SignatureIdentifier
+ )o;
+ return Object.Equals(signature, that.signature) && Object.Equals(signatureName, that.signatureName) && Object.Equals
+ (signingDate, that.signingDate);
+ }
+
+ public override int GetHashCode() {
+ return JavaUtil.ArraysHashCode((Object)signature, signatureName, signingDate);
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/SignatureValidationReport.cs b/itext/itext.sign/itext/signatures/validation/report/xml/SignatureValidationReport.cs
new file mode 100644
index 0000000000..9f6d665a8e
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/SignatureValidationReport.cs
@@ -0,0 +1,70 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Commons.Utils;
+using iText.Signatures.Cms;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class SignatureValidationReport : AbstractIdentifiableObject, SubValidationReport {
+ private readonly SignatureIdentifier signatureIdentifier;
+
+ private SignatureValidationStatus status;
+
+ public SignatureValidationReport(ValidationObjects validationObjects, CMSContainer signature, String signatureName
+ , DateTime signingDate)
+ : base("S") {
+ signatureIdentifier = new SignatureIdentifier(validationObjects, signature, signatureName, signingDate);
+ }
+
+ public virtual SignatureIdentifier GetSignatureIdentifier() {
+ return signatureIdentifier;
+ }
+
+ public virtual void SetSignatureValidationStatus(SignatureValidationStatus status) {
+ this.status = status;
+ }
+
+ public virtual SignatureValidationStatus GetSignatureValidationStatus() {
+ return status;
+ }
+
+ public override bool Equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || GetType() != o.GetType()) {
+ return false;
+ }
+ iText.Signatures.Validation.Report.Xml.SignatureValidationReport that = (iText.Signatures.Validation.Report.Xml.SignatureValidationReport
+ )o;
+ return signatureIdentifier.Equals(that.signatureIdentifier) && (status == null || status.Equals(that.status
+ ));
+ }
+
+ public override int GetHashCode() {
+ return JavaUtil.ArraysHashCode((Object)signatureIdentifier, status);
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/SignatureValidationStatus.cs b/itext/itext.sign/itext/signatures/validation/report/xml/SignatureValidationStatus.cs
new file mode 100644
index 0000000000..82d4b8ad89
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/SignatureValidationStatus.cs
@@ -0,0 +1,445 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.Collections.Generic;
+using iText.Commons.Utils;
+using iText.IO.Util;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class SignatureValidationStatus {
+ private static readonly IDictionary MAIN_INDICATION_VALUE_MAP
+ = new Dictionary(EnumUtil.GetAllValuesOfEnum().Count);
+
+ private static readonly IDictionary MESSAGE_TYPE_VALUE_MAP =
+ new Dictionary(EnumUtil.GetAllValuesOfEnum().Count);
+
+ private readonly IList> messages = new List>();
+
+ private SignatureValidationStatus.MainIndication mainIndication;
+
+ private SignatureValidationStatus.SubIndication subIndication;
+
+ private bool subIndicationSet = false;
+
+ static SignatureValidationStatus() {
+ MAIN_INDICATION_VALUE_MAP.Put(SignatureValidationStatus.MainIndication.TOTAL_PASSED, "urn:etsi:019102:mainindication:total-passed"
+ );
+ MAIN_INDICATION_VALUE_MAP.Put(SignatureValidationStatus.MainIndication.TOTAL_FAILED, "urn:etsi:019102:mainindication:total-failed "
+ );
+ MAIN_INDICATION_VALUE_MAP.Put(SignatureValidationStatus.MainIndication.INDETERMINATE, "urn:etsi:019102:mainindication:indeterminate"
+ );
+ MAIN_INDICATION_VALUE_MAP.Put(SignatureValidationStatus.MainIndication.PASSED, "urn:etsi:019102:mainindication:passed"
+ );
+ MAIN_INDICATION_VALUE_MAP.Put(SignatureValidationStatus.MainIndication.FAILED, "urn:etsi:019102:mainindication:failed "
+ );
+ MESSAGE_TYPE_VALUE_MAP.Put(SignatureValidationStatus.MessageType.INFO, "urn:cef:dss:message:info");
+ MESSAGE_TYPE_VALUE_MAP.Put(SignatureValidationStatus.MessageType.WARN, "urn:cef:dss:message:warn");
+ MESSAGE_TYPE_VALUE_MAP.Put(SignatureValidationStatus.MessageType.ERROR, "urn:cef:dss:message:error");
+ }
+
+ public SignatureValidationStatus() {
+ }
+
+ // Declaring default constructor explicitly to avoid removing it unintentionally.
+ public virtual void SetMainIndication(SignatureValidationStatus.MainIndication mainIndication) {
+ this.mainIndication = mainIndication;
+ }
+
+ public virtual SignatureValidationStatus.MainIndication GetMainIndication() {
+ return mainIndication;
+ }
+
+ public virtual String GetMainIndicationAsString() {
+ return MAIN_INDICATION_VALUE_MAP.Get(mainIndication);
+ }
+
+ public virtual void SetSubIndication(SignatureValidationStatus.SubIndication subIndication) {
+ this.subIndication = subIndication;
+ this.subIndicationSet = true;
+ }
+
+ public virtual SignatureValidationStatus.SubIndication GetSubIndication() {
+ return subIndication;
+ }
+
+ public virtual String GetSubIndicationAsString() {
+ if (!subIndicationSet) {
+ return null;
+ }
+ return subIndication.ToString();
+ }
+
+ public virtual void AddMessage(String reason, SignatureValidationStatus.MessageType messageType) {
+ this.messages.Add(new Pair(reason, MESSAGE_TYPE_VALUE_MAP.Get(messageType)));
+ }
+
+ public virtual ICollection> GetMessages() {
+ return messages;
+ }
+
+ /// This enum holds all possible MainIndication values
+ public enum MainIndication {
+ TOTAL_PASSED,
+ TOTAL_FAILED,
+ INDETERMINATE,
+ PASSED,
+ FAILED
+ }
+
+ /// This enum holds all possible SubIndication values
+ public enum SubIndication {
+ ///
+ /// The signature is not conformant to one of the base standards to the
+ /// extent that the cryptographic verification building block is unable
+ /// to process it.
+ ///
+ ///
+ /// The signature is not conformant to one of the base standards to the
+ /// extent that the cryptographic verification building block is unable
+ /// to process it.
+ ///
+ /// The validation process shall provide any information available why parsing
+ /// of the signature failed.
+ ///
+ FORMAT_FAILURE,
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because at least one hash of a signed data object(s) that has
+ /// been included in the signing process does not match the
+ /// corresponding hash value in the signature.
+ ///
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because at least one hash of a signed data object(s) that has
+ /// been included in the signing process does not match the
+ /// corresponding hash value in the signature.
+ ///
+ /// The validation process shall provide:
+ /// An identifier (s) (e.g. a URI or OID) uniquely identifying the element within
+ /// the signed data object (such as the signature attributes, or the SD) that
+ /// caused the failure.
+ ///
+ HASH_FAILURE,
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because the signature value in the signature could not be verified
+ /// using the signer's public key in the signing certificate.
+ ///
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because the signature value in the signature could not be verified
+ /// using the signer's public key in the signing certificate.
+ ///
+ /// The validation process shall output:
+ /// The signing certificate used in the validation process.
+ ///
+ SIG_CRYPTO_FAILURE,
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because:
+ /// • the signing certificate has been revoked; and
+ /// • there is proof that the signature has been created after the revocation time.
+ ///
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because:
+ /// • the signing certificate has been revoked; and
+ /// • there is proof that the signature has been created after the revocation time.
+ ///
+ /// The validation process shall provide the following:
+ /// • The certificate chain used in the validation process.
+ /// • The time and, if available, the reason of revocation of the signing certificate.
+ ///
+ REVOKED,
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because there is proof that the signature has been created after
+ /// the expiration date (notAfter) of the signing certificate.
+ ///
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because there is proof that the signature has been created after
+ /// the expiration date (notAfter) of the signing certificate.
+ ///
+ /// The process shall output:
+ /// The validated certificate chain.
+ ///
+ EXPIRED,
+ ///
+ /// The signature validation process results into TOTAL-FAILED
+ /// because there is proof that the signature was created before the
+ /// issuance date (notBefore) of the signing certificate.
+ ///
+ NOT_YET_VALID,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because one or more attributes of the signature do not match the
+ /// validation constraints.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because one or more attributes of the signature do not match the
+ /// validation constraints.
+ ///
+ /// The validation process shall provide:
+ /// The set of constraints that have not been met by the signature.
+ ///
+ SIG_CONSTRAINTS_FAILURE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the certificate chain used in the validation process does not
+ /// match the validation constraints related to the certificate.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the certificate chain used in the validation process does not
+ /// match the validation constraints related to the certificate.
+ ///
+ /// The validation process shall output:
+ /// • The certificate chain used in the validation process.
+ /// • The set of constraints that have not been met by the chain.
+ ///
+ CHAIN_CONSTRAINTS_FAILURE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the set of certificates available for chain validation
+ /// produced an error for an unspecified reason.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the set of certificates available for chain validation
+ /// produced an error for an unspecified reason.
+ ///
+ /// The process shall output:
+ /// Additional information regarding the reason.
+ ///
+ CERTIFICATE_CHAIN_GENERAL_FAILURE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because at least one of the algorithms that have been used in
+ /// material (e.g. the signature value, a certificate...) involved in
+ /// validating the signature, or the size of a key used with such an
+ /// algorithm, is below the required cryptographic security level, and:
+ /// • this material was produced after the time up to which
+ /// this algorithm/key was considered secure (if such a
+ /// time is known); and
+ /// • the material is not protected by a sufficiently strong
+ /// time-stamp applied before the time up to which the
+ /// algorithm/key was considered secure (if such a time is known).
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because at least one of the algorithms that have been used in
+ /// material (e.g. the signature value, a certificate...) involved in
+ /// validating the signature, or the size of a key used with such an
+ /// algorithm, is below the required cryptographic security level, and:
+ /// • this material was produced after the time up to which
+ /// this algorithm/key was considered secure (if such a
+ /// time is known); and
+ /// • the material is not protected by a sufficiently strong
+ /// time-stamp applied before the time up to which the
+ /// algorithm/key was considered secure (if such a time is known).
+ ///
+ /// The process shall output:
+ /// • Identification of the material (signature, certificate) that is produced using an algorithm or
+ /// key size below the required cryptographic security level.
+ /// • If known, the time up to which the algorithm or key size were considered secure.
+ ///
+ CRYPTO_CONSTRAINTS_FAILURE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because a given formal policy file could not be processed for any
+ /// reason (e.g. not accessible, not parseable, digest mismatch, etc.).
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because a given formal policy file could not be processed for any
+ /// reason (e.g. not accessible, not parseable, digest mismatch, etc.).
+ ///
+ /// The validation process shall provide additional information on the problem.
+ ///
+ POLICY_PROCESSING_ERROR,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the electronic document containing the details of the policy
+ /// is not available.
+ ///
+ SIGNATURE_POLICY_NOT_AVAILABLE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because some constraints on the order of signature time-stamps
+ /// and/or signed data object(s) time-stamps are not respected.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because some constraints on the order of signature time-stamps
+ /// and/or signed data object(s) time-stamps are not respected.
+ ///
+ /// The validation process shall output the list of time-stamps that do no respect
+ /// the ordering constraints.
+ ///
+ TIMESTAMP_ORDER_FAILURE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the signing certificate cannot be identified.
+ ///
+ NO_SIGNING_CERTIFICATE_FOUND,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because no certificate chain has been found for the identified
+ /// signing certificate.
+ ///
+ NO_CERTIFICATE_CHAIN_FOUND,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the signing certificate was revoked at the validation date/time.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the signing certificate was revoked at the validation date/time.
+ /// However, the Signature Validation Algorithm cannot ascertain that the
+ /// signing time lies before or after the revocation time.
+ ///
+ /// The validation process shall provide the following:
+ /// • The certificate chain used in the validation process.
+ /// • The time and the reason of revocation of the signing certificate.
+ ///
+ REVOKED_NO_POE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because at least one certificate chain was found but an
+ /// intermediate CA certificate is revoked.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because at least one certificate chain was found but an
+ /// intermediate CA certificate is revoked.
+ ///
+ /// The validation process shall provide the following:
+ /// • The certificate chain which includes the revoked CA certificate.
+ /// • The time and the reason of revocation of the certificate.
+ ///
+ REVOKED_CA_NO_POE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the signing certificate is expired or not yet valid at the
+ /// validation date/time and the Signature Validation Algorithm
+ /// cannot ascertain that the signing time lies within the validity interval
+ /// of the signing certificate.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the signing certificate is expired or not yet valid at the
+ /// validation date/time and the Signature Validation Algorithm
+ /// cannot ascertain that the signing time lies within the validity interval
+ /// of the signing certificate. The certificate is known not to be revoked.
+ ///
+ OUT_OF_BOUNDS_NOT_REVOKED,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because the signing certificate is expired or not yet valid at the
+ /// validation date/time and the Signature Validation Algorithm
+ /// cannot ascertain that the signing time lies within the validity interval
+ /// of the signing certificate.
+ ///
+ OUT_OF_BOUNDS_NO_POE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because at least one of the algorithms that have been used in
+ /// objects (e.g. the signature value, a certificate, etc.) involved in
+ /// validating the signature, or the size of a key used with such an
+ /// algorithm, is below the required cryptographic security level, and
+ /// there is no proof that this material was produced before the time up
+ /// to which this algorithm/key was considered secure.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because at least one of the algorithms that have been used in
+ /// objects (e.g. the signature value, a certificate, etc.) involved in
+ /// validating the signature, or the size of a key used with such an
+ /// algorithm, is below the required cryptographic security level, and
+ /// there is no proof that this material was produced before the time up
+ /// to which this algorithm/key was considered secure.
+ ///
+ /// The process shall output:
+ /// • Identification of the material (signature, certificate) that is
+ /// produced using an algorithm or key size below the required
+ /// cryptographic security level.
+ /// If known, the time up to which the algorithm or key size were consider secure.
+ ///
+ CRYPTO_CONSTRAINTS_FAILURE_NO_POE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because a proof of existence is missing to ascertain that a signed
+ /// object has been produced before some compromising even
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because a proof of existence is missing to ascertain that a signed
+ /// object has been produced before some compromising even
+ ///
+ /// The validation process shall identify at least the signed objects for which the
+ /// POEs are missing.
+ /// • The validation process should provide additional information on the problem.
+ ///
+ NO_POE,
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because not all constraints can be fulfilled using available information.
+ ///
+ ///
+ /// The signature validation process results into INDETERMINATE
+ /// because not all constraints can be fulfilled using available information.
+ /// However, it may be possible to do so using additional revocation
+ /// information that will be available at a later point of time.
+ ///
+ /// The validation process shall output the point of time, where the necessary
+ /// revocation information is expected to become available.
+ ///
+ TRY_LATER,
+ ///
+ /// The signature validation processresults into INDETERMINATE
+ /// because signed data cannot beobtained.
+ ///
+ ///
+ /// The signature validation processresults into INDETERMINATE
+ /// because signed data cannot beobtained.
+ ///
+ /// The process should output when available:
+ /// The identifier(s) (e.g. a URI) of the signed data that caused the failure.
+ ///
+ SIGNED_DATA_NOT_FOUND
+ }
+
+ /// This enum holds the possible message type values
+ public enum MessageType {
+ INFO,
+ WARN,
+ ERROR
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/SubValidationReport.cs b/itext/itext.sign/itext/signatures/validation/report/xml/SubValidationReport.cs
new file mode 100644
index 0000000000..1fbdb46b96
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/SubValidationReport.cs
@@ -0,0 +1,29 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal interface SubValidationReport {
+ void SetSignatureValidationStatus(SignatureValidationStatus status);
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/ValidationObjects.cs b/itext/itext.sign/itext/signatures/validation/report/xml/ValidationObjects.cs
new file mode 100644
index 0000000000..01a969e708
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/ValidationObjects.cs
@@ -0,0 +1,47 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.Collections.Generic;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class ValidationObjects {
+ private readonly IDictionary objects = new Dictionary();
+
+ public virtual T AddObject(T @object)
+ where T : CollectableObject {
+ Object existing = objects.Get(@object);
+ if (existing != null) {
+ return (T)existing;
+ }
+ objects.Put(@object, @object);
+ return @object;
+ }
+
+ public virtual ICollection GetObjects() {
+ return objects.Values;
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/XmlGeneratorCollectableObjectVisitor.cs b/itext/itext.sign/itext/signatures/validation/report/xml/XmlGeneratorCollectableObjectVisitor.cs
new file mode 100644
index 0000000000..5227366901
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/XmlGeneratorCollectableObjectVisitor.cs
@@ -0,0 +1,63 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.Xml;
+
+namespace iText.Signatures.Validation.Report.Xml {
+//\cond DO_NOT_DOCUMENT
+ internal class XmlGeneratorCollectableObjectVisitor : CollectableObjectVisitor {
+ private readonly XmlDocument doc;
+
+ private readonly XmlNode parent;
+
+ public XmlGeneratorCollectableObjectVisitor(XmlDocument doc, XmlNode parent) {
+ this.doc = doc;
+ this.parent = parent;
+ }
+
+ public virtual void Visit(CertificateWrapper certificateWrapper) {
+ XmlNode validationObject = CreateValidationObjectElement(certificateWrapper.GetIdentifier(), "urn:etsi:019102:validationObject:certificate"
+ );
+ XmlNode representation = doc.CreateElement("ValidationObjectRepresentation");
+ XmlNode b64 = doc.CreateElement("base64");
+ b64.InnerText = certificateWrapper.GetBase64ASN1Structure();
+ representation.AppendChild(b64);
+ validationObject.AppendChild(representation);
+ parent.AppendChild(validationObject);
+ }
+
+ public virtual void Visit(POEValidationReport poeValidationReport) {
+ }
+
+ // Will be completed later
+ private XmlNode CreateValidationObjectElement(Identifier identifier, String typeName) {
+ XmlElement validationObject = doc.CreateElement("ValidationObject");
+ validationObject.SetAttribute("id", identifier.GetId());
+ XmlNode objectType = doc.CreateElement("ObjectType");
+ objectType.InnerText = typeName;
+ validationObject.AppendChild(objectType);
+ return validationObject;
+ }
+ }
+//\endcond
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/XmlReportGenerator.cs b/itext/itext.sign/itext/signatures/validation/report/xml/XmlReportGenerator.cs
new file mode 100644
index 0000000000..b93db2498f
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/XmlReportGenerator.cs
@@ -0,0 +1,138 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+using iText.Commons.Utils;
+
+namespace iText.Signatures.Validation.Report.Xml {
+ ///
+ /// This class will convert a
+ ///
+ /// to its xml representation.
+ ///
+ public class XmlReportGenerator {
+ public const String DOC_NS = "http://uri.etsi.org/19102/v1.2.1#";
+
+ public const String DS_NS = "http://www.w3.org/2000/09/xmldsig#";
+
+ public const String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
+
+ public const String XS_NS = "http://www.w3.org/2001/XMLSchema";
+
+ private readonly XmlReportOptions options;
+
+ /// Instantiate a new instance of XmlReportGenerator.
+ /// the conversion options to use
+ public XmlReportGenerator(XmlReportOptions options) {
+ this.options = options;
+ }
+
+ ///
+ /// Generate xlm representation of a
+ /// .
+ ///
+ /// the report to transform
+ /// the writer instance to write the resulting xml to
+ public virtual void Generate(PadesValidationReport report, TextWriter writer) {
+ XmlDocument doc = new XmlDocument();
+ XmlElement root = doc.CreateElement("ValidationReport");
+ // Register namespaces in root node.
+ root.SetAttribute("xmlns", DOC_NS);
+ root.SetAttribute("xmlns:ds", DS_NS);
+ root.SetAttribute("xmlns:xsi", XSI_NS);
+ root.SetAttribute("xmlns:xs", XS_NS);
+ doc.AppendChild(root);
+ foreach (SignatureValidationReport signatureValidation in report.GetSignatureValidationReports()) {
+ AddSignatureReport(doc, root, signatureValidation);
+ }
+ XmlNode signatureValidationObjects = root.AppendChild(doc.CreateElement("SignatureValidationObjects"));
+ XmlGeneratorCollectableObjectVisitor visitor = new XmlGeneratorCollectableObjectVisitor(doc, signatureValidationObjects
+ );
+ foreach (CollectableObject @object in report.GetValidationObjects()) {
+ @object.Accept(visitor);
+ }
+ // Convert to pretty printed xml.
+ XmlTextWriter xmlWriter = new XmlTextWriter(writer);
+ xmlWriter.Formatting = Formatting.Indented;
+
+ doc.Save(xmlWriter);
+ }
+
+ private static void AddSignatureReport(XmlDocument doc, XmlElement root, SignatureValidationReport signatureValidation
+ ) {
+ XmlNode sigValNode = root.AppendChild(doc.CreateElement("SignatureValidationReport"));
+ // Create elements with one of the defined namespaces. For the default namespace, there is no namespace prefix.
+ // For other namespaces, the correct namespace prefix must be added.
+ XmlElement signatureIdentifier = doc.CreateElement("SignatureIdentifier");
+ signatureIdentifier.SetAttribute("id", signatureValidation.GetSignatureIdentifier().GetIdentifier().GetId(
+ ));
+ sigValNode.AppendChild(signatureIdentifier);
+ XmlNode digestAlgAndValue = signatureIdentifier.AppendChild(doc.CreateElement("DigestAlgAndValue"
+ ));
+ // Use setAttributeNS only when the attribute has a different namespace as the element.
+ ((XmlElement)digestAlgAndValue.AppendChild(doc.CreateElement("ds", "DigestMethod", DS_NS))).SetAttribute(
+ "Algorithm", "", signatureValidation.GetSignatureIdentifier().GetDigestMethodAlgorithm());
+ digestAlgAndValue.AppendChild(doc.CreateElement("ds", "DigestValue", DS_NS)).InnerText = signatureValidation
+ .GetSignatureIdentifier().GetDigestValue();
+ signatureIdentifier.AppendChild(doc.CreateElement("ds", "SignatureValue", DS_NS)).InnerText = signatureValidation
+ .GetSignatureIdentifier().GetBase64SignatureValue();
+ signatureIdentifier.AppendChild(doc.CreateElement("HashOnly")).InnerText = signatureValidation.GetSignatureIdentifier
+ ().IsHashOnly().ToString().ToLower();
+ signatureIdentifier.AppendChild(doc.CreateElement("DocHashOnly")).InnerText = signatureValidation
+ .GetSignatureIdentifier().IsDocHashOnly().ToString().ToLower();
+ XmlNode status = doc.CreateElement("SignatureValidationStatus");
+ XmlNode mainIndication = doc.CreateElement("MainIndication");
+ mainIndication.InnerText = signatureValidation.GetSignatureValidationStatus().GetMainIndicationAsString();
+ status.AppendChild(mainIndication);
+ sigValNode.AppendChild(status);
+ String subIndication = signatureValidation.GetSignatureValidationStatus().GetSubIndicationAsString();
+ if (subIndication != null) {
+ XmlNode subIndicationNode = doc.CreateElement("SubIndication");
+ subIndicationNode.InnerText = subIndication;
+ status.AppendChild(subIndicationNode);
+ }
+ ICollection> messages = signatureValidation.GetSignatureValidationStatus().GetMessages
+ ();
+ if (!messages.IsEmpty()) {
+ XmlNode associatedValidationReportData = doc.CreateElement("AssociatedValidationReportData");
+ status.AppendChild(associatedValidationReportData);
+ XmlNode additionalValidationReportData = doc.CreateElement("AdditionalValidationReportData");
+ associatedValidationReportData.AppendChild(additionalValidationReportData);
+ foreach (Pair message in messages) {
+ XmlNode reportData = doc.CreateElement("ReportData");
+ XmlNode type = doc.CreateElement("Type");
+ type.InnerText = message.GetValue();
+ reportData.AppendChild(type);
+ XmlElement value = doc.CreateElement("Value");
+ value.SetAttribute("type", XSI_NS, "xs:string");
+ value.InnerText = message.GetKey();
+ reportData.AppendChild(value);
+ additionalValidationReportData.AppendChild(reportData);
+ }
+ }
+ }
+ }
+}
diff --git a/itext/itext.sign/itext/signatures/validation/report/xml/XmlReportOptions.cs b/itext/itext.sign/itext/signatures/validation/report/xml/XmlReportOptions.cs
new file mode 100644
index 0000000000..2baabb5eb0
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/validation/report/xml/XmlReportOptions.cs
@@ -0,0 +1,35 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+namespace iText.Signatures.Validation.Report.Xml {
+ ///
+ /// Manages the options for converting a
+ ///
+ /// into its xml representation
+ ///
+ public class XmlReportOptions {
+ /// Create a new instance of XmlReportOptions
+ public XmlReportOptions() {
+ }
+ // Declaring default constructor explicitly to avoid removing it unintentionally
+ }
+}
diff --git a/port-hash b/port-hash
index eaf12899de..05ea0bee4f 100644
--- a/port-hash
+++ b/port-hash
@@ -1 +1 @@
-99202aca794f5c7df2d4ecfa5c23ecaad35da666
+dd25f1a8f8aaca079e593adb93dfc1399dfac7bd
\ No newline at end of file