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" + "\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 @@ + + + + + + + Industry Weightings in HSI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Financials + + + + Information Technology + + + + Properties & Construction + + + + Telecommunications + + + + Energy + + + + Utilities + + + + Conglomerates + + + + Consumer Services + + + + Consumer Goods + + + + Industrials + + + + Materials + + + + 0% + + + + 20% + + + + 40% + + + + 60% + + + + 80% + + + + 0 + + + + 10 + + + + 20 + + + + + + + + + + 46.97% + + + + + + + + + + + 11.91% + + + + + + + + + + + 10.45% + + + + + + + + + + + 7.41% + + + + + + + + + + + 6.73% + + + + + + + + + + + 5.49% + + + + + + + + + + + 4.58% + + + + + + + + + + + 3.33% + + + + + + + + + + + 2.75% + + + + + + + + + + + 0.38% + + + + + + + + + + + 0.00% + + + + + + + + + + + 12 + + + + + + + + + + + 3 + + + + + + + + + + + 10 + + + + + + + + + + + 2 + + + + + + + + + + + 5 + + + + + + + + + + + 5 + + + + + + + + + + + 3 + + + + + + + + + + + 4 + + + + + + + + + + + 5 + + + + + + + + + + + 1 + + + + + + + + + + + 0 + + + + + + + + + + + + + + Weighting + + + + + + + + + + + No. Of Constituents ? ? ? ? ? + + + + + + + + + + Weighting + + + + + No. Of Constituents + + + + + + \ 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 @@ + + + + + + + HSI and its Total Return Index ("TRI") + + + + + + + + + + + + + + + + + + Mar-12 + + + + Sep-12 + + + + Mar-13 + + + + Sep-13 + + + + Mar-14 + + + + Sep-14 + + + + Mar-15 + + + + Sep-15 + + + + Mar-16 + + + + Sep-16 + + + + Mar-17 + + + + 50 + + + + 100 + + + + 150 + + + + 200 + + + + + + + + + + + HSI + + + + + + + + + + + HSI TRI ? ? ? ? ? + + + + + + + + + \ 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 @@ + + + + + + + + + + + + + Tabelle.30 + + CCC + + + + + + + + CCC + + + + + + \ 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