Removed large whitespace in signature dictionary to get valid signatures.

Whitespace was causing ByteRange to not cover the entire document.  Ideally should be everything outside the < > in the signature Contents field.
This commit is contained in:
Gunnsteinn Hall 2019-01-17 22:45:10 +00:00
parent 7bd43b16be
commit 649dbf0af6
2 changed files with 28 additions and 17 deletions

View File

@ -19,7 +19,7 @@ import (
"github.com/unidoc/unidoc/pdf/core"
)
// PdfAppender appends a new Pdf content to an existing Pdf document.
// PdfAppender appends new PDF content to an existing PDF document via incremental updates.
type PdfAppender struct {
rs io.ReadSeeker
parser *core.PdfParser
@ -416,7 +416,6 @@ func (a *PdfAppender) Sign(pageNum int, handler SignatureHandler) (acroForm *Pdf
appearance.V = sig.ToPdfObject()
appearance.FT = core.MakeName("Sig")
appearance.V = sig.ToPdfObject()
//appearance.Ff = core.MakeInteger(0)
appearance.T = core.MakeString("Signature1")
appearance.F = core.MakeInteger(132)
appearance.P = page.ToPdfObject()
@ -424,9 +423,14 @@ func (a *PdfAppender) Sign(pageNum int, handler SignatureHandler) (acroForm *Pdf
core.MakeInteger(0))
appearance.Signature = sig
// Add the signature appearance to the page annotations.
page.Annotations = append(page.Annotations, appearance.PdfAnnotationWidget.PdfAnnotation)
a.pages[pageIndex] = page
// Update acroform.
a.ReplaceAcroForm(acroForm)
return acroForm, appearance, nil
}
@ -437,7 +441,6 @@ func (a *PdfAppender) ReplaceAcroForm(acroForm *PdfAcroForm) {
// Write writes the Appender output to io.Writer.
func (a *PdfAppender) Write(w io.Writer) error {
writer := NewPdfWriter()
pagesDict, ok := core.GetDict(writer.pages)
@ -499,7 +502,7 @@ func (a *PdfAppender) Write(w io.Writer) error {
common.Log.Trace("Page Parent: %T", parent)
parentDict, ok := parent.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return errors.New("Invalid Parent object")
return errors.New("invalid Parent object")
}
for _, field := range inheritedFields {
common.Log.Trace("Field %s", field)
@ -593,10 +596,13 @@ func (a *PdfAppender) Write(w io.Writer) error {
writerW = bytes.NewBuffer(nil)
}
// Do a mock write to get offsets.
// TODO(gunnsth): Only needed when dealing with signatures?
if err := writer.Write(writerW); err != nil {
return err
}
// TODO(gunnsth): Consider whether the dynamic content can be handled with generic write hooks?
if hasSigDict {
bufferData := writerW.(*bytes.Buffer).Bytes()
byteRange := core.MakeArray()

View File

@ -12,7 +12,8 @@ import (
"github.com/unidoc/unidoc/pdf/core"
)
// pdfSignDictionary is needed because of the digital checksum calculates after a new file creation and writes as a value into PdfDictionary in the existing file.
// pdfSignDictionary is used as a wrapper around PdfSignature for digital checksum calculation
// and population of /Contents and /ByteRange.
type pdfSignDictionary struct {
*core.PdfObjectDictionary
handler *SignatureHandler
@ -52,15 +53,15 @@ func (d *pdfSignDictionary) WriteString() string {
out.WriteString(" ")
d.byteRangeOffsetStart = out.Len()
out.WriteString(v.WriteString())
out.WriteString(" ")
d.byteRangeOffsetEnd = out.Len()
out.WriteString(" ")
d.byteRangeOffsetEnd = out.Len() - 1
case "Contents":
out.WriteString(k.WriteString())
out.WriteString(" ")
d.contentsOffsetStart = out.Len()
out.WriteString(v.WriteString())
out.WriteString(" ")
d.contentsOffsetEnd = out.Len()
out.WriteString(" ")
d.contentsOffsetEnd = out.Len() - 1
default:
out.WriteString(k.WriteString())
out.WriteString(" ")
@ -100,7 +101,11 @@ type PdfSignature struct {
// NewPdfSignature creates a new PdfSignature object.
func NewPdfSignature() *PdfSignature {
sig := &PdfSignature{}
sigDict := &pdfSignDictionary{PdfObjectDictionary: core.MakeDict(), handler: &sig.Handler, signature: sig}
sigDict := &pdfSignDictionary{
PdfObjectDictionary: core.MakeDict(),
handler: &sig.Handler,
signature: sig,
}
sig.container = core.MakeIndirectObject(sigDict)
return sig
}
@ -172,7 +177,9 @@ func (sig *PdfSignature) ToPdfObject() core.PdfObject {
if sig.Contents != nil {
dict.Set("Contents", sig.Contents)
}
// FIXME: ByteRange and Contents need to be updated dynamically.
// NOTE: ByteRange and Contents need to be updated dynamically.
// TODO: Currently dynamic update is only in the appender, need to support in the PdfWriter
// too for the initial signature on document creation.
return container
}
@ -251,11 +258,9 @@ func (r *PdfReader) newPdfSignatureFromIndirect(container *core.PdfIndirectObjec
type PdfSignatureField struct {
container *core.PdfIndirectObject
V *PdfSignature
// Type: /Sig
// V: *PdfSignature...
Lock *core.PdfIndirectObject // Shall be an indirect reference.
SV *core.PdfIndirectObject // Shall be an indirect reference.
V *PdfSignature
Lock *core.PdfIndirectObject
SV *core.PdfIndirectObject
Kids *core.PdfObjectArray
}
@ -304,7 +309,7 @@ type PdfSignatureFieldLock struct {
// (Table 234 - p. 455 in PDF32000_2008).
type PdfSignatureFieldSeed struct {
container *core.PdfIndirectObject
// Type
Ff *core.PdfObjectInteger
Filter *core.PdfObjectName
SubFilter *core.PdfObjectArray