diff --git a/Signature/AddDigitalSignature/.editorconfig b/Signature/AddDigitalSignature/.editorconfig new file mode 100644 index 0000000..3126322 --- /dev/null +++ b/Signature/AddDigitalSignature/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# CS0618: Type or member is obsolete +dotnet_diagnostic.CS0618.severity = warning diff --git a/Signature/AddDigitalSignature/AddDigitalSignature.csproj b/Signature/AddDigitalSignature/AddDigitalSignature.csproj new file mode 100644 index 0000000..ba3dc1c --- /dev/null +++ b/Signature/AddDigitalSignature/AddDigitalSignature.csproj @@ -0,0 +1,105 @@ + + + + + Debug + AnyCPU + {2EAC8F00-1327-4327-8E48-E6A90D04D66F} + WinExe + AddDigitalSignature + AddDigitalSignature + v4.8 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/Signature/AddDigitalSignature/AddDigitalSignature.sln b/Signature/AddDigitalSignature/AddDigitalSignature.sln new file mode 100644 index 0000000..ea152a4 --- /dev/null +++ b/Signature/AddDigitalSignature/AddDigitalSignature.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35707.178 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddDigitalSignature", "AddDigitalSignature.csproj", "{2EAC8F00-1327-4327-8E48-E6A90D04D66F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2EAC8F00-1327-4327-8E48-E6A90D04D66F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EAC8F00-1327-4327-8E48-E6A90D04D66F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EAC8F00-1327-4327-8E48-E6A90D04D66F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EAC8F00-1327-4327-8E48-E6A90D04D66F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Signature/AddDigitalSignature/AddDigitalSignature_NET.csproj b/Signature/AddDigitalSignature/AddDigitalSignature_NET.csproj new file mode 100644 index 0000000..0ed0a83 --- /dev/null +++ b/Signature/AddDigitalSignature/AddDigitalSignature_NET.csproj @@ -0,0 +1,16 @@ + + + + WinExe + net8.0-windows + enable + enable + true + + + + + + + + diff --git a/Signature/AddDigitalSignature/AddDigitalSignature_NET.sln b/Signature/AddDigitalSignature/AddDigitalSignature_NET.sln new file mode 100644 index 0000000..8885bce --- /dev/null +++ b/Signature/AddDigitalSignature/AddDigitalSignature_NET.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35707.178 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddDigitalSignature_NET", "AddDigitalSignature_NET.csproj", "{075D44C0-3D4B-49B7-AC77-F6CB196B12BF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {075D44C0-3D4B-49B7-AC77-F6CB196B12BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {075D44C0-3D4B-49B7-AC77-F6CB196B12BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {075D44C0-3D4B-49B7-AC77-F6CB196B12BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {075D44C0-3D4B-49B7-AC77-F6CB196B12BF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Signature/AddDigitalSignature/App.config b/Signature/AddDigitalSignature/App.config new file mode 100644 index 0000000..193aecc --- /dev/null +++ b/Signature/AddDigitalSignature/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Signature/AddDigitalSignature/App.xaml b/Signature/AddDigitalSignature/App.xaml new file mode 100644 index 0000000..f8b3c87 --- /dev/null +++ b/Signature/AddDigitalSignature/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/Signature/AddDigitalSignature/App.xaml.cs b/Signature/AddDigitalSignature/App.xaml.cs new file mode 100644 index 0000000..a33773a --- /dev/null +++ b/Signature/AddDigitalSignature/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace AddDigitalSignature +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/Signature/AddDigitalSignature/Data/Barcode.pdf b/Signature/AddDigitalSignature/Data/Barcode.pdf new file mode 100644 index 0000000..6d10bb5 Binary files /dev/null and b/Signature/AddDigitalSignature/Data/Barcode.pdf differ diff --git a/Signature/AddDigitalSignature/ExtensionMethods.cs b/Signature/AddDigitalSignature/ExtensionMethods.cs new file mode 100644 index 0000000..aadbe14 --- /dev/null +++ b/Signature/AddDigitalSignature/ExtensionMethods.cs @@ -0,0 +1,223 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AddDigitalSignature +{ + public static class ExtensionMethods + { + + public static void Clear(this BlockingCollection blockingCollection) + { + try + { + if (blockingCollection == null) + { + return; + } + + while (blockingCollection.Count > 0) + { + string item; + blockingCollection.TryTake(out item); + item = null; + } + + blockingCollection.Dispose(); + } + catch (System.Exception ex) + { + //cGlobalSettings.oLogger.WriteLogException("Clear", ex); + } + + } + + + public static void Clear(this BlockingCollection blockingCollection) + { + try + { + if (blockingCollection == null) + { + return; + } + + while (blockingCollection.Count > 0) + { + int item; + blockingCollection.TryTake(out item); + } + + blockingCollection.Dispose(); + } + catch (System.Exception ex) + { + //cGlobalSettings.oLogger.WriteLogException("Clear", ex); + } + + } + + public static IEnumerable Distinct(this IEnumerable @this, Func keySelector) + { + return @this.GroupBy(keySelector).Select(grps => grps).Select(e => e.First()); + } + + + public static Dictionary + Merge(Dictionary[] dicts, + Func, TValue> resolveDuplicates) + { + if (resolveDuplicates == null) + resolveDuplicates = new Func, TValue>(group => group.First()); + + return dicts.SelectMany, KeyValuePair>(dict => dict) + .ToLookup(pair => pair.Key, pair => pair.Value) + .ToDictionary(group => group.Key, group => resolveDuplicates(group)); + } + + + + + + + + + public static Dictionary Merge(this IEnumerable> dicts, + Func, TValue> resolveDuplicates) + { + if (resolveDuplicates == null) + resolveDuplicates = new Func, TValue>(group => group.First()); + + return dicts.SelectMany, KeyValuePair>(dict => dict) + .ToLookup(pair => pair.Key, pair => pair.Value) + .ToDictionary(group => group.Key, group => resolveDuplicates(group)); + } + + public static long ToLong(long nFileSizeHigh, long nFileSizeLow) + { + return (long)((nFileSizeHigh << 0x20) | (nFileSizeLow & 0xffffffffL)); + + } + + public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME filetime) + { + long highBits = filetime.dwHighDateTime; + highBits = highBits << 32; + return DateTime.FromFileTimeUtc(highBits + (long)filetime.dwLowDateTime); + } + + + public static long ToLong(this System.Runtime.InteropServices.ComTypes.FILETIME filetime) + { + long highBits = filetime.dwHighDateTime; + highBits = highBits << 32; + return DateTime.FromFileTimeUtc(highBits + (long)filetime.dwLowDateTime).Ticks; + } + + /// + /// http://stackoverflow.com/questions/419019/split-list-into-sublists-with-linq + /// + /// + /// + /// + /// + /// + public static List> Split(this List source, int groupSize) + { + return source + .Select((x, i) => new { Index = i, Value = x }) + .GroupBy(x => x.Index / groupSize/*3*/) + .Select(x => x.Select(v => v.Value).ToList()) + .ToList(); + } + + + // public static string SafeGetString(this SQLiteDataReader reader, int colIndex) + // { + // if (!reader.IsDBNull(colIndex)) + // return reader.GetString(colIndex); + // else + // return string.Empty; + // } + + // public static Int32 SafeGetInt32(this SQLiteDataReader reader, int colIndex, Int32 defaultReturnValue) + // { + // if (!reader.IsDBNull(colIndex)) + // return reader.GetInt32(colIndex); + // else + // return defaultReturnValue; + // } + + // public static Int64 SafeGetInt64(this SQLiteDataReader reader, int colIndex, Int64 defaultReturnValue) + // { + // if (!reader.IsDBNull(colIndex)) + // return reader.GetInt64(colIndex); + // else + // return defaultReturnValue; + // } + + // public static T SafeGetValue(this SQLiteDataReader reader, int colIndex, T defaultReturnValue) + // { + // if (!reader.IsDBNull(colIndex)) + // { + // if (typeof(T) == typeof(int)) + // { + // return (T)Convert.ChangeType(reader.GetInt32(colIndex), typeof(T)); + // } + // else if (typeof(T) == typeof(long)) + // { + // return (T)Convert.ChangeType(reader.GetInt64(colIndex), typeof(T)); + // } + // else if (typeof(T) == typeof(string)) + // { + // return (T)Convert.ChangeType(reader.GetString(colIndex), typeof(T)); + // } + // else + // { + ////#error "not defined" + // Debug.Assert(false); + // } + + + // } + + // return defaultReturnValue; + // } + + public static List> Split(this Dictionary source, int groupSize) + { + return source + .Select((x, i) => new { Index = i, Value = x }) + .GroupBy(x => x.Index / groupSize/*3*/) + .Select(x => x.Select(v => v.Value).ToDictionary(z => z.Key, z => z.Value)) + .ToList(); + } + + + + public static IEnumerable Split(this string str, int n) + { + if (String.IsNullOrEmpty(str) || n < 1) + { + throw new ArgumentException(); + } + + for (int i = 0; i < str.Length; i += n) + { + yield return str.Substring(i, Math.Min(n, str.Length - i)); + } + } + } + + static class DataRowExtensions + { + public static object GetValueWithContainsCheck(this DataRow row, string column) + { + return row.Table.Columns.Contains(column) ? row?[column] : null; + } + } +} diff --git a/Signature/AddDigitalSignature/MainWindow.xaml b/Signature/AddDigitalSignature/MainWindow.xaml new file mode 100644 index 0000000..ebc38ff --- /dev/null +++ b/Signature/AddDigitalSignature/MainWindow.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/Signature/AddDigitalSignature/MainWindow.xaml.cs b/Signature/AddDigitalSignature/MainWindow.xaml.cs new file mode 100644 index 0000000..337f195 --- /dev/null +++ b/Signature/AddDigitalSignature/MainWindow.xaml.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using System.Xml.Linq; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.X509; +using Syncfusion.Licensing.security; +using Syncfusion.Pdf; +using Syncfusion.Pdf.Graphics; +using Syncfusion.Pdf.Interactive; +using Syncfusion.Pdf.Parsing; +using Syncfusion.Pdf.Security; + +namespace AddDigitalSignature +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + PdfLoadedDocument loadedDocument; + const string DatetimeFormat = "dd/MM/yyyy HH:mm:sszzz"; + RectangleF Bounds = RectangleF.Empty; + static string certFilePath = "MyTestCert.pfx"; + static string certPassword = "YourPassword"; + double pixelsPerDip; + string filepath; + string fileSavePath; + public MainWindow() + { + Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Ngo9BigBOggjHTQxAR8/V1NHaF5cXmpCf1FpRmJGdld5fUVHYVZUTXxaS00DNHVRdkdgWH9edHVWQmhdUEF2WEA="); + InitializeComponent(); + } + + private void Window_Loaded(object sender, RoutedEventArgs e) + { +#if NETCOREAPP + filepath = @"../../../Data/Barcode.pdf"; +#else + filepath = @"../../Data/Barcode.pdf"; +#endif + PdfLoadedDocument loadedDocument = new PdfLoadedDocument(filepath); + docView.Load(loadedDocument); + } + private void Draw_Click(object sender, RoutedEventArgs e) + { + loadedDocument = docView.LoadedDocument; + docView.AnnotationMode = Syncfusion.Windows.PdfViewer.PdfDocumentView.PdfViewerAnnotationMode.Rectangle; + } + + private void BtnAdd_Click(object sender, RoutedEventArgs e) + { + if (loadedDocument != null) + { + PdfSignature signature = null; + PdfUnitConvertor unitConvertor = null; + + System.Windows.Point position = new System.Windows.Point(10, 10); + + PdfGraphics graphics = null; + CreateOwnDigitalID(); + + X509Certificate2 x509Cert = new X509Certificate2(certFilePath, certPassword); + PdfCertificate cert = new PdfCertificate(x509Cert); + + //Create a signature with loaded digital ID. + signature = new PdfSignature(loadedDocument, loadedDocument.Pages[0], cert, "Signature"); + + signature.SignedName = cert.SubjectName; + signature.Reason = "Testing data"; + signature.LocationInfo = "India"; + signature.EnableValidationAppearance = false; + signature.EnableLtv = true; + + signature.Settings.DigestAlgorithm = DigestAlgorithm.SHA256; + signature.Settings.CryptographicStandard = CryptographicStandard.CMS; + + //Create a font to draw text. + PdfStandardFont font = new PdfStandardFont(PdfFontFamily.TimesRoman, 10); + PdfStandardFont fontMain = new PdfStandardFont(PdfFontFamily.TimesRoman, 14); + + string str = cert.SubjectName; + var dpi = VisualTreeHelper.GetDpi(this); + pixelsPerDip = dpi.PixelsPerDip; + + + System.Windows.Media.FormattedText formattedTextMain = new System.Windows.Media.FormattedText(str, + System.Globalization.CultureInfo.GetCultureInfo("en-us"), + System.Windows.FlowDirection.LeftToRight, + new System.Windows.Media.Typeface("Times New Roman"), FontSize = 14, System.Windows.Media.Brushes.Black,pixelsPerDip); + + double textWidthMain = formattedTextMain.Width; + + float width = 0; + + if (str.Contains(" ")) + { + width = GetWidth(str) + 20; + } + else + { + width = (float)textWidthMain + 20; + } + + double InnerRectWidth = GetInnerRectWidth(str, cert.IssuerName, signature.Reason, signature.LocationInfo, DateTime.Now.ToString(DatetimeFormat)); + + string updated = string.Empty; + + bool bcorrectLength = true; + + + if (str.Length < 40) + { + string phrase = str; + string[] words = phrase.Split(' '); + + if (words.Count() > 1) + { + foreach (var word in words) + { + if (word.Length > 12) + { + bcorrectLength = false; + break; + } + } + + if (bcorrectLength) + updated = string.Join(Environment.NewLine, words); + else + { + int size = str.Length / 3; + IEnumerable s = str.Split(size); + updated = string.Join(Environment.NewLine, s); + } + } + else + { + updated = words[0]; + } + } + else + { + int size = str.Length / 3; + + IEnumerable s = str.Split(size); + updated = string.Join(Environment.NewLine, s); + } + + unitConvertor = new PdfUnitConvertor(); + PointF bounds = new PointF(((float)position.X / (float)100) * 100, ((float)position.Y / (float)100) * 100); + PointF point = unitConvertor.ConvertFromPixels(bounds, PdfGraphicsUnit.Point); + + SizeF pageSize = loadedDocument.Pages[0].Size; + + if (point.X + width + InnerRectWidth + 20 > pageSize.Width) + { + point.X = point.X - (point.X + width + (float)InnerRectWidth + 20 - pageSize.Width); + } + if (point.Y + 120 > pageSize.Height) + { + point.Y = point.Y - (point.Y + 120 - pageSize.Height); + } + + //Set bounds to the signature. + signature.Bounds = GetRelativeBounds(loadedDocument.Pages[0] as PdfLoadedPage, new System.Drawing.RectangleF((float)point.X, (float)point.Y, (float)(width + InnerRectWidth + 20), 120)); + + graphics = signature.Appearance.Normal.Graphics; + PdfPageRotateAngle angle = loadedDocument.Pages[0].Rotation; + + graphics.Save(); + + if (angle == PdfPageRotateAngle.RotateAngle90) + { + graphics.TranslateTransform(0, signature.Bounds.Height); + graphics.RotateTransform(-90); + + } + else if (angle == PdfPageRotateAngle.RotateAngle180) + { + graphics.TranslateTransform(signature.Bounds.Width, signature.Bounds.Height); + graphics.RotateTransform(-180); + + } + else if (angle == PdfPageRotateAngle.RotateAngle270) + { + graphics.TranslateTransform(signature.Bounds.Width, 0); + graphics.RotateTransform(-270); + + } + + + + signature.Appearance.Normal.Graphics.DrawRectangle(PdfPens.Black, PdfBrushes.White, new System.Drawing.RectangleF(0, 0, (float)(width + InnerRectWidth + 20), 120)); + signature.Appearance.Normal.Graphics.DrawString(updated, fontMain, PdfBrushes.Black, 10, 0); + + signature.Appearance.Normal.Graphics.DrawString("Digitally Signed by", font, PdfBrushes.Black, width + 10, 0); + signature.Appearance.Normal.Graphics.DrawString(str, font, PdfBrushes.Black, width + 10, 15); + signature.Appearance.Normal.Graphics.DrawString("Issued by", font, PdfBrushes.Black, width + 10, 30); + signature.Appearance.Normal.Graphics.DrawString(cert.IssuerName, font, PdfBrushes.Black, width + 10, 45); + signature.Appearance.Normal.Graphics.DrawString("Location: " + signature.LocationInfo, font, PdfBrushes.Black, width + 10, 60); + + if (signature.Reason != "Not Available") + { + signature.Appearance.Normal.Graphics.DrawString("Reason: " + signature.Reason, font, PdfBrushes.Black, width + 10, 75); + signature.Appearance.Normal.Graphics.DrawString("Signed Date:", font, PdfBrushes.Black, width + 10, 90); + signature.Appearance.Normal.Graphics.DrawString(DateTime.Now.ToString(DatetimeFormat), font, PdfBrushes.Black, width + 10, 105); + } + else + { + signature.Appearance.Normal.Graphics.DrawString("Signed Date:", font, PdfBrushes.Black, width + 10, 75); + signature.Appearance.Normal.Graphics.DrawString(DateTime.Now.ToString(DatetimeFormat), font, PdfBrushes.Black, width + 10, 90); + } + Bounds = unitConvertor.ConvertFromPixels(Bounds, PdfGraphicsUnit.Point); + signature.Bounds = new RectangleF(Bounds.X, Bounds.Y, Bounds.Width, Bounds.Height); + graphics.Restore(); + +#if NETCOREAPP + fileSavePath = @"../../../Barcode_Sign1.pdf"; +#else + fileSavePath = @"../../Barcode_Sign1.pdf"; +#endif + loadedDocument.Save(fileSavePath); + + if (docView.IsLoaded) + docView.Unload(); + + docView.Load(fileSavePath); + } + } + + private static RectangleF GetRelativeBounds(PdfLoadedPage page, RectangleF bounds) + { + SizeF pagesize = page.Size; + RectangleF rectangle = bounds; + + if (page.Rotation == PdfPageRotateAngle.RotateAngle90) + { + rectangle.X = bounds.Y; + rectangle.Y = pagesize.Height - ((bounds.X + bounds.Width)); + rectangle.Width = bounds.Height; + rectangle.Height = bounds.Width; + } + else if (page.Rotation == PdfPageRotateAngle.RotateAngle270) + { + rectangle.Y = bounds.X; + rectangle.X = pagesize.Width - (bounds.Y + bounds.Height); + rectangle.Width = bounds.Height; + rectangle.Height = bounds.Width; + } + else if (page.Rotation == PdfPageRotateAngle.RotateAngle180) + { + rectangle.X = pagesize.Width - (bounds.X + bounds.Width); + rectangle.Y = pagesize.Height - (bounds.Y + bounds.Height); + } + return rectangle; + } + + private float GetInnerRectWidth(string text, string issuedBy, string Reason, string Location, string Time) + { + + float ret = 0; + + List lstWidth = new List(); + System.Windows.Media.FormattedText formattedText = new System.Windows.Media.FormattedText(text, + System.Globalization.CultureInfo.GetCultureInfo("en-us"), + System.Windows.FlowDirection.LeftToRight, + new System.Windows.Media.Typeface("Times New Roman"), FontSize = 10, System.Windows.Media.Brushes.Black,pixelsPerDip); + + lstWidth.Add(formattedText.Width); + + System.Windows.Media.FormattedText IssuerText = new System.Windows.Media.FormattedText(issuedBy, + System.Globalization.CultureInfo.GetCultureInfo("en-us"), + System.Windows.FlowDirection.LeftToRight, + new System.Windows.Media.Typeface("Times New Roman"), FontSize = 10, System.Windows.Media.Brushes.Black,pixelsPerDip); + + lstWidth.Add(IssuerText.Width); + + + System.Windows.Media.FormattedText reasonText = new System.Windows.Media.FormattedText(Reason, + System.Globalization.CultureInfo.GetCultureInfo("en-us"), + System.Windows.FlowDirection.LeftToRight, + new System.Windows.Media.Typeface("Times New Roman"), FontSize = 10, System.Windows.Media.Brushes.Black, pixelsPerDip); + + lstWidth.Add(reasonText.Width); + + System.Windows.Media.FormattedText locationText = new System.Windows.Media.FormattedText(Location, + System.Globalization.CultureInfo.GetCultureInfo("en-us"), + System.Windows.FlowDirection.LeftToRight, + new System.Windows.Media.Typeface("Times New Roman"), FontSize = 10, System.Windows.Media.Brushes.Black, pixelsPerDip); + + lstWidth.Add(locationText.Width); + + System.Windows.Media.FormattedText timeText = new System.Windows.Media.FormattedText(Time, + System.Globalization.CultureInfo.GetCultureInfo("en-us"), + System.Windows.FlowDirection.LeftToRight, + new System.Windows.Media.Typeface("Times New Roman"), FontSize = 10, System.Windows.Media.Brushes.Black, pixelsPerDip); + + lstWidth.Add(timeText.Width); + + + ret = (float)lstWidth.Max(); + return ret; + } + + private float GetWidth(string str) + { + float ret = 0; + + List lstWidth = new List(); + string phrase = str; + string[] words = phrase.Split(' '); + + foreach (var word in words) + { + FormattedText splitedWord = new FormattedText(word, + System.Globalization.CultureInfo.GetCultureInfo("en-us"), + FlowDirection.LeftToRight, + new Typeface("Times New Roman"), FontSize = 14, System.Windows.Media.Brushes.Black,pixelsPerDip); + + lstWidth.Add(splitedWord.Width); + } + + ret = (float)lstWidth.Max(); + return ret; + } + + static void CreateOwnDigitalID() + { + // Generate an RSA key pair + RsaKeyPairGenerator rsaKeyPairGenerator = new RsaKeyPairGenerator(); + rsaKeyPairGenerator.Init(new KeyGenerationParameters(new Org.BouncyCastle.Security.SecureRandom(), 2048)); + AsymmetricCipherKeyPair keyPair = rsaKeyPairGenerator.GenerateKeyPair(); + + // Create a self-signed certificate generator + X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator(); + certificateGenerator.SetSerialNumber(BigInteger.ValueOf(1)); + certificateGenerator.SetSubjectDN(new X509Name("CN=MyTestCert")); + certificateGenerator.SetIssuerDN(new X509Name("CN=MyTestCert")); + certificateGenerator.SetNotBefore(DateTime.UtcNow.Date); + certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(1)); + certificateGenerator.SetPublicKey(keyPair.Public); + + // Sign the certificate with the private key + ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WithRSA", keyPair.Private); + Org.BouncyCastle.X509.X509Certificate generatedCertificate = certificateGenerator.Generate(signatureFactory); + + // Create a PKCS#12 store to hold the certificate and private key + Pkcs12Store store = new Pkcs12StoreBuilder().Build(); + X509CertificateEntry certificateEntry = new X509CertificateEntry(generatedCertificate); + AsymmetricKeyEntry privateKeyEntry = new AsymmetricKeyEntry(keyPair.Private); + store.SetKeyEntry("alias", privateKeyEntry, new[] { certificateEntry }); + + // Export the PKCS#12 store to a byte array + MemoryStream pfxStream = new MemoryStream(); + store.Save(pfxStream, "YourPassword".ToCharArray(), new Org.BouncyCastle.Security.SecureRandom()); + + // Save the byte array to a file + File.WriteAllBytes(certFilePath, pfxStream.ToArray()); + + Console.WriteLine("Certificate created successfully and saved to " + certFilePath); + } + + private void docView_ShapeAnnotationChanged(object sender, Syncfusion.Windows.PdfViewer.ShapeAnnotationChangedEventArgs e) + { + if (e.Action == Syncfusion.Windows.PdfViewer.AnnotationChangedAction.Add || e.Action == Syncfusion.Windows.PdfViewer.AnnotationChangedAction.Resize) + { + Bounds = e.NewBounds; + } + } + + } +} diff --git a/Signature/AddDigitalSignature/Properties/AssemblyInfo.cs b/Signature/AddDigitalSignature/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2f328d5 --- /dev/null +++ b/Signature/AddDigitalSignature/Properties/AssemblyInfo.cs @@ -0,0 +1,46 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyDescription("")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// diff --git a/Signature/AddDigitalSignature/Properties/Resources.Designer.cs b/Signature/AddDigitalSignature/Properties/Resources.Designer.cs new file mode 100644 index 0000000..8fea8c3 --- /dev/null +++ b/Signature/AddDigitalSignature/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AddDigitalSignature.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AddDigitalSignature.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Signature/AddDigitalSignature/Properties/Resources.resx b/Signature/AddDigitalSignature/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Signature/AddDigitalSignature/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Signature/AddDigitalSignature/Properties/Settings.Designer.cs b/Signature/AddDigitalSignature/Properties/Settings.Designer.cs new file mode 100644 index 0000000..63f2d4a --- /dev/null +++ b/Signature/AddDigitalSignature/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AddDigitalSignature.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Signature/AddDigitalSignature/Properties/Settings.settings b/Signature/AddDigitalSignature/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/Signature/AddDigitalSignature/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Signature/AddDigitalSignature/packages.config b/Signature/AddDigitalSignature/packages.config new file mode 100644 index 0000000..dc9995a --- /dev/null +++ b/Signature/AddDigitalSignature/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file