From 88875196c82b11ef22383bacb41adb8e278dfdec Mon Sep 17 00:00:00 2001 From: Angelina Pavlovets Date: Thu, 29 Aug 2024 22:08:02 +0000 Subject: [PATCH] Use IMessageDigest instead of IDigest in .NET DEVSIX-8106 Autoported commit. Original commit hash: [a3c9c9d68] Manual files: sharpenConfiguration.xml --- .../signatures/testutils/SignTestPortUtil.cs | 2 +- .../testutils/client/TestTsaClient.cs | 4 +- .../commons/bouncycastle/crypto/IDigest.cs | 60 ----------------- .../crypto/securityhandler/SecurityHandler.cs | 35 ++++++---- .../itext/signatures/DigestAlgorithms.cs | 26 ++------ .../itext.sign/itext/signatures/ITSAClient.cs | 8 +-- .../itext.sign/itext/signatures/PdfSigner.cs | 2 +- .../itext/signatures/PdfTwoPhaseSigner.cs | 64 +++++++++++-------- .../itext.sign/itext/signatures/SignUtils.cs | 4 +- .../itext/signatures/TSAClientBouncyCastle.cs | 4 +- port-hash | 2 +- 11 files changed, 78 insertions(+), 133 deletions(-) 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 41b2c45dff..542a58424e 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/testutils/SignTestPortUtil.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/testutils/SignTestPortUtil.cs @@ -57,7 +57,7 @@ public static IOcspRequest GenerateOcspRequestWithNonce(ICertID id) { return gen.Build(); } - public static IDigest GetMessageDigest(String hashAlgorithm) { + public static IMessageDigest GetMessageDigest(String hashAlgorithm) { return FACTORY.CreateIDigest(hashAlgorithm); } 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 7d21547297..9a51942f6a 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 @@ -54,8 +54,8 @@ public virtual int GetTokenSizeEstimate() { return 4096; } - public virtual IDigest GetMessageDigest() { - return (IDigest)SignTestPortUtil.GetMessageDigest(DIGEST_ALG); + public virtual IMessageDigest GetMessageDigest() { + return SignTestPortUtil.GetMessageDigest(DIGEST_ALG); } public virtual byte[] GetTimeStampToken(byte[] imprint) { diff --git a/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs b/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs index 16eeff2629..2bdb63bac6 100644 --- a/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs +++ b/itext/itext.commons/itext/commons/bouncycastle/crypto/IDigest.cs @@ -29,65 +29,5 @@ namespace iText.Commons.Bouncycastle.Crypto { /// to switch between bouncy-castle and bouncy-castle FIPS implementations. /// public interface IDigest : IMessageDigest { - /// - /// Calls actual - /// Digest - /// method for the wrapped IDigest object. - /// - /// byte array - /// - /// byte array. - /// - byte[] Digest(byte[] enc2); - - /// - /// Calls actual - /// Digest - /// method for the wrapped IDigest object. - /// Leaves the digest reset. - /// - /// - /// byte array. - /// - byte[] Digest(); - - /// - /// Gets byte length of wrapped digest algorithm. - /// - /// digest length - int GetDigestLength(); - - /// - /// Calls actual - /// Update - /// method for the wrapped IDigest object. - /// - /// byte array buffer - /// offset - /// buffer length - void Update(byte[] buf, int off, int len); - - /// - /// Calls actual - /// Update - /// method for the wrapped IDigest object. - /// - /// byte array buffer - void Update(byte[] buf); - - /// - /// Calls actual - /// Reset - /// method for the wrapped IDigest object. - /// - void Reset(); - - /// - /// Gets actual - /// AlgorithmName - /// for the wrapped IDigest object. - /// - /// algorithm name. - string GetAlgorithmName(); } } diff --git a/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs b/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs index 722e5e09cb..a8c7b91695 100644 --- a/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs +++ b/itext/itext.kernel/itext/kernel/crypto/securityhandler/SecurityHandler.cs @@ -26,8 +26,9 @@ You should have received a copy of the GNU Affero General Public License using iText.Bouncycastleconnector; using iText.Commons; using iText.Commons.Bouncycastle; -using iText.Commons.Bouncycastle.Crypto; +using iText.Commons.Digest; using iText.Commons.Utils; +using iText.Kernel.Crypto; using iText.Kernel.Exceptions; using iText.Kernel.Logs; @@ -60,7 +61,7 @@ public abstract class SecurityHandler { /// protected internal int nextObjectKeySize; - protected internal IDigest md5; + protected internal IMessageDigest md5; /// Work area to prepare the object/generation bytes protected internal byte[] extra = new byte[5]; @@ -92,23 +93,35 @@ public virtual void SetHashKeyForNextObject(int objNumber, int objGeneration) { } } + /// Gets a stream wrapper, responsible for encryption. + /// + /// + /// + /// to be wrapped + /// + /// + /// + /// + /// , responsible for encryption. + /// public abstract OutputStreamEncryption GetEncryptionStream(Stream os); + /// Gets decryptor object. + /// + /// + /// + /// public abstract IDecryptor GetDecryptor(); - - /// - /// Gets encryption key for a particular object/generation. - /// + + /// Gets encryption key for a particular object/generation. /// encryption key for a particular object/generation. - public byte[] GetNextObjectKey() { + public virtual byte[] GetNextObjectKey() { return JavaUtil.ArraysCopyOf(nextObjectKey, nextObjectKey.Length); } - /// - /// Gets global encryption key. - /// + /// Gets global encryption key. /// global encryption key. - public byte[] GetMkey() { + public virtual byte[] GetMkey() { return JavaUtil.ArraysCopyOf(mkey, mkey.Length); } diff --git a/itext/itext.sign/itext/signatures/DigestAlgorithms.cs b/itext/itext.sign/itext/signatures/DigestAlgorithms.cs index 7316c1f7ee..dd0f147cd9 100644 --- a/itext/itext.sign/itext/signatures/DigestAlgorithms.cs +++ b/itext/itext.sign/itext/signatures/DigestAlgorithms.cs @@ -27,7 +27,6 @@ You should have received a copy of the GNU Affero General Public License using iText.Bouncycastleconnector; using iText.Commons; using iText.Commons.Bouncycastle; -using iText.Commons.Bouncycastle.Crypto; using iText.Commons.Digest; using iText.Signatures.Exceptions; using iText.Signatures.Logs; @@ -190,15 +189,15 @@ static DigestAlgorithms() { /// Get a digest algorithm. /// oid of the digest algorithm /// MessageDigest object - public static IDigest GetMessageDigestFromOid(String digestOid) { + public static IMessageDigest GetMessageDigestFromOid(String digestOid) { return GetMessageDigest(GetDigest(digestOid)); } /// Creates a MessageDigest object that can be used to create a hash. /// the algorithm you want to use to create a hash /// a MessageDigest object - public static IDigest GetMessageDigest(String hashAlgorithm) { - return (IDigest)SignUtils.GetMessageDigest(hashAlgorithm); + public static IMessageDigest GetMessageDigest(String hashAlgorithm) { + return SignUtils.GetMessageDigest(hashAlgorithm); } /// Creates a hash using a specific digest algorithm and a provider. @@ -206,7 +205,7 @@ public static IDigest GetMessageDigest(String hashAlgorithm) { /// the algorithm used to create the hash /// the hash public static byte[] Digest(Stream data, String hashAlgorithm) { - IDigest messageDigest = GetMessageDigest(hashAlgorithm); + IMessageDigest messageDigest = GetMessageDigest(hashAlgorithm); return Digest(data, messageDigest); } @@ -214,7 +213,7 @@ public static byte[] Digest(Stream data, String hashAlgorithm) { /// data to be digested /// algorithm to be used /// digest of the data - public static byte[] Digest(Stream data, IDigest messageDigest) { + public static byte[] Digest(Stream data, IMessageDigest messageDigest) { byte[] buf = new byte[8192]; int n; while ((n = data.Read(buf)) > 0) { @@ -223,21 +222,6 @@ 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/ITSAClient.cs b/itext/itext.sign/itext/signatures/ITSAClient.cs index 017a9eff5e..512e125cd0 100644 --- a/itext/itext.sign/itext/signatures/ITSAClient.cs +++ b/itext/itext.sign/itext/signatures/ITSAClient.cs @@ -20,7 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -using iText.Commons.Bouncycastle.Crypto; +using iText.Commons.Digest; namespace iText.Signatures { /// Time Stamp Authority client (caller) interface. @@ -47,15 +47,15 @@ public interface ITSAClient { /// /// Returns the - /// + /// /// to digest the data imprint /// /// /// The - /// + /// /// object. /// - IDigest GetMessageDigest(); + IMessageDigest GetMessageDigest(); /// Returns RFC 3161 timeStampToken. /// byte[] - data imprint to be time-stamped diff --git a/itext/itext.sign/itext/signatures/PdfSigner.cs b/itext/itext.sign/itext/signatures/PdfSigner.cs index aa5891f530..4fd1a115d3 100644 --- a/itext/itext.sign/itext/signatures/PdfSigner.cs +++ b/itext/itext.sign/itext/signatures/PdfSigner.cs @@ -531,7 +531,7 @@ public virtual void SignDetached(IExternalDigest externalDigest, IExternalSignat sgn.SetSignaturePolicy(signaturePolicy); } Stream data = GetRangeStream(); - byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm, externalDigest); + byte[] hash = DigestAlgorithms.Digest(data, SignUtils.GetMessageDigest(hashAlgorithm, externalDigest)); IList ocspList = new List(); if (chain.Length > 1 && ocspClient != null) { for (int j = 0; j < chain.Length - 1; ++j) { diff --git a/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs b/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs index 0e160ecbd2..fede49e263 100644 --- a/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs +++ b/itext/itext.sign/itext/signatures/PdfTwoPhaseSigner.cs @@ -23,6 +23,7 @@ You should have received a copy of the GNU Affero General Public License using System; using System.Collections.Generic; using System.IO; +using iText.Commons.Digest; using iText.Kernel.Exceptions; using iText.Kernel.Pdf; using iText.Signatures.Cms; @@ -92,38 +93,15 @@ 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) { - 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; + IMessageDigest digest; if (externalDigest != null) { - digest = DigestAlgorithms.Digest(data, digestAlgorithm, externalDigest); + digest = externalDigest.GetMessageDigest(digestAlgorithm); } else { - digest = DigestAlgorithms.Digest(data, SignUtils.GetMessageDigest(digestAlgorithm)); + digest = 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; + return PrepareDocumentForSignature(signerProperties, digest, filter, subFilter, estimatedSize, includeDate + ); } /// Adds an existing signature to a PDF where space was already reserved. @@ -185,5 +163,35 @@ internal virtual PdfSigner CreatePdfSigner(SignerProperties signerProperties) { return new PdfSigner(reader, outputStream, null, stampingProperties, signerProperties); } //\endcond + + private byte[] PrepareDocumentForSignature(SignerProperties signerProperties, IMessageDigest 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; + } } } diff --git a/itext/itext.sign/itext/signatures/SignUtils.cs b/itext/itext.sign/itext/signatures/SignUtils.cs index cb1f748294..c372ca2ad3 100644 --- a/itext/itext.sign/itext/signatures/SignUtils.cs +++ b/itext/itext.sign/itext/signatures/SignUtils.cs @@ -85,8 +85,8 @@ internal static byte[] GetExtensionValueByOid(IX509Crl crl, String oid) { return extensionValue.IsNull() ? null : extensionValue.GetDerEncoded(); } - internal static IDigest GetMessageDigest(String hashAlgorithm) { - return (IDigest)new BouncyCastleDigest().GetMessageDigest(hashAlgorithm); + internal static IMessageDigest GetMessageDigest(String hashAlgorithm) { + return new BouncyCastleDigest().GetMessageDigest(hashAlgorithm); } internal static IMessageDigest GetMessageDigest(String hashAlgorithm, IExternalDigest externalDigest) { diff --git a/itext/itext.sign/itext/signatures/TSAClientBouncyCastle.cs b/itext/itext.sign/itext/signatures/TSAClientBouncyCastle.cs index 708c55b93a..86d47cda92 100644 --- a/itext/itext.sign/itext/signatures/TSAClientBouncyCastle.cs +++ b/itext/itext.sign/itext/signatures/TSAClientBouncyCastle.cs @@ -27,9 +27,9 @@ You should have received a copy of the GNU Affero General Public License using iText.Commons; using iText.Commons.Bouncycastle; using iText.Commons.Bouncycastle.Asn1.Cmp; -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.Kernel.Exceptions; using iText.Signatures.Exceptions; @@ -152,7 +152,7 @@ public virtual void SetTSAReqPolicy(String tsaReqPolicy) { /// Gets the MessageDigest to digest the data imprint /// the digest algorithm name - public virtual IDigest GetMessageDigest() { + public virtual IMessageDigest GetMessageDigest() { return SignUtils.GetMessageDigest(digestAlgorithm); } diff --git a/port-hash b/port-hash index 0e7b1735f1..9787f8f1b3 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -b8f684a0dd103255900f1cf090e811e8c2444b11 +a3c9c9d6814bd576835e9bc229734bc43079a05d \ No newline at end of file