diff --git a/src/iTextSharp.LGPLv2.Core/System/Encodings/EncodingsRegistry.cs b/src/iTextSharp.LGPLv2.Core/System/Encodings/EncodingsRegistry.cs index 6b47028..b4174a9 100644 --- a/src/iTextSharp.LGPLv2.Core/System/Encodings/EncodingsRegistry.cs +++ b/src/iTextSharp.LGPLv2.Core/System/Encodings/EncodingsRegistry.cs @@ -17,7 +17,9 @@ public sealed class EncodingsRegistry private EncodingsRegistry() { +#if !NET40 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); +#endif } /// diff --git a/src/iTextSharp.LGPLv2.Core/System/NetUtils/WebUtils.cs b/src/iTextSharp.LGPLv2.Core/System/NetUtils/WebUtils.cs index c1184bc..0e0d86f 100644 --- a/src/iTextSharp.LGPLv2.Core/System/NetUtils/WebUtils.cs +++ b/src/iTextSharp.LGPLv2.Core/System/NetUtils/WebUtils.cs @@ -15,7 +15,11 @@ public static Stream GetResponseStream(this Uri url) return new FileStream(url.LocalPath, FileMode.Open, FileAccess.Read, FileShare.Read); } var w = WebRequest.Create(url); - return w.GetResponseAsync().Result.GetResponseStream(); +#if NET40 + return w.GetResponse().GetResponseStream(); +#else + return w.GetResponseAsync().GetAwaiter().GetResult().GetResponseStream(); +#endif } public static Stream GetResponseStream(this string url) diff --git a/src/iTextSharp.LGPLv2.Core/_1-dotnet_pack.bat b/src/iTextSharp.LGPLv2.Core/_1-dotnet_pack.bat index 6cc1f55..b0c7ce2 100644 --- a/src/iTextSharp.LGPLv2.Core/_1-dotnet_pack.bat +++ b/src/iTextSharp.LGPLv2.Core/_1-dotnet_pack.bat @@ -1,2 +1,2 @@ dotnet pack -c release -paue \ No newline at end of file +pause \ No newline at end of file diff --git a/src/iTextSharp.LGPLv2.Core/_2-dotnet_build.bat b/src/iTextSharp.LGPLv2.Core/_2-dotnet_build.bat new file mode 100644 index 0000000..b4b0e75 --- /dev/null +++ b/src/iTextSharp.LGPLv2.Core/_2-dotnet_build.bat @@ -0,0 +1,2 @@ +dotnet build +pause \ No newline at end of file diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp.LGPLv2.Core.csproj b/src/iTextSharp.LGPLv2.Core/iTextSharp.LGPLv2.Core.csproj index ecc53ab..215c82c 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp.LGPLv2.Core.csproj +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp.LGPLv2.Core.csproj @@ -1,10 +1,10 @@  iTextSharp.LGPLv2.Core is an unofficial port of the last LGPL version of the iTextSharp (V4.1.6) to .NET Core. - 1.3.4 + 1.4.0 latest Vahid Nasiri - netstandard1.3;netstandard2.0 + net40;netstandard1.3;netstandard2.0 $(NoWarn);1591 true iTextSharp.LGPLv2.Core @@ -56,4 +56,10 @@ NETSTANDARD2_0 + + + + + NET40 + diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/Document.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/Document.cs index f20ac8b..d031acd 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/Document.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/Document.cs @@ -129,11 +129,17 @@ public Document(Rectangle pageSize, float marginLeft, float marginRight, float m /// public static string Product { get; } = "iTextSharp.LGPLv2.Core"; +#if NET40 + /// + /// Gets the release number. + /// + public static string Release { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); +#else /// /// Gets the release number. /// public static string Release { get; } = typeof(Document).GetTypeInfo().Assembly.GetName().Version.ToString(); - +#endif /// /// Returns the lower left y-coordinate. /// diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/BaseFont.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/BaseFont.cs index 6dd1968..cf53e1e 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/BaseFont.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/BaseFont.cs @@ -5,7 +5,9 @@ using System.Collections; using System.util; using iTextSharp.text.xml.simpleparser; +#if !NET40 using System.Runtime.Loader; +#endif namespace iTextSharp.text.pdf { @@ -1114,7 +1116,11 @@ public static Stream GetResourceStream(string key) // Try to use resource loader to load the properties file. try { +#if NET40 + var assm = Assembly.GetExecutingAssembly(); +#else var assm = typeof(BaseFont).GetTypeInfo().Assembly; +#endif istr = assm.GetManifestResourceStream(key); } catch @@ -1138,7 +1144,11 @@ public static Stream GetResourceStream(string key) string dir = (string)obj; try { +#if NET40 + var asm = Assembly.LoadFrom(dir); +#else var asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(dir); +#endif istr = asm.GetManifestResourceStream(key); } catch diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/OcspClientBouncyCastle.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/OcspClientBouncyCastle.cs index e612173..87f180c 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/OcspClientBouncyCastle.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/OcspClientBouncyCastle.cs @@ -58,16 +58,30 @@ public byte[] GetEncoded() con.ContentType = "application/ocsp-request"; con.Accept = "application/ocsp-response"; con.Method = "POST"; +#if NET40 + Stream outp = con.GetRequestStream(); +#else Stream outp = con.GetRequestStreamAsync().Result; +#endif outp.Write(array, 0, array.Length); outp.Dispose(); - HttpWebResponse response = (HttpWebResponse)con.GetResponseAsync().Result; + +#if NET40 + HttpWebResponse response = (HttpWebResponse)con.GetResponse(); +#else + HttpWebResponse response = (HttpWebResponse)con.GetResponseAsync().GetAwaiter().GetResult(); +#endif + if (response.StatusCode != HttpStatusCode.OK) throw new IOException($"Invalid HTTP response: {(int)response.StatusCode}"); Stream inp = response.GetResponseStream(); OcspResp ocspResponse = new OcspResp(inp); inp.Dispose(); +#if NET40 + response.Close(); +#else response.Dispose(); +#endif if (ocspResponse.Status != 0) throw new IOException("Invalid status: " + ocspResponse.Status); diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfEncryption.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfEncryption.cs index 2e521a6..d245d56 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfEncryption.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfEncryption.cs @@ -258,6 +258,21 @@ public PdfDictionary GetEncryptionDictionary() } } +#if NET40 + SHA1 sh = new SHA1CryptoServiceProvider(); + byte[] encodedRecipient = null; + byte[] seed = PublicKeyHandler.GetSeed(); + sh.TransformBlock(seed, 0, seed.Length, seed, 0); + for (int i = 0; i < PublicKeyHandler.GetRecipientsSize(); i++) + { + encodedRecipient = PublicKeyHandler.GetEncodedRecipient(i); + sh.TransformBlock(encodedRecipient, 0, encodedRecipient.Length, encodedRecipient, 0); + } + if (!_encryptMetadata) + sh.TransformBlock(MetadataPad, 0, MetadataPad.Length, MetadataPad, 0); + sh.TransformFinalBlock(seed, 0, 0); + byte[] mdResult = sh.Hash; +#else byte[] mdResult; using (var sh = IncrementalHash.CreateHash(HashAlgorithmName.SHA1)) { @@ -273,6 +288,7 @@ public PdfDictionary GetEncryptionDictionary() mdResult = sh.GetHashAndReset(); } +#endif SetupByEncryptionKey(mdResult, _keyLength); } @@ -377,8 +393,27 @@ public void SetCryptoMode(int mode, int kl) throw new ArgumentException("No valid encryption mode"); } } + public void SetHashKey(int number, int generation) { +#if NET40 + using (var md5 = new MD5CryptoServiceProvider()) + { + md5.Initialize(); + Extra[0] = (byte)number; + Extra[1] = (byte)(number >> 8); + Extra[2] = (byte)(number >> 16); + Extra[3] = (byte)generation; + Extra[4] = (byte)(generation >> 8); + md5.TransformBlock(Mkey, 0, Mkey.Length, Mkey, 0); + md5.TransformBlock(Extra, 0, Extra.Length, Extra, 0); + if (_revision == AES_128) + md5.TransformBlock(_salt, 0, _salt.Length, _salt, 0); + + md5.TransformFinalBlock(Extra, 0, 0); + Key = md5.Hash; + } +#else using (var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5)) { Extra[0] = (byte)number; @@ -393,6 +428,7 @@ public void SetHashKey(int number, int generation) Key = md5.GetHashAndReset(); } +#endif KeySize = Mkey.Length + 5; if (KeySize > 16) @@ -509,7 +545,31 @@ private void setupGlobalEncryptionKey(byte[] documentId, byte[] userPad, byte[] Permissions = permissions; // use variable keylength Mkey = new byte[_keyLength / 8]; + byte[] digest = new byte[Mkey.Length]; +#if NET40 + //fixed by ujihara in order to follow PDF refrence + using (var md5 = new MD5CryptoServiceProvider()) + { + md5.Initialize(); + md5.TransformBlock(userPad, 0, userPad.Length, userPad, 0); + md5.TransformBlock(ownerKey, 0, ownerKey.Length, ownerKey, 0); + + byte[] ext = new byte[4]; + ext[0] = (byte)permissions; + ext[1] = (byte)(permissions >> 8); + ext[2] = (byte)(permissions >> 16); + ext[3] = (byte)(permissions >> 24); + md5.TransformBlock(ext, 0, 4, ext, 0); + if (documentId != null) + md5.TransformBlock(documentId, 0, documentId.Length, documentId, 0); + if (!_encryptMetadata) + md5.TransformBlock(MetadataPad, 0, MetadataPad.Length, MetadataPad, 0); + md5.TransformFinalBlock(ext, 0, 0); + + Array.Copy(md5.Hash, 0, digest, 0, Mkey.Length); + } +#else //fixed by ujihara in order to follow PDF refrence var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5); md5.AppendData(userPad, 0, userPad.Length); @@ -526,9 +586,8 @@ private void setupGlobalEncryptionKey(byte[] documentId, byte[] userPad, byte[] if (!_encryptMetadata) md5.AppendData(MetadataPad, 0, MetadataPad.Length); - byte[] digest = new byte[Mkey.Length]; Array.Copy(md5.GetHashAndReset(), 0, digest, 0, Mkey.Length); - +#endif // only use the really needed bits as input for the hash @@ -556,13 +615,22 @@ private void setupUserKey() if (_revision == STANDARD_ENCRYPTION_128 || _revision == AES_128) { byte[] digest; +#if NET40 + using (var md5 = new MD5CryptoServiceProvider()) + { + md5.Initialize(); + md5.TransformBlock(_pad, 0, _pad.Length, _pad, 0); + md5.TransformFinalBlock(DocumentId, 0, DocumentId.Length); + digest = md5.Hash; + } +#else using (var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5)) { md5.AppendData(_pad, 0, _pad.Length); md5.AppendData(DocumentId, 0, DocumentId.Length); digest = md5.GetHashAndReset(); } - +#endif Array.Copy(digest, 0, UserKey, 0, 16); for (int k = 16; k < 32; ++k) UserKey[k] = 0; diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfReader.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfReader.cs index 6a9d412..16a5a9f 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfReader.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfReader.cs @@ -3044,7 +3044,7 @@ protected internal void RebuildXref() int top = 0; trailer = null; byte[] line = new byte[64]; - for (;;) + for (; ; ) { int pos = Tokens.FilePointer; if (!Tokens.ReadLineSegment(line)) @@ -3502,7 +3502,22 @@ private void readDecryptedDocObj() throw new UnsupportedPdfException("Bad certificate and key."); } +#if NET40 + using (var sh = new SHA1CryptoServiceProvider()) + { + sh.TransformBlock(envelopedData, 0, 20, envelopedData, 0); + for (int i = 0; i < recipients.Size; i++) + { + byte[] encodedRecipient = recipients[i].GetBytes(); + sh.TransformBlock(encodedRecipient, 0, encodedRecipient.Length, encodedRecipient, 0); + } + if ((cryptoMode & PdfWriter.DO_NOT_ENCRYPT_METADATA) != 0) + sh.TransformBlock(PdfEncryption.MetadataPad, 0, PdfEncryption.MetadataPad.Length, PdfEncryption.MetadataPad, 0); + sh.TransformFinalBlock(envelopedData, 0, 0); + encryptionKey = sh.Hash; + } +#else using (var sh = IncrementalHash.CreateHash(HashAlgorithmName.SHA1)) { sh.AppendData(envelopedData, 0, 20); @@ -3516,6 +3531,7 @@ private void readDecryptedDocObj() encryptionKey = sh.GetHashAndReset(); } +#endif } decrypt = new PdfEncryption(); decrypt.SetCryptoMode(cryptoMode, lengthValue); diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/TSAClientBouncyCastle.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/TSAClientBouncyCastle.cs index b2a1902..8498353 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/TSAClientBouncyCastle.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/TSAClientBouncyCastle.cs @@ -160,10 +160,20 @@ protected internal virtual byte[] GetTsaResponse(byte[] requestBytes) authInfo = Convert.ToBase64String(Encoding.UTF8.GetBytes(authInfo)); con.Headers["Authorization"] = "Basic " + authInfo; } + +#if NET40 + Stream outp = con.GetRequestStream(); +#else Stream outp = con.GetRequestStreamAsync().Result; +#endif outp.Write(requestBytes, 0, requestBytes.Length); outp.Dispose(); - HttpWebResponse response = (HttpWebResponse)con.GetResponseAsync().Result; + +#if NET40 + HttpWebResponse response = (HttpWebResponse)con.GetResponse(); +#else + HttpWebResponse response = (HttpWebResponse)con.GetResponseAsync().GetAwaiter().GetResult(); +#endif if (response.StatusCode != HttpStatusCode.OK) throw new IOException("Invalid HTTP response: " + (int)response.StatusCode); Stream inp = response.GetResponseStream(); @@ -177,7 +187,12 @@ protected internal virtual byte[] GetTsaResponse(byte[] requestBytes) baos.Write(buffer, 0, bytesRead); } inp.Dispose(); +#if NET40 + response.Close(); +#else response.Dispose(); +#endif + byte[] respBytes = baos.ToArray(); if (encoding != null && Util.EqualsIgnoreCase(encoding, "base64")) diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/XfaForm.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/XfaForm.cs index e56ac72..26b3b43 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/XfaForm.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/XfaForm.cs @@ -170,7 +170,11 @@ public static byte[] SerializeDoc(XmlNode n) }; var xw = XmlWriter.Create(fout, xwSettings); n.WriteContentTo(xw); +#if NET40 + xw.Close(); +#else xw.Dispose(); +#endif return fout.ToArray(); } diff --git a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/xml/ParserBase.cs b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/xml/ParserBase.cs index d11f66f..909489f 100644 --- a/src/iTextSharp.LGPLv2.Core/iTextSharp/text/xml/ParserBase.cs +++ b/src/iTextSharp.LGPLv2.Core/iTextSharp/text/xml/ParserBase.cs @@ -86,7 +86,11 @@ public void Parse(XmlReader reader) { if (reader != null) { +#if NET40 + reader.Close(); +#else reader.Dispose(); +#endif } } }