PdfSharpCore icon indicating copy to clipboard operation
PdfSharpCore copied to clipboard

Digital signature

Open pamapa opened this issue 3 years ago • 7 comments

part of #237

I am not so sure if the taken approach is the right way to:

  • PdfItem.WriteObject vs PdfItem.Write seems error prone
  • is the position tracker approach really needed, can't that be done more elegant?

We current do not need to sign PDFs for our project, therefore i am not investing time for this feature. In order somebody else wants to work on this, i am pushing my changes on a draft branch. This branch is not intended to be merged like it is now...

pamapa avatar Jun 02 '22 08:06 pamapa

Codecov Report

:exclamation: No coverage uploaded for pull request base (master@4c3bcbb). Click here to learn what that means. The diff coverage is n/a.

@@            Coverage Diff            @@
##             master     #243   +/-   ##
=========================================
  Coverage          ?   26.07%           
=========================================
  Files             ?      244           
  Lines             ?    23645           
  Branches          ?     2833           
=========================================
  Hits              ?     6165           
  Misses            ?    16984           
  Partials          ?      496           

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 4c3bcbb...b3e1154. Read the comment docs.

codecov-commenter avatar Jun 04 '22 06:06 codecov-commenter

Are you sure this works? For me, Adobe Reader validates the signature OK, but in the place of the visible signature I got an empty rectangle.

mmmilan avatar Oct 04 '22 09:10 mmmilan

I'm not 100% sure, its some time ago i did this. At the end we did not need that feature so i stopped and archived this MR as a starting point for somebody else. In the issue i have referenced the places where i did take the code parts from. In general i am not 100% sure if this approach is the right way to do it anyway, as it is very invasive (see description above). So feel free to hack on this and improve it :-)

Have you seen SignatureTestConsole, this might be a good starting point.

pamapa avatar Oct 04 '22 10:10 pamapa

Thanks for your reply! Yes, I'm fiddling with SignatureTestConsole, I've just added my own certificate. If this had worked for you, I must have messed up something...

mmmilan avatar Oct 04 '22 10:10 mmmilan

@mmmilan @pamapa Its not visible because XForm.Finish() is not implemented in PdfSharpCore. https://github.com/ststeiger/PdfSharpCore/blob/8b9076c465123bc195c0d844dcec81eafae4fa3f/PdfSharpCore/Drawing/XForm.cs#L178 versus https://github.com/empira/PDFsharp/blob/3205bd933b464d150c0f42e8bcdff3314b6c6164/src/PdfSharp/Drawing/XForm.cs#L231

It also doesn't work in SignatureTestConsole by default, because that project's first target framework is netcoreapp3.1, and in the version of PdfSharpCore that this PR is based on, the particular XGraphics ctor that this work requires just silently doesn't create the renderer unless the TFM is net5.0 or higher: https://github.com/pamapa/PdfSharpCore/blob/b3e115417785be2f84150b14b7210854b0767997/PdfSharpCore/Drawing/XGraphics.cs#L211-L217 (this was fixed recently upstream in https://github.com/ststeiger/PdfSharpCore/pull/295)

If you change SignatureTestConsole to target .NET 6 specifically, and also go add the following implementation of XForm.Finish(), then it works:

        internal virtual void Finish()
        {
            if (_formState == FormState.NotATemplate || _formState == FormState.Finished)
                return;

            Debug.Assert(_formState == FormState.Created || _formState == FormState.UnderConstruction);
            _formState = FormState.Finished;
            Gfx.Dispose();
            Gfx = null;

            if (PdfRenderer != null)
            {
                //pdfForm.CreateStream(PdfEncoders.RawEncoding.GetBytes(PdfRenderer.GetContent()));
                PdfRenderer.Close();
                Debug.Assert(PdfRenderer == null);

                if (_document.Options.CompressContentStreams)
                {
                    _pdfForm.Stream.Value = Filtering.FlateDecode.Encode(_pdfForm.Stream.Value, _document.Options.FlateEncodeMode);
                    _pdfForm.Elements["/Filter"] = new PdfName("/FlateDecode");
                }
                int length = _pdfForm.Stream.Length;
                _pdfForm.Elements.SetInteger("/Length", length);
            }
        }

ascott18 avatar Nov 30 '22 02:11 ascott18

It works! Thank you!

mmmilan avatar Nov 30 '22 07:11 mmmilan

@ascott18 nice work

pamapa avatar Nov 30 '22 08:11 pamapa