Retry with expected signature lenght

This commit is contained in:
Paul van Brouwershaven
2022-06-29 21:07:59 +02:00
parent 2ce268ea4d
commit 3caf640baa
2 changed files with 18 additions and 10 deletions

View File

@@ -225,7 +225,7 @@ func (context *SignContext) GetTSA(sign_content []byte) (timestamp_response []by
ts_request_reader := bytes.NewReader(ts_request) ts_request_reader := bytes.NewReader(ts_request)
req, err := http.NewRequest("POST", context.SignData.TSA.URL, ts_request_reader) req, err := http.NewRequest("POST", context.SignData.TSA.URL, ts_request_reader)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("error requesting timestamp (%s): %w", context.SignData.TSA.URL, err)
} }
req.Header.Add("Content-Type", "application/timestamp-query") req.Header.Add("Content-Type", "application/timestamp-query")
@@ -247,9 +247,9 @@ func (context *SignContext) GetTSA(sign_content []byte) (timestamp_response []by
if err == nil { if err == nil {
defer resp.Body.Close() defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body) body, _ := ioutil.ReadAll(resp.Body)
err = errors.New("Non success response (" + strconv.Itoa(code) + "): " + string(body)) err = errors.New("non success response (" + strconv.Itoa(code) + "): " + string(body))
} else { } else {
err = errors.New("Non success response (" + strconv.Itoa(code) + ")") err = errors.New("non success response (" + strconv.Itoa(code) + ")")
} }
return nil, err return nil, err
@@ -274,7 +274,10 @@ func (context *SignContext) replaceSignature() error {
hex.Encode(dst, signature) hex.Encode(dst, signature)
if uint32(len(dst)) > context.SignatureMaxLength { if uint32(len(dst)) > context.SignatureMaxLength {
return errors.New("Signature is too big to fit in reserved space.") // TODO: Should we log this retry?
// set new base and try signing again
context.SignatureMaxLengthBase += (uint32(len(dst)) - context.SignatureMaxLength) + 1
return context.SignPDF()
} }
context.OutputBuffer.Seek(0, 0) context.OutputBuffer.Seek(0, 0)

View File

@@ -8,9 +8,10 @@ import (
"os" "os"
"time" "time"
"bitbucket.org/digitorus/pdf" "github.com/digitorus/pdf"
"bitbucket.org/digitorus/pdfsign/revocation" "github.com/digitorus/pdfsign/revocation"
"github.com/digitorus/pkcs7" "github.com/digitorus/pkcs7"
"github.com/mattetti/filebuffer" "github.com/mattetti/filebuffer"
) )
@@ -90,6 +91,7 @@ type SignContext struct {
SignatureContentsStartByte int64 SignatureContentsStartByte int64
ByteRangeValues []int64 ByteRangeValues []int64
SignatureMaxLength uint32 SignatureMaxLength uint32
SignatureMaxLengthBase uint32
} }
func SignFile(input string, output string, sign_data SignData) error { func SignFile(input string, output string, sign_data SignData) error {
@@ -123,6 +125,7 @@ func Sign(input io.ReadSeeker, output io.Writer, rdr *pdf.Reader, size int64, si
sign_data.ObjectId = uint32(rdr.XrefInformation.ItemCount) + 3 sign_data.ObjectId = uint32(rdr.XrefInformation.ItemCount) + 3
// We do size+1 because we insert a newline. // We do size+1 because we insert a newline.
context := SignContext{ context := SignContext{
Filesize: size + 1, Filesize: size + 1,
PDFReader: rdr, PDFReader: rdr,
@@ -137,7 +140,8 @@ func Sign(input io.ReadSeeker, output io.Writer, rdr *pdf.Reader, size int64, si
InfoData: InfoData{ InfoData: InfoData{
ObjectId: uint32(rdr.XrefInformation.ItemCount) + 2, ObjectId: uint32(rdr.XrefInformation.ItemCount) + 2,
}, },
SignData: sign_data, SignData: sign_data,
SignatureMaxLengthBase: uint32(hex.EncodedLen(512)),
} }
err := context.SignPDF() err := context.SignPDF()
@@ -160,6 +164,7 @@ func (context *SignContext) SignPDF() error {
context.OutputBuffer = filebuffer.New([]byte{}) context.OutputBuffer = filebuffer.New([]byte{})
// Copy old file into new file. // Copy old file into new file.
context.InputFile.Seek(0, 0)
if _, err := io.Copy(context.OutputBuffer, context.InputFile); err != nil { if _, err := io.Copy(context.OutputBuffer, context.InputFile); err != nil {
return err return err
} }
@@ -170,9 +175,9 @@ func (context *SignContext) SignPDF() error {
} }
// Base size for signature. // Base size for signature.
context.SignatureMaxLength = uint32(hex.EncodedLen(512)) context.SignatureMaxLength = context.SignatureMaxLengthBase
switch string(context.SignData.Certificate.SignatureAlgorithm) { switch context.SignData.Certificate.SignatureAlgorithm.String() {
case "SHA1-RSA": case "SHA1-RSA":
case "ECDSA-SHA1": case "ECDSA-SHA1":
case "DSA-SHA1": case "DSA-SHA1":
@@ -221,7 +226,7 @@ func (context *SignContext) SignPDF() error {
// Add estimated size for TSA. // Add estimated size for TSA.
// We can't kow actual size of TSA until after signing. // We can't kow actual size of TSA until after signing.
if context.SignData.TSA.URL != "" { if context.SignData.TSA.URL != "" {
context.SignatureMaxLength += uint32(hex.EncodedLen(4000)) context.SignatureMaxLength += uint32(hex.EncodedLen(6000))
} }
// Fetch revocation data before adding signature placeholder. // Fetch revocation data before adding signature placeholder.