mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-04 22:17:22 +08:00
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:
parent
7bd43b16be
commit
649dbf0af6
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/unidoc/unidoc/pdf/core"
|
"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 {
|
type PdfAppender struct {
|
||||||
rs io.ReadSeeker
|
rs io.ReadSeeker
|
||||||
parser *core.PdfParser
|
parser *core.PdfParser
|
||||||
@ -416,7 +416,6 @@ func (a *PdfAppender) Sign(pageNum int, handler SignatureHandler) (acroForm *Pdf
|
|||||||
appearance.V = sig.ToPdfObject()
|
appearance.V = sig.ToPdfObject()
|
||||||
appearance.FT = core.MakeName("Sig")
|
appearance.FT = core.MakeName("Sig")
|
||||||
appearance.V = sig.ToPdfObject()
|
appearance.V = sig.ToPdfObject()
|
||||||
//appearance.Ff = core.MakeInteger(0)
|
|
||||||
appearance.T = core.MakeString("Signature1")
|
appearance.T = core.MakeString("Signature1")
|
||||||
appearance.F = core.MakeInteger(132)
|
appearance.F = core.MakeInteger(132)
|
||||||
appearance.P = page.ToPdfObject()
|
appearance.P = page.ToPdfObject()
|
||||||
@ -424,9 +423,14 @@ func (a *PdfAppender) Sign(pageNum int, handler SignatureHandler) (acroForm *Pdf
|
|||||||
core.MakeInteger(0))
|
core.MakeInteger(0))
|
||||||
appearance.Signature = sig
|
appearance.Signature = sig
|
||||||
|
|
||||||
|
// Add the signature appearance to the page annotations.
|
||||||
|
page.Annotations = append(page.Annotations, appearance.PdfAnnotationWidget.PdfAnnotation)
|
||||||
|
|
||||||
a.pages[pageIndex] = page
|
a.pages[pageIndex] = page
|
||||||
|
|
||||||
|
// Update acroform.
|
||||||
a.ReplaceAcroForm(acroForm)
|
a.ReplaceAcroForm(acroForm)
|
||||||
|
|
||||||
return acroForm, appearance, nil
|
return acroForm, appearance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +441,6 @@ func (a *PdfAppender) ReplaceAcroForm(acroForm *PdfAcroForm) {
|
|||||||
|
|
||||||
// Write writes the Appender output to io.Writer.
|
// Write writes the Appender output to io.Writer.
|
||||||
func (a *PdfAppender) Write(w io.Writer) error {
|
func (a *PdfAppender) Write(w io.Writer) error {
|
||||||
|
|
||||||
writer := NewPdfWriter()
|
writer := NewPdfWriter()
|
||||||
|
|
||||||
pagesDict, ok := core.GetDict(writer.pages)
|
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)
|
common.Log.Trace("Page Parent: %T", parent)
|
||||||
parentDict, ok := parent.PdfObject.(*core.PdfObjectDictionary)
|
parentDict, ok := parent.PdfObject.(*core.PdfObjectDictionary)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("Invalid Parent object")
|
return errors.New("invalid Parent object")
|
||||||
}
|
}
|
||||||
for _, field := range inheritedFields {
|
for _, field := range inheritedFields {
|
||||||
common.Log.Trace("Field %s", field)
|
common.Log.Trace("Field %s", field)
|
||||||
@ -593,10 +596,13 @@ func (a *PdfAppender) Write(w io.Writer) error {
|
|||||||
writerW = bytes.NewBuffer(nil)
|
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 {
|
if err := writer.Write(writerW); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(gunnsth): Consider whether the dynamic content can be handled with generic write hooks?
|
||||||
if hasSigDict {
|
if hasSigDict {
|
||||||
bufferData := writerW.(*bytes.Buffer).Bytes()
|
bufferData := writerW.(*bytes.Buffer).Bytes()
|
||||||
byteRange := core.MakeArray()
|
byteRange := core.MakeArray()
|
||||||
|
@ -12,7 +12,8 @@ import (
|
|||||||
"github.com/unidoc/unidoc/pdf/core"
|
"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 {
|
type pdfSignDictionary struct {
|
||||||
*core.PdfObjectDictionary
|
*core.PdfObjectDictionary
|
||||||
handler *SignatureHandler
|
handler *SignatureHandler
|
||||||
@ -53,14 +54,14 @@ func (d *pdfSignDictionary) WriteString() string {
|
|||||||
d.byteRangeOffsetStart = out.Len()
|
d.byteRangeOffsetStart = out.Len()
|
||||||
out.WriteString(v.WriteString())
|
out.WriteString(v.WriteString())
|
||||||
out.WriteString(" ")
|
out.WriteString(" ")
|
||||||
d.byteRangeOffsetEnd = out.Len()
|
d.byteRangeOffsetEnd = out.Len() - 1
|
||||||
case "Contents":
|
case "Contents":
|
||||||
out.WriteString(k.WriteString())
|
out.WriteString(k.WriteString())
|
||||||
out.WriteString(" ")
|
out.WriteString(" ")
|
||||||
d.contentsOffsetStart = out.Len()
|
d.contentsOffsetStart = out.Len()
|
||||||
out.WriteString(v.WriteString())
|
out.WriteString(v.WriteString())
|
||||||
out.WriteString(" ")
|
out.WriteString(" ")
|
||||||
d.contentsOffsetEnd = out.Len()
|
d.contentsOffsetEnd = out.Len() - 1
|
||||||
default:
|
default:
|
||||||
out.WriteString(k.WriteString())
|
out.WriteString(k.WriteString())
|
||||||
out.WriteString(" ")
|
out.WriteString(" ")
|
||||||
@ -100,7 +101,11 @@ type PdfSignature struct {
|
|||||||
// NewPdfSignature creates a new PdfSignature object.
|
// NewPdfSignature creates a new PdfSignature object.
|
||||||
func NewPdfSignature() *PdfSignature {
|
func NewPdfSignature() *PdfSignature {
|
||||||
sig := &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)
|
sig.container = core.MakeIndirectObject(sigDict)
|
||||||
return sig
|
return sig
|
||||||
}
|
}
|
||||||
@ -172,7 +177,9 @@ func (sig *PdfSignature) ToPdfObject() core.PdfObject {
|
|||||||
if sig.Contents != nil {
|
if sig.Contents != nil {
|
||||||
dict.Set("Contents", sig.Contents)
|
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
|
return container
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,10 +259,8 @@ type PdfSignatureField struct {
|
|||||||
container *core.PdfIndirectObject
|
container *core.PdfIndirectObject
|
||||||
|
|
||||||
V *PdfSignature
|
V *PdfSignature
|
||||||
// Type: /Sig
|
Lock *core.PdfIndirectObject
|
||||||
// V: *PdfSignature...
|
SV *core.PdfIndirectObject
|
||||||
Lock *core.PdfIndirectObject // Shall be an indirect reference.
|
|
||||||
SV *core.PdfIndirectObject // Shall be an indirect reference.
|
|
||||||
Kids *core.PdfObjectArray
|
Kids *core.PdfObjectArray
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +309,7 @@ type PdfSignatureFieldLock struct {
|
|||||||
// (Table 234 - p. 455 in PDF32000_2008).
|
// (Table 234 - p. 455 in PDF32000_2008).
|
||||||
type PdfSignatureFieldSeed struct {
|
type PdfSignatureFieldSeed struct {
|
||||||
container *core.PdfIndirectObject
|
container *core.PdfIndirectObject
|
||||||
// Type
|
|
||||||
Ff *core.PdfObjectInteger
|
Ff *core.PdfObjectInteger
|
||||||
Filter *core.PdfObjectName
|
Filter *core.PdfObjectName
|
||||||
SubFilter *core.PdfObjectArray
|
SubFilter *core.PdfObjectArray
|
||||||
|
Loading…
x
Reference in New Issue
Block a user