Exemple #1
0
        /// <summary>
        /// Create Xades <QualifyingProperties> from the <SignatureProperties> and <DataObjectProperties> elements
        /// </summary>
        /// <param name="signedXml"></param>
        /// <param name="document"></param>
        /// <param name="certificate"></param>
        private void CreateXadesQualifyingProperties(XadesSignedXml signedXml, XmlDocument document, X509Certificate2 certificate)
        {
            string signatureRootId    = CreateId(XadesSignatureRootId);
            string signedPropertiesId = CreateId(XadesSignedPropertiesId);

            // build xades XML
            XmlElement qualifyingProperties = document.CreateElement("QualifyingProperties", XadesNamespaceUrl);

            qualifyingProperties.SetAttribute("Target", $"#{signatureRootId}");
            XmlElement signedProperties = qualifyingProperties.CreateChild("SignedProperties", XadesNamespaceUrl);

            signedProperties.SetAttribute("Id", signedPropertiesId);

            XmlElement signatureProperties = SignatureProperties.CreateXadesSignatureProperties(document, certificate, SignatureType);

            signedProperties.AppendChild(signatureProperties);
            XmlElement dataObjectProperties = CreateXadesDataObjectProperties(document);

            if (dataObjectProperties.ChildNodes.Count > 0)
            {
                signedProperties.AppendChild(dataObjectProperties);
            }

            // add reference to xades XML
            signedXml.AddXadesObject(new DataObject(null, null, null, qualifyingProperties));
            Reference signedPropertiesReference = new Reference($"#{signedPropertiesId}")
            {
                TransformChain = XadesTransformChain, DigestMethod = XadesDigestMethod, Type = XadesReferenceType
            };

            signedXml.AddReference(signedPropertiesReference);

            signedXml.Signature.Id = signatureRootId;
        }
Exemple #2
0
        public int CreatePDF(Stream stream)
        {
            GcPdfDocument doc  = new GcPdfDocument();
            Page          page = doc.NewPage();
            TextFormat    tf   = new TextFormat()
            {
                Font = StandardFonts.Times, FontSize = 14
            };

            page.Graphics.DrawString(
                "Hello, World!\r\nSigned below by GcPdfWeb SignDoc sample.",
                tf, new PointF(72, 72));

            // Init a test certificate:
            var pfxPath           = Path.Combine("Resources", "Misc", "GcPdfTest.pfx");
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
                                                         X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            SignatureProperties sp = new SignatureProperties();

            sp.Certificate = cert;
            sp.Location    = "GcPdfWeb Sample Browser";
            sp.SignerName  = "GcPdfWeb";

            // Init a signature field to hold the signature:
            SignatureField sf = new SignatureField();

            sf.Widget.Rect                     = new RectangleF(72, 72 * 2, 72 * 4, 36);
            sf.Widget.Page                     = page;
            sf.Widget.BackColor                = Color.LightSeaGreen;
            sf.Widget.TextFormat.Font          = StandardFonts.Helvetica;
            sf.Widget.ButtonAppearance.Caption = $"Signer: {sp.SignerName}\r\nLocation: {sp.Location}";
            // Add the signature field to the document:
            doc.AcroForm.Fields.Add(sf);
            // Connect the signature field and signature props:
            sp.SignatureField = sf;

            // Sign and save the document:
            // NOTES:
            // - Signing and saving is an atomic operation, the two cannot be separated.
            // - The stream passed to the Sign() method must be readable.
            doc.Sign(sp, stream);

            // Rewind the stream to read the document just created
            // into another GcPdfDocument and verify the signature:
            stream.Seek(0, SeekOrigin.Begin);
            GcPdfDocument doc2 = new GcPdfDocument();

            doc2.Load(stream);
            SignatureField sf2 = (SignatureField)doc2.AcroForm.Fields[0];

            if (!sf2.Value.VerifySignature())
            {
                throw new Exception("Failed to verify the signature");
            }

            // Done (the generated and signed document has already been saved to 'stream').
            return(doc.Pages.Count);
        }
Exemple #3
0
        // This method is almost exactly the same as the SignDoc sample,
        // but adds a second signature field (does not sign it though):
        private Stream CreateAndSignPdf()
        {
            GcPdfDocument doc  = new GcPdfDocument();
            Page          page = doc.NewPage();
            TextFormat    tf   = new TextFormat()
            {
                Font = StandardFonts.Times, FontSize = 14
            };

            page.Graphics.DrawString(
                "Hello, World!\r\nSigned below TWICE by GcPdfWeb SignIncremental sample.",
                tf, new PointF(72, 72));

            // Init a test certificate:
            var pfxPath           = Path.Combine("Resources", "Misc", "GcPdfTest.pfx");
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
                                                         X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            SignatureProperties sp = new SignatureProperties();

            sp.Certificate = cert;
            sp.Location    = "GcPdfWeb Sample Browser";
            sp.SignerName  = "GcPdfWeb";

            // Init a signature field to hold the signature:
            SignatureField sf = new SignatureField();

            sf.Widget.Rect      = new RectangleF(72, 72 * 2, 72 * 4, 36);
            sf.Widget.Page      = page;
            sf.Widget.BackColor = Color.LightSeaGreen;
            // Add the signature field to the document:
            doc.AcroForm.Fields.Add(sf);
            // Connect the signature field and signature props:
            sp.SignatureField = sf;

            // Add a second signature field:
            SignatureField sf2 = new SignatureField()
            {
                Name = "SecondSignature"
            };

            sf2.Widget.Rect      = new RectangleF(72, 72 * 3, 72 * 4, 36);
            sf2.Widget.Page      = page;
            sf2.Widget.BackColor = Color.LightYellow;
            // Add the signature field to the document:
            doc.AcroForm.Fields.Add(sf2);

            var ms = new MemoryStream();

            doc.Sign(sp, ms);
            return(ms);
        }
Exemple #4
0
        public int CreatePDF(Stream stream)
        {
            GcPdfDocument doc = new GcPdfDocument();

            // Load a signed document (we use code similar to the SignDoc sample):
            doc.Load(CreateAndSignPdf());
            // Init a second certificate:
            var pfxPath           = Path.Combine("Resources", "Misc", "JohnDoe.pfx");
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "secret",
                                                         X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            SignatureProperties sp2 = new SignatureProperties()
            {
                Certificate = cert,
                Location    = "GcPdfWeb Sample Browser",
                SignerName  = "Jaime Smith",
            };
            // Find the 2nd (not yet filled) signature field:
            var sfld2 = doc.AcroForm.Fields["SecondSignature"] as SignatureField;

            // Connect the signature field and signature props:
            sp2.SignatureField = sfld2 ?? throw new Exception("Unexpected: could not find 'SecondSignature' field");
            // Sign and save the document:
            doc.Sign(sp2, stream);

            // Rewind the stream to read the document just created
            // into another GcPdfDocument and verify all signatures:
            stream.Seek(0, SeekOrigin.Begin);
            GcPdfDocument doc2 = new GcPdfDocument();

            doc2.Load(stream);
            foreach (var fld in doc2.AcroForm.Fields)
            {
                if (fld is SignatureField sfld)
                {
                    if (!sfld.Value.VerifySignature())
                    {
                        throw new Exception($"Failed to verify signature for field {sfld.Name}");
                    }
                }
            }

            // Done (the generated and signed document has already been saved to 'stream').
            return(doc.Pages.Count);
        }
Exemple #5
0
        // Main entry point of this sample:
        public int CreatePDF(Stream stream)
        {
            // Set up a font collection with the fonts we need:
            _fc.RegisterDirectory(Path.Combine("Resources", "Fonts"));
            // Set that font collection on input fields' text layout
            // (we will also set it on all text layouts that we'll use):
            _inputTl.FontCollection = _fc;
            // Set up layout and formatting for input fields:
            _inputTl.ParagraphAlignment = ParagraphAlignment.Center;
            _inputTf.FontName           = "Segoe UI";
            _inputTf.FontSize           = 12;
            _inputTf.FontBold           = true;

            // Create the time sheet input form
            // (in a real-life scenario, we probably would only create it once,
            // and then re-use the form PDF):
            var doc = MakeTimeSheetForm();

            // At this point, 'doc' is an empty AcroForm.
            // In a real-life app it would be distributed to employees
            // for them to fill and send back.
            FillEmployeeData(doc);

            //
            // At this point the form is filled with employee's data.
            //

            // Supervisor data (in a real app, these would probably be fetched from a db):
            var supName     = "Jane Donahue";
            var supSignDate = DateTime.Now.ToShortDateString();

            SetFieldValue(doc, _Names.EmpSuper, supName);
            SetFieldValue(doc, _Names.SupSignDate, supSignDate);

            // The next step is to 'flatten' the form: we loop over document AcroForm's fields,
            // drawing their current values in place, and then remove the fields.
            // This produces a PDF with text fields' values as part of the regular (non-editable) content:
            FlattenDoc(doc);

            // Now we digitally sign the flattened document on behalf of the 'manager':
            var pfxPath           = Path.Combine("Resources", "Misc", "GcPdfTest.pfx");
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
                                                         X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            SignatureProperties sp = new SignatureProperties();

            sp.Certificate = cert;
            sp.Location    = "GcPdfWeb - TimeSheet sample";
            sp.SignerName  = supName;

            // Connect the signature field and signature props:
            SignatureField supSign = doc.AcroForm.Fields.First(f_ => f_.Name == _Names.SupSign) as SignatureField;

            sp.SignatureField = supSign;
            supSign.Widget.ButtonAppearance.Caption = supName;
            // Some browser PDF viewers do not show form fields, so we render a placeholder:
            supSign.Widget.Page.Graphics.DrawString("digitally signed", new TextFormat()
            {
                FontName = "Segoe UI", FontSize = 9
            }, supSign.Widget.Rect);

            // Done, now save the document with supervisor signature:
            doc.Sign(sp, stream);
            // Dispose images only after the document is saved:
            _disposables.ForEach(d_ => d_.Dispose());
            return(doc.Pages.Count);
        }
Exemple #6
0
        // Main entry point of this sample:
        public int CreatePDF(Stream stream)
        {
            // Set up a font collection with the fonts we need:
            _fc.RegisterDirectory(Path.Combine("Resources", "Fonts"));
            // Set that font collection on input fields' text layout
            // (we will also set it on all text layouts that we'll use):
            _inputTl.FontCollection = _fc;
            // Set up layout and formatting for input fields:
            _inputTl.ParagraphAlignment = ParagraphAlignment.Center;
            _inputTf.FontName           = "Segoe UI";
            _inputTf.FontSize           = 12;
            _inputTf.FontBold           = true;

            // Create the time sheet input form
            // (in a real-life scenario, we probably would only create it once,
            // and then re-use the form PDF):
            var doc = MakeTimeSheetForm();

            // At this point, 'doc' is an empty AcroForm.
            // In a real-life app it would be distributed to employees
            // for them to fill and send back.
            using (var empSignedStream = FillEmployeeData(doc))
            {
                //
                // At this point 'empSignedStream' contains the form filled with employee's data and signed by them.
                //

                // Load the employee-signed document:
                doc.Load(empSignedStream);

                // Fill in supervisor data:
                var supName     = "Jane Donahue";
                var supSignDate = DateTime.Now.ToShortDateString();
                SetFieldValue(doc, _Names.EmpSuper, supName);
                SetFieldValue(doc, _Names.SupSignDate, supSignDate);

                // Digitally sign the document on behalf of the supervisor:
                var pfxPath           = Path.Combine("Resources", "Misc", "GcPdfTest.pfx");
                X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
                                                             X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
                SignatureProperties sp = new SignatureProperties()
                {
                    Certificate = cert,
                    Location    = "GcPdfWeb - TimeSheet Incremental",
                    SignerName  = supName,
                    SignatureDigestAlgorithm = SignatureDigestAlgorithm.SHA512,
                    // Connect the signature field and signature props:
                    SignatureField = doc.AcroForm.Fields.First(f_ => f_.Name == _Names.SupSign) as SignatureField,
                };

                // Any changes to the document would invalidate the employee's signature, so we cannot do this:
                // supSign.Widget.ButtonAppearance.Caption = supName;
                //
                // Done, now save the document with supervisor signature:
                // NOTE: in order to not invalidate the employee's signature,
                // we MUST use incremental update here (which is true by default in Sign() method):
                doc.Sign(sp, stream);
                _logo.Dispose();
                return(doc.Pages.Count);
            }
        }
Exemple #7
0
        // Fill in employee info and working hours with sample data:
        private Stream FillEmployeeData(GcPdfDocument doc)
        {
            // For the purposes of this sample, we fill the form with random data:
            var empName = "Jaime Smith";

            SetFieldValue(doc, _Names.EmpName, empName);
            SetFieldValue(doc, _Names.EmpNum, "12345");
            SetFieldValue(doc, _Names.EmpDep, "Research & Development");
            SetFieldValue(doc, _Names.EmpTitle, "Senior Developer");
            SetFieldValue(doc, _Names.EmpStatus, "Full Time");
            var      rand    = new Random((int)DateTime.Now.Ticks);
            DateTime workday = DateTime.Now.AddDays(-15);

            while (workday.DayOfWeek != DayOfWeek.Sunday)
            {
                workday = workday.AddDays(1);
            }
            TimeSpan wkTot = TimeSpan.Zero, wkReg = TimeSpan.Zero, wkOvr = TimeSpan.Zero;

            for (int i = 0; i < 7; ++i)
            {
                // Start time:
                var start = new DateTime(workday.Year, workday.Month, workday.Day, rand.Next(6, 12), rand.Next(0, 59), 0);
                SetFieldValue(doc, _Names.DtNames[_Names.Dows[i]][0], start.ToShortDateString());
                SetFieldValue(doc, _Names.DtNames[_Names.Dows[i]][1], start.ToShortTimeString());
                // End time:
                var end = start.AddHours(rand.Next(8, 14)).AddMinutes(rand.Next(0, 59));
                SetFieldValue(doc, _Names.DtNames[_Names.Dows[i]][2], end.ToShortTimeString());
                var tot = end - start;
                var reg = TimeSpan.FromHours((start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday) ? 8 : 0);
                var ovr = tot.Subtract(reg);
                SetFieldValue(doc, _Names.DtNames[_Names.Dows[i]][3], reg.ToString(@"hh\:mm"));
                SetFieldValue(doc, _Names.DtNames[_Names.Dows[i]][4], ovr.ToString(@"hh\:mm"));
                SetFieldValue(doc, _Names.DtNames[_Names.Dows[i]][5], tot.ToString(@"hh\:mm"));
                wkTot += tot;
                wkOvr += ovr;
                wkReg += reg;
                //
                workday = workday.AddDays(1);
            }
            SetFieldValue(doc, _Names.TotalReg, wkReg.TotalHours.ToString("F"));
            SetFieldValue(doc, _Names.TotalOvr, wkOvr.TotalHours.ToString("F"));
            SetFieldValue(doc, _Names.TotalHours, wkTot.TotalHours.ToString("F"));
            SetFieldValue(doc, _Names.EmpSignDate, workday.ToShortDateString());

            // Digitally sign the document on behalf of the 'employee':
            var pfxPath           = Path.Combine("Resources", "Misc", "JohnDoe.pfx");
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "secret",
                                                         X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            SignatureProperties sp = new SignatureProperties()
            {
                Certificate = cert,
                DocumentAccessPermissions = AccessPermissions.FormFillingAndAnnotations,
                Reason     = "I confirm time sheet is correct.",
                Location   = "TimeSheetIncremental sample",
                SignerName = empName,
            };

            // Connect the signature field and signature props:
            SignatureField empSign = doc.AcroForm.Fields.First(f_ => f_.Name == _Names.EmpSign) as SignatureField;

            sp.SignatureField = empSign;
            empSign.Widget.ButtonAppearance.Caption = empName;
            // Some browser PDF viewers do not show form fields, so we render a placeholder:
            empSign.Widget.Page.Graphics.DrawString("digitally signed", new TextFormat()
            {
                FontName = "Segoe UI", FontSize = 9
            }, empSign.Widget.Rect);

            // We now 'flatten' the form: loop over document AcroForm's fields,
            // drawing their current values in place, and then remove the fields.
            // This produces a PDF with text fields' values as part of the regular
            // (non-editable) content (we leave fields filled by the supervisor):
            FlattenDoc(doc, _Names.EmpSuper, _Names.SupSignDate);

            // Done, now save the document with employee's signature:
            var ms = new MemoryStream();

            // Note that we do NOT use incremental update here (3rd parameter is false)
            // as this is not needed yet (but will be needed/used when signing by supervisor later):
            doc.Sign(sp, ms, false);
            return(ms);
        }
Exemple #8
0
        public int CreatePDF(Stream stream)
        {
            GcPdfDocument doc  = new GcPdfDocument();
            Page          page = doc.NewPage();
            TextFormat    tf   = new TextFormat()
            {
                Font = StandardFonts.Times, FontSize = 14
            };

            page.Graphics.DrawString(
                "Hello, World!\r\nSigned below by GcPdfWeb SignatureAppearance sample.",
                tf, new PointF(72, 72));

            // Init a test certificate:
            var pfxPath           = Path.Combine("Resources", "Misc", "GcPdfTest.pfx");
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
                                                         X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            SignatureProperties sp = new SignatureProperties();

            sp.Certificate = cert;
            sp.Location    = "GcPdfWeb Sample Browser";
            sp.SignerName  = "GcPdfWeb";

            // Create a signature field to hold the signature:
            SignatureField sf = new SignatureField();

            // Add the signature field to the document:
            doc.AcroForm.Fields.Add(sf);
            // Connect the signature field and signature props:
            sp.SignatureField = sf;

            // Set up the signature field:
            sf.Widget.Rect = new RectangleF(page.Size.Width - 72 * 4, 72 * 2, 72 * 3, 72);
            sf.Widget.Page = page;
            // Widget visual props will be overridden by sf.Widget.AppearanceStreams.Normal.Default set below:
            sf.Widget.BackColor = Color.PeachPuff;
            sf.Widget.Border    = new GrapeCity.Documents.Pdf.Annotations.Border()
            {
                Color = Color.SaddleBrown,
                Width = 3,
            };
            sf.Widget.ButtonAppearance.Caption = $"Signer: {sp.SignerName}\r\nLocation: {sp.Location}";
            // Create custom signature appearance stream:
            var rc  = new RectangleF(PointF.Empty, sf.Widget.Rect.Size);
            var fxo = new FormXObject(doc, rc);

            rc.Inflate(-4, -4);
            fxo.Graphics.FillEllipse(rc, Color.CornflowerBlue);
            fxo.Graphics.DrawEllipse(rc, new Pen(Color.RoyalBlue, 3));
            rc.Inflate(-5, -5);
            fxo.Graphics.DrawEllipse(rc, new Pen(Color.LightSteelBlue, 1));
            fxo.Graphics.DrawString($"Signed by {sp.SignerName}\non {DateTime.Now.ToShortDateString()}.",
                                    new TextFormat()
            {
                FontName   = "Times New Roman",
                FontSize   = 14,
                FontItalic = true,
                ForeColor  = Color.Navy
            },
                                    fxo.Bounds,
                                    TextAlignment.Center, ParagraphAlignment.Center, false);
            sf.Widget.AppearanceStreams.Normal.Default = fxo;

            // Reset signature appearance so that the widget appearance stream is used:
            sp.SignatureAppearance = null;

            // Sign and save the document:
            // NOTES:
            // - Signing and saving is an atomic operation, the two cannot be separated.
            // - The stream passed to the Sign() method must be readable.
            doc.Sign(sp, stream);

            // Done (the generated and signed docment has already been saved to 'stream').
            return(doc.Pages.Count);
        }