diff --git a/itext.tests/itext.kernel.tests/itext/kernel/geom/PageSizeTest.cs b/itext.tests/itext.kernel.tests/itext/kernel/geom/PageSizeTest.cs new file mode 100644 index 0000000000..0d10c90155 --- /dev/null +++ b/itext.tests/itext.kernel.tests/itext/kernel/geom/PageSizeTest.cs @@ -0,0 +1,88 @@ +/* +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.Kernel.Pdf; +using iText.Kernel.Pdf.Annot; +using iText.Kernel.Utils; +using iText.Test; + +namespace iText.Kernel.Geom { + [NUnit.Framework.Category("IntegrationTest")] + public class PageSizeTest : ExtendedITextTest { + public static readonly String DESTINATION_FOLDER = NUnit.Framework.TestContext.CurrentContext.TestDirectory + + "/test/itext/kernel/geom/PageSizeTest/"; + + public static readonly String SOURCE_FOLDER = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext + .CurrentContext.TestDirectory) + "/resources/itext/kernel/geom/PageSizeTest/"; + + [NUnit.Framework.OneTimeSetUp] + public static void BeforeClass() { + CreateOrClearDestinationFolder(DESTINATION_FOLDER); + } + + [NUnit.Framework.OneTimeTearDown] + public static void AfterClass() { + CompareTool.Cleanup(DESTINATION_FOLDER); + } + + [NUnit.Framework.Test] + public virtual void EmptyA9PageTest() { + String outPdf = DESTINATION_FOLDER + "emptyA9Page.pdf"; + String cmpPdf = SOURCE_FOLDER + "cmp_emptyA9Page.pdf"; + PdfDocument doc = new PdfDocument(CompareTool.CreateTestPdfWriter(outPdf)); + doc.AddNewPage(PageSize.A9); + doc.Close(); + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outPdf, cmpPdf, DESTINATION_FOLDER, "diff" + )); + } + + [NUnit.Framework.Test] + public virtual void NotEmptyA9PageTest() { + String outPdf = DESTINATION_FOLDER + "notEmptyA9Page.pdf"; + String cmpPdf = SOURCE_FOLDER + "cmp_notEmptyA9Page.pdf"; + PdfDocument doc = new PdfDocument(CompareTool.CreateTestPdfWriter(outPdf)); + PdfPage page = doc.AddNewPage(PageSize.A9); + PdfAnnotation annotation = new PdfFreeTextAnnotation(new Rectangle(50, 10, 50, 50), new PdfString("some content" + )); + page.AddAnnotation(annotation); + doc.Close(); + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outPdf, cmpPdf, DESTINATION_FOLDER, "diff" + )); + } + + [NUnit.Framework.Test] + public virtual void AllATypePageSizesTest() { + String outPdf = DESTINATION_FOLDER + "allATypePageSizes.pdf"; + String cmpPdf = SOURCE_FOLDER + "cmp_allATypePageSizes.pdf"; + PageSize[] pageSizes = new PageSize[] { PageSize.A0, PageSize.A1, PageSize.A2, PageSize.A3, PageSize.A4, PageSize + .A5, PageSize.A6, PageSize.A7, PageSize.A8, PageSize.A9, PageSize.A10 }; + PdfDocument doc = new PdfDocument(CompareTool.CreateTestPdfWriter(outPdf)); + foreach (PageSize pageSize in pageSizes) { + doc.AddNewPage(pageSize); + } + doc.Close(); + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outPdf, cmpPdf, DESTINATION_FOLDER, "diff" + )); + } + } +} diff --git a/itext.tests/itext.kernel.tests/itext/kernel/geom/PageSizeUnitTest.cs b/itext.tests/itext.kernel.tests/itext/kernel/geom/PageSizeUnitTest.cs index 7152a8e63c..abd046ec88 100644 --- a/itext.tests/itext.kernel.tests/itext/kernel/geom/PageSizeUnitTest.cs +++ b/itext.tests/itext.kernel.tests/itext/kernel/geom/PageSizeUnitTest.cs @@ -34,5 +34,12 @@ public virtual void ConstructFromRectangleTest() { NUnit.Framework.Assert.AreEqual(rectangle.width, pageSize.width, 1e-5); NUnit.Framework.Assert.AreEqual(rectangle.height, pageSize.height, 1e-5); } + + [NUnit.Framework.Test] + public virtual void A9pageSizeTest() { + PageSize size = new PageSize(PageSize.A9); + NUnit.Framework.Assert.AreEqual(148, size.height, 1e-5); + NUnit.Framework.Assert.AreEqual(105, size.width, 1e-5); + } } } diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_allATypePageSizes.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_allATypePageSizes.pdf new file mode 100644 index 0000000000..a2958f3900 Binary files /dev/null and b/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_allATypePageSizes.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_emptyA9Page.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_emptyA9Page.pdf new file mode 100644 index 0000000000..bcfd19df2b Binary files /dev/null and b/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_emptyA9Page.pdf differ diff --git a/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_notEmptyA9Page.pdf b/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_notEmptyA9Page.pdf new file mode 100644 index 0000000000..151cfc29b0 Binary files /dev/null and b/itext.tests/itext.kernel.tests/resources/itext/kernel/geom/PageSizeTest/cmp_notEmptyA9Page.pdf differ diff --git a/itext.tests/itext.layout.tests/itext/layout/ListTest.cs b/itext.tests/itext.layout.tests/itext/layout/ListTest.cs index 71926ddfdd..a7a783c4aa 100644 --- a/itext.tests/itext.layout.tests/itext/layout/ListTest.cs +++ b/itext.tests/itext.layout.tests/itext/layout/ListTest.cs @@ -93,7 +93,7 @@ public virtual void ListNestedInTableTest01() { List list = new List(ListNumberingType.DECIMAL).Add("first string").Add("second string").Add("third string" ).Add("fourth string"); Table table = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth(); - table.AddCell(new Cell().Add(list).SetVerticalAlignment(VerticalAlignment.BOTTOM)); + table.AddCell(new Cell().Add(list).SetVerticalAlignment(VerticalAlignment.BOTTOM).SetFontSize(10)); document.Add(table); document.Close(); NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_listNestedInTableTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_listNestedInTableTest01.pdf index ea65a81ec1..e94bf819ac 100644 Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_listNestedInTableTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_listNestedInTableTest01.pdf differ diff --git a/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7ManuallyPortedTest.cs b/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7ManuallyPortedTest.cs index 61d8ec8b03..fd1577733c 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7ManuallyPortedTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7ManuallyPortedTest.cs @@ -72,5 +72,16 @@ public virtual void VerifyRsaSha3SignatureTest() { VerifyIsoExtensionExample("SHA3-256withRSA", "sample-rsa-sha3_256.pdf"); } } + + [NUnit.Framework.Test] + public virtual void VerifyRsaPssSha3SignatureTest() + { + if ("BC".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) { + VerifyIsoExtensionExample("RSASSA-PSS", "sample-pss-sha3_256.pdf"); + } else { + // Signer "RSASSA-PSS not recognised in BCFIPS mode + NUnit.Framework.Assert.Catch(typeof(PdfException), () => VerifyIsoExtensionExample("RSASSA-PSS", "sample-pss-sha3_256.pdf")); + } + } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/IsoSignatureExtensionsRoundtripTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/IsoSignatureExtensionsRoundtripTest.cs index 23b7626062..fbc548db63 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/sign/IsoSignatureExtensionsRoundtripTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/sign/IsoSignatureExtensionsRoundtripTest.cs @@ -142,7 +142,18 @@ public virtual void TestRsaWithSha3_512() { } [NUnit.Framework.Test] - public virtual void TestRsaWithSha3_256() { + public virtual void TestRsaSsaPssWithSha3_256() + { + if ("BC".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) { + DoRoundTrip("rsa", DigestAlgorithms.SHA3_256, "RSASSA-PSS", new DerObjectIdentifier(SecurityIDs.ID_RSASSA_PSS)); + } else { + // Signer RSASSA-PSS not recognised in BCFIPS mode + NUnit.Framework.Assert.Catch(typeof(PdfException), () => DoRoundTrip("rsa", DigestAlgorithms.SHA3_256, "RSASSA-PSS", new DerObjectIdentifier(SecurityIDs.ID_RSASSA_PSS))); + } + } + + [NUnit.Framework.Test] + public virtual void TestDsaWithSha3_256() { if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) { DoRoundTrip("dsa", DigestAlgorithms.SHA3_256, NistObjectIdentifiers.IdDsaWithSha3_256); } else { diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/RSASSAPSSTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/RSASSAPSSTest.cs index 6ee3d03a9d..c9d3e108f9 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/sign/RSASSAPSSTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/sign/RSASSAPSSTest.cs @@ -65,7 +65,7 @@ public virtual void SignWithRsaSsaPssTest() String cmpFileName = "cmp_simplePssSignature.pdf"; if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) { - // Signer RSASSA-PSS not recognised in BC mode + // Signer RSASSA-PSS not recognised in BCFIPS mode NUnit.Framework.Assert.Catch(typeof(PdfException), () => { DoRoundTrip(digestName, "RSASSA-PSS", outFileName, @@ -91,7 +91,7 @@ public virtual void SignWithRsaSsaPssAlternativeNomenclatureTest() if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) { - // Signer RSASSA-PSS not recognised in BC mode + // Signer RSASSA-PSS not recognised in BCFIPS mode NUnit.Framework.Assert.Catch(typeof(PdfException), () => { DoRoundTrip(digestName, @@ -116,7 +116,7 @@ public virtual void SignWithRsaSsaSha384PssTest() { String outFileName = "simplePssSignatureSha384.pdf"; if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) { - // Signer RSASSA-PSS not recognised in BC mode + // Signer RSASSA-PSS not recognised in BCFIPS mode NUnit.Framework.Assert.Catch(typeof(PdfException), () => { DoRoundTrip(digestName, "RSASSA-PSS", outFileName, @@ -137,7 +137,7 @@ public virtual void SignWithRsaSsaCustomSaltLengthTest() { String cmpFileName = "cmp_simplePssSignature.pdf"; if ("BCFIPS".Equals(BOUNCY_CASTLE_FACTORY.GetProviderName())) { - // Signer RSASSA-PSS not recognised in BC mode + // Signer RSASSA-PSS not recognised in BCFIPS mode NUnit.Framework.Assert.Catch(typeof(PdfException), () => { DoRoundTrip(digestName, "RSASSA-PSS", outFileName, new RSASSAPSSMechanismParams( diff --git a/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestCrlClientWrapper.cs b/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestCrlClientWrapper.cs index 04a56a3ead..f7a27ed561 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestCrlClientWrapper.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestCrlClientWrapper.cs @@ -33,12 +33,21 @@ public class TestCrlClientWrapper : ICrlClient { private readonly IList calls = new List(); + private Func> onGetEncoded; + public TestCrlClientWrapper(ICrlClient wrappedClient) { this.wrappedClient = wrappedClient; } public virtual ICollection GetEncoded(IX509Certificate checkCert, String url) { - ICollection crlBytesCollection = wrappedClient.GetEncoded(checkCert, url); + TestCrlClientWrapper.CrlClientCall call = new TestCrlClientWrapper.CrlClientCall(checkCert, url); + ICollection crlBytesCollection; + if (onGetEncoded != null) { + crlBytesCollection = onGetEncoded.Invoke(call); + } + else { + crlBytesCollection = wrappedClient.GetEncoded(checkCert, url); + } IList crlResponses = new List(); foreach (byte[] crlBytes in crlBytesCollection) { try { @@ -48,7 +57,8 @@ public virtual ICollection GetEncoded(IX509Certificate checkCert, String throw new Exception("Deserializing CRL response failed", e); } } - calls.Add(new TestCrlClientWrapper.CrlClientCall(checkCert, url, crlResponses)); + call.SetResponses(crlResponses); + calls.Add(call); return crlBytesCollection; } @@ -56,17 +66,26 @@ public virtual ICollection GetEncoded(IX509Certificate checkCert, String return calls; } + public virtual iText.Signatures.Testutils.Client.TestCrlClientWrapper OnGetEncodedDo(Func> callBack) { + onGetEncoded = callBack; + return this; + } + public class CrlClientCall { public readonly IX509Certificate checkCert; public readonly String url; - public readonly IList responses; + public IList responses; - public CrlClientCall(IX509Certificate checkCert, String url, IList responses) { + public CrlClientCall(IX509Certificate checkCert, String url) { this.checkCert = checkCert; this.url = url; - this.responses = responses; + } + + public virtual void SetResponses(IList crlResponses) { + responses = crlResponses; } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestOcspClientWrapper.cs b/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestOcspClientWrapper.cs index 687103e839..e920b505a4 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestOcspClientWrapper.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestOcspClientWrapper.cs @@ -38,16 +38,27 @@ public class TestOcspClientWrapper : IOcspClient { private readonly IOcspClient wrappedClient; + private Func onGetEncoded; + public TestOcspClientWrapper(IOcspClient wrappedClient) { this.wrappedClient = wrappedClient; } public virtual byte[] GetEncoded(IX509Certificate checkCert, IX509Certificate issuerCert, String url) { - byte[] response = wrappedClient.GetEncoded(checkCert, issuerCert, url); + TestOcspClientWrapper.OcspClientCall call = new TestOcspClientWrapper.OcspClientCall(checkCert, issuerCert + , url); + byte[] response; + if (onGetEncoded != null) { + response = onGetEncoded.Invoke(call); + } + else { + response = wrappedClient.GetEncoded(checkCert, issuerCert, url); + } try { IBasicOcspResponse basicOCSPResp = BOUNCY_CASTLE_FACTORY.CreateBasicOCSPResponse(BOUNCY_CASTLE_FACTORY.CreateASN1Primitive (response)); - calls.Add(new TestOcspClientWrapper.OcspClientCall(checkCert, issuerCert, url, basicOCSPResp)); + call.SetResponce(basicOCSPResp); + calls.Add(call); } catch (System.IO.IOException e) { throw new Exception("deserializing ocsp response failed", e); @@ -59,6 +70,12 @@ public virtual byte[] GetEncoded(IX509Certificate checkCert, IX509Certificate is return calls; } + public virtual iText.Signatures.Testutils.Client.TestOcspClientWrapper OnGetEncodedDo(Func callBack) { + onGetEncoded = callBack; + return this; + } + public class OcspClientCall { public readonly IX509Certificate checkCert; @@ -66,14 +83,16 @@ public class OcspClientCall { public readonly String url; - public readonly IBasicOcspResponse response; + public IBasicOcspResponse response; - public OcspClientCall(IX509Certificate checkCert, IX509Certificate issuerCert, String url, IBasicOcspResponse - response) { + public OcspClientCall(IX509Certificate checkCert, IX509Certificate issuerCert, String url) { this.checkCert = checkCert; this.issuerCert = issuerCert; this.url = url; - this.response = response; + } + + public virtual void SetResponce(IBasicOcspResponse basicOCSPResp) { + response = basicOCSPResp; } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CRLValidatorTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CRLValidatorTest.cs index 155377c22a..931f6e4ff7 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CRLValidatorTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CRLValidatorTest.cs @@ -326,6 +326,37 @@ public virtual void CertExpiredAfterDateFromExpiredCertOnCrlExtensionTest() { (0)); } + [NUnit.Framework.Test] + public virtual void CertificateRetrieverFailureTest() { + RetrieveTestResources("happyPath"); + byte[] crl = CreateCrl(crlIssuerCert, crlIssuerKey, TimeTestUtil.TEST_DATE_TIME.AddDays(-5), TimeTestUtil. + TEST_DATE_TIME.AddDays(+5)); + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(); + mockCertificateRetriever.OngetCrlIssuerCertificatesDo((c) => { + throw new Exception("just testing"); + } + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + validatorChainBuilder.WithCRLValidator(new CRLValidator(validatorChainBuilder)); + ValidationReport report = PerformValidation("happyPath", TimeTestUtil.TEST_DATE_TIME, crl); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(CRLValidator.CRL_ISSUER_REQUEST_FAILED))); + } + + [NUnit.Framework.Test] + public virtual void ChainValidatorFailureTest() { + RetrieveTestResources("happyPath"); + byte[] crl = CreateCrl(crlIssuerCert, crlIssuerKey, TimeTestUtil.TEST_DATE_TIME.AddDays(-5), TimeTestUtil. + TEST_DATE_TIME.AddDays(+5)); + mockChainValidator.OnCallDo((c) => { + throw new Exception("Just testing"); + } + ); + ValidationReport report = PerformValidation("happyPath", TimeTestUtil.TEST_DATE_TIME, crl); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(CRLValidator.CRL_ISSUER_CHAIN_FAILED))); + } + [NUnit.Framework.Test] public virtual void ProvidedTimeIsUsedForResponderValidation() { RetrieveTestResources("happyPath"); diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CertificateChainValidatorTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CertificateChainValidatorTest.cs index 77d53d2a03..d39d5d8f66 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CertificateChainValidatorTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/CertificateChainValidatorTest.cs @@ -26,6 +26,7 @@ You should have received a copy of the GNU Affero General Public License using iText.Commons.Utils; using iText.Signatures; using iText.Signatures.Testutils; +using iText.Signatures.Testutils.Client; using iText.Signatures.Validation.V1.Context; using iText.Signatures.Validation.V1.Extensions; using iText.Signatures.Validation.V1.Mocks; @@ -469,5 +470,110 @@ public virtual void RootCertificateTrustedForTimestampTest() { )).HasLogItem((l) => l.WithMessage(CertificateChainValidator.ISSUER_MISSING, (i) => rootCert.GetSubjectDN ()))); } + + [NUnit.Framework.Test] + public virtual void TrustStoreFailureTest() { + String chainName = CERTS_SRC + "chain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate signingCert = (IX509Certificate)certificateChain[0]; + IX509Certificate intermediateCert = (IX509Certificate)certificateChain[1]; + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(certificateRetriever + ).OnGetTrustedCertificatesStoreDo(() => { + throw new Exception("Test trust store failure"); + } + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + CertificateChainValidator validator = validatorChainBuilder.BuildCertificateChainValidator(); + certificateRetriever.AddKnownCertificates(JavaCollectionsUtil.SingletonList(intermediateCert + )); + certificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + ValidationReport report = validator.ValidateCertificate(baseContext, signingCert, TimeTestUtil.TEST_DATE_TIME + ); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItems(1, 10, (la) => la.WithMessage(CertificateChainValidator.TRUSTSTORE_RETRIEVAL_FAILED))); + } + + [NUnit.Framework.Test] + public virtual void IssuerRetrievalFailureTest() { + String chainName = CERTS_SRC + "chain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate signingCert = (IX509Certificate)certificateChain[0]; + IX509Certificate intermediateCert = (IX509Certificate)certificateChain[1]; + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(certificateRetriever + ).OnRetrieveIssuerCertificateDo((c) => { + throw new Exception("Test issuer retrieval failure"); + } + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + CertificateChainValidator validator = validatorChainBuilder.BuildCertificateChainValidator(); + certificateRetriever.AddKnownCertificates(JavaCollectionsUtil.SingletonList(intermediateCert + )); + certificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + ValidationReport report = validator.ValidateCertificate(baseContext, signingCert, TimeTestUtil.TEST_DATE_TIME + ); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItems(1, 10, (la) => la.WithMessage(CertificateChainValidator.ISSUER_RETRIEVAL_FAILED))); + } + + [NUnit.Framework.Test] + public virtual void RevocationValidationFailureTest() { + String chainName = CERTS_SRC + "chain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate signingCert = (IX509Certificate)certificateChain[0]; + IX509Certificate intermediateCert = (IX509Certificate)certificateChain[1]; + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + mockRevocationDataValidator.OnValidateDo((c) => { + throw new Exception("Test revocation validation failure"); + } + ); + CertificateChainValidator validator = validatorChainBuilder.BuildCertificateChainValidator(); + certificateRetriever.AddKnownCertificates(JavaCollectionsUtil.SingletonList(intermediateCert + )); + certificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + ValidationReport report = validator.ValidateCertificate(baseContext, signingCert, TimeTestUtil.TEST_DATE_TIME + ); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItems(1, 10, (la) => la.WithMessage(CertificateChainValidator.REVOCATION_VALIDATION_FAILED))); + } + + [NUnit.Framework.Test] + public virtual void AddCrlClientPasstroughTest() { + CertificateChainValidator validator = validatorChainBuilder.BuildCertificateChainValidator(); + validator.AddCrlClient(new TestCrlClient()); + NUnit.Framework.Assert.AreEqual(1, mockRevocationDataValidator.crlClientsAdded.Count); + } + + [NUnit.Framework.Test] + public virtual void AddOcdpClientPasstroughTest() { + CertificateChainValidator validator = validatorChainBuilder.BuildCertificateChainValidator(); + validator.AddOcspClient(new TestOcspClient()); + NUnit.Framework.Assert.AreEqual(1, mockRevocationDataValidator.ocspClientsAdded.Count); + } + + [NUnit.Framework.Test] + public virtual void TestStopOnInvalidRevocationResultTest() { + mockRevocationDataValidator.OnValidateDo((c) => c.report.AddReportItem(new ReportItem("test", "test", ReportItem.ReportItemStatus + .INVALID))); + String chainName = CERTS_SRC + "chain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate signingCert = (IX509Certificate)certificateChain[0]; + IX509Certificate intermediateCert = (IX509Certificate)certificateChain[1]; + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + properties.SetContinueAfterFailure(ValidatorContexts.All(), CertificateSources.All(), false); + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(certificateRetriever + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + CertificateChainValidator validator = validatorChainBuilder.BuildCertificateChainValidator(); + certificateRetriever.AddKnownCertificates(JavaCollectionsUtil.SingletonList(intermediateCert + )); + certificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + ValidationReport report = validator.ValidateCertificate(baseContext, signingCert, TimeTestUtil.TEST_DATE_TIME + ); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INVALID)); + NUnit.Framework.Assert.AreEqual(0, mockCertificateRetriever.getCrlIssuerCertificatesCalls.Count); + NUnit.Framework.Assert.AreEqual(1, mockRevocationDataValidator.calls.Count); + } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/OCSPValidatorTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/OCSPValidatorTest.cs index 68566e305c..bdfe2fd09f 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/OCSPValidatorTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/OCSPValidatorTest.cs @@ -379,6 +379,81 @@ public virtual void CertExpiredAfterArchiveCutoffDateTest() { (0).HasNumberOfLogs(0)); } + [NUnit.Framework.Test] + public virtual void CertificateRetrieverRetrieveIssuerCertificateFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + mockCertificateRetriever.OnRetrieveIssuerCertificateDo((c) => { + throw new Exception("Test retrieveMissingCertificates failure"); + } + ); + ValidationReport report = ValidateTest(checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(OCSPValidator.UNABLE_TO_RETRIEVE_ISSUER))); + } + + [NUnit.Framework.Test] + public virtual void CertificateRetrieverRetrieveOCSPResponderCertificateFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(certificateRetriever + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + mockCertificateRetriever.OnRetrieveOCSPResponderCertificateDo((c) => { + throw new Exception("Test retrieveMissingCertificates failure"); + } + ); + ValidationReport report = ValidateTest(checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(OCSPValidator.OCSP_RESPONDER_NOT_RETRIEVED))); + } + + [NUnit.Framework.Test] + public virtual void CertificateRetrieverIsCertificateTrustedFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(certificateRetriever + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + mockCertificateRetriever.OnIsCertificateTrustedDo((c) => { + throw new Exception("Test isCertificateTrusted failure"); + } + ); + ValidationReport report = ValidateTest(checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(OCSPValidator.OCSP_RESPONDER_TRUST_NOT_RETRIEVED))); + } + + [NUnit.Framework.Test] + public virtual void CertificateRetrieverIsCertificateTrustedForOcspFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + MockIssuingCertificateRetriever mockCertificateRetriever = new MockIssuingCertificateRetriever(certificateRetriever + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetriever); + mockCertificateRetriever.OnIsCertificateTrustedDo((c) => false); + MockTrustedCertificatesStore mockTrustedStore = new MockTrustedCertificatesStore(certificateRetriever.GetTrustedCertificatesStore + ()); + mockCertificateRetriever.OnGetTrustedCertificatesStoreDo(() => mockTrustedStore); + mockTrustedStore.OnIsCertificateTrustedForOcspDo((c) => { + throw new Exception("Test isCertificateTrustedForOcsp failure"); + } + ); + ValidationReport report = ValidateTest(checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(OCSPValidator.OCSP_RESPONDER_TRUST_NOT_RETRIEVED))); + } + + [NUnit.Framework.Test] + public virtual void CertificateChainValidationFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + mockCertificateChainValidator.OnCallDo((c) => { + throw new Exception("Test chain validation failure"); + } + ); + ValidationReport report = ValidateTest(checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(OCSPValidator.OCSP_RESPONDER_NOT_VERIFIED))); + } + private ValidationReport ValidateTest(DateTime checkDate) { return ValidateTest(checkDate, checkDate.AddDays(1), 0); } diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/RevocationDataValidatorTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/RevocationDataValidatorTest.cs index aca2558a94..31de609504 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/RevocationDataValidatorTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/RevocationDataValidatorTest.cs @@ -308,7 +308,7 @@ public virtual void CrlEncodingErrorTest() { parameters.SetFreshness(ValidatorContexts.All(), CertificateSources.All(), TimeBasedContexts.All(), TimeSpan.FromDays (2)); RevocationDataValidator validator = validatorChainBuilder.BuildRevocationDataValidator(); - validator.AddCrlClient(new _ICrlClient_409(crl)).Validate(report, baseContext, checkCert, TimeTestUtil.TEST_DATE_TIME + validator.AddCrlClient(new _ICrlClient_410(crl)).Validate(report, baseContext, checkCert, TimeTestUtil.TEST_DATE_TIME ); AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE ).HasLogItem((la) => la.WithCheckName(RevocationDataValidator.REVOCATION_DATA_CHECK).WithMessage(MessageFormatUtil @@ -317,8 +317,8 @@ public virtual void CrlEncodingErrorTest() { ))); } - private sealed class _ICrlClient_409 : ICrlClient { - public _ICrlClient_409(byte[] crl) { + private sealed class _ICrlClient_410 : ICrlClient { + public _ICrlClient_410(byte[] crl) { this.crl = crl; } @@ -416,7 +416,7 @@ public virtual void ResponsesFromValidationClientArePassedTest() { mockCrlValidator.OnCallDo((c) => NUnit.Framework.Assert.AreEqual(crlGeneration, c.responseGenerationDate)); ValidationReport report = new ValidationReport(); RevocationDataValidator validator = validatorChainBuilder.GetRevocationDataValidator(); - ValidationOcspClient ocspClient = new _ValidationOcspClient_526(); + ValidationOcspClient ocspClient = new _ValidationOcspClient_527(); TestOcspResponseBuilder ocspBuilder = new TestOcspResponseBuilder(responderCert, ocspRespPrivateKey); byte[] ocspResponseBytes = new TestOcspClient().AddBuilderForCertIssuer(caCert, ocspBuilder).GetEncoded(checkCert , caCert, null); @@ -424,7 +424,7 @@ public virtual void ResponsesFromValidationClientArePassedTest() { )); ocspClient.AddResponse(basicOCSPResp, ocspGeneration, TimeBasedContext.HISTORICAL); validator.AddOcspClient(ocspClient); - ValidationCrlClient crlClient = new _ValidationCrlClient_541(); + ValidationCrlClient crlClient = new _ValidationCrlClient_542(); TestCrlBuilder crlBuilder = new TestCrlBuilder(caCert, caPrivateKey, checkDate); byte[] crlResponseBytes = new List(new TestCrlClient().AddBuilderForCertIssuer(crlBuilder).GetEncoded (checkCert, null))[0]; @@ -434,8 +434,8 @@ public virtual void ResponsesFromValidationClientArePassedTest() { validator.Validate(report, baseContext, checkCert, checkDate); } - private sealed class _ValidationOcspClient_526 : ValidationOcspClient { - public _ValidationOcspClient_526() { + private sealed class _ValidationOcspClient_527 : ValidationOcspClient { + public _ValidationOcspClient_527() { } public override byte[] GetEncoded(IX509Certificate checkCert, IX509Certificate issuerCert, String url) { @@ -444,8 +444,8 @@ public override byte[] GetEncoded(IX509Certificate checkCert, IX509Certificate i } } - private sealed class _ValidationCrlClient_541 : ValidationCrlClient { - public _ValidationCrlClient_541() { + private sealed class _ValidationCrlClient_542 : ValidationCrlClient { + public _ValidationCrlClient_542() { } public override ICollection GetEncoded(IX509Certificate checkCert, String url) { @@ -511,18 +511,18 @@ public virtual void TimeBasedContextProperlySetOnlineClientsTest() { RevocationDataValidator validator = validatorChainBuilder.GetRevocationDataValidator(); TestOcspResponseBuilder ocspBuilder = new TestOcspResponseBuilder(responderCert, ocspRespPrivateKey); TestOcspClient testOcspClient = new TestOcspClient().AddBuilderForCertIssuer(caCert, ocspBuilder); - OcspClientBouncyCastle ocspClient = new _OcspClientBouncyCastle_620(testOcspClient, null); + OcspClientBouncyCastle ocspClient = new _OcspClientBouncyCastle_621(testOcspClient, null); validator.AddOcspClient(ocspClient); TestCrlBuilder crlBuilder = new TestCrlBuilder(caCert, caPrivateKey, checkDate); TestCrlClient testCrlClient = new TestCrlClient().AddBuilderForCertIssuer(crlBuilder); - CrlClientOnline crlClient = new _CrlClientOnline_630(testCrlClient); + CrlClientOnline crlClient = new _CrlClientOnline_631(testCrlClient); validator.AddCrlClient(crlClient); validator.Validate(report, baseContext.SetTimeBasedContext(TimeBasedContext.HISTORICAL), checkCert, checkDate ); } - private sealed class _OcspClientBouncyCastle_620 : OcspClientBouncyCastle { - public _OcspClientBouncyCastle_620(TestOcspClient testOcspClient, OCSPVerifier baseArg1) + private sealed class _OcspClientBouncyCastle_621 : OcspClientBouncyCastle { + public _OcspClientBouncyCastle_621(TestOcspClient testOcspClient, OCSPVerifier baseArg1) : base(baseArg1) { this.testOcspClient = testOcspClient; } @@ -534,8 +534,8 @@ public override byte[] GetEncoded(IX509Certificate checkCert, IX509Certificate r private readonly TestOcspClient testOcspClient; } - private sealed class _CrlClientOnline_630 : CrlClientOnline { - public _CrlClientOnline_630(TestCrlClient testCrlClient) { + private sealed class _CrlClientOnline_631 : CrlClientOnline { + public _CrlClientOnline_631(TestCrlClient testCrlClient) { this.testCrlClient = testCrlClient; } @@ -545,5 +545,153 @@ public override ICollection GetEncoded(IX509Certificate checkCert, Strin private readonly TestCrlClient testCrlClient; } + + [NUnit.Framework.Test] + public virtual void BasicOCSPValidatorFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + TestOcspResponseBuilder builder = new TestOcspResponseBuilder(responderCert, ocspRespPrivateKey); + builder.SetProducedAt(checkDate.AddDays(5)); + builder.SetThisUpdate(DateTimeUtil.GetCalendar(checkDate.AddDays(5))); + builder.SetNextUpdate(DateTimeUtil.GetCalendar(checkDate.AddDays(10))); + TestOcspClientWrapper ocspClient = new TestOcspClientWrapper(new TestOcspClient().AddBuilderForCertIssuer( + caCert, builder)); + ValidationReport report = new ValidationReport(); + certificateRetriever.AddTrustedCertificates(JavaCollectionsUtil.SingletonList(caCert)); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddFreshnessResponse(TimeSpan.FromDays(-2)); + RevocationDataValidator validator = validatorChainBuilder.BuildRevocationDataValidator(); + validator.AddOcspClient(ocspClient); + mockOCSPValidator.OnCallDo((c) => { + throw new Exception("Test OCSP client failure"); + } + ); + validator.Validate(report, baseContext, checkCert, checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.VALID) + // the logitem from the OCSP valdiation should be copied to the final report + .HasLogItem((l) => l.WithMessage(RevocationDataValidator.OCSP_VALIDATOR_FAILURE))); + } + + [NUnit.Framework.Test] + public virtual void OCSPValidatorFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + DateTime revocationDate = checkDate.AddDays(-1); + TestCrlBuilder builder = new TestCrlBuilder(caCert, caPrivateKey, checkDate); + builder.SetNextUpdate(checkDate.AddDays(10)); + builder.AddCrlEntry(checkCert, revocationDate, FACTORY.CreateCRLReason().GetKeyCompromise()); + TestCrlClientWrapper crlClient = new TestCrlClientWrapper(new TestCrlClient().AddBuilderForCertIssuer(builder + )); + ValidationReport report = new ValidationReport(); + certificateRetriever.AddTrustedCertificates(JavaCollectionsUtil.SingletonList(caCert)); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddFreshnessResponse(TimeSpan.FromDays(0)); + ReportItem reportItem = new ReportItem("validator", "message", ReportItem.ReportItemStatus.INFO); + mockCrlValidator.OnCallDo((c) => { + throw new Exception("Test OCSP client failure"); + } + ); + RevocationDataValidator validator = validatorChainBuilder.BuildRevocationDataValidator().AddCrlClient(crlClient + ); + validator.Validate(report, baseContext, checkCert, checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.VALID) + // the logitem from the OCSP valdiation should be copied to the final report + .HasLogItem((l) => l.WithMessage(RevocationDataValidator.CRL_VALIDATOR_FAILURE))); + } + + //certificateRetriever.retrieveIssuerCertificate + [NUnit.Framework.Test] + public virtual void CertificateRetrieverRetrieveIssuerCertificateFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + TestOcspResponseBuilder builder = new TestOcspResponseBuilder(responderCert, ocspRespPrivateKey); + builder.SetProducedAt(checkDate.AddDays(5)); + builder.SetThisUpdate(DateTimeUtil.GetCalendar(checkDate.AddDays(5))); + builder.SetNextUpdate(DateTimeUtil.GetCalendar(checkDate.AddDays(10))); + TestOcspClientWrapper ocspClient = new TestOcspClientWrapper(new TestOcspClient().AddBuilderForCertIssuer( + caCert, builder)); + ValidationReport report = new ValidationReport(); + certificateRetriever.AddTrustedCertificates(JavaCollectionsUtil.SingletonList(caCert)); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddFreshnessResponse(TimeSpan.FromDays(-2)); + MockIssuingCertificateRetriever mockCertificateRetreiver = new MockIssuingCertificateRetriever(certificateRetriever + ).OnRetrieveIssuerCertificateDo((c) => { + throw new Exception("Test retrieveIssuerCertificate failure"); + } + ); + validatorChainBuilder.WithIssuingCertificateRetriever(mockCertificateRetreiver); + RevocationDataValidator validator = validatorChainBuilder.BuildRevocationDataValidator(); + validator.AddOcspClient(ocspClient); + ReportItem reportItem = new ReportItem("validator", "message", ReportItem.ReportItemStatus.INFO); + mockOCSPValidator.OnCallDo((c) => c.report.AddReportItem(reportItem)); + validator.Validate(report, baseContext, checkCert, checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(RevocationDataValidator.ISSUER_RETRIEVAL_FAILED))); + } + + [NUnit.Framework.Test] + public virtual void OcspClientGetEncodedFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + TestOcspResponseBuilder builder = new TestOcspResponseBuilder(responderCert, ocspRespPrivateKey); + builder.SetProducedAt(checkDate.AddDays(5)); + builder.SetThisUpdate(DateTimeUtil.GetCalendar(checkDate.AddDays(5))); + builder.SetNextUpdate(DateTimeUtil.GetCalendar(checkDate.AddDays(10))); + TestOcspClientWrapper ocspClient = new TestOcspClientWrapper(new TestOcspClient().AddBuilderForCertIssuer( + caCert, builder)); + ValidationReport report = new ValidationReport(); + certificateRetriever.AddTrustedCertificates(JavaCollectionsUtil.SingletonList(caCert)); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddFreshnessResponse(TimeSpan.FromDays(-2)); + RevocationDataValidator validator = validatorChainBuilder.BuildRevocationDataValidator(); + validator.AddOcspClient(ocspClient); + ReportItem reportItem = new ReportItem("validator", "message", ReportItem.ReportItemStatus.INFO); + mockOCSPValidator.OnCallDo((c) => c.report.AddReportItem(reportItem)); + ocspClient.OnGetEncodedDo((c) => { + throw new Exception("Test onGetEncoded failure"); + } + ); + validator.Validate(report, baseContext, checkCert, checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(RevocationDataValidator.OCSP_CLIENT_FAILURE, (p) => ocspClient))); + } + + [NUnit.Framework.Test] + public virtual void CrlClientGetEncodedFailureTest() { + DateTime checkDate = TimeTestUtil.TEST_DATE_TIME; + DateTime revocationDate = checkDate.AddDays(-1); + TestCrlBuilder builder = new TestCrlBuilder(caCert, caPrivateKey, checkDate); + builder.SetNextUpdate(checkDate.AddDays(10)); + builder.AddCrlEntry(checkCert, revocationDate, FACTORY.CreateCRLReason().GetKeyCompromise()); + TestCrlClientWrapper crlClient = new TestCrlClientWrapper(new TestCrlClient().AddBuilderForCertIssuer(builder + )); + ValidationReport report = new ValidationReport(); + certificateRetriever.AddTrustedCertificates(JavaCollectionsUtil.SingletonList(caCert)); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddRevocationOnlineFetchingResponse(SignatureValidationProperties.OnlineFetching.NEVER_FETCH + ); + mockParameters.AddFreshnessResponse(TimeSpan.FromDays(0)); + ReportItem reportItem = new ReportItem("validator", "message", ReportItem.ReportItemStatus.INFO); + mockCrlValidator.OnCallDo((c) => c.report.AddReportItem(reportItem)); + RevocationDataValidator validator = validatorChainBuilder.BuildRevocationDataValidator().AddCrlClient(crlClient + ); + crlClient.OnGetEncodedDo((c) => { + throw new Exception("Test getEncoded failure"); + } + ); + validator.Validate(report, baseContext, checkCert, checkDate); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INDETERMINATE + ).HasLogItem((l) => l.WithMessage(RevocationDataValidator.CRL_CLIENT_FAILURE, (p) => crlClient.ToString + ()))); + } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorIntegrationTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorIntegrationTest.cs index 1e67d28990..cd0d475ddc 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorIntegrationTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorIntegrationTest.cs @@ -101,6 +101,7 @@ public virtual void ShortValidityCertsWithOcspTest() { SignatureValidator signatureValidator = builder.BuildSignatureValidator(); report = signatureValidator.ValidateSignatures(document); } + // ocsp validation date is wrong but why AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.VALID).HasLogItem ((al) => al.WithCheckName(DocumentRevisionsValidator.DOC_MDP_CHECK).WithMessage(DocumentRevisionsValidator .UNEXPECTED_ENTRY_IN_XREF, (i) => 30)).HasLogItem((al) => al.WithCheckName(SignatureValidator.SIGNATURE_VERIFICATION diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorTest.cs index ed53da2cfb..679067c179 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/SignatureValidatorTest.cs @@ -343,5 +343,115 @@ public virtual void ValidateMultipleSignatures() { ("1701704311986") && c.checkDate.Equals(date1))); } } + + [NUnit.Framework.Test] + public virtual void SignatureChainValidatorFailureTest() { + String chainName = CERTS_SRC + "validCertsChain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "validDoc.pdf"))) { + mockCertificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + mockCertificateChainValidator.OnCallDo((c) => { + throw new Exception("Test chain validation failure"); + } + ); + SignatureValidator signatureValidator = builder.BuildSignatureValidator(); + ValidationReport report = signatureValidator.ValidateLatestSignature(document); + AssertValidationReport.AssertThat(report, (r) => r.HasLogItem((l) => l.WithMessage(SignatureValidator.CHAIN_VALIDATION_FAILED + ))); + } + } + + [NUnit.Framework.Test] + public virtual void TimeStampChainValidatorFailureTest() { + String chainName = CERTS_SRC + "validCertsChain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + IX509Certificate intermediateCert = (IX509Certificate)certificateChain[1]; + IX509Certificate signCert = (IX509Certificate)certificateChain[0]; + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "timestampSignatureDoc.pdf"))) { + mockCertificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + mockCertificateChainValidator.OnCallDo((c) => { + throw new Exception("Test chain validation failure"); + } + ); + SignatureValidator signatureValidator = builder.BuildSignatureValidator(); + ValidationReport report = signatureValidator.ValidateLatestSignature(document); + AssertValidationReport.AssertThat(report, (r) => r.HasLogItem((l) => l.WithMessage(SignatureValidator.CHAIN_VALIDATION_FAILED + ))); + } + } + + [NUnit.Framework.Test] + public virtual void CertificateRetrieverAddKnownCertificatesFromDSSFailureTest() { + String chainName = CERTS_SRC + "validCertsChain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "docWithDss.pdf"))) { + mockCertificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + mockCertificateRetriever.OnAddKnownCertificatesDo((c) => { + throw new Exception("Test add know certificates failure"); + } + ); + SignatureValidator signatureValidator = builder.BuildSignatureValidator(); + ValidationReport report = signatureValidator.ValidateLatestSignature(document); + AssertValidationReport.AssertThat(report, (r) => r.HasLogItems(1, int.MaxValue, (l) => l.WithMessage(SignatureValidator + .ADD_KNOWN_CERTIFICATES_FAILED))); + } + } + + [NUnit.Framework.Test] + public virtual void CertificateRetrieverAddKnownCertificatesFromSignatureFailureTest() { + String chainName = CERTS_SRC + "validCertsChain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "validDoc.pdf"))) { + mockCertificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + mockCertificateRetriever.OnAddKnownCertificatesDo((c) => { + throw new Exception("Test add know certificates failure"); + } + ); + SignatureValidator signatureValidator = builder.BuildSignatureValidator(); + ValidationReport report = signatureValidator.ValidateLatestSignature(document); + AssertValidationReport.AssertThat(report, (r) => r.HasLogItems(1, int.MaxValue, (l) => l.WithMessage(SignatureValidator + .ADD_KNOWN_CERTIFICATES_FAILED))); + } + } + + [NUnit.Framework.Test] + public virtual void CertificateRetrieverAddKnownCertificatesFromTimestampFailureTest() { + String chainName = CERTS_SRC + "validCertsChain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "timestampSignatureDoc.pdf"))) { + mockCertificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + mockCertificateRetriever.OnAddKnownCertificatesDo((c) => { + throw new Exception("Test add know certificates failure"); + } + ); + SignatureValidator signatureValidator = builder.BuildSignatureValidator(); + ValidationReport report = signatureValidator.ValidateLatestSignature(document); + AssertValidationReport.AssertThat(report, (r) => r.HasLogItems(1, int.MaxValue, (l) => l.WithMessage(SignatureValidator + .ADD_KNOWN_CERTIFICATES_FAILED))); + } + } + + [NUnit.Framework.Test] + public virtual void DocumentRevisionValidatorFailureTest() { + String chainName = CERTS_SRC + "validCertsChain.pem"; + IX509Certificate[] certificateChain = PemFileHelper.ReadFirstChain(chainName); + IX509Certificate rootCert = (IX509Certificate)certificateChain[2]; + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "validDoc.pdf"))) { + mockCertificateRetriever.SetTrustedCertificates(JavaCollectionsUtil.SingletonList(rootCert)); + mockDocumentRevisionsValidator.OnCallDo((c) => { + throw new Exception("Test add know certificates failure"); + } + ); + SignatureValidator signatureValidator = builder.BuildSignatureValidator(); + ValidationReport report = signatureValidator.ValidateSignatures(document); + AssertValidationReport.AssertThat(report, (r) => r.HasLogItem((l) => l.WithMessage(SignatureValidator.REVISIONS_VALIDATION_FAILED + ))); + } + } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockDocumentRevisionsValidator.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockDocumentRevisionsValidator.cs index b623da3bcc..bd1825cb16 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockDocumentRevisionsValidator.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockDocumentRevisionsValidator.cs @@ -20,6 +20,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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.Kernel.Pdf; using iText.Signatures.Validation.V1; using iText.Signatures.Validation.V1.Context; @@ -27,14 +29,25 @@ You should have received a copy of the GNU Affero General Public License namespace iText.Signatures.Validation.V1.Mocks { public class MockDocumentRevisionsValidator : DocumentRevisionsValidator { + public Action onCallHandler; + private ReportItem.ReportItemStatus reportItemStatus = ReportItem.ReportItemStatus.INFO; + private IList calls = new List(); + public MockDocumentRevisionsValidator() : base(new ValidatorChainBuilder()) { } public override ValidationReport ValidateAllDocumentRevisions(ValidationContext context, PdfDocument document ) { + MockDocumentRevisionsValidator.RevisionsValidatorCall call = new MockDocumentRevisionsValidator.RevisionsValidatorCall + (context, document); + calls.Add(call); + if (onCallHandler != null) { + onCallHandler(call); + } ValidationReport report = new ValidationReport(); if (reportItemStatus != ReportItem.ReportItemStatus.INFO) { report.AddReportItem(new ReportItem("test", "test", reportItemStatus)); @@ -45,5 +58,20 @@ public override ValidationReport ValidateAllDocumentRevisions(ValidationContext public virtual void SetReportItemStatus(ReportItem.ReportItemStatus reportItemStatus) { this.reportItemStatus = reportItemStatus; } + + public virtual void OnCallDo(Action callback) { + onCallHandler = callback; + } + + public class RevisionsValidatorCall { + public readonly ValidationContext context; + + public readonly PdfDocument document; + + public RevisionsValidatorCall(ValidationContext context, PdfDocument document) { + this.context = context; + this.document = document; + } + } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockIssuingCertificateRetriever.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockIssuingCertificateRetriever.cs index 2e8e4977f5..58cd6c56fa 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockIssuingCertificateRetriever.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockIssuingCertificateRetriever.cs @@ -22,38 +22,75 @@ You should have received a copy of the GNU Affero General Public License */ using System; using System.Collections.Generic; +using System.IO; +using iText.Commons.Bouncycastle.Asn1.Ocsp; using iText.Commons.Bouncycastle.Cert; using iText.Signatures; +using iText.Signatures.Validation.V1; namespace iText.Signatures.Validation.V1.Mocks { public class MockIssuingCertificateRetriever : IssuingCertificateRetriever { + private readonly IssuingCertificateRetriever wrapped; + public IList retrieveMissingCertificatesCalls = new List(); public IList getCrlIssuerCertificatesCalls = new List(); + public IList retrieveIssuerCertificateCalls = new List(); + + public IList retrieveOCSPResponderCertificateCalls = new List(); + public IList> setTrustedCertificatesCalls = new List>(); public IList> addKnownCertificatesCalls = new List>(); + public IList> addTrustedCertificatesCalls = new List>(); + public IList isCertificateTrustedDoCalls = new List(); + public IList getIssuerCertByURICalls = new List(); + + public int getTrustedCertificatesStoreCallCount = 0; + private Func retrieveMissingCertificatesHandler; private Func getCrlIssuerCertificatesHandler; + private Func retrieveIssuerCertificateHandler; + + private Func retrieveOCSPResponderCertificateHandler; + private Action> setTrustedCertificatesHandler; private Action> addKnownCertificatesHandler; + private Action> addTrustedCertificatesHandler; + private Func isCertificateTrustedDoHandler; + private Func getTrustedCertificatesStoreHandler; + + private Func getIssuerCertByURIHandler; + + public MockIssuingCertificateRetriever() { + wrapped = null; + } + + public MockIssuingCertificateRetriever(IssuingCertificateRetriever fallback) { + wrapped = fallback; + } + public override IX509Certificate[] RetrieveMissingCertificates(IX509Certificate[] chain) { retrieveMissingCertificatesCalls.Add(chain); if (retrieveMissingCertificatesHandler != null) { return retrieveMissingCertificatesHandler.Invoke(chain); } + if (wrapped != null) { + return wrapped.RetrieveMissingCertificates(chain); + } return new IX509Certificate[0]; } @@ -62,13 +99,42 @@ public override IX509Certificate[] GetCrlIssuerCertificates(IX509Crl crl) { if (getCrlIssuerCertificatesHandler != null) { return getCrlIssuerCertificatesHandler.Invoke(crl); } + if (wrapped != null) { + return wrapped.GetCrlIssuerCertificates(crl); + } return new IX509Certificate[0]; } + public override IX509Certificate RetrieveIssuerCertificate(IX509Certificate certificate) { + retrieveIssuerCertificateCalls.Add(certificate); + if (retrieveIssuerCertificateHandler != null) { + return retrieveIssuerCertificateHandler.Invoke(certificate); + } + if (wrapped != null) { + return wrapped.RetrieveIssuerCertificate(certificate); + } + return null; + } + + public override IX509Certificate RetrieveOCSPResponderCertificate(IBasicOcspResponse ocspResp) { + retrieveOCSPResponderCertificateCalls.Add(ocspResp); + if (retrieveOCSPResponderCertificateHandler != null) { + return retrieveOCSPResponderCertificateHandler.Invoke(ocspResp); + } + if (wrapped != null) { + return wrapped.RetrieveOCSPResponderCertificate(ocspResp); + } + return null; + } + public override void SetTrustedCertificates(ICollection certificates) { setTrustedCertificatesCalls.Add(certificates); if (setTrustedCertificatesHandler != null) { setTrustedCertificatesHandler(certificates); + return; + } + if (wrapped != null) { + wrapped.SetTrustedCertificates(certificates); } } @@ -76,6 +142,21 @@ public override void AddKnownCertificates(ICollection certific addKnownCertificatesCalls.Add(certificates); if (addKnownCertificatesHandler != null) { addKnownCertificatesHandler(certificates); + return; + } + if (wrapped != null) { + wrapped.AddKnownCertificates(certificates); + } + } + + public override void AddTrustedCertificates(ICollection certificates) { + addTrustedCertificatesCalls.Add(certificates); + if (addTrustedCertificatesHandler != null) { + addTrustedCertificatesHandler(certificates); + return; + } + if (wrapped != null) { + wrapped.AddTrustedCertificates(certificates); } } @@ -84,37 +165,89 @@ public override bool IsCertificateTrusted(IX509Certificate certificate) { if (isCertificateTrustedDoHandler != null) { return isCertificateTrustedDoHandler.Invoke(certificate); } + if (wrapped != null) { + return wrapped.IsCertificateTrusted(certificate); + } return true; } - public virtual MockIssuingCertificateRetriever OnRetrieveMissingCertificatesDo(Func callback) { + public override TrustedCertificatesStore GetTrustedCertificatesStore() { + getTrustedCertificatesStoreCallCount++; + if (getTrustedCertificatesStoreHandler != null) { + return getTrustedCertificatesStoreHandler(); + } + if (wrapped != null) { + return wrapped.GetTrustedCertificatesStore(); + } + return null; + } + + protected internal override Stream GetIssuerCertByURI(String uri) { + getIssuerCertByURICalls.Add(uri); + if (getIssuerCertByURIHandler != null) { + return getIssuerCertByURIHandler.Invoke(uri); + } + return null; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnRetrieveMissingCertificatesDo + (Func callback) { retrieveMissingCertificatesHandler = callback; return this; } - public virtual MockIssuingCertificateRetriever OngetCrlIssuerCertificatesDo(Func callback) { + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OngetCrlIssuerCertificatesDo + (Func callback) { getCrlIssuerCertificatesHandler = callback; return this; } - public virtual MockIssuingCertificateRetriever OnSetTrustedCertificatesDo(Action> callback) { + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnRetrieveIssuerCertificateDo + (Func callback) { + retrieveIssuerCertificateHandler = callback; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnRetrieveOCSPResponderCertificateDo + (Func callback) { + retrieveOCSPResponderCertificateHandler = callback; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnSetTrustedCertificatesDo + (Action> callback) { setTrustedCertificatesHandler = callback; return this; } - public virtual MockIssuingCertificateRetriever OnAddKnownCertificatesDo(Action> callback) { + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnAddKnownCertificatesDo + (Action> callback) { addKnownCertificatesHandler = callback; return this; } - public virtual MockIssuingCertificateRetriever OnIsCertificateTrustedDo(Func callback - ) { + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnAddTrustedCertificatesDo + (Action> callback) { + addTrustedCertificatesHandler = callback; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnIsCertificateTrustedDo + (Func callback) { isCertificateTrustedDoHandler = callback; return this; } + + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnGetTrustedCertificatesStoreDo + (Func callBack) { + getTrustedCertificatesStoreHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockIssuingCertificateRetriever OnGetIssuerCertByURIHandlerDo + (Func callBack) { + getIssuerCertByURIHandler = callBack; + return this; + } } } diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockRevocationDataValidator.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockRevocationDataValidator.cs index d748596b96..4cbab47d6e 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockRevocationDataValidator.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockRevocationDataValidator.cs @@ -37,6 +37,12 @@ public class MockRevocationDataValidator : RevocationDataValidator { public IList calls = new List(); + private Action onValidateHandler; + + private Action onAddCrlClientHandler; + + private Action onAddOCSPClientHandler; + /// /// Creates new /// @@ -48,18 +54,46 @@ public MockRevocationDataValidator() public override RevocationDataValidator AddCrlClient(ICrlClient crlClient) { crlClientsAdded.Add(crlClient); + if (onAddCrlClientHandler != null) { + onAddCrlClientHandler(crlClient); + } return this; } public override RevocationDataValidator AddOcspClient(IOcspClient ocspClient) { ocspClientsAdded.Add(ocspClient); + if (onAddOCSPClientHandler != null) { + onAddOCSPClientHandler(ocspClient); + } return this; } public override void Validate(ValidationReport report, ValidationContext context, IX509Certificate certificate , DateTime validationDate) { - calls.Add(new MockRevocationDataValidator.RevocationDataValidatorCall(report, context, certificate, validationDate - )); + MockRevocationDataValidator.RevocationDataValidatorCall call = new MockRevocationDataValidator.RevocationDataValidatorCall + (report, context, certificate, validationDate); + calls.Add(call); + if (onValidateHandler != null) { + onValidateHandler(call); + } + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockRevocationDataValidator OnValidateDo(Action callBack) { + onValidateHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockRevocationDataValidator OnAddCerlClientDo(Action callBack) { + onAddCrlClientHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockRevocationDataValidator OnAddOCSPClientDo(Action callBack) { + onAddOCSPClientHandler = callBack; + return this; } public sealed class RevocationDataValidatorCall { diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockTrustedCertificatesStore.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockTrustedCertificatesStore.cs new file mode 100644 index 0000000000..87b622e7a1 --- /dev/null +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/v1/mocks/MockTrustedCertificatesStore.cs @@ -0,0 +1,292 @@ +/* +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.Bouncycastle.Cert; +using iText.Signatures.Validation.V1; + +namespace iText.Signatures.Validation.V1.Mocks { + public class MockTrustedCertificatesStore : TrustedCertificatesStore { + private readonly TrustedCertificatesStore wrapped; + + public IList isCertificateGenerallyTrustedCalls = new List(); + + public IList isCertificateTrustedForOcspCalls = new List(); + + public IList isCertificateTrustedForCrlCalls = new List(); + + public IList isCertificateTrustedForTimestampCalls = new List(); + + public IList isCertificateTrustedForCACalls = new List(); + + public IList getGenerallyTrustedCertificateCalls = new List(); + + public IList getCertificateTrustedForOcspCalls = new List(); + + public IList getCertificateTrustedForCrlCalls = new List(); + + public IList getCertificateTrustedForTimestampCalls = new List(); + + public IList getCertificateTrustedForCACalls = new List(); + + public IList getKnownCertificateCalls = new List(); + + public int getAllTrustedCertificatesCallCount = 0; + + private Func isCertificateGenerallyTrustedHandler; + + private Func isCertificateTrustedForOcspHandler; + + private Func isCertificateTrustedForCrlHandler; + + private Func isCertificateTrustedForTimestampHandler; + + private Func isCertificateTrustedForCAHandler; + + private Func getGenerallyTrustedCertificateHandler; + + private Func getCertificateTrustedForOcspHandler; + + private Func getCertificateTrustedForCrlHandler; + + private Func getCertificateTrustedForTimestampHandler; + + private Func getCertificateTrustedForCAHandler; + + private Func getKnownCertificateHandler; + + private Func> getAllTrustedCertificatesHandler; + + public MockTrustedCertificatesStore() { + this.wrapped = null; + } + + public MockTrustedCertificatesStore(TrustedCertificatesStore wrapped) { + this.wrapped = wrapped; + } + + public override bool IsCertificateGenerallyTrusted(IX509Certificate certificate) { + isCertificateGenerallyTrustedCalls.Add(certificate); + if (isCertificateGenerallyTrustedHandler != null) { + return isCertificateGenerallyTrustedHandler.Invoke(certificate); + } + if (wrapped != null) { + return wrapped.IsCertificateGenerallyTrusted(certificate); + } + return true; + } + + public override bool IsCertificateTrustedForOcsp(IX509Certificate certificate) { + isCertificateTrustedForOcspCalls.Add(certificate); + if (isCertificateTrustedForOcspHandler != null) { + return isCertificateTrustedForOcspHandler.Invoke(certificate); + } + if (wrapped != null) { + return wrapped.IsCertificateTrustedForOcsp(certificate); + } + return true; + } + + public override bool IsCertificateTrustedForCrl(IX509Certificate certificate) { + isCertificateTrustedForCrlCalls.Add(certificate); + if (isCertificateTrustedForCrlHandler != null) { + return isCertificateTrustedForCrlHandler.Invoke(certificate); + } + if (wrapped != null) { + return wrapped.IsCertificateTrustedForCrl(certificate); + } + return true; + } + + public override bool IsCertificateTrustedForTimestamp(IX509Certificate certificate) { + isCertificateTrustedForTimestampCalls.Add(certificate); + if (isCertificateTrustedForTimestampHandler != null) { + return isCertificateTrustedForTimestampHandler.Invoke(certificate); + } + if (wrapped != null) { + return wrapped.IsCertificateTrustedForTimestamp(certificate); + } + return true; + } + + public override bool IsCertificateTrustedForCA(IX509Certificate certificate) { + isCertificateTrustedForCACalls.Add(certificate); + if (isCertificateTrustedForCAHandler != null) { + return isCertificateTrustedForCAHandler.Invoke(certificate); + } + if (wrapped != null) { + return wrapped.IsCertificateTrustedForCA(certificate); + } + return true; + } + + public override IX509Certificate GetGenerallyTrustedCertificate(String certificateName) { + getGenerallyTrustedCertificateCalls.Add(certificateName); + if (getGenerallyTrustedCertificateHandler != null) { + return getGenerallyTrustedCertificateHandler.Invoke(certificateName); + } + if (wrapped != null) { + return wrapped.GetGenerallyTrustedCertificate(certificateName); + } + return null; + } + + public override IX509Certificate GetCertificateTrustedForOcsp(String certificateName) { + getCertificateTrustedForOcspCalls.Add(certificateName); + if (getCertificateTrustedForOcspHandler != null) { + return getCertificateTrustedForOcspHandler.Invoke(certificateName); + } + if (wrapped != null) { + return wrapped.GetCertificateTrustedForOcsp(certificateName); + } + return null; + } + + public override IX509Certificate GetCertificateTrustedForCrl(String certificateName) { + getCertificateTrustedForCrlCalls.Add(certificateName); + if (getCertificateTrustedForCrlHandler != null) { + return getCertificateTrustedForCrlHandler.Invoke(certificateName); + } + if (wrapped != null) { + return wrapped.GetCertificateTrustedForCrl(certificateName); + } + return null; + } + + public override IX509Certificate GetCertificateTrustedForTimestamp(String certificateName) { + getCertificateTrustedForTimestampCalls.Add(certificateName); + if (getCertificateTrustedForTimestampHandler != null) { + return getCertificateTrustedForTimestampHandler.Invoke(certificateName); + } + if (wrapped != null) { + return wrapped.GetCertificateTrustedForTimestamp(certificateName); + } + return null; + } + + public override IX509Certificate GetCertificateTrustedForCA(String certificateName) { + getCertificateTrustedForCACalls.Add(certificateName); + if (getCertificateTrustedForCAHandler != null) { + return getCertificateTrustedForCAHandler.Invoke(certificateName); + } + if (wrapped != null) { + return wrapped.GetCertificateTrustedForCA(certificateName); + } + return null; + } + + public override IX509Certificate GetKnownCertificate(String certificateName) { + getKnownCertificateCalls.Add(certificateName); + if (getKnownCertificateHandler != null) { + return getKnownCertificateHandler.Invoke(certificateName); + } + if (wrapped != null) { + return wrapped.GetKnownCertificate(certificateName); + } + return null; + } + + public override ICollection GetAllTrustedCertificates() { + getAllTrustedCertificatesCallCount++; + if (getAllTrustedCertificatesHandler != null) { + return getAllTrustedCertificatesHandler(); + } + if (wrapped != null) { + return wrapped.GetAllTrustedCertificates(); + } + return null; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnIsCertificateGenerallyTrustedDo + (Func callBack) { + isCertificateGenerallyTrustedHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnIsCertificateTrustedForOcspDo + (Func callBack) { + isCertificateTrustedForOcspHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnIsCertificateTrustedForCrlDo + (Func callBack) { + isCertificateTrustedForCrlHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnIsCertificateTrustedForTimestampDo + (Func callBack) { + isCertificateTrustedForTimestampHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnIsCertificateTrustedForCADo + (Func callBack) { + isCertificateTrustedForCAHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnGetGenerallyTrustedCertificateDo + (Func callBack) { + getGenerallyTrustedCertificateHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnGetCertificateTrustedForOcspDo + (Func callBack) { + getCertificateTrustedForOcspHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnGetCertificateTrustedForCrlDo + (Func callBack) { + getCertificateTrustedForCrlHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnGetCertificateTrustedForTimestampDo + (Func callBack) { + getCertificateTrustedForTimestampHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnGetCertificateTrustedForCADo + (Func callBack) { + getCertificateTrustedForCAHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnGetKnownCertificateDo(Func + callBack) { + getKnownCertificateHandler = callBack; + return this; + } + + public virtual iText.Signatures.Validation.V1.Mocks.MockTrustedCertificatesStore OnGetAllTrustedCertificatesDo + (Func> callBack) { + getAllTrustedCertificatesHandler = callBack; + return this; + } + } +} diff --git a/itext/itext.bouncy-castle-adapter/itext/bouncycastle/crypto/SignerBC.cs b/itext/itext.bouncy-castle-adapter/itext/bouncycastle/crypto/SignerBC.cs index da479e76d1..7f31efb2b6 100644 --- a/itext/itext.bouncy-castle-adapter/itext/bouncycastle/crypto/SignerBC.cs +++ b/itext/itext.bouncy-castle-adapter/itext/bouncycastle/crypto/SignerBC.cs @@ -66,6 +66,23 @@ public void InitSign(IPrivateKey key) { InitSign(key, lastHashAlgorithm, lastEncryptionAlgorithm); } + /// + public void InitRsaPssSigner(string digestAlgoName, int saltLen, int trailerField) { + if (iSigner != null) { + return; + } + // If trailerField == 1 then trailer = 0xBC (it's the default one) + if (trailerField != 1) { + throw new ArgumentException("unknown trailer field"); + } + + Org.BouncyCastle.Crypto.IDigest digest = Org.BouncyCastle.Security.DigestUtilities.GetDigest(digestAlgoName); + Org.BouncyCastle.Crypto.ISigner signer = new Org.BouncyCastle.Crypto.Signers.PssSigner( + new Org.BouncyCastle.Crypto.Engines.RsaBlindedEngine(), digest, digest, saltLen, 0xBC); + + this.iSigner = signer; + } + /// public void Update(byte[] buf, int off, int len) { iSigner.BlockUpdate(buf, off, len); @@ -130,23 +147,24 @@ public override String ToString() { } private void InitVerify(IPublicKey publicKey, string hashAlgorithm, string encrAlgorithm) { - if (string.IsNullOrEmpty(hashAlgorithm)) { - iSigner = SignerUtilities.GetSigner(encrAlgorithm); - } else { - iSigner = SignerUtilities.GetSigner(hashAlgorithm + "with" + encrAlgorithm); + if (iSigner == null) { + if (string.IsNullOrEmpty(hashAlgorithm)) { + iSigner = SignerUtilities.GetSigner(encrAlgorithm); + } else { + iSigner = SignerUtilities.GetSigner(hashAlgorithm + "with" + encrAlgorithm); + } } - + iSigner.Init(false, ((PublicKeyBC) publicKey).GetPublicKey()); } private void InitSign(IPrivateKey key, string hashAlgorithm, string encrAlgorithm) { - if (string.IsNullOrEmpty(hashAlgorithm)) - { - iSigner = SignerUtilities.GetSigner(encrAlgorithm); - } - else - { - iSigner = SignerUtilities.GetSigner(hashAlgorithm + "with" + encrAlgorithm); + if (iSigner == null) { + if (string.IsNullOrEmpty(hashAlgorithm)) { + iSigner = SignerUtilities.GetSigner(encrAlgorithm); + } else { + iSigner = SignerUtilities.GetSigner(hashAlgorithm + "with" + encrAlgorithm); + } } iSigner.Init(true, ((PrivateKeyBC) key).GetPrivateKey()); diff --git a/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/SignerBCFips.cs b/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/SignerBCFips.cs index f36688736d..d86eed0e91 100644 --- a/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/SignerBCFips.cs +++ b/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/SignerBCFips.cs @@ -69,6 +69,12 @@ public void InitSign(IPrivateKey key) { InitSign(key, lastHashAlgorithm, lastEncryptionAlgorithm); } + /// + public void InitRsaPssSigner(string digestAlgoName, int saltLen, int trailerField) { + // Not supported yet + // Leave empty, we will throw in another place + } + /// public void Update(byte[] buf, int off, int len) { if (digest != null) { diff --git a/itext/itext.commons/itext/commons/bouncycastle/crypto/ISigner.cs b/itext/itext.commons/itext/commons/bouncycastle/crypto/ISigner.cs index 269201c491..9a3c9d9ba6 100644 --- a/itext/itext.commons/itext/commons/bouncycastle/crypto/ISigner.cs +++ b/itext/itext.commons/itext/commons/bouncycastle/crypto/ISigner.cs @@ -41,7 +41,15 @@ public interface ISigner { /// /// public key void InitSign(IPrivateKey key); - + + /// + /// Creates actual signer object to create RSASSA-PSS signature + /// + /// digect algorithm + /// salt length + /// trailer field + void InitRsaPssSigner(string digestAlgoName, int saltLen, int trailerField); + /// /// Calls actual /// Update diff --git a/itext/itext.kernel/itext/kernel/geom/PageSize.cs b/itext/itext.kernel/itext/kernel/geom/PageSize.cs index 68d9f2b54f..fb1a6f000e 100644 --- a/itext/itext.kernel/itext/kernel/geom/PageSize.cs +++ b/itext/itext.kernel/itext/kernel/geom/PageSize.cs @@ -40,7 +40,7 @@ public class PageSize : Rectangle { public static readonly iText.Kernel.Geom.PageSize A8 = new iText.Kernel.Geom.PageSize(148, 210); - public static readonly iText.Kernel.Geom.PageSize A9 = new iText.Kernel.Geom.PageSize(105, 547); + public static readonly iText.Kernel.Geom.PageSize A9 = new iText.Kernel.Geom.PageSize(105, 148); public static readonly iText.Kernel.Geom.PageSize A10 = new iText.Kernel.Geom.PageSize(74, 105); diff --git a/itext/itext.sign/itext/signatures/SignUtils.cs b/itext/itext.sign/itext/signatures/SignUtils.cs index ce24447399..34242d59f7 100644 --- a/itext/itext.sign/itext/signatures/SignUtils.cs +++ b/itext/itext.sign/itext/signatures/SignUtils.cs @@ -267,12 +267,9 @@ internal static IEnumerable GetCertificates(ListGets the signature data. + /// the signature data. + public virtual byte[] GetSignatureData() { + return signatureData; + } + /// Sets the certificate that is used to sign a document and adds it to the signed attributes. /// the certificate that is used to sign /// the oid of the digest algorithm to be added to the signed attributes diff --git a/itext/itext.sign/itext/signatures/validation/v1/CRLValidator.cs b/itext/itext.sign/itext/signatures/validation/v1/CRLValidator.cs index ac509277ef..dd40004ab8 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/CRLValidator.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/CRLValidator.cs @@ -67,6 +67,14 @@ public class CRLValidator { internal const String CRL_ISSUER_NOT_FOUND = "Unable to validate CRL response: no issuer certificate found."; //\endcond +//\cond DO_NOT_DOCUMENT + internal const String CRL_ISSUER_REQUEST_FAILED = "Unable to validate CRL response: Unexpected exception occurred retrieving issuer certificate."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String CRL_ISSUER_CHAIN_FAILED = "Unable to validate CRL response: Unexpected exception occurred validating issuer certificate."; +//\endcond + //\cond DO_NOT_DOCUMENT internal const String CRL_ISSUER_NO_COMMON_ROOT = "The CRL issuer does not share the root of the inspected certificate."; //\endcond @@ -246,6 +254,8 @@ private static IIssuingDistributionPoint GetIssuingDistributionPointExtension(IX } catch (System.IO.IOException) { } + catch (Exception) { + } // Ignore exception. return FACTORY.CreateIssuingDistributionPoint(issuingDistPointExtension); } @@ -260,6 +270,8 @@ private static DateTime GetExpiredCertsOnCRLExtensionDate(IX509Crl crl) { } catch (System.IO.IOException) { } + catch (Exception) { + } // Ignore exception. if (expiredCertsOnCRL != null) { try { @@ -292,8 +304,16 @@ private static int ComputeInterimReasonsMask(IIssuingDistributionPoint issuingDi private void VerifyCrlIntegrity(ValidationReport report, ValidationContext context, IX509Certificate certificate , IX509Crl crl, DateTime responseGenerationDate) { - IX509Certificate[] certs = certificateRetriever.GetCrlIssuerCertificates(crl); - if (certs.Length == 0) { + IX509Certificate[] certs = null; + try { + certs = certificateRetriever.GetCrlIssuerCertificates(crl); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(certificate, CRL_CHECK, CRL_ISSUER_REQUEST_FAILED, e, ReportItem.ReportItemStatus + .INDETERMINATE)); + return; + } + if (certs == null || certs.Length == 0) { report.AddReportItem(new CertificateReportItem(certificate, CRL_CHECK, CRL_ISSUER_NOT_FOUND, ReportItem.ReportItemStatus .INDETERMINATE)); return; @@ -306,17 +326,13 @@ private void VerifyCrlIntegrity(ValidationReport report, ValidationContext conte .INDETERMINATE)); return; } - try { - crl.Verify(crlIssuer.GetPublicKey()); - } - catch (Exception e) { - report.AddReportItem(new CertificateReportItem(certificate, CRL_CHECK, CRL_INVALID, e, ReportItem.ReportItemStatus - .INDETERMINATE)); - return; - } + SafeCalling.OnExceptionLog(() => crl.Verify(crlIssuer.GetPublicKey()), report, (e) => new CertificateReportItem + (certificate, CRL_CHECK, CRL_INVALID, e, ReportItem.ReportItemStatus.INDETERMINATE)); ValidationReport responderReport = new ValidationReport(); - builder.GetCertificateChainValidator().Validate(responderReport, context.SetCertificateSource(CertificateSource - .CRL_ISSUER), (IX509Certificate)crlIssuer, responseGenerationDate); + SafeCalling.OnExceptionLog(() => builder.GetCertificateChainValidator().Validate(responderReport, context. + SetCertificateSource(CertificateSource.CRL_ISSUER), (IX509Certificate)crlIssuer, responseGenerationDate + ), report, (e) => new CertificateReportItem(certificate, CRL_CHECK, CRL_ISSUER_CHAIN_FAILED, e, ReportItem.ReportItemStatus + .INDETERMINATE)); AddResponderValidationReport(report, responderReport); } diff --git a/itext/itext.sign/itext/signatures/validation/v1/CertificateChainValidator.cs b/itext/itext.sign/itext/signatures/validation/v1/CertificateChainValidator.cs index 9a170f7b9f..46926c87b1 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/CertificateChainValidator.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/CertificateChainValidator.cs @@ -74,6 +74,26 @@ public class CertificateChainValidator { internal const String ISSUER_CANNOT_BE_VERIFIED = "Issuer certificate {0} for subject certificate {1} cannot be mathematically verified."; //\endcond +//\cond DO_NOT_DOCUMENT + internal const String ISSUER_VERIFICATION_FAILED = "Unexpected exception occurred while verifying issuer certificate."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String ISSUER_RETRIEVAL_FAILED = "Unexpected exception occurred while retrieving certificate issuer from IssuingCertificateRetriever."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String TRUSTSTORE_RETRIEVAL_FAILED = "Unexpected exception occurred while retrieving trust store from IssuingCertificateRetriever."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String REVOCATION_VALIDATION_FAILED = "Unexpected exception occurred while validating certificate revocation."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String VALIDITY_PERIOD_CHECK_FAILED = "Unexpected exception occurred while validating certificate validity period."; +//\endcond + private readonly SignatureValidationProperties properties; private readonly IssuingCertificateRetriever certificateRetriever; @@ -192,7 +212,9 @@ public virtual ValidationReport Validate(ValidationReport result, ValidationCont if (StopValidation(result, localContext)) { return result; } - if (CheckIfCertIsTrusted(result, localContext, certificate)) { + if (SafeCalling.OnExceptionLog(() => CheckIfCertIsTrusted(result, localContext, certificate), false, result + , (e) => new CertificateReportItem(certificate, CERTIFICATE_CHECK, TRUSTSTORE_RETRIEVAL_FAILED, e, ReportItem.ReportItemStatus + .INFO))) { return result; } ValidateRevocationData(result, localContext, certificate, validationDate); @@ -286,6 +308,10 @@ private void ValidateValidityPeriod(ValidationReport result, IX509Certificate ce result.AddReportItem(new CertificateReportItem(certificate, VALIDITY_CHECK, MessageFormatUtil.Format(NOT_YET_VALID_CERTIFICATE , certificate.GetSubjectDN()), e, ReportItem.ReportItemStatus.INVALID)); } + catch (Exception e) { + result.AddReportItem(new CertificateReportItem(certificate, VALIDITY_CHECK, MessageFormatUtil.Format(VALIDITY_PERIOD_CHECK_FAILED + , certificate.GetSubjectDN()), e, ReportItem.ReportItemStatus.INVALID)); + } } private void ValidateRequiredExtensions(ValidationReport result, ValidationContext context, IX509Certificate @@ -303,13 +329,22 @@ private void ValidateRequiredExtensions(ValidationReport result, ValidationConte private void ValidateRevocationData(ValidationReport report, ValidationContext context, IX509Certificate certificate , DateTime validationDate) { - revocationDataValidator.Validate(report, context, certificate, validationDate); + SafeCalling.OnRuntimeExceptionLog(() => revocationDataValidator.Validate(report, context, certificate, validationDate + ), report, (e) => new CertificateReportItem(certificate, CERTIFICATE_CHECK, REVOCATION_VALIDATION_FAILED + , e, ReportItem.ReportItemStatus.INDETERMINATE)); } private void ValidateChain(ValidationReport result, ValidationContext context, IX509Certificate certificate , DateTime validationDate) { - IX509Certificate issuerCertificate = (IX509Certificate)certificateRetriever.RetrieveIssuerCertificate(certificate - ); + IX509Certificate issuerCertificate = null; + try { + issuerCertificate = (IX509Certificate)certificateRetriever.RetrieveIssuerCertificate(certificate); + } + catch (Exception e) { + result.AddReportItem(new CertificateReportItem(certificate, CERTIFICATE_CHECK, ISSUER_RETRIEVAL_FAILED, e, + ReportItem.ReportItemStatus.INDETERMINATE)); + return; + } if (issuerCertificate == null) { result.AddReportItem(new CertificateReportItem(certificate, CERTIFICATE_CHECK, MessageFormatUtil.Format(ISSUER_MISSING , certificate.GetSubjectDN()), ReportItem.ReportItemStatus.INDETERMINATE)); @@ -324,6 +359,12 @@ private void ValidateChain(ValidationReport result, ValidationContext context, I )); return; } + catch (Exception e) { + result.AddReportItem(new CertificateReportItem(certificate, CERTIFICATE_CHECK, MessageFormatUtil.Format(ISSUER_VERIFICATION_FAILED + , issuerCertificate.GetSubjectDN(), certificate.GetSubjectDN()), e, ReportItem.ReportItemStatus.INVALID + )); + return; + } this.Validate(result, context.SetCertificateSource(CertificateSource.CERT_ISSUER), issuerCertificate, validationDate ); } diff --git a/itext/itext.sign/itext/signatures/validation/v1/DocumentRevisionsValidator.cs b/itext/itext.sign/itext/signatures/validation/v1/DocumentRevisionsValidator.cs index faff91cd14..e11e5a5b50 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/DocumentRevisionsValidator.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/DocumentRevisionsValidator.cs @@ -163,6 +163,10 @@ public class DocumentRevisionsValidator { internal const String REVISIONS_RETRIEVAL_FAILED = "Wasn't possible to retrieve document revisions."; //\endcond +//\cond DO_NOT_DOCUMENT + internal const String REVISIONS_RETRIEVAL_FAILED_UNEXPECTEDLY = "Unexpected exception while retrieving document revisions."; +//\endcond + //\cond DO_NOT_DOCUMENT internal const String SIGNATURE_MODIFIED = "Signature {0} was unexpectedly modified."; //\endcond @@ -310,6 +314,11 @@ public virtual ValidationReport ValidateAllDocumentRevisions(ValidationContext c .INDETERMINATE)); return report; } + catch (Exception e) { + report.AddReportItem(new ReportItem(DOC_MDP_CHECK, REVISIONS_RETRIEVAL_FAILED_UNEXPECTEDLY, e, ReportItem.ReportItemStatus + .INDETERMINATE)); + return report; + } SignatureUtil signatureUtil = new SignatureUtil(document); IList signatures = new List(signatureUtil.GetSignatureNames()); if (signatures.IsEmpty()) { @@ -417,6 +426,10 @@ internal virtual void ValidateRevision(DocumentRevision previousRevision, Docume validationReport.AddReportItem(new ReportItem(DOC_MDP_CHECK, REVISIONS_READING_EXCEPTION, exception, ReportItem.ReportItemStatus .INDETERMINATE)); } + catch (Exception exception) { + validationReport.AddReportItem(new ReportItem(DOC_MDP_CHECK, REVISIONS_READING_EXCEPTION, exception, ReportItem.ReportItemStatus + .INDETERMINATE)); + } } //\endcond @@ -543,6 +556,10 @@ private void LockAllFormFields(DocumentRevision revision, IList excluded report.AddReportItem(new ReportItem(FIELD_MDP_CHECK, REVISIONS_READING_EXCEPTION, exception, ReportItem.ReportItemStatus .INDETERMINATE)); } + catch (Exception exception) { + report.AddReportItem(new ReportItem(FIELD_MDP_CHECK, REVISIONS_READING_EXCEPTION, exception, ReportItem.ReportItemStatus + .INDETERMINATE)); + } } private void UpdateCertificationSignatureAccessPermissions(PdfSignature signature, ValidationReport report @@ -619,6 +636,9 @@ private bool RevisionContainsSignature(DocumentRevision revision, String signatu } catch (System.IO.IOException) { } + catch (Exception) { + } + //ignored return false; } diff --git a/itext/itext.sign/itext/signatures/validation/v1/OCSPValidator.cs b/itext/itext.sign/itext/signatures/validation/v1/OCSPValidator.cs index 31db4ec83f..42f3dad3ba 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/OCSPValidator.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/OCSPValidator.cs @@ -66,6 +66,19 @@ public class OCSPValidator { + "by issuer certificate or any from the trusted store."; //\endcond +//\cond DO_NOT_DOCUMENT + internal const String OCSP_RESPONDER_NOT_RETRIEVED = "OCSP response could not be verified: \" +\n" + " \"Unexpected exception occurred retrieving responder."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String OCSP_RESPONDER_NOT_VERIFIED = "OCSP response could not be verified: \" +\n" + " \" Unexpected exception occurred while validating responder certificate."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String OCSP_RESPONDER_TRUST_NOT_RETRIEVED = "OCSP response could not be verified: \" +\n" + + " \"responder trust state could not be retrieved."; +//\endcond + //\cond DO_NOT_DOCUMENT internal const String OCSP_IS_NO_LONGER_VALID = "OCSP is no longer valid: {0} after {1}"; //\endcond @@ -75,8 +88,11 @@ public class OCSPValidator { //\endcond //\cond DO_NOT_DOCUMENT - internal const String UNABLE_TO_CHECK_IF_ISSUERS_MATCH = "OCSP response could not be verified: unable to check" - + " if issuers match."; + internal const String UNABLE_TO_CHECK_IF_ISSUERS_MATCH = "OCSP response could not be verified: Unexpected exception occurred checking if issuers match."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String UNABLE_TO_RETRIEVE_ISSUER = "OCSP response could not be verified: Unexpected exception occurred while retrieving issuer"; //\endcond //\cond DO_NOT_DOCUMENT @@ -145,7 +161,15 @@ public virtual void Validate(ValidationReport report, ValidationContext context, .INDETERMINATE)); return; } - IX509Certificate issuerCert = certificateRetriever.RetrieveIssuerCertificate(certificate); + IX509Certificate issuerCert; + try { + issuerCert = certificateRetriever.RetrieveIssuerCertificate(certificate); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(certificate, OCSP_CHECK, UNABLE_TO_RETRIEVE_ISSUER, e, ReportItem.ReportItemStatus + .INDETERMINATE)); + return; + } // Check if the issuer of the certID and signCert matches, i.e. check that issuerNameHash and issuerKeyHash // fields of the certID is the hash of the issuer's name and public key: try { @@ -240,14 +264,30 @@ private void VerifyOcspResponder(ValidationReport report, ValidationContext cont // If the issuer certificate didn't sign the ocsp response, look for authorized ocsp responses // from the properties or from the certificate chain received with response. if (responderCert == null) { - responderCert = (IX509Certificate)certificateRetriever.RetrieveOCSPResponderCertificate(ocspResp); + try { + responderCert = (IX509Certificate)certificateRetriever.RetrieveOCSPResponderCertificate(ocspResp); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(issuerCert, OCSP_CHECK, OCSP_RESPONDER_NOT_RETRIEVED, e, ReportItem.ReportItemStatus + .INDETERMINATE)); + return; + } if (responderCert == null) { report.AddReportItem(new CertificateReportItem(issuerCert, OCSP_CHECK, OCSP_COULD_NOT_BE_VERIFIED, ReportItem.ReportItemStatus .INDETERMINATE)); return; } - if (!certificateRetriever.IsCertificateTrusted(responderCert) && !certificateRetriever.GetTrustedCertificatesStore - ().IsCertificateTrustedForOcsp(responderCert)) { + bool needsToBeSignedByIssuer = false; + try { + needsToBeSignedByIssuer = (!certificateRetriever.IsCertificateTrusted(responderCert) && !certificateRetriever + .GetTrustedCertificatesStore().IsCertificateTrustedForOcsp(responderCert)); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(responderCert, OCSP_CHECK, OCSP_RESPONDER_TRUST_NOT_RETRIEVED + , e, ReportItem.ReportItemStatus.INDETERMINATE)); + return; + } + if (needsToBeSignedByIssuer) { // RFC 6960 4.2.2.2. Authorized Responders: // "Systems relying on OCSP responses MUST recognize a delegation certificate as being issued // by the CA that issued the certificate in question only if the delegation certificate and the @@ -263,17 +303,38 @@ private void VerifyOcspResponder(ValidationReport report, ValidationContext cont } // Validating of the ocsp signer's certificate (responderCert) described in the // RFC6960 4.2.2.2.1. Revocation Checking of an Authorized Responder. - builder.GetCertificateChainValidator().Validate(responderReport, localContext, responderCert, responseGenerationDate - ); + try { + builder.GetCertificateChainValidator().Validate(responderReport, localContext, responderCert, responseGenerationDate + ); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(responderCert, OCSP_CHECK, OCSP_RESPONDER_NOT_VERIFIED, e, + ReportItem.ReportItemStatus.INDETERMINATE)); + return; + } } else { - builder.GetCertificateChainValidator().Validate(responderReport, localContext.SetCertificateSource(CertificateSource - .TRUSTED), responderCert, responseGenerationDate); + try { + builder.GetCertificateChainValidator().Validate(responderReport, localContext.SetCertificateSource(CertificateSource + .TRUSTED), responderCert, responseGenerationDate); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(responderCert, OCSP_CHECK, OCSP_RESPONDER_NOT_VERIFIED, e, + ReportItem.ReportItemStatus.INDETERMINATE)); + return; + } } } else { - builder.GetCertificateChainValidator().Validate(responderReport, localContext.SetCertificateSource(CertificateSource - .CERT_ISSUER), responderCert, responseGenerationDate); + try { + builder.GetCertificateChainValidator().Validate(responderReport, localContext.SetCertificateSource(CertificateSource + .CERT_ISSUER), responderCert, responseGenerationDate); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(responderCert, OCSP_CHECK, OCSP_RESPONDER_NOT_VERIFIED, e, + ReportItem.ReportItemStatus.INDETERMINATE)); + return; + } } AddResponderValidationReport(report, responderReport); } diff --git a/itext/itext.sign/itext/signatures/validation/v1/RevocationDataValidator.cs b/itext/itext.sign/itext/signatures/validation/v1/RevocationDataValidator.cs index b3a184b240..72ac922adf 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/RevocationDataValidator.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/RevocationDataValidator.cs @@ -28,7 +28,6 @@ You should have received a copy of the GNU Affero General Public License using iText.Commons.Bouncycastle.Asn1.Ocsp; using iText.Commons.Bouncycastle.Cert; using iText.Commons.Bouncycastle.Cert.Ocsp; -using iText.Commons.Bouncycastle.Security; using iText.Commons.Utils; using iText.Commons.Utils.Collections; using iText.Signatures; @@ -60,11 +59,31 @@ public class RevocationDataValidator { //\endcond //\cond DO_NOT_DOCUMENT - internal const String CANNOT_PARSE_OCSP = "OCSP response from \"{0}\" OCSP client cannot be parsed."; + internal const String CANNOT_PARSE_OCSP = "OCSP response from \"{0}\" OCSP response cannot be parsed."; //\endcond //\cond DO_NOT_DOCUMENT - internal const String CANNOT_PARSE_CRL = "CRL response from \"{0}\" CRL client cannot be parsed."; + internal const String CANNOT_PARSE_CRL = "CRL response from \"{0}\" CRL response cannot be parsed."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String ISSUER_RETRIEVAL_FAILED = "Retrieval of the certificate issuer failed."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String OCSP_CLIENT_FAILURE = "Unexpected exception occurred in OCSP client \"{0}\"."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String CRL_CLIENT_FAILURE = "Unexpected exception occurred in CRL client \"{0}\"."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String OCSP_VALIDATOR_FAILURE = "Unexpected exception occurred in OCSP validator."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String CRL_VALIDATOR_FAILURE = "Unexpected exception occurred in CRL validator."; //\endcond private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory @@ -196,15 +215,18 @@ private void ValidateRevocationData(ValidationReport report, ValidationContext c if (i < ocspResponses.Count && (j >= crlResponses.Count || ocspResponses[i].singleResp.GetThisUpdate().After (crlResponses[j].crl.GetThisUpdate()))) { RevocationDataValidator.OcspResponseValidationInfo validationInfo = ocspResponses[i]; - ocspValidator.Validate(revDataValidationReport, context.SetTimeBasedContext(validationInfo.timeBasedContext - ), certificate, validationInfo.singleResp, validationInfo.basicOCSPResp, validationDate, validationInfo - .trustedGenerationDate); + SafeCalling.OnRuntimeExceptionLog(() => ocspValidator.Validate(revDataValidationReport, context.SetTimeBasedContext + (validationInfo.timeBasedContext), certificate, validationInfo.singleResp, validationInfo.basicOCSPResp + , validationDate, validationInfo.trustedGenerationDate), report, (e) => new CertificateReportItem(certificate + , REVOCATION_DATA_CHECK, OCSP_VALIDATOR_FAILURE, e, ReportItem.ReportItemStatus.INFO)); i++; } else { RevocationDataValidator.CrlValidationInfo validationInfo = crlResponses[j]; - crlValidator.Validate(revDataValidationReport, context.SetTimeBasedContext(validationInfo.timeBasedContext - ), certificate, validationInfo.crl, validationDate, validationInfo.trustedGenerationDate); + SafeCalling.OnRuntimeExceptionLog(() => crlValidator.Validate(revDataValidationReport, context.SetTimeBasedContext + (validationInfo.timeBasedContext), certificate, validationInfo.crl, validationDate, validationInfo.trustedGenerationDate + ), report, (e) => new CertificateReportItem(certificate, REVOCATION_DATA_CHECK, CRL_VALIDATOR_FAILURE, + e, ReportItem.ReportItemStatus.INFO)); j++; } if (ValidationReport.ValidationResult.INDETERMINATE == revDataValidationReport.GetValidationResult()) { @@ -229,6 +251,15 @@ private void ValidateRevocationData(ValidationReport report, ValidationContext c report, ValidationContext context, IX509Certificate certificate) { IList ocspResponses = new List(); + IX509Certificate issuerCert; + try { + issuerCert = (IX509Certificate)certificateRetriever.RetrieveIssuerCertificate(certificate); + } + catch (Exception e) { + report.AddReportItem(new CertificateReportItem(certificate, REVOCATION_DATA_CHECK, ISSUER_RETRIEVAL_FAILED + , e, ReportItem.ReportItemStatus.INDETERMINATE)); + return ocspResponses; + } foreach (IOcspClient ocspClient in ocspClients) { if (ocspClient is ValidationOcspClient) { ValidationOcspClient validationOcspClient = (ValidationOcspClient)ocspClient; @@ -239,8 +270,10 @@ private void ValidateRevocationData(ValidationReport report, ValidationContext c } } else { - byte[] basicOcspRespBytes = ocspClient.GetEncoded(certificate, (IX509Certificate)certificateRetriever.RetrieveIssuerCertificate - (certificate), null); + byte[] basicOcspRespBytes = null; + basicOcspRespBytes = SafeCalling.OnRuntimeExceptionLog(() => ocspClient.GetEncoded(certificate, issuerCert + , null), null, report, (e) => new CertificateReportItem(certificate, REVOCATION_DATA_CHECK, MessageFormatUtil + .Format(OCSP_CLIENT_FAILURE, ocspClient), e, ReportItem.ReportItemStatus.INFO)); if (basicOcspRespBytes != null) { try { IBasicOcspResponse basicOCSPResp = BOUNCY_CASTLE_FACTORY.CreateBasicOCSPResponse(BOUNCY_CASTLE_FACTORY.CreateASN1Primitive @@ -252,6 +285,10 @@ private void ValidateRevocationData(ValidationReport report, ValidationContext c report.AddReportItem(new ReportItem(REVOCATION_DATA_CHECK, MessageFormatUtil.Format(CANNOT_PARSE_OCSP, ocspClient ), e, ReportItem.ReportItemStatus.INFO)); } + catch (Exception e) { + report.AddReportItem(new ReportItem(REVOCATION_DATA_CHECK, MessageFormatUtil.Format(CANNOT_PARSE_OCSP, ocspClient + ), e, ReportItem.ReportItemStatus.INFO)); + } } } } @@ -259,10 +296,14 @@ private void ValidateRevocationData(ValidationReport report, ValidationContext c .SetValidatorContext(ValidatorContext.OCSP_VALIDATOR)); if (SignatureValidationProperties.OnlineFetching.ALWAYS_FETCH == onlineFetching || (SignatureValidationProperties.OnlineFetching .FETCH_IF_NO_OTHER_DATA_AVAILABLE == onlineFetching && ocspResponses.IsEmpty())) { - IBasicOcspResponse basicOCSPResp = new OcspClientBouncyCastle(null).GetBasicOCSPResp(certificate, (IX509Certificate - )certificateRetriever.RetrieveIssuerCertificate(certificate), null); - FillOcspResponses(ocspResponses, basicOCSPResp, DateTimeUtil.GetCurrentUtcTime(), TimeBasedContext.PRESENT - ); + SafeCalling.OnRuntimeExceptionLog(() => { + IBasicOcspResponse basicOCSPResp = new OcspClientBouncyCastle(null).GetBasicOCSPResp(certificate, issuerCert + , null); + FillOcspResponses(ocspResponses, basicOCSPResp, DateTimeUtil.GetCurrentUtcTime(), TimeBasedContext.PRESENT + ); + } + , report, (e) => new CertificateReportItem(certificate, REVOCATION_DATA_CHECK, MessageFormatUtil.Format(OCSP_CLIENT_FAILURE + , "OcspClientBouncyCastle"), e, ReportItem.ReportItemStatus.INDETERMINATE)); } return ocspResponses; } @@ -305,22 +346,15 @@ private static void FillOcspResponses(IList crlBytesCollection = crlClient.GetEncoded(certificate, null); - foreach (byte[] crlBytes in crlBytesCollection) { - try { - crlResponses.Add(new RevocationDataValidator.CrlValidationInfo((IX509Crl)CertificateUtil.ParseCrlFromBytes - (crlBytes), DateTimeUtil.GetCurrentUtcTime(), TimeBasedContext.PRESENT)); - } - catch (Exception) { - report.AddReportItem(new CertificateReportItem(certificate, REVOCATION_DATA_CHECK, MessageFormatUtil.Format - (CANNOT_PARSE_CRL, crlClient), ReportItem.ReportItemStatus.INFO)); - } - } - } - catch (AbstractGeneralSecurityException) { - report.AddReportItem(new CertificateReportItem(certificate, REVOCATION_DATA_CHECK, MessageFormatUtil.Format - (CANNOT_PARSE_CRL, crlClient), ReportItem.ReportItemStatus.INFO)); + ICollection crlBytesCollection = SafeCalling.OnExceptionLog(() => crlClient.GetEncoded(certificate + , null), JavaCollectionsUtil.EmptyList(), report, (e) => new CertificateReportItem(certificate + , REVOCATION_DATA_CHECK, MessageFormatUtil.Format(CRL_CLIENT_FAILURE, crlClient), e, ReportItem.ReportItemStatus + .INFO)); + foreach (byte[] crlBytes in crlBytesCollection) { + SafeCalling.OnExceptionLog(() => crlResponses.Add(new RevocationDataValidator.CrlValidationInfo((IX509Crl) + CertificateUtil.ParseCrlFromBytes(crlBytes), DateTimeUtil.GetCurrentUtcTime(), TimeBasedContext.PRESENT + )), report, (e) => new CertificateReportItem(certificate, REVOCATION_DATA_CHECK, MessageFormatUtil.Format + (CANNOT_PARSE_CRL, crlClient), e, ReportItem.ReportItemStatus.INFO)); } } return crlResponses; diff --git a/itext/itext.sign/itext/signatures/validation/v1/SafeCalling.cs b/itext/itext.sign/itext/signatures/validation/v1/SafeCalling.cs new file mode 100644 index 0000000000..e15e8f0114 --- /dev/null +++ b/itext/itext.sign/itext/signatures/validation/v1/SafeCalling.cs @@ -0,0 +1,97 @@ +/* +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.Validation.V1.Report; + +namespace iText.Signatures.Validation.V1 { +//\cond DO_NOT_DOCUMENT + internal sealed class SafeCalling { + private SafeCalling() { + } + + /// Adds a report item to the report when an exception is thrown in the action. + /// The action to perform + /// The report to add the ReportItem to + /// A callback to generate a ReportItem + public static void OnExceptionLog(Action action, ValidationReport report, Func reportItemCreator + ) { + try { + action(); + } + catch (Exception e) { + report.AddReportItem(reportItemCreator.Invoke(e)); + } + } + + /// Adds a report item to the report when an exception is thrown in the action. + /// The action to perform + /// The value to return when an exception is thrown + /// The report to add the ReportItem to + /// A callback to generate a ReportItem + /// The returned value from the action + /// + public static T OnExceptionLog(Func action, T defaultValue, ValidationReport report, Func reportItemCreator) { + try { + return action(); + } + catch (Exception e) { + report.AddReportItem(reportItemCreator.Invoke(e)); + } + return defaultValue; + } + + /// Adds a report item to the report when an exception is thrown in the action. + /// The action to perform + /// The report to add the ReportItem to + /// A callback to generate a ReportItem + public static void OnRuntimeExceptionLog(Action action, ValidationReport report, Func reportItemCreator) { + try { + action(); + } + catch (Exception e) { + report.AddReportItem(reportItemCreator.Invoke(e)); + } + } + + /// Adds a report item to the report when an exception is thrown in the action. + /// The action to perform + /// The value to return when an exception is thrown + /// The report to add the ReportItem to + /// A callback to generate a ReportItem + /// The returned value from the action + /// + public static T OnRuntimeExceptionLog(Func action, T defaultValue, ValidationReport report, Func reportItemCreator) { + try { + return action(); + } + catch (Exception e) { + report.AddReportItem(reportItemCreator.Invoke(e)); + } + return defaultValue; + } + } +//\endcond +} diff --git a/itext/itext.sign/itext/signatures/validation/v1/SignatureValidator.cs b/itext/itext.sign/itext/signatures/validation/v1/SignatureValidator.cs index 60456da353..dcd3bc541c 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/SignatureValidator.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/SignatureValidator.cs @@ -76,10 +76,32 @@ internal class SignatureValidator { //\endcond //\cond DO_NOT_DOCUMENT - internal const String REVISIONS_RETRIEVAL_FAILED = "Wasn't possible to retrieve document revisions."; + internal const String TIMESTAMP_VERIFICATION_FAILED = "Unexpected exception occurred during mathematical verification of time stamp signature."; //\endcond - private const String TIMESTAMP_EXTRACTION_FAILED = "Unable to extract timestamp from timestamp signature"; +//\cond DO_NOT_DOCUMENT + internal const String REVISIONS_RETRIEVAL_FAILED = "Unexpected exception occurred during document revisions retrieval."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String TIMESTAMP_EXTRACTION_FAILED = "Unexpected exception occurred retrieving prove of existence from timestamp signature"; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String CHAIN_VALIDATION_FAILED = "Unexpected exception occurred during certificate chain validation."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String CERTIFITICATE_VERIFICATION_FAILED = "Unexpected exception occurred during mathematical certificate verification."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String REVISIONS_VALIDATION_FAILED = "Unexpected exception occurred during revisions validation."; +//\endcond + +//\cond DO_NOT_DOCUMENT + internal const String ADD_KNOWN_CERTIFICATES_FAILED = "Unexpected exception occurred adding known certificates to certificate retriever."; +//\endcond private static readonly IBouncyCastleFactory BOUNCY_CASTLE_FACTORY = BouncyCastleFactoryCreator.GetFactory (); @@ -150,10 +172,14 @@ public virtual iText.Signatures.Validation.V1.SignatureValidator SetEventCountin /// public virtual ValidationReport ValidateSignatures(PdfDocument document) { ValidationReport report = new ValidationReport(); - documentRevisionsValidator.SetEventCountingMetaInfo(metaInfo); - ValidationReport revisionsValidationReport = documentRevisionsValidator.ValidateAllDocumentRevisions(validationContext - , document); - report.Merge(revisionsValidationReport); + SafeCalling.OnRuntimeExceptionLog(() => { + documentRevisionsValidator.SetEventCountingMetaInfo(metaInfo); + ValidationReport revisionsValidationReport = documentRevisionsValidator.ValidateAllDocumentRevisions(validationContext + , document); + report.Merge(revisionsValidationReport); + } + , report, (e) => new ReportItem(SIGNATURE_VERIFICATION, REVISIONS_VALIDATION_FAILED, e, ReportItem.ReportItemStatus + .INDETERMINATE)); if (StopValidation(report, validationContext)) { return report; } @@ -175,6 +201,10 @@ public virtual ValidationReport ValidateSignatures(PdfDocument document) { report.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, REVISIONS_RETRIEVAL_FAILED, e, ReportItem.ReportItemStatus .INDETERMINATE)); } + catch (Exception e) { + report.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, REVISIONS_RETRIEVAL_FAILED, e, ReportItem.ReportItemStatus + .INDETERMINATE)); + } } return report; } @@ -190,7 +220,9 @@ internal virtual ValidationReport ValidateLatestSignature(PdfDocument document) return validationReport; } IList certificatesFromDss = GetCertificatesFromDss(validationReport, document); - certificateRetriever.AddKnownCertificates(certificatesFromDss); + SafeCalling.OnRuntimeExceptionLog(() => certificateRetriever.AddKnownCertificates(certificatesFromDss), validationReport + , (e) => new ReportItem(SIGNATURE_VERIFICATION, ADD_KNOWN_CERTIFICATES_FAILED, e, ReportItem.ReportItemStatus + .INFO)); if (pkcs7.IsTsp()) { ValidateTimestampChain(validationReport, pkcs7.GetCertificates(), pkcs7.GetSigningCertificate()); if (UpdateLastKnownPoE(validationReport, pkcs7.GetTimeStampTokenInfo())) { @@ -215,10 +247,14 @@ internal virtual ValidationReport ValidateLatestSignature(PdfDocument document) } } IX509Certificate[] certificates = pkcs7.GetCertificates(); - certificateRetriever.AddKnownCertificates(JavaUtil.ArraysAsList(certificates)); + SafeCalling.OnRuntimeExceptionLog(() => certificateRetriever.AddKnownCertificates(JavaUtil.ArraysAsList(certificates + )), validationReport, (e) => new ReportItem(SIGNATURE_VERIFICATION, ADD_KNOWN_CERTIFICATES_FAILED, e, + ReportItem.ReportItemStatus.INFO)); IX509Certificate signingCertificate = pkcs7.GetSigningCertificate(); ValidationReport signatureReport = new ValidationReport(); - certificateChainValidator.Validate(signatureReport, validationContext, signingCertificate, lastKnownPoE); + SafeCalling.OnExceptionLog(() => certificateChainValidator.Validate(signatureReport, validationContext, signingCertificate + , lastKnownPoE), validationReport, (e) => new CertificateReportItem(signingCertificate, SIGNATURE_VERIFICATION + , CHAIN_VALIDATION_FAILED, e, ReportItem.ReportItemStatus.INDETERMINATE)); if (isPoEUpdated && signatureReport.GetValidationResult() != ValidationReport.ValidationResult.VALID) { // We can only use PoE retrieved from timestamp attribute in case main signature validation is successful. // That's why if the result is not valid, we set back lastKnownPoE value, validation context and rev data. @@ -253,6 +289,10 @@ private PdfPKCS7 MathematicallyVerifySignature(ValidationReport validationReport validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(CANNOT_VERIFY_SIGNATURE , latestSignatureName), e, ReportItem.ReportItemStatus.INVALID)); } + catch (Exception e) { + validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(CANNOT_VERIFY_SIGNATURE + , latestSignatureName), e, ReportItem.ReportItemStatus.INVALID)); + } return pkcs7; } @@ -268,6 +308,10 @@ private ValidationReport ValidateEmbeddedTimestamp(PdfPKCS7 pkcs7) { tsValidationReport.AddReportItem(new ReportItem(TIMESTAMP_VERIFICATION, CANNOT_VERIFY_TIMESTAMP, e, ReportItem.ReportItemStatus .INVALID)); } + catch (Exception e) { + tsValidationReport.AddReportItem(new ReportItem(TIMESTAMP_VERIFICATION_FAILED, TIMESTAMP_VERIFICATION_FAILED + , e, ReportItem.ReportItemStatus.INVALID)); + } if (StopValidation(tsValidationReport, validationContext)) { return tsValidationReport; } @@ -283,6 +327,10 @@ private ValidationReport ValidateEmbeddedTimestamp(PdfPKCS7 pkcs7) { tsValidationReport.AddReportItem(new ReportItem(TIMESTAMP_VERIFICATION, CANNOT_VERIFY_TIMESTAMP, e, ReportItem.ReportItemStatus .INVALID)); } + catch (Exception e) { + tsValidationReport.AddReportItem(new ReportItem(TIMESTAMP_VERIFICATION_FAILED, TIMESTAMP_VERIFICATION_FAILED + , e, ReportItem.ReportItemStatus.INVALID)); + } if (StopValidation(tsValidationReport, validationContext)) { return tsValidationReport; } @@ -294,9 +342,17 @@ private ValidationReport ValidateEmbeddedTimestamp(PdfPKCS7 pkcs7) { private void ValidateTimestampChain(ValidationReport validationReport, IX509Certificate[] knownCerts, IX509Certificate signingCert) { - certificateRetriever.AddKnownCertificates(JavaUtil.ArraysAsList(knownCerts)); - certificateChainValidator.Validate(validationReport, validationContext.SetCertificateSource(CertificateSource - .TIMESTAMP), signingCert, lastKnownPoE); + SafeCalling.OnExceptionLog(() => certificateRetriever.AddKnownCertificates(JavaUtil.ArraysAsList(knownCerts + )), validationReport, (e) => new ReportItem(SIGNATURE_VERIFICATION, ADD_KNOWN_CERTIFICATES_FAILED, e, + ReportItem.ReportItemStatus.INFO)); + try { + certificateChainValidator.Validate(validationReport, validationContext.SetCertificateSource(CertificateSource + .TIMESTAMP), signingCert, lastKnownPoE); + } + catch (Exception e) { + validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, CHAIN_VALIDATION_FAILED, e, ReportItem.ReportItemStatus + .INFO)); + } } private bool UpdateLastKnownPoE(ValidationReport tsValidationReport, ITstInfo timeStampTokenInfo) { @@ -365,6 +421,10 @@ private void RetrieveOcspResponsesFromDss(ValidationReport validationReport, Val validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(CANNOT_PARSE_OCSP_FROM_DSS , ocspStream), e, ReportItem.ReportItemStatus.INFO)); } + catch (Exception e) { + validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(CANNOT_PARSE_OCSP_FROM_DSS + , ocspStream), e, ReportItem.ReportItemStatus.INFO)); + } } } } @@ -378,14 +438,10 @@ private void RetrieveCrlResponsesFromDss(ValidationReport validationReport, Vali if (crls != null) { for (int i = 0; i < crls.Size(); ++i) { PdfStream crlStream = crls.GetAsStream(i); - try { - validationCrlClient.AddCrl((IX509Crl)CertificateUtil.ParseCrlFromBytes(crlStream.GetBytes()), lastKnownPoE - , context.GetTimeBasedContext()); - } - catch (Exception e) { - validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(CANNOT_PARSE_CRL_FROM_DSS - , crlStream), e, ReportItem.ReportItemStatus.INFO)); - } + SafeCalling.OnExceptionLog(() => validationCrlClient.AddCrl((IX509Crl)CertificateUtil.ParseCrlFromBytes(crlStream + .GetBytes()), lastKnownPoE, context.GetTimeBasedContext()), validationReport, (e) => new ReportItem(SIGNATURE_VERIFICATION + , MessageFormatUtil.Format(CANNOT_PARSE_CRL_FROM_DSS, crlStream), e, ReportItem.ReportItemStatus.INFO) + ); } } } @@ -407,6 +463,10 @@ private IList GetCertificatesFromDss(ValidationReport validati validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(CANNOT_PARSE_CERT_FROM_DSS , certStream), e, ReportItem.ReportItemStatus.INFO)); } + catch (Exception e) { + validationReport.AddReportItem(new ReportItem(SIGNATURE_VERIFICATION, MessageFormatUtil.Format(CANNOT_PARSE_CERT_FROM_DSS + , certStream), e, ReportItem.ReportItemStatus.INFO)); + } } } } diff --git a/itext/itext.sign/itext/signatures/validation/v1/ValidationCrlClient.cs b/itext/itext.sign/itext/signatures/validation/v1/ValidationCrlClient.cs index 172e06d95f..02eba73211 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/ValidationCrlClient.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/ValidationCrlClient.cs @@ -82,6 +82,8 @@ public virtual ICollection GetEncoded(IX509Certificate checkCert, String } catch (AbstractCrlException) { } + catch (Exception) { + } } // Do nothing. return byteResponses; diff --git a/itext/itext.sign/itext/signatures/validation/v1/ValidationOcspClient.cs b/itext/itext.sign/itext/signatures/validation/v1/ValidationOcspClient.cs index 3ac467c5ac..da39bd7f26 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/ValidationOcspClient.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/ValidationOcspClient.cs @@ -89,6 +89,9 @@ public virtual byte[] GetEncoded(IX509Certificate checkCert, IX509Certificate is catch (System.IO.IOException) { return null; } + catch (Exception) { + return null; + } } } } diff --git a/itext/itext.sign/itext/signatures/validation/v1/extensions/BasicConstraintsExtension.cs b/itext/itext.sign/itext/signatures/validation/v1/extensions/BasicConstraintsExtension.cs index b024727da5..ff9dd3d936 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/extensions/BasicConstraintsExtension.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/extensions/BasicConstraintsExtension.cs @@ -20,6 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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; @@ -99,6 +100,9 @@ public override bool ExistsInCertificate(IX509Certificate certificate) { catch (System.IO.IOException) { return false; } + catch (Exception) { + return false; + } if (pathLength >= 0) { return certificate.GetBasicConstraints() >= pathLength; } diff --git a/itext/itext.sign/itext/signatures/validation/v1/extensions/CertificateExtension.cs b/itext/itext.sign/itext/signatures/validation/v1/extensions/CertificateExtension.cs index ebe781417e..8486be8e06 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/extensions/CertificateExtension.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/extensions/CertificateExtension.cs @@ -100,6 +100,9 @@ public virtual bool ExistsInCertificate(IX509Certificate certificate) { catch (System.IO.IOException) { return false; } + catch (Exception) { + return false; + } return Object.Equals(providedExtensionValue, extensionValue); } diff --git a/itext/itext.sign/itext/signatures/validation/v1/extensions/ExtendedKeyUsageExtension.cs b/itext/itext.sign/itext/signatures/validation/v1/extensions/ExtendedKeyUsageExtension.cs index 3c1353cfb6..8d2993fa60 100644 --- a/itext/itext.sign/itext/signatures/validation/v1/extensions/ExtendedKeyUsageExtension.cs +++ b/itext/itext.sign/itext/signatures/validation/v1/extensions/ExtendedKeyUsageExtension.cs @@ -82,17 +82,24 @@ public ExtendedKeyUsageExtension(IList extendedKeyUsageOids) /// public override bool ExistsInCertificate(IX509Certificate certificate) { IList providedExtendedKeyUsage = new List(); - try { - if (certificate.GetExtendedKeyUsage() == null) { + try + { + if (certificate.GetExtendedKeyUsage() == null) + { return false; } - foreach (string singleExtendedKeyUsage in certificate.GetExtendedKeyUsage()) { + + foreach (string singleExtendedKeyUsage in certificate.GetExtendedKeyUsage()) + { providedExtendedKeyUsage.Add(singleExtendedKeyUsage); } } catch (AbstractCertificateParsingException) { return false; } + catch (Exception) { + return false; + } return providedExtendedKeyUsage.Contains(ANY_EXTENDED_KEY_USAGE_OID) || new HashSet(providedExtendedKeyUsage ).ContainsAll(extendedKeyUsageOids); } diff --git a/port-hash b/port-hash index 96a6f0cb8d..e6a5e69f48 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -b35c28b993564c2a7eb0be14fe05d3e5a323f125 +c22b8702578f0acaab04f0bfc7be9c8b5d6029e3 \ No newline at end of file