diff --git a/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDocumentIdTest.cs b/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDocumentIdTest.cs
index eae63a3c71..2346243b9e 100644
--- a/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDocumentIdTest.cs
+++ b/itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDocumentIdTest.cs
@@ -22,7 +22,7 @@ You should have received a copy of the GNU Affero General Public License
*/
using System;
using System.IO;
-using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.IO.Source;
using iText.Kernel.Exceptions;
using iText.Kernel.Pdf.Canvas;
@@ -67,7 +67,7 @@ public virtual void ChangeIdTest() {
[NUnit.Framework.Test]
public virtual void ChangeIdTest02() {
MemoryStream baos = new MemoryStream();
- IDigest md5;
+ IMessageDigest md5;
try {
md5 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("MD5");
}
@@ -94,7 +94,7 @@ public virtual void ChangeIdTest02() {
public virtual void ChangeIdTest03() {
MemoryStream baosInitial = new MemoryStream();
MemoryStream baosModified = new MemoryStream();
- IDigest md5;
+ IMessageDigest md5;
try {
md5 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("MD5");
}
@@ -138,7 +138,7 @@ public virtual void ChangeIdTest03() {
[NUnit.Framework.Test]
public virtual void FetchReaderIdTest() {
MemoryStream baos = new MemoryStream();
- IDigest md5;
+ IMessageDigest md5;
try {
md5 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("MD5");
}
@@ -165,7 +165,7 @@ public virtual void FetchReaderIdTest() {
[NUnit.Framework.Test]
public virtual void WriterPropertiesPriorityTest() {
MemoryStream baos = new MemoryStream();
- IDigest md5;
+ IMessageDigest md5;
try {
md5 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("MD5");
}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/BouncyCastleDigestUnitTest.cs b/itext.tests/itext.sign.tests/itext/signatures/BouncyCastleDigestUnitTest.cs
new file mode 100644
index 0000000000..fa96ba7306
--- /dev/null
+++ b/itext.tests/itext.sign.tests/itext/signatures/BouncyCastleDigestUnitTest.cs
@@ -0,0 +1,151 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Bouncycastleconnector;
+using iText.Commons.Bouncycastle;
+using iText.Commons.Bouncycastle.Security;
+using iText.Commons.Digest;
+using iText.Test;
+
+namespace iText.Signatures {
+ [NUnit.Framework.Category("BouncyCastleUnitTest")]
+ public class BouncyCastleDigestUnitTest : ExtendedITextTest {
+ private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
+ private static readonly bool FIPS_MODE = FIPS_MODE = "BCFIPS".Equals(FACTORY.GetProviderName());
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestMD2Test() {
+ if (FIPS_MODE) {
+ NUnit.Framework.Assert.Catch(typeof(AbstractGeneralSecurityException), () =>
+ new BouncyCastleDigest().GetMessageDigest("MD2"));
+ }
+ else {
+ GetMessageDigestTest("MD2", "MD2");
+ }
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestMD5Test() {
+ GetMessageDigestTest("MD5", "MD5");
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestSHA1Test() {
+ GetMessageDigestTest("SHA1", "SHA-1");
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestSHA224Test() {
+ if (FIPS_MODE) {
+ NUnit.Framework.Assert.Catch(typeof(AbstractGeneralSecurityException), () =>
+ new BouncyCastleDigest().GetMessageDigest("SHA-224"));
+ }
+ else {
+ GetMessageDigestTest("SHA224", "SHA-224");
+ }
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestSHA256Test() {
+ GetMessageDigestTest("SHA256", "SHA-256");
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestSHA384Test() {
+ GetMessageDigestTest("SHA384", "SHA-384");
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestSHA512Test() {
+ GetMessageDigestTest("SHA512", "SHA-512");
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestRIPEMD128Test() {
+ if (FIPS_MODE) {
+ NUnit.Framework.Assert.Catch(typeof(AbstractGeneralSecurityException), () =>
+ new BouncyCastleDigest().GetMessageDigest("RIPEMD128"));
+ }
+ else {
+ GetMessageDigestTest("RIPEMD128", "RIPEMD128");
+ }
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestRIPEMD160Test() {
+ if (FIPS_MODE) {
+ NUnit.Framework.Assert.Catch(typeof(AbstractGeneralSecurityException), () =>
+ new BouncyCastleDigest().GetMessageDigest("RIPEMD160"));
+ }
+ else {
+ GetMessageDigestTest("RIPEMD160", "RIPEMD160");
+ }
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestRIPEMD256Test() {
+ if (FIPS_MODE) {
+ NUnit.Framework.Assert.Catch(typeof(AbstractGeneralSecurityException), () =>
+ new BouncyCastleDigest().GetMessageDigest("RIPEMD256"));
+ }
+ else {
+ GetMessageDigestTest("RIPEMD256", "RIPEMD256");
+ }
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestGOST3411Test() {
+ if (FIPS_MODE) {
+ NUnit.Framework.Assert.Catch(typeof(AbstractGeneralSecurityException), () =>
+ new BouncyCastleDigest().GetMessageDigest("Gost3411"));
+ }
+ else {
+ GetMessageDigestTest("Gost3411", "Gost3411");
+ }
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestNullTest() {
+ IExternalDigest digest = new BouncyCastleDigest();
+ NUnit.Framework.Assert.Catch(typeof(ArgumentException), () => digest.GetMessageDigest(null));
+ }
+
+ [NUnit.Framework.Test]
+ public virtual void GetMessageDigestUnknownTest() {
+ IExternalDigest digest = new BouncyCastleDigest();
+ if (FIPS_MODE) {
+ NUnit.Framework.Assert.Catch(typeof(AbstractGeneralSecurityException), () => digest.GetMessageDigest("unknown"));
+ }
+ else {
+ NUnit.Framework.Assert.Catch(typeof(AbstractSecurityUtilityException),
+ () => digest.GetMessageDigest("unknown"));
+ }
+ }
+
+ private static void GetMessageDigestTest(String hashAlgorithm, String expectedDigestAlgorithm) {
+ IMessageDigest digest = new BouncyCastleDigest().GetMessageDigest(hashAlgorithm);
+ NUnit.Framework.Assert.IsNotNull(digest);
+ NUnit.Framework.Assert.AreEqual(expectedDigestAlgorithm, digest.GetAlgorithmName());
+ }
+ }
+}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7Test.cs b/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7Test.cs
index 9369ce1a08..8dbbce2303 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7Test.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/PdfPKCS7Test.cs
@@ -45,7 +45,7 @@ public virtual void UnknownHashAlgorithmTest() {
// only the hash algorithm is altered
String hashAlgorithm = "";
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => new PdfPKCS7(null, chain, hashAlgorithm
- , false));
+ , new BouncyCastleDigest(), false));
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(SignExceptionMessageConstant.UNKNOWN_HASH_ALGORITHM
, hashAlgorithm), e.Message);
}
@@ -67,7 +67,7 @@ public virtual void SimpleCreationTest() {
[NUnit.Framework.Test]
public virtual void SimpleCreationWithPrivateKeyTest() {
String hashAlgorithm = DigestAlgorithms.SHA256;
- PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, false);
+ PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, new BouncyCastleDigest(), false);
String expectedOid = DigestAlgorithms.GetAllowedDigest(hashAlgorithm);
NUnit.Framework.Assert.AreEqual(expectedOid, pkcs7.GetDigestAlgorithmOid());
NUnit.Framework.Assert.AreEqual(chain[0], pkcs7.GetSigningCertificate());
@@ -79,7 +79,8 @@ public virtual void SimpleCreationWithPrivateKeyTest() {
public virtual void NotAvailableSignatureTest() {
String hashAlgorithm = "GOST3411";
// Throws different exceptions on .net and java, bc/bcfips
- NUnit.Framework.Assert.Catch(typeof(Exception), () => new PdfPKCS7(pk, chain, hashAlgorithm, false));
+ NUnit.Framework.Assert.Catch(typeof(Exception), () => new PdfPKCS7(pk, chain, hashAlgorithm, new BouncyCastleDigest
+ (), false));
}
[NUnit.Framework.Test]
@@ -232,7 +233,7 @@ public virtual void IsRevocationValidExceptionDuringValidationTest() {
[NUnit.Framework.Test]
public virtual void GetEncodedPkcs1Test() {
String hashAlgorithm = DigestAlgorithms.SHA256;
- PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, true);
+ PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, new BouncyCastleDigest(), true);
byte[] bytes = pkcs7.GetEncodedPKCS1();
byte[] cmpBytes = File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER + "cmpBytesPkcs1.txt"));
IAsn1OctetString outOctetString = BOUNCY_CASTLE_FACTORY.CreateASN1OctetString(bytes);
@@ -243,7 +244,7 @@ public virtual void GetEncodedPkcs1Test() {
[NUnit.Framework.Test]
public virtual void GetEncodedPkcs1NullPrivateKeyTest() {
String hashAlgorithm = DigestAlgorithms.SHA256;
- PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, hashAlgorithm, true);
+ PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, hashAlgorithm, new BouncyCastleDigest(), true);
Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfException), () => pkcs7.GetEncodedPKCS1());
NUnit.Framework.Assert.AreEqual(KernelExceptionMessageConstant.UNKNOWN_PDF_EXCEPTION, exception.Message);
}
@@ -251,7 +252,7 @@ public virtual void GetEncodedPkcs1NullPrivateKeyTest() {
[NUnit.Framework.Test]
public virtual void GetEncodedPkcs7UnknownExceptionTest() {
String hashAlgorithm = DigestAlgorithms.SHA256;
- PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, true);
+ PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, new BouncyCastleDigest(), true);
TestTsaClient testTsa = new TestTsaClient(JavaUtil.ArraysAsList(chain), pk);
Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfException), () => pkcs7.GetEncodedPKCS7(null,
PdfSigner.CryptoStandard.CMS, testTsa, null, null));
@@ -261,7 +262,7 @@ public virtual void GetEncodedPkcs7UnknownExceptionTest() {
[NUnit.Framework.Test]
public virtual void GetEncodedPkcs7Test() {
String hashAlgorithm = DigestAlgorithms.SHA256;
- PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, true);
+ PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, new BouncyCastleDigest(), true);
byte[] bytes = pkcs7.GetEncodedPKCS7();
byte[] cmpBytes = File.ReadAllBytes(System.IO.Path.Combine(SOURCE_FOLDER + "cmpBytesPkcs7.txt"));
IAsn1Object outStream = BOUNCY_CASTLE_FACTORY.CreateASN1Primitive(bytes);
@@ -273,7 +274,7 @@ public virtual void GetEncodedPkcs7Test() {
[NUnit.Framework.Test]
public virtual void GetEncodedPkcs7WithRevocationInfoTest() {
String hashAlgorithm = DigestAlgorithms.SHA256;
- PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, true);
+ PdfPKCS7 pkcs7 = new PdfPKCS7(pk, chain, hashAlgorithm, new BouncyCastleDigest(), true);
pkcs7.GetSignedDataCRLs().Add(SignTestPortUtil.ParseCrlFromStream(new FileStream(SOURCE_FOLDER + "firstCrl.bin"
, FileMode.Open, FileAccess.Read)));
pkcs7.GetSignedDataOcsps().Add(BOUNCY_CASTLE_FACTORY.CreateBasicOCSPResponse(BOUNCY_CASTLE_FACTORY.CreateASN1InputStream
@@ -309,7 +310,7 @@ public virtual void VerifyBrainpoolSha2SignatureTest() {
// PdfPKCS7 is created here the same way it's done in PdfSigner#signDetached
private static PdfPKCS7 CreateSimplePdfPKCS7() {
- return new PdfPKCS7(null, chain, DigestAlgorithms.SHA256, false);
+ return new PdfPKCS7(null, chain, DigestAlgorithms.SHA256, new BouncyCastleDigest(), false);
}
private String SerializedAsString(byte[] serialized) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/PdfSignerUnitTest.cs b/itext.tests/itext.sign.tests/itext/signatures/PdfSignerUnitTest.cs
index 100a241502..47ba58672d 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/PdfSignerUnitTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/PdfSignerUnitTest.cs
@@ -118,7 +118,8 @@ public virtual void SignWithFieldLockNotNullTest() {
signer.SetPageRect(new Rectangle(100, 100, 10, 10));
signer.fieldLock = new PdfSigFieldLock();
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsTrue(signer.closed);
}
@@ -127,9 +128,10 @@ public virtual void SignDetachedWhenAlreadySignedIsNotPossibleTest() {
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimpleDocument())), new ByteArrayOutputStream
(), new StampingProperties());
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
- Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => signer.SignDetached(pks, chain, null
- , null, null, 0, PdfSigner.CryptoStandard.CADES));
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
+ Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => signer.SignDetached(new BouncyCastleDigest
+ (), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES));
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.THIS_INSTANCE_OF_PDF_SIGNER_ALREADY_CLOSED, e
.Message);
}
@@ -139,7 +141,8 @@ public virtual void SignExternalWhenAlreadySignedIsNotPossibleTest() {
PdfSigner signer = new PdfSigner(new PdfReader(new MemoryStream(CreateSimpleDocument())), new ByteArrayOutputStream
(), new StampingProperties());
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
Exception e = NUnit.Framework.Assert.Catch(typeof(PdfException), () => signer.SignExternalContainer(new ExternalBlankSignatureContainer
(new PdfDictionary()), 0));
NUnit.Framework.Assert.AreEqual(SignExceptionMessageConstant.THIS_INSTANCE_OF_PDF_SIGNER_ALREADY_CLOSED, e
diff --git a/itext.tests/itext.sign.tests/itext/signatures/PdfTwoPhaseSignerUnitTest.cs b/itext.tests/itext.sign.tests/itext/signatures/PdfTwoPhaseSignerUnitTest.cs
index ccad772b59..c3c0d891c0 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/PdfTwoPhaseSignerUnitTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/PdfTwoPhaseSignerUnitTest.cs
@@ -70,6 +70,24 @@ public virtual void PrepareDocumentTestWithSHA256() {
NUnit.Framework.Assert.AreEqual(estimatedSize, signature.GetContents().GetValueBytes().Length);
}
+ [NUnit.Framework.Test]
+ public virtual void PrepareDocumentTestWithExternalDigest() {
+ PdfReader reader = new PdfReader(new MemoryStream(CreateSimpleDocument()));
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ PdfTwoPhaseSigner signer = new PdfTwoPhaseSigner(reader, outputStream);
+ int estimatedSize = 8079;
+ SignerProperties signerProperties = new SignerProperties();
+ signer.SetExternalDigest(new BouncyCastleDigest());
+ byte[] digest = signer.PrepareDocumentForSignature(signerProperties, DigestAlgorithms.SHA256, PdfName.Adobe_PPKLite
+ , PdfName.Adbe_pkcs7_detached, estimatedSize, false);
+ String fieldName = signerProperties.GetFieldName();
+ PdfReader resultReader = new PdfReader(new MemoryStream(outputStream.ToArray()));
+ PdfDocument resultDoc = new PdfDocument(resultReader);
+ SignatureUtil signatureUtil = new SignatureUtil(resultDoc);
+ PdfSignature signature = signatureUtil.GetSignature(fieldName);
+ NUnit.Framework.Assert.AreEqual(estimatedSize, signature.GetContents().GetValueBytes().Length);
+ }
+
[NUnit.Framework.Test]
public virtual void AddSignatureToPreparedDocumentTest() {
PdfReader reader = new PdfReader(new MemoryStream(CreateSimpleDocument()));
diff --git a/itext.tests/itext.sign.tests/itext/signatures/TSAClientBouncyCastleTest.cs b/itext.tests/itext.sign.tests/itext/signatures/TSAClientBouncyCastleTest.cs
index e78fadf319..a2ab5253ac 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/TSAClientBouncyCastleTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/TSAClientBouncyCastleTest.cs
@@ -27,6 +27,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Cert;
using iText.Commons.Bouncycastle.Crypto;
using iText.Commons.Bouncycastle.Tsp;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.Kernel.Exceptions;
using iText.Signatures.Exceptions;
@@ -124,7 +125,7 @@ public virtual void GetMessageDigestTest() {
int tokenSizeEstimate = 4096;
TSAClientBouncyCastle tsaClientBouncyCastle = new TSAClientBouncyCastle(url, userName, password, tokenSizeEstimate
, digestAlgorithm);
- IDigest digest = tsaClientBouncyCastle.GetMessageDigest();
+ IMessageDigest digest = tsaClientBouncyCastle.GetMessageDigest();
NUnit.Framework.Assert.IsNotNull(digest);
NUnit.Framework.Assert.AreEqual(digestAlgorithm, digest.GetAlgorithmName());
}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/AnnotationsSigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/AnnotationsSigningTest.cs
index 067fb81d18..7d5b1b2f43 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/AnnotationsSigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/AnnotationsSigningTest.cs
@@ -145,7 +145,7 @@ protected internal virtual void Sign(String src, String name, String dest, IX509
}
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
- signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, subfilter);
}
private static IDictionary> GetTestMap(Rectangle ignoredArea) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/EncryptedSigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/EncryptedSigningTest.cs
index 9bffa81b80..a58c9f5586 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/EncryptedSigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/EncryptedSigningTest.cs
@@ -78,7 +78,8 @@ public virtual void SignEncryptedPdfTest() {
signer.SetFieldName(fieldName);
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
//Password to open out and cmp files are the same
ReaderProperties properties = new ReaderProperties().SetPassword(ownerPass);
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf, properties, properties
@@ -97,7 +98,8 @@ public virtual void SignCertificateSecurityPdfTest() {
.UseAppendMode());
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
ReaderProperties properties = new ReaderProperties().SetPublicKeySecurityParams(chain[0], pk);
//Public key to open out and cmp files are the same
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf, properties, properties
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 a4a083e8ea..f5f7a56f07 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/IsoSignatureExtensionsRoundtripTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/IsoSignatureExtensionsRoundtripTest.cs
@@ -236,14 +236,14 @@ public virtual void TestIsoExtensionsWithMultipleSignatures() {
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA3_256);
PdfSigner signer = new PdfSigner(new PdfReader(in1), baos1, new StampingProperties());
signer.SetFieldName("Signature1");
- signer.SignDetached(pks, signChain1, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain1, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
}
using (Stream in2 = new MemoryStream(baos1.ToArray())) {
IPrivateKey signPrivateKey = ReadUnencryptedPrivateKey(System.IO.Path.Combine(SOURCE_FOLDER, keySample2 + ".key.pem"));
IExternalSignature pks = new PrivateKeySignature(signPrivateKey, DigestAlgorithms.SHA512);
PdfSigner signer = new PdfSigner(new PdfReader(in2), baos2, new StampingProperties());
signer.SetFieldName("Signature2");
- signer.SignDetached(pks, signChain2, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain2, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
}
CheckIsoExtensions(baos2.ToArray(), JavaUtil.ArraysAsList(32001, 32002));
}
@@ -286,7 +286,7 @@ private void DoSign(String keySampleName, String digestAlgo, String signatureAlg
signer.SetFieldName(SIGNATURE_FIELD);
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 650, 200, 100)).SetReason("Test").SetLocation
("TestCity").SetLayer2Text("Approval test signature.\nCreated by iText.");
- signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
}
private void DoVerify(String fileName, DerObjectIdentifier expectedSigAlgoIdentifier) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/LtvSigTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/LtvSigTest.cs
index b8005b5c4d..1b69f1501d 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/LtvSigTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/LtvSigTest.cs
@@ -104,7 +104,7 @@ public virtual void LtvEnabledSingleSignatureNoCrlDataTest() {
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(ltvFileName, FileMode.Create),
new StampingProperties());
signer.SetFieldName("Signature1");
- signer.SignDetached(pks, signChain, crlNotAvailableList, testOcspClient, testTsa, 0, PdfSigner.CryptoStandard
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain, crlNotAvailableList, testOcspClient, testTsa, 0, PdfSigner.CryptoStandard
.CADES);
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(ltvFileName, compareFile));
}
@@ -138,7 +138,7 @@ public virtual void LtvEnabledSingleSignatureNoOcspDataTest() {
PdfSigner signer = new PdfSigner(new PdfReader(srcFileName), new FileStream(ltvFileName, FileMode.Create),
new StampingProperties());
signer.SetFieldName("Signature1");
- signer.SignDetached(pks, signChain, JavaCollectionsUtil.SingletonList(testCrlClient), null, testTsa
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain, JavaCollectionsUtil.SingletonList(testCrlClient), null, testTsa
, 0, PdfSigner.CryptoStandard.CADES);
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(ltvFileName, compareFile));
}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/PadesSignatureLevelTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/PadesSignatureLevelTest.cs
index 04cc49979d..64b8f0e45c 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/PadesSignatureLevelTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/PadesSignatureLevelTest.cs
@@ -77,7 +77,7 @@ public virtual void PadesSignatureLevelTTest01() {
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 650, 200, 100)).SetReason("Test").SetLocation
("TestCity").SetLayer2Text("Approval test signature.\nCreated by iText.");
TestTsaClient testTsa = new TestTsaClient(JavaUtil.ArraysAsList(tsaChain), tsaPrivateKey);
- signer.SignDetached(pks, signRsaChain, null, null, testTsa, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, signRsaChain, null, null, testTsa, 0, PdfSigner.CryptoStandard.CADES);
TestSignUtils.BasicCheckSignedDoc(destinationFolder + "padesSignatureLevelTTest01.pdf", "Signature1");
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, cmpFileName));
}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/Pdf20SigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/Pdf20SigningTest.cs
index 7cdfac5abb..11e129eacb 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/Pdf20SigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/Pdf20SigningTest.cs
@@ -160,7 +160,7 @@ protected internal virtual void Sign(String src, String name, String dest, IX509
signer.SetFieldName(name);
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
- signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, subfilter);
}
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
@@ -186,7 +186,7 @@ protected internal virtual void Sign(String src, String name, String dest, IX509
}
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
- signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, subfilter);
}
protected internal virtual void Sign(String src, String name, String dest, IX509Certificate[] chain, IPrivateKey
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/PdfASigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/PdfASigningTest.cs
index 7d61d020cf..dc60162022 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/PdfASigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/PdfASigningTest.cs
@@ -100,7 +100,8 @@ public virtual void SigningPdfA2DocumentTest() {
signer.SetFieldLockDict(new PdfSigFieldLock());
signer.SetCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED);
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(new VeraPdfValidator().Validate(@out));
}
@@ -152,8 +153,8 @@ public virtual void FailedSigningPdfA2DocumentTest() {
signer.SetPageRect(rect).GetSignatureAppearance().SetReason("pdfA test").SetLocation("TestCity").SetLayer2Font
(font).SetReuseAppearance(false);
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- Exception e = NUnit.Framework.Assert.Catch(typeof(PdfAConformanceException), () => signer.SignDetached(pks
- , chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES));
+ Exception e = NUnit.Framework.Assert.Catch(typeof(PdfAConformanceException), () => signer.SignDetached(new
+ BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES));
NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfaExceptionMessageConstant.ALL_THE_FONTS_MUST_BE_EMBEDDED_THIS_ONE_IS_NOT_0
, "Helvetica"), e.Message);
}
@@ -190,7 +191,7 @@ protected internal virtual void Sign(String src, String name, String dest, IX509
}
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
- signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, subfilter);
}
private static IDictionary> GetTestMap(Rectangle ignoredArea) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/PdfSignatureAppearanceTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/PdfSignatureAppearanceTest.cs
index 542178fdad..7ed14df636 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/PdfSignatureAppearanceTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/PdfSignatureAppearanceTest.cs
@@ -140,7 +140,8 @@ public virtual void TestSigningInAppendModeWithHybridDocument() {
(1).SetSignatureAppearance(appearance);
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
// Make sure iText can open the document
new PdfDocument(new PdfReader(dest)).Close();
// Assert that the document can be rendered correctly
@@ -162,7 +163,8 @@ public virtual void FontColorTest01() {
(ColorConstants.RED).SetContent("Verified and signed by me."));
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
, "diff_"));
}
@@ -204,7 +206,8 @@ public virtual void SignExistingNotMergedFieldNotReusedAPTest() {
.GetFieldName()).SetContent("Verified and signed by me."));
signer.GetSignatureField().SetReuseAppearance(false);
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
, "diff_"));
}
@@ -225,7 +228,8 @@ public virtual void SignExistingNotMergedFieldReusedAPTest() {
signer.SetReason("Test 1").SetLocation("TestCity").SetSignatureAppearance(appearance);
signer.GetSignatureField().SetReuseAppearance(true);
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
, "diff_"));
}
@@ -244,7 +248,8 @@ public virtual void SignExistingNotMergedFieldReusedAPEntryNDicTest() {
.GetFieldName()).SetContent("Verified and signed by me."));
signer.GetSignatureField().SetReuseAppearance(true);
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, SOURCE_FOLDER + "cmp_" + fileName, DESTINATION_FOLDER
, "diff_"));
}
@@ -275,7 +280,8 @@ public virtual void Layer0Test() {
(ColorConstants.BLACK).Circle(50, 50, 50).FillStroke().RestoreState();
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
}
@@ -297,7 +303,8 @@ public virtual void Layer0WithImageTest() {
appearance.SetLayer2Text("Hello");
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
}
@@ -320,7 +327,8 @@ public virtual void Layer0WithImageAndPositiveImageScaleTest() {
appearance.SetLayer2Text("Hello");
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
}
@@ -343,7 +351,8 @@ public virtual void Layer0WithImageAndNegativeImageScaleTest() {
appearance.SetLayer2Text("Hello");
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
}
@@ -370,7 +379,8 @@ public virtual void Layer2Test() {
(ColorConstants.BLACK).Circle(50, 50, 50).FillStroke().RestoreState();
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
}
@@ -394,7 +404,8 @@ public virtual void CreateAndSignSignatureFieldTest() {
signer.SetReason("Appearance is tested").SetLocation("TestCity").SetSignatureAppearance(appearance);
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_createdAndSignedSignatureField.pdf");
}
@@ -413,7 +424,8 @@ public virtual void SignExistedSignatureFieldTest() {
signer.GetSignatureField().SetReuseAppearance(true);
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
}
@@ -472,7 +484,8 @@ public virtual void SignatureFieldAppearanceTest() {
(appearance);
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(dest, cmp));
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, cmp, DESTINATION_FOLDER, "diff_"));
}
@@ -505,7 +518,8 @@ private void TestReuseAppearance(String src, String fileName, bool useDeprecated
signer.SetReason("Test 1").SetLocation("TestCity").SetSignatureAppearance(new SignatureFieldAppearance(fieldName
).SetContent("New appearance").SetFontColor(ColorConstants.GREEN));
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, cmp, DESTINATION_FOLDER, "diff_"));
}
@@ -540,7 +554,8 @@ private void TestLayers(String src, String fileName, bool useDeprecated) {
}
// Signing
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
CompareSignatureAppearances(dest, SOURCE_FOLDER + "cmp_" + fileName);
}
@@ -557,7 +572,8 @@ private void TestSignatureOnRotatedPage(int pageNum, PdfSignatureAppearance.Rend
(SOURCE_FOLDER + "itext.png")).SetPageNumber(pageNum);
signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
// Make sure iText can open the document
new PdfDocument(new PdfReader(dest)).Close();
try {
@@ -585,7 +601,8 @@ private void TestSignatureAppearanceAutoscale(String dest, Rectangle rect, PdfSi
signer.SetFieldName("Signature1");
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
}
private static void AssertAppearanceFontSize(String filename, float expectedFontSize) {
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 96ba64bb3e..a7f56ac4a3 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/RSASSAPSSTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/RSASSAPSSTest.cs
@@ -187,7 +187,7 @@ private void DoSign(String digestAlgo, String signatureAlgo, String outFile, IAp
//IExternalSignature pks = new PrivateKeySignature(signPrivateKey, digestAlgo, @params);
PdfSigner signer = new PdfSigner(new PdfReader(SOURCE_FILE), fos, new StampingProperties());
signer.SetFieldName(SIGNATURE_FIELD);
- signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
}
}
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/SequentialSignaturesTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/SequentialSignaturesTest.cs
index 84e422ea11..e9dc8b4b45 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/SequentialSignaturesTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/SequentialSignaturesTest.cs
@@ -64,7 +64,8 @@ public virtual void SequentialSignOfFileWithAnnots() {
signer.SetFieldName(signatureName);
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 350, 200, 100)).SetReason("Test").SetLocation
("TestCity").SetLayer2Text("Approval test signature.\nCreated by iText.");
- signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard
+ .CADES);
TestSignUtils.BasicCheckSignedDoc(outFileName, signatureName);
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outFileName, cmpFileName));
}
@@ -88,7 +89,8 @@ public virtual void SecondSignOfTaggedDocTest() {
appearance.SetPageNumber(1);
signer.GetSignatureAppearance().SetPageRect(new Rectangle(50, 550, 200, 100)).SetReason("Test2").SetLocation
("TestCity2").SetLayer2Text("Approval test signature #2.\nCreated by iText.");
- signer.SignDetached(pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, signChain, null, null, null, 0, PdfSigner.CryptoStandard
+ .CADES);
TestSignUtils.BasicCheckSignedDoc(outFileName, "Signature1");
TestSignUtils.BasicCheckSignedDoc(outFileName, "Signature2");
using (PdfDocument twiceSigned = new PdfDocument(new PdfReader(outFileName))) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/SignDeferredTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/SignDeferredTest.cs
index 5f5635b4ef..50aeb09873 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/SignDeferredTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/SignDeferredTest.cs
@@ -216,7 +216,7 @@ internal static byte[] SignDocBytesHash(byte[] docBytesHash, IPrivateKey pk, IX5
}
byte[] signatureContent = null;
try {
- PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, HASH_ALGORITHM, false);
+ PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, HASH_ALGORITHM, new BouncyCastleDigest(), false);
byte[] attributes = pkcs7.GetAuthenticatedAttributeBytes(docBytesHash, PdfSigner.CryptoStandard.CMS, null,
null);
PrivateKeySignature signature = new PrivateKeySignature(pk, HASH_ALGORITHM);
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/SignedAppearanceTextTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/SignedAppearanceTextTest.cs
index a204195c93..afb28b8770 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/SignedAppearanceTextTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/SignedAppearanceTextTest.cs
@@ -263,7 +263,8 @@ protected internal virtual void Sign(String src, String name, String dest, Strin
}
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
}
private static IDictionary> GetTestMap(Rectangle ignoredArea) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/SimpleSigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/SimpleSigningTest.cs
index c61d1aee6c..d8127b9885 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/SimpleSigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/SimpleSigningTest.cs
@@ -119,7 +119,8 @@ public virtual void SignWithTempFileTest() {
CreateAppearance(signer, "Test 1", "TestCity", false, rect, 12f);
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256);
- signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES
+ );
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(outPdf, cmpPdf, DESTINATION_FOLDER, "diff_"
, GetTestMap(rect)));
NUnit.Framework.Assert.IsNull(SignaturesCompareTool.CompareSignatures(outPdf, cmpPdf));
@@ -141,7 +142,7 @@ protected internal virtual void Sign(String src, String name, String dest, IX509
CreateAppearance(signer, reason, location, setReuseAppearance, rectangleForNewField, fontSize);
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
- signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, subfilter);
}
private static IDictionary> GetTestMap(Rectangle ignoredArea) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/TaggedPdfSigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/TaggedPdfSigningTest.cs
index b066d05a13..247c6ed889 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/TaggedPdfSigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/TaggedPdfSigningTest.cs
@@ -122,7 +122,7 @@ protected internal virtual void Sign(String src, String name, String dest, IX509
signer.SetFieldName(name);
// Creating the signature
IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
- signer.SignDetached(pks, chain, null, null, null, 0, subfilter);
+ signer.SignDetached(new BouncyCastleDigest(), pks, chain, null, null, null, 0, subfilter);
}
private static IDictionary> GetTestMap(Rectangle ignoredArea) {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/sign/TwoPhaseSigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/sign/TwoPhaseSigningTest.cs
index 4fe52119fb..b64562c30e 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/sign/TwoPhaseSigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/sign/TwoPhaseSigningTest.cs
@@ -24,11 +24,11 @@ You should have received a copy of the GNU Affero General Public License
using System.IO;
using System.Security.Cryptography;
using System.Xml.Serialization;
-using Org.BouncyCastle.Asn1;
using iText.Bouncycastleconnector;
using iText.Commons.Bouncycastle;
using iText.Commons.Bouncycastle.Cert;
using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.IO.Source;
using iText.Kernel.Exceptions;
@@ -37,7 +37,6 @@ You should have received a copy of the GNU Affero General Public License
using iText.Signatures.Exceptions;
using iText.Signatures.Testutils;
using iText.Test;
-using AlgorithmIdentifier = Org.BouncyCastle.Asn1.X509.AlgorithmIdentifier;
using SignerInfo = iText.Signatures.Cms.SignerInfo;
namespace iText.Signatures.Sign {
@@ -280,7 +279,7 @@ public virtual void TestWithCMS() {
}
private byte[] SignDigest(byte[] data, String hashAlgorithm) {
- PdfPKCS7 sgn = new PdfPKCS7((IPrivateKey)null, chain, hashAlgorithm, false);
+ PdfPKCS7 sgn = new PdfPKCS7((IPrivateKey)null, chain, hashAlgorithm, new BouncyCastleDigest(), false);
byte[] sh = sgn.GetAuthenticatedAttributeBytes(data, PdfSigner.CryptoStandard.CMS, null, null);
PrivateKeySignature pkSign = new PrivateKeySignature(pk, hashAlgorithm);
byte[] signData = pkSign.Sign(sh);
@@ -314,7 +313,7 @@ private byte[] PrepareDocumentAndCMS(FileInfo document, ByteArrayOutputStream pr
cms.AddCertificates(chain);
byte[] signedAttributesToSign = cms.GetSerializedSignedAttributes();
- IDigest sha = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest(DIGEST_ALGORITHM
+ IMessageDigest sha = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest(DIGEST_ALGORITHM
);
byte[] dataToSign = sha.Digest(signedAttributesToSign);
diff --git a/itext.tests/itext.sign.tests/itext/signatures/testutils/SignTestPortUtil.cs b/itext.tests/itext.sign.tests/itext/signatures/testutils/SignTestPortUtil.cs
index 075ef52611..41b2c45dff 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/testutils/SignTestPortUtil.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/testutils/SignTestPortUtil.cs
@@ -32,6 +32,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Crypto;
using iText.Commons.Bouncycastle.Crypto.Generators;
using iText.Commons.Bouncycastle.Math;
+using iText.Commons.Digest;
using iText.Kernel.Pdf;
namespace iText.Signatures.Testutils {
diff --git a/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestTsaClient.cs b/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestTsaClient.cs
index dd46f38c70..7d21547297 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestTsaClient.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/testutils/client/TestTsaClient.cs
@@ -28,6 +28,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Crypto;
using iText.Commons.Bouncycastle.Math;
using iText.Commons.Bouncycastle.Tsp;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.Signatures;
using iText.Signatures.Testutils;
@@ -54,7 +55,7 @@ public virtual int GetTokenSizeEstimate() {
}
public virtual IDigest GetMessageDigest() {
- return SignTestPortUtil.GetMessageDigest(DIGEST_ALG);
+ return (IDigest)SignTestPortUtil.GetMessageDigest(DIGEST_ALG);
}
public virtual byte[] GetTimeStampToken(byte[] imprint) {
diff --git a/itext/itext.bouncy-castle-adapter/itext/bouncycastle/BouncyCastleFactory.cs b/itext/itext.bouncy-castle-adapter/itext/bouncycastle/BouncyCastleFactory.cs
index 2155a77548..3c8fb4830b 100644
--- a/itext/itext.bouncy-castle-adapter/itext/bouncycastle/BouncyCastleFactory.cs
+++ b/itext/itext.bouncy-castle-adapter/itext/bouncycastle/BouncyCastleFactory.cs
@@ -948,7 +948,11 @@ public ICollection CreateX509Crls(Stream input) {
///
public IDigest CreateIDigest(string hashAlgorithm) {
- return new DigestBC(DigestUtilities.GetDigest(hashAlgorithm));
+ try {
+ return new DigestBC(DigestUtilities.GetDigest(hashAlgorithm));
+ } catch (SecurityUtilityException e) {
+ throw new SecurityUtilityExceptionBC(e);
+ }
}
///
diff --git a/itext/itext.bouncy-castle-adapter/itext/bouncycastle/security/SecurityUtilityExceptionBC.cs b/itext/itext.bouncy-castle-adapter/itext/bouncycastle/security/SecurityUtilityExceptionBC.cs
new file mode 100644
index 0000000000..89580cefee
--- /dev/null
+++ b/itext/itext.bouncy-castle-adapter/itext/bouncycastle/security/SecurityUtilityExceptionBC.cs
@@ -0,0 +1,82 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2024 Apryse Group NV
+ Authors: Apryse Software.
+
+ This program is offered under a commercial and under the AGPL license.
+ For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+ AGPL licensing:
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+using System;
+using iText.Commons.Bouncycastle.Security;
+using iText.Commons.Utils;
+using Org.BouncyCastle.Security;
+
+namespace iText.Bouncycastle.Security {
+ /// Wrapper class for .
+ public class SecurityUtilityExceptionBC : AbstractSecurityUtilityException {
+ private readonly SecurityUtilityException exception;
+ ///
+ /// Creates new wrapper for .
+ ///
+ ///
+ /// to be wrapped
+ ///
+ public SecurityUtilityExceptionBC(SecurityUtilityException exception) {
+ this.exception = exception;
+ }
+
+ /// Get actual org.bouncycastle object being wrapped.
+ /// wrapped .
+ public SecurityUtilityException GetException() {
+ return exception;
+ }
+
+ /// Indicates whether some other object is "equal to" this one.
+ /// Indicates whether some other object is "equal to" this one. Compares wrapped objects.
+ public override bool Equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || GetType() != o.GetType()) {
+ return false;
+ }
+ SecurityUtilityExceptionBC that = (SecurityUtilityExceptionBC) o;
+ return Object.Equals(exception, that.exception);
+ }
+
+ /// Returns a hash code value based on the wrapped object.
+ public override int GetHashCode() {
+ return JavaUtil.ArraysHashCode(exception);
+ }
+
+ ///
+ /// Delegates
+ /// toString
+ /// method call to the wrapped object.
+ ///
+ public override String ToString() {
+ return exception.ToString();
+ }
+
+ ///
+ /// Delegates
+ /// getMessage
+ /// method call to the wrapped exception.
+ ///
+ public override String Message => exception.Message;
+ }
+}
\ No newline at end of file
diff --git a/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/BouncyCastleFipsFactory.cs b/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/BouncyCastleFipsFactory.cs
index cbab7eee33..d7e0202e75 100644
--- a/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/BouncyCastleFipsFactory.cs
+++ b/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/BouncyCastleFipsFactory.cs
@@ -83,7 +83,6 @@ You should have received a copy of the GNU Affero General Public License
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Asymmetric;
using Org.BouncyCastle.Crypto.Fips;
-using Org.BouncyCastle.Ocsp;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Operators;
using Org.BouncyCastle.Operators.Utilities;
diff --git a/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/DigestBCFips.cs b/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/DigestBCFips.cs
index 7497738f30..78d9b1a21b 100644
--- a/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/DigestBCFips.cs
+++ b/itext/itext.bouncy-castle-fips-adapter/itext/bouncycastlefips/crypto/DigestBCFips.cs
@@ -60,6 +60,8 @@ public DigestBCFips(IStreamCalculator iDigest) {
/// hash algorithm to create IStreamCalculator
///
public DigestBCFips(string hashAlgorithm) {
+ if (hashAlgorithm == null)
+ throw new ArgumentNullException(nameof(hashAlgorithm));
if ("MD5".Equals(hashAlgorithm)) {
md5 = System.Security.Cryptography.MD5.Create();
algorithmName = "MD5";
diff --git a/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs b/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs
index 1fc53cdbd4..16eeff2629 100644
--- a/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs
+++ b/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs
@@ -20,12 +20,15 @@ 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 iText.Commons.Digest;
+
namespace iText.Commons.Bouncycastle.Crypto {
///
/// This interface represents the wrapper for IDigest that provides the ability
/// to switch between bouncy-castle and bouncy-castle FIPS implementations.
///
- public interface IDigest {
+ public interface IDigest : IMessageDigest {
///
/// Calls actual
/// Digest
diff --git a/itext/itext.commons/itext/commons/bouncycastle/security/AbstractSecurityUtilityException.cs b/itext/itext.commons/itext/commons/bouncycastle/security/AbstractSecurityUtilityException.cs
new file mode 100644
index 0000000000..8b481448dc
--- /dev/null
+++ b/itext/itext.commons/itext/commons/bouncycastle/security/AbstractSecurityUtilityException.cs
@@ -0,0 +1,45 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2024 Apryse Group NV
+ Authors: Apryse Software.
+
+ This program is offered under a commercial and under the AGPL license.
+ For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+ AGPL licensing:
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+using System;
+
+namespace iText.Commons.Bouncycastle.Security {
+ ///
+ /// This class represents the wrapper for SecurityUtilityException that provides the ability
+ /// to switch between bouncy-castle and bouncy-castle FIPS implementations.
+ ///
+ public class AbstractSecurityUtilityException : Exception {
+ ///
+ /// Base constructor for .
+ ///
+ protected AbstractSecurityUtilityException() {
+ }
+
+ ///
+ /// Creates new wrapper instance for .
+ /// The abstract class constructor gets executed from a derived class.
+ ///
+ /// Exception message
+ protected AbstractSecurityUtilityException(string message) : base(message) {
+ }
+ }
+}
diff --git a/itext/itext.commons/itext/commons/digest/IMessageDigest.cs b/itext/itext.commons/itext/commons/digest/IMessageDigest.cs
new file mode 100644
index 0000000000..b06ed79b1e
--- /dev/null
+++ b/itext/itext.commons/itext/commons/digest/IMessageDigest.cs
@@ -0,0 +1,72 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2024 Apryse Group NV
+ Authors: Apryse Software.
+
+ This program is offered under a commercial and under the AGPL license.
+ For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+ AGPL licensing:
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+namespace iText.Commons.Digest {
+ ///
+ /// This interface should be implemented to provide applications the functionality of a message digest algorithm.
+ ///
+ public interface IMessageDigest {
+ ///
+ /// Performs a final update on the digest using the specified array of bytes,
+ /// then completes the digest computation.
+ ///
+ /// the input to be updated before the digest is completed
+ /// The array of bytes for the resulting hash value
+ byte[] Digest(byte[] enc);
+
+ ///
+ /// Completes the hash computation by performing final operations such as padding.
+ /// Leaves the digest reset.
+ ///
+ /// The array of bytes for the resulting hash value
+ byte[] Digest();
+
+ ///
+ /// Gets byte length of wrapped digest algorithm.
+ ///
+ /// The length of the digest in bytes.
+ int GetDigestLength();
+
+ ///
+ /// Updates the digest using the specified array of bytes, starting at the specified offset.
+ ///
+ /// byte array buffer
+ /// the offset to start from in the array of bytes
+ /// the number of bytes to use, starting at offset
+ void Update(byte[] buf, int off, int len);
+
+ ///
+ /// Updates the digest using the specified array of bytes.
+ ///
+ /// byte array buffer
+ void Update(byte[] buf);
+
+ /// Resets the digest for further use.
+ void Reset();
+
+ ///
+ /// Returns a string that identifies the algorithm, independent of implementation details.
+ ///
+ /// The name of the algorithm.
+ string GetAlgorithmName();
+ }
+}
\ No newline at end of file
diff --git a/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubKeySecurityHandler.cs b/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubKeySecurityHandler.cs
index 6483828d14..9344d8eabf 100644
--- a/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubKeySecurityHandler.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubKeySecurityHandler.cs
@@ -31,6 +31,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Cert;
using iText.Commons.Bouncycastle.Crypto;
using iText.Commons.Bouncycastle.Security;
+using iText.Commons.Digest;
using iText.IO.Util;
using iText.Kernel.Crypto;
using iText.Kernel.Exceptions;
@@ -55,7 +56,7 @@ protected internal PubKeySecurityHandler() {
}
protected internal virtual byte[] ComputeGlobalKey(String messageDigestAlgorithm, bool encryptMetadata) {
- IDigest md;
+ IMessageDigest md;
byte[] encodedRecipient;
try {
md = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest(messageDigestAlgorithm
@@ -87,7 +88,7 @@ protected internal static byte[] ComputeGlobalKeyOnReading(PdfDictionary encrypt
}
byte[] envelopedData = EncryptionUtils.FetchEnvelopedData(certificateKey, certificate, recipients);
byte[] encryptionKey;
- IDigest md;
+ IMessageDigest md;
try {
md = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest(digestAlgorithm);
md.Update(envelopedData, 0, 20);
diff --git a/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs b/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs
index b74c0f6524..2eb4a8cc7b 100644
--- a/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs
@@ -27,7 +27,6 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons;
using iText.Commons.Bouncycastle;
using iText.Commons.Bouncycastle.Crypto;
-using iText.Kernel.Crypto;
using iText.Kernel.Exceptions;
using iText.Kernel.Logs;
diff --git a/itext/itext.kernel/itext/kernel/crypto/securityhandler/StandardHandlerUsingAes256.cs b/itext/itext.kernel/itext/kernel/crypto/securityhandler/StandardHandlerUsingAes256.cs
index c46f5d4052..51143e15e2 100644
--- a/itext/itext.kernel/itext/kernel/crypto/securityhandler/StandardHandlerUsingAes256.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/securityhandler/StandardHandlerUsingAes256.cs
@@ -24,8 +24,8 @@ You should have received a copy of the GNU Affero General Public License
using System.IO;
using Microsoft.Extensions.Logging;
using iText.Commons;
-using iText.Commons.Bouncycastle.Crypto;
using iText.Commons.Bouncycastle.Math;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.IO.Util;
using iText.Kernel.Crypto;
@@ -243,8 +243,8 @@ private byte[] ComputeHash(byte[] password, byte[] salt, int saltOffset, int sal
}
private byte[] ComputeHash(byte[] password, byte[] salt, int saltOffset, int saltLen, byte[] userKey) {
- IDigest mdSha256 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("SHA-256"
- );
+ IMessageDigest mdSha256 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest
+ ("SHA-256");
mdSha256.Update(password);
mdSha256.Update(salt, saltOffset, saltLen);
if (userKey != null) {
@@ -253,10 +253,10 @@ private byte[] ComputeHash(byte[] password, byte[] salt, int saltOffset, int sal
byte[] k = mdSha256.Digest();
if (isPdf2) {
// See 7.6.4.3.3 "Algorithm 2.B"
- IDigest mdSha384 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("SHA-384"
- );
- IDigest mdSha512 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("SHA-512"
- );
+ IMessageDigest mdSha384 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest
+ ("SHA-384");
+ IMessageDigest mdSha512 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest
+ ("SHA-512");
int userKeyLen = userKey != null ? userKey.Length : 0;
int passAndUserKeyLen = password.Length + userKeyLen;
// k1 repetition length
@@ -279,7 +279,7 @@ private byte[] ComputeHash(byte[] password, byte[] salt, int saltOffset, int sal
(k, 16, 32));
byte[] e = cipher.ProcessBlock(k1, 0, k1.Length);
// c)
- IDigest md = null;
+ IMessageDigest md = null;
IBigInteger i_1 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateBigInteger(1,
JavaUtil.ArraysCopyOf(e, 16));
int remainder = i_1.Remainder(iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateBigInteger().ValueOf
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs b/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs
index a6dd9d4844..fe15fdd153 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs
@@ -24,6 +24,7 @@ You should have received a copy of the GNU Affero General Public License
using System.IO;
using iText.Commons.Bouncycastle.Cert;
using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.IO.Source;
using iText.Kernel.Crypto;
@@ -328,7 +329,7 @@ public PdfEncryption(PdfDictionary pdfDict, IPrivateKey certificateKey, IX509Cer
}
public static byte[] GenerateNewDocumentId() {
- IDigest sha512;
+ IMessageDigest sha512;
try {
sha512 = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("SHA-512");
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/SmartModePdfObjectsSerializer.cs b/itext/itext.kernel/itext/kernel/pdf/SmartModePdfObjectsSerializer.cs
index f05f6fe622..cba3b1bcb8 100644
--- a/itext/itext.kernel/itext/kernel/pdf/SmartModePdfObjectsSerializer.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/SmartModePdfObjectsSerializer.cs
@@ -22,13 +22,13 @@ You should have received a copy of the GNU Affero General Public License
*/
using System;
using System.Collections.Generic;
-using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.IO.Source;
using iText.Kernel.Exceptions;
namespace iText.Kernel.Pdf {
internal class SmartModePdfObjectsSerializer {
- private IDigest sha512;
+ private IMessageDigest sha512;
private Dictionary serializedContentToObj = new Dictionary<
SerializedObjectContent, PdfIndirectReference>();
diff --git a/itext/itext.sign/itext/signatures/BouncyCastleDigest.cs b/itext/itext.sign/itext/signatures/BouncyCastleDigest.cs
new file mode 100644
index 0000000000..9e9c535865
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/BouncyCastleDigest.cs
@@ -0,0 +1,39 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2024 Apryse Group NV
+ Authors: Apryse Software.
+
+ This program is offered under a commercial and under the AGPL license.
+ For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+ AGPL licensing:
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+using iText.Bouncycastleconnector;
+using iText.Commons.Bouncycastle;
+using iText.Commons.Digest;
+
+namespace iText.Signatures {
+ ///
+ /// Implementation for digests accessed directly from the BouncyCastle library.
+ ///
+ public class BouncyCastleDigest : IExternalDigest {
+ private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();
+
+ ///
+ public IMessageDigest GetMessageDigest(string hashAlgorithm) {
+ return FACTORY.CreateIDigest(hashAlgorithm);
+ }
+ }
+}
\ No newline at end of file
diff --git a/itext/itext.sign/itext/signatures/DigestAlgorithms.cs b/itext/itext.sign/itext/signatures/DigestAlgorithms.cs
index 5f403cf139..7316c1f7ee 100644
--- a/itext/itext.sign/itext/signatures/DigestAlgorithms.cs
+++ b/itext/itext.sign/itext/signatures/DigestAlgorithms.cs
@@ -28,6 +28,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons;
using iText.Commons.Bouncycastle;
using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.Signatures.Exceptions;
using iText.Signatures.Logs;
@@ -197,7 +198,7 @@ public static IDigest GetMessageDigestFromOid(String digestOid) {
/// the algorithm you want to use to create a hash
/// a MessageDigest object
public static IDigest GetMessageDigest(String hashAlgorithm) {
- return SignUtils.GetMessageDigest(hashAlgorithm);
+ return (IDigest)SignUtils.GetMessageDigest(hashAlgorithm);
}
/// Creates a hash using a specific digest algorithm and a provider.
@@ -222,6 +223,21 @@ public static byte[] Digest(Stream data, IDigest messageDigest) {
return messageDigest.Digest();
}
+ /// Create a digest based on the inputstream.
+ /// data to be digested
+ /// algorithm to be used
+ /// external digest to be used
+ /// digest of the data
+ public static byte[] Digest(Stream data, String hashAlgorithm, IExternalDigest externalDigest) {
+ byte[] buf = new byte[8192];
+ int n;
+ IMessageDigest messageDigest = SignUtils.GetMessageDigest(hashAlgorithm, externalDigest);
+ while ((n = data.Read(buf)) > 0) {
+ messageDigest.Update(buf, 0, n);
+ }
+ return messageDigest.Digest();
+ }
+
/// Gets the digest name for a certain id.
/// an id (for instance "1.2.840.113549.2.5")
/// a digest name (for instance "MD5")
diff --git a/itext/itext.sign/itext/signatures/IExternalDigest.cs b/itext/itext.sign/itext/signatures/IExternalDigest.cs
new file mode 100644
index 0000000000..6b551c8b33
--- /dev/null
+++ b/itext/itext.sign/itext/signatures/IExternalDigest.cs
@@ -0,0 +1,39 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
+using iText.Commons.Digest;
+
+namespace iText.Signatures {
+ ///
+ /// ExternalDigest allows the use of implementations of
+ ///
+ /// other than
+ /// .
+ ///
+ public interface IExternalDigest {
+ /// Returns the MessageDigest associated with the provided hashing algorithm.
+ /// String value representing the hashing algorithm
+ /// MessageDigest MessageDigest object
+ IMessageDigest GetMessageDigest(String hashAlgorithm);
+ }
+}
diff --git a/itext/itext.sign/itext/signatures/ITSAClient.cs b/itext/itext.sign/itext/signatures/ITSAClient.cs
index 9a35d842b9..017a9eff5e 100644
--- a/itext/itext.sign/itext/signatures/ITSAClient.cs
+++ b/itext/itext.sign/itext/signatures/ITSAClient.cs
@@ -47,12 +47,12 @@ public interface ITSAClient {
///
/// Returns the
- ///
+ ///
/// to digest the data imprint
///
///
/// The
- ///
+ ///
/// object.
///
IDigest GetMessageDigest();
diff --git a/itext/itext.sign/itext/signatures/LtvVerification.cs b/itext/itext.sign/itext/signatures/LtvVerification.cs
index d90c32b929..c625d65dee 100644
--- a/itext/itext.sign/itext/signatures/LtvVerification.cs
+++ b/itext/itext.sign/itext/signatures/LtvVerification.cs
@@ -31,8 +31,8 @@ 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.Crypto;
using iText.Commons.Bouncycastle.Operator;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.IO.Font;
using iText.IO.Source;
@@ -432,7 +432,8 @@ private PdfName GetSignatureHashKey(String signatureName) {
}
private static byte[] HashBytesSha1(byte[] b) {
- IDigest sh = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("SHA1");
+ IMessageDigest sh = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest("SHA1"
+ );
return sh.Digest(b);
}
diff --git a/itext/itext.sign/itext/signatures/PKCS7ExternalSignatureContainer.cs b/itext/itext.sign/itext/signatures/PKCS7ExternalSignatureContainer.cs
index 192286ccf0..b9a2c07ff3 100644
--- a/itext/itext.sign/itext/signatures/PKCS7ExternalSignatureContainer.cs
+++ b/itext/itext.sign/itext/signatures/PKCS7ExternalSignatureContainer.cs
@@ -58,7 +58,7 @@ public PKCS7ExternalSignatureContainer(IPrivateKey privateKey, IX509Certificate[
}
public virtual byte[] Sign(Stream data) {
- PdfPKCS7 sgn = new PdfPKCS7((IPrivateKey)null, chain, hashAlgorithm, false);
+ PdfPKCS7 sgn = new PdfPKCS7((IPrivateKey)null, chain, hashAlgorithm, new BouncyCastleDigest(), false);
if (signaturePolicy != null) {
sgn.SetSignaturePolicy(signaturePolicy);
}
diff --git a/itext/itext.sign/itext/signatures/PadesTwoPhaseSigningHelper.cs b/itext/itext.sign/itext/signatures/PadesTwoPhaseSigningHelper.cs
index f0e3a59bab..ca9d9ce73f 100644
--- a/itext/itext.sign/itext/signatures/PadesTwoPhaseSigningHelper.cs
+++ b/itext/itext.sign/itext/signatures/PadesTwoPhaseSigningHelper.cs
@@ -27,7 +27,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle;
using iText.Commons.Bouncycastle.Asn1;
using iText.Commons.Bouncycastle.Cert;
-using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.Kernel.Exceptions;
using iText.Kernel.Pdf;
@@ -334,8 +334,8 @@ public virtual CMSContainer CreateCMSContainerWithoutSignature(IX509Certificate[
signerInfo.SetDigestAlgorithm(new AlgorithmIdentifier(digestAlgorithmOid));
cms.AddCertificates(x509FullChain);
cms.SetSignerInfo(signerInfo);
- IDigest messageDigest = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest(
- DigestAlgorithms.GetDigest(digestAlgorithmOid));
+ IMessageDigest messageDigest = iText.Bouncycastleconnector.BouncyCastleFactoryCreator.GetFactory().CreateIDigest
+ (DigestAlgorithms.GetDigest(digestAlgorithmOid));
int realSignatureSize = messageDigest.GetDigestLength() + (int)cms.GetSizeEstimation();
if (tsaClient != null) {
realSignatureSize += tsaClient.GetTokenSizeEstimate();
diff --git a/itext/itext.sign/itext/signatures/PdfPKCS7.cs b/itext/itext.sign/itext/signatures/PdfPKCS7.cs
index 90a3185da8..c12656f68c 100644
--- a/itext/itext.sign/itext/signatures/PdfPKCS7.cs
+++ b/itext/itext.sign/itext/signatures/PdfPKCS7.cs
@@ -39,6 +39,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Cert.Ocsp;
using iText.Commons.Bouncycastle.Crypto;
using iText.Commons.Bouncycastle.Math;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.Kernel.Exceptions;
using iText.Kernel.Pdf;
@@ -81,8 +82,9 @@ public class PdfPKCS7 {
/// the hash algorithm
/// the provider or null for the default provider
/// true if the sub-filter is adbe.pkcs7.sha1
- public PdfPKCS7(IPrivateKey privKey, IX509Certificate[] certChain, String hashAlgorithm, bool hasEncapContent
- ) {
+ public PdfPKCS7(IPrivateKey privKey, IX509Certificate[] certChain, String hashAlgorithm, IExternalDigest interfaceDigest
+ , bool hasEncapContent) {
+ this.interfaceDigest = interfaceDigest;
// message digest
digestAlgorithmOid = DigestAlgorithms.GetAllowedDigest(hashAlgorithm);
if (digestAlgorithmOid == null) {
@@ -117,6 +119,17 @@ public PdfPKCS7(IPrivateKey privKey, IX509Certificate[] certChain, String hashAl
}
}
+ /// Assembles all the elements needed to create a signature, except for the data.
+ /// the private key
+ /// the certificate chain
+ /// the hash algorithm
+ /// the provider or null for the default provider
+ /// true if the sub-filter is adbe.pkcs7.sha1
+ public PdfPKCS7(IPrivateKey privKey, IX509Certificate[] certChain, String hashAlgorithm, bool hasEncapContent
+ )
+ : this(privKey, certChain, hashAlgorithm, new BouncyCastleDigest(), hasEncapContent) {
+ }
+
// Constructors for validating existing signatures
/// Use this constructor if you want to verify a signature using the sub-filter adbe.x509.rsa_sha1.
/// the /Contents key
@@ -281,7 +294,7 @@ public PdfPKCS7(byte[] contentsKey, PdfName filterSubtype) {
IEssCertID[] cerv2m = sv2.GetCerts();
IEssCertID cerv2 = cerv2m[0];
byte[] enc2 = signCert.GetEncoded();
- IDigest m2 = SignUtils.GetMessageDigest("SHA-1");
+ IMessageDigest m2 = SignUtils.GetMessageDigest("SHA-1");
byte[] signCertHash = m2.Digest(enc2);
byte[] hs2 = cerv2.GetCertHash();
if (!JavaUtil.ArraysEquals(signCertHash, hs2)) {
@@ -298,7 +311,7 @@ public PdfPKCS7(byte[] contentsKey, PdfName filterSubtype) {
IEssCertIDv2 cerv2 = cerv2m[0];
IAlgorithmIdentifier ai2 = cerv2.GetHashAlgorithm();
byte[] enc2 = signCert.GetEncoded();
- IDigest m2 = SignUtils.GetMessageDigest(DigestAlgorithms.GetDigest(ai2.GetAlgorithm().GetId()));
+ IMessageDigest m2 = SignUtils.GetMessageDigest(DigestAlgorithms.GetDigest(ai2.GetAlgorithm().GetId()));
byte[] signCertHash = m2.Digest(enc2);
byte[] hs2 = cerv2.GetCertHash();
if (!JavaUtil.ArraysEquals(signCertHash, hs2)) {
@@ -457,7 +470,7 @@ public virtual int GetSigningInfoVersion() {
private readonly String digestAlgorithmOid;
/// The object that will create the digest
- private IDigest messageDigest;
+ private IMessageDigest messageDigest;
/// The digest algorithms
private ICollection digestalgos;
@@ -561,6 +574,8 @@ public virtual String GetSignatureAlgorithmName() {
/*
* DIGITAL SIGNATURE CREATION
*/
+ private IExternalDigest interfaceDigest;
+
// The signature is created externally
/// The signature value or signed digest, if created outside this class
private byte[] externalSignatureValue;
@@ -1045,7 +1060,7 @@ private IDerSet GetAuthenticatedAttributeSet(byte[] secondDigest, ICollectionencrypted digest
- private IDigest encContDigest;
+ private IMessageDigest encContDigest;
// Stefan Santesson
/// Indicates if a signature has already been verified
diff --git a/itext/itext.sign/itext/signatures/PdfPadesSigner.cs b/itext/itext.sign/itext/signatures/PdfPadesSigner.cs
index e7f482c301..b4fd535e3b 100644
--- a/itext/itext.sign/itext/signatures/PdfPadesSigner.cs
+++ b/itext/itext.sign/itext/signatures/PdfPadesSigner.cs
@@ -57,6 +57,8 @@ public class PdfPadesSigner {
private String temporaryDirectoryPath = null;
+ private IExternalDigest externalDigest = new BouncyCastleDigest();
+
private StampingProperties stampingProperties = new StampingProperties().UseAppendMode();
private MemoryStream tempOutputStream;
@@ -490,6 +492,34 @@ public virtual iText.Signatures.PdfPadesSigner SetCrlClient(ICrlClient crlClient
return this;
}
+ ///
+ /// Set
+ ///
+ /// to be used for main signing operation.
+ ///
+ ///
+ /// Set
+ ///
+ /// to be used for main signing operation.
+ ///
+ /// If none is set,
+ ///
+ /// instance will be used instead.
+ ///
+ ///
+ ///
+ ///
+ /// to be used for main signing operation.
+ ///
+ ///
+ /// same instance of
+ ///
+ ///
+ public virtual iText.Signatures.PdfPadesSigner SetExternalDigest(IExternalDigest externalDigest) {
+ this.externalDigest = externalDigest;
+ return this;
+ }
+
///
/// Set
///
@@ -606,7 +636,7 @@ private void PerformSignDetached(SignerProperties signerProperties, bool isFinal
IX509Certificate[] fullChain = issuingCertificateRetriever.RetrieveMissingCertificates(chain);
PdfSigner signer = CreatePdfSigner(signerProperties, isFinal);
try {
- signer.SignDetached(externalSignature, fullChain, null, null, tsaClient, estimatedSize, PdfSigner.CryptoStandard
+ signer.SignDetached(externalDigest, externalSignature, fullChain, null, null, tsaClient, estimatedSize, PdfSigner.CryptoStandard
.CADES);
}
finally {
diff --git a/itext/itext.sign/itext/signatures/PdfSigner.cs b/itext/itext.sign/itext/signatures/PdfSigner.cs
index 702ee1f4eb..56f9a0cf64 100644
--- a/itext/itext.sign/itext/signatures/PdfSigner.cs
+++ b/itext/itext.sign/itext/signatures/PdfSigner.cs
@@ -26,6 +26,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Asn1.Esf;
using iText.Commons.Bouncycastle.Cert;
using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.Forms;
using iText.Forms.Fields;
@@ -556,6 +557,28 @@ public virtual PdfSignatureFormField GetSignatureField() {
return null;
}
+ /// Signs the document using the detached mode, CMS or CAdES equivalent.
+ ///
+ /// Signs the document using the detached mode, CMS or CAdES equivalent.
+ ///
+ /// NOTE: This method closes the underlying pdf document. This means, that current instance
+ /// of PdfSigner cannot be used after this method call.
+ ///
+ /// the interface providing the actual signing
+ /// the certificate chain
+ /// the CRL list
+ /// the OCSP client
+ /// the Timestamp client
+ /// an implementation that provides the digest
+ /// the reserved size for the signature. It will be estimated if 0
+ /// Either Signature.CMS or Signature.CADES
+ public virtual void SignDetached(IExternalDigest externalDigest, IExternalSignature externalSignature, IX509Certificate
+ [] chain, ICollection crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize
+ , PdfSigner.CryptoStandard sigtype) {
+ SignDetached(externalDigest, externalSignature, chain, crlList, ocspClient, tsaClient, estimatedSize, sigtype
+ , (ISignaturePolicyIdentifier)null);
+ }
+
/// Signs the document using the detached mode, CMS or CAdES equivalent.
///
/// Signs the document using the detached mode, CMS or CAdES equivalent.
@@ -573,8 +596,31 @@ public virtual PdfSignatureFormField GetSignatureField() {
public virtual void SignDetached(IExternalSignature externalSignature, IX509Certificate[] chain, ICollection
crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, PdfSigner.CryptoStandard
sigtype) {
- SignDetached(externalSignature, chain, crlList, ocspClient, tsaClient, estimatedSize, sigtype, (ISignaturePolicyIdentifier
- )null);
+ SignDetached(new BouncyCastleDigest(), externalSignature, chain, crlList, ocspClient, tsaClient, estimatedSize
+ , sigtype, (ISignaturePolicyIdentifier)null);
+ }
+
+ /// Signs the document using the detached mode, CMS or CAdES equivalent.
+ ///
+ /// Signs the document using the detached mode, CMS or CAdES equivalent.
+ ///
+ /// NOTE: This method closes the underlying pdf document. This means, that current instance
+ /// of PdfSigner cannot be used after this method call.
+ ///
+ /// the interface providing the actual signing
+ /// the certificate chain
+ /// the CRL list
+ /// the OCSP client
+ /// the Timestamp client
+ /// an implementation that provides the digest
+ /// the reserved size for the signature. It will be estimated if 0
+ /// Either Signature.CMS or Signature.CADES
+ /// the signature policy (for EPES signatures)
+ public virtual void SignDetached(IExternalDigest externalDigest, IExternalSignature externalSignature, IX509Certificate
+ [] chain, ICollection crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize
+ , PdfSigner.CryptoStandard sigtype, SignaturePolicyInfo signaturePolicy) {
+ SignDetached(externalDigest, externalSignature, chain, crlList, ocspClient, tsaClient, estimatedSize, sigtype
+ , signaturePolicy.ToSignaturePolicyIdentifier());
}
/// Signs the document using the detached mode, CMS or CAdES equivalent.
@@ -595,8 +641,8 @@ public virtual void SignDetached(IExternalSignature externalSignature, IX509Cert
public virtual void SignDetached(IExternalSignature externalSignature, IX509Certificate[] chain, ICollection
crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, PdfSigner.CryptoStandard
sigtype, SignaturePolicyInfo signaturePolicy) {
- SignDetached(externalSignature, chain, crlList, ocspClient, tsaClient, estimatedSize, sigtype, signaturePolicy
- .ToSignaturePolicyIdentifier());
+ SignDetached(new BouncyCastleDigest(), externalSignature, chain, crlList, ocspClient, tsaClient, estimatedSize
+ , sigtype, signaturePolicy);
}
/// Signs the document using the detached mode, CMS or CAdES equivalent.
@@ -617,6 +663,29 @@ public virtual void SignDetached(IExternalSignature externalSignature, IX509Cert
public virtual void SignDetached(IExternalSignature externalSignature, IX509Certificate[] chain, ICollection
crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, PdfSigner.CryptoStandard
sigtype, ISignaturePolicyIdentifier signaturePolicy) {
+ SignDetached(new BouncyCastleDigest(), externalSignature, chain, crlList, ocspClient, tsaClient, estimatedSize
+ , sigtype, signaturePolicy);
+ }
+
+ /// Signs the document using the detached mode, CMS or CAdES equivalent.
+ ///
+ /// Signs the document using the detached mode, CMS or CAdES equivalent.
+ ///
+ /// NOTE: This method closes the underlying pdf document. This means, that current instance
+ /// of PdfSigner cannot be used after this method call.
+ ///
+ /// the interface providing the actual signing
+ /// the certificate chain
+ /// the CRL list
+ /// the OCSP client
+ /// the Timestamp client
+ /// an implementation that provides the digest
+ /// the reserved size for the signature. It will be estimated if 0
+ /// Either Signature.CMS or Signature.CADES
+ /// the signature policy (for EPES signatures)
+ public virtual void SignDetached(IExternalDigest externalDigest, IExternalSignature externalSignature, IX509Certificate
+ [] chain, ICollection crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize
+ , PdfSigner.CryptoStandard sigtype, ISignaturePolicyIdentifier signaturePolicy) {
if (closed) {
throw new PdfException(SignExceptionMessageConstant.THIS_INSTANCE_OF_PDF_SIGNER_ALREADY_CLOSED);
}
@@ -672,12 +741,12 @@ public virtual void SignDetached(IExternalSignature externalSignature, IX509Cert
IDictionary exc = new Dictionary();
exc.Put(PdfName.Contents, estimatedSize * 2 + 2);
PreClose(exc);
- PdfPKCS7 sgn = new PdfPKCS7((IPrivateKey)null, chain, hashAlgorithm, false);
+ PdfPKCS7 sgn = new PdfPKCS7((IPrivateKey)null, chain, hashAlgorithm, externalDigest, false);
if (signaturePolicy != null) {
sgn.SetSignaturePolicy(signaturePolicy);
}
Stream data = GetRangeStream();
- byte[] hash = DigestAlgorithms.Digest(data, SignUtils.GetMessageDigest(hashAlgorithm));
+ byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm, externalDigest);
IList ocspList = new List();
if (chain.Length > 1 && ocspClient != null) {
for (int j = 0; j < chain.Length - 1; ++j) {
@@ -768,7 +837,7 @@ public virtual void Timestamp(ITSAClient tsa, String signatureName) {
exc.Put(PdfName.Contents, contentEstimated * 2 + 2);
PreClose(exc);
Stream data = GetRangeStream();
- IDigest messageDigest = tsa.GetMessageDigest();
+ IMessageDigest messageDigest = tsa.GetMessageDigest();
byte[] buf = new byte[4096];
int n;
while ((n = data.Read(buf)) > 0) {
diff --git a/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs b/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs
index 0ed0fee311..5861774d90 100644
--- a/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs
+++ b/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs
@@ -1,30 +1,28 @@
/*
- 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;
+This file is part of the iText (R) project.
+Copyright (c) 1998-2024 Apryse Group NV
+Authors: Apryse Software.
+
+This program is offered under a commercial and under the AGPL license.
+For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
+
+AGPL licensing:
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+using System;
using System.Collections.Generic;
using System.IO;
-using iText.Commons.Bouncycastle.Cert;
-using iText.Commons.Bouncycastle.Crypto;
using iText.Kernel.Exceptions;
using iText.Kernel.Pdf;
using iText.Signatures.Cms;
@@ -36,6 +34,8 @@ public class PdfTwoPhaseSigner {
private readonly Stream outputStream;
+ private IExternalDigest externalDigest;
+
private StampingProperties stampingProperties = new StampingProperties().UseAppendMode();
private bool closed;
@@ -62,10 +62,38 @@ public PdfTwoPhaseSigner(PdfReader reader, Stream outputStream) {
/// the message digest of the prepared document.
public virtual byte[] PrepareDocumentForSignature(SignerProperties signerProperties, String digestAlgorithm
, PdfName filter, PdfName subFilter, int estimatedSize, bool includeDate) {
- IDigest digest;
- digest = SignUtils.GetMessageDigest(digestAlgorithm);
- return PrepareDocumentForSignature(signerProperties, digest, filter, subFilter, estimatedSize, includeDate
- );
+ if (closed) {
+ throw new PdfException(SignExceptionMessageConstant.THIS_INSTANCE_OF_PDF_SIGNER_ALREADY_CLOSED);
+ }
+ PdfSigner pdfSigner = CreatePdfSigner(signerProperties);
+ PdfDocument document = pdfSigner.GetDocument();
+ if (document.GetPdfVersion().CompareTo(PdfVersion.PDF_2_0) < 0) {
+ document.GetCatalog().AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL2);
+ }
+ document.GetCatalog().AddDeveloperExtension(PdfDeveloperExtension.ISO_32002);
+ document.GetCatalog().AddDeveloperExtension(PdfDeveloperExtension.ISO_32001);
+ PdfSignature cryptoDictionary = pdfSigner.CreateSignatureDictionary(includeDate);
+ cryptoDictionary.Put(PdfName.Filter, filter);
+ cryptoDictionary.Put(PdfName.SubFilter, subFilter);
+ pdfSigner.cryptoDictionary = cryptoDictionary;
+ IDictionary exc = new Dictionary();
+ exc.Put(PdfName.Contents, estimatedSize * 2 + 2);
+ pdfSigner.PreClose(exc);
+ Stream data = pdfSigner.GetRangeStream();
+ byte[] digest;
+ if (externalDigest != null) {
+ digest = DigestAlgorithms.Digest(data, digestAlgorithm, externalDigest);
+ }
+ else {
+ digest = DigestAlgorithms.Digest(data, SignUtils.GetMessageDigest(digestAlgorithm));
+ }
+ byte[] paddedSig = new byte[estimatedSize];
+ PdfDictionary dic2 = new PdfDictionary();
+ dic2.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true));
+ pdfSigner.Close(dic2);
+ pdfSigner.closed = true;
+ closed = true;
+ return digest;
}
/// Adds an existing signature to a PDF where space was already reserved.
@@ -90,6 +118,17 @@ public static void AddSignatureToPreparedDocument(PdfDocument document, String f
applier.Apply((a) => signedContent);
}
+ /// Use the external digest to inject specific digest implementations
+ /// the IExternalDigest instance to use to generate Digests
+ ///
+ /// same instance of
+ ///
+ ///
+ public virtual iText.Signatures.PdfTwoPhaseSigner SetExternalDigest(IExternalDigest externalDigest) {
+ this.externalDigest = externalDigest;
+ return this;
+ }
+
/// Set stamping properties to be used during main signing operation.
///
/// Set stamping properties to be used during main signing operation.
@@ -112,53 +151,7 @@ public virtual iText.Signatures.PdfTwoPhaseSigner SetStampingProperties(Stamping
}
internal virtual PdfSigner CreatePdfSigner(SignerProperties signerProperties) {
- PdfSigner signer = new PdfSigner(reader, outputStream, null, stampingProperties);
- signer.SetFieldLockDict(signerProperties.GetFieldLockDict());
- signer.SetFieldName(signerProperties.GetFieldName());
- // We need to update field name because signer could change it
- signerProperties.SetFieldName(signer.GetFieldName());
- signer.SetCertificationLevel(signerProperties.GetCertificationLevel());
- signer.SetPageRect(signerProperties.GetPageRect());
- signer.SetPageNumber(signerProperties.GetPageNumber());
- signer.SetSignDate(signerProperties.GetSignDate());
- signer.SetSignatureCreator(signerProperties.GetSignatureCreator());
- signer.SetContact(signerProperties.GetContact());
- signer.SetReason(signerProperties.GetReason());
- signer.SetLocation(signerProperties.GetLocation());
- signer.SetSignatureAppearance(signerProperties.GetSignatureAppearance());
- return signer;
- }
-
- private byte[] PrepareDocumentForSignature(SignerProperties signerProperties, IDigest messageDigest, PdfName
- filter, PdfName subFilter, int estimatedSize, bool includeDate) {
- if (closed) {
- throw new PdfException(SignExceptionMessageConstant.THIS_INSTANCE_OF_PDF_SIGNER_ALREADY_CLOSED);
- }
- PdfSigner pdfSigner = CreatePdfSigner(signerProperties);
-
- PdfDocument document = pdfSigner.GetDocument();
- if (document.GetPdfVersion().CompareTo(PdfVersion.PDF_2_0) < 0) {
- document.GetCatalog().AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL2);
- }
- document.GetCatalog().AddDeveloperExtension(PdfDeveloperExtension.ISO_32002);
- document.GetCatalog().AddDeveloperExtension(PdfDeveloperExtension.ISO_32001);
-
- PdfSignature cryptoDictionary = pdfSigner.CreateSignatureDictionary(includeDate);
- cryptoDictionary.Put(PdfName.Filter, filter);
- cryptoDictionary.Put(PdfName.SubFilter, subFilter);
- pdfSigner.cryptoDictionary = cryptoDictionary;
- IDictionary exc = new Dictionary();
- exc.Put(PdfName.Contents, estimatedSize * 2 + 2);
- pdfSigner.PreClose(exc);
- Stream data = pdfSigner.GetRangeStream();
- byte[] digest = DigestAlgorithms.Digest(data, messageDigest);
- byte[] paddedSig = new byte[estimatedSize];
- PdfDictionary dic2 = new PdfDictionary();
- dic2.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true));
- pdfSigner.Close(dic2);
- pdfSigner.closed = true;
- closed = true;
- return digest;
+ return new PdfSigner(reader, outputStream, null, stampingProperties, signerProperties);
}
}
-}
\ No newline at end of file
+}
diff --git a/itext/itext.sign/itext/signatures/SignUtils.cs b/itext/itext.sign/itext/signatures/SignUtils.cs
index 6ec496806f..90ff2ec818 100644
--- a/itext/itext.sign/itext/signatures/SignUtils.cs
+++ b/itext/itext.sign/itext/signatures/SignUtils.cs
@@ -37,6 +37,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Crypto;
using iText.Commons.Bouncycastle.Math;
using iText.Commons.Bouncycastle.Tsp;
+using iText.Commons.Digest;
using iText.Kernel.Exceptions;
using iText.Kernel.Pdf;
using iText.Signatures.Exceptions;
@@ -84,7 +85,11 @@ internal static byte[] GetExtensionValueByOid(IX509Crl crl, String oid) {
}
internal static IDigest GetMessageDigest(String hashAlgorithm) {
- return FACTORY.CreateIDigest(hashAlgorithm);
+ return (IDigest)new BouncyCastleDigest().GetMessageDigest(hashAlgorithm);
+ }
+
+ internal static IMessageDigest GetMessageDigest(String hashAlgorithm, IExternalDigest externalDigest) {
+ return externalDigest.GetMessageDigest(hashAlgorithm);
}
internal static Stream GetHttpResponse(Uri urlt) {
diff --git a/itext/itext.sign/itext/signatures/cms/SignerInfo.cs b/itext/itext.sign/itext/signatures/cms/SignerInfo.cs
index 7271bdbb95..898e290cad 100644
--- a/itext/itext.sign/itext/signatures/cms/SignerInfo.cs
+++ b/itext/itext.sign/itext/signatures/cms/SignerInfo.cs
@@ -29,7 +29,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Commons.Bouncycastle.Asn1.Ocsp;
using iText.Commons.Bouncycastle.Asn1.X509;
using iText.Commons.Bouncycastle.Cert;
-using iText.Commons.Bouncycastle.Crypto;
+using iText.Commons.Digest;
using iText.Commons.Utils;
using iText.Kernel.Exceptions;
using iText.Signatures;
@@ -202,7 +202,7 @@ public virtual void AddSignerCertificateToSignedAttributes(IX509Certificate cert
if (signedAttributesReadOnly) {
throw new InvalidOperationException(SignExceptionMessageConstant.CMS_SIGNERINFO_READONLY);
}
- IDigest md = DigestAlgorithms.GetMessageDigestFromOid(digestAlgorithmOid);
+ IMessageDigest md = DigestAlgorithms.GetMessageDigestFromOid(digestAlgorithmOid);
IAsn1EncodableVector certContents = BC_FACTORY.CreateASN1EncodableVector();
// don't add if it is the default value
if (!SecurityIDs.ID_SHA256.Equals(digestAlgorithmOid)) {
diff --git a/port-hash b/port-hash
index 1a36faf6e3..37a74860c4 100644
--- a/port-hash
+++ b/port-hash
@@ -1 +1 @@
-abe3f098b9d6dedcab048715f32f1de25b60e65c
+6c148671399e3139a12b53b220048d1742ee2655