Check errors

This commit is contained in:
Paul van Brouwershaven
2022-06-30 18:04:25 +02:00
parent 0e77069efa
commit 44ac3c7806
8 changed files with 87 additions and 54 deletions

View File

@@ -80,7 +80,10 @@ func leftPad(s string, padStr string, pLen int) string {
}
func writePartFromSourceFileToTargetFile(input_file io.ReadSeeker, output_file io.Writer, offset int64, length int64) error {
input_file.Seek(offset, 0)
_, err := input_file.Seek(offset, 0)
if err != nil {
return err
}
// Create a small buffer for proper IO handling.
max_chunk_length := int64(1024)

View File

@@ -124,35 +124,35 @@ func TestWritePartFromSourceFileToTargetFile(t *testing.T) {
return
}
writePartFromSourceFileToTargetFile(input_file, writer, 0, 0)
_ = writePartFromSourceFileToTargetFile(input_file, writer, 0, 0)
writer.Flush()
if writer.Buffered() != 0 {
t.Errorf("Content was copied while length was 0")
}
writePartFromSourceFileToTargetFile(input_file, writer, 0, -20)
_ = writePartFromSourceFileToTargetFile(input_file, writer, 0, -20)
writer.Flush()
if writer.Buffered() != 0 {
t.Errorf("Content was copied while length was smaller than 0")
}
writePartFromSourceFileToTargetFile(input_file, writer, 0, 8)
_ = writePartFromSourceFileToTargetFile(input_file, writer, 0, 8)
writer.Flush()
if string(b.Bytes()) != "%PDF-2.0" {
t.Errorf("Wrong content was copied, got %s but expected %s", string(b.Bytes()), "%PDF-2.0")
if b.String() != "%PDF-2.0" {
t.Errorf("Wrong content was copied, got %s but expected %s", b.String(), "%PDF-2.0")
}
writePartFromSourceFileToTargetFile(input_file, writer, 33, 8)
_ = writePartFromSourceFileToTargetFile(input_file, writer, 33, 8)
writer.Flush()
if string(b.Bytes()) != "%PDF-2.0/Catalog" {
t.Errorf("Wrong content was copied, got %s but expected %s", string(b.Bytes()), "%PDF-2.0/Catalog")
if b.String() != "%PDF-2.0/Catalog" {
t.Errorf("Wrong content was copied, got %s but expected %s", b.String(), "%PDF-2.0/Catalog")
}
writePartFromSourceFileToTargetFile(input_file, writer, 0, 1200)
_ = writePartFromSourceFileToTargetFile(input_file, writer, 0, 1200)
if writer.Buffered() != 1200 {
t.Errorf("Requested 1200 bytes but only got %d", writer.Buffered())

View File

@@ -6,7 +6,9 @@ import (
)
func (context *SignContext) updateByteRange() error {
context.OutputBuffer.Seek(0, 0)
if _, err := context.OutputBuffer.Seek(0, 0); err != nil {
return err
}
output_file_size := int64(context.OutputBuffer.Buff.Len())
// Calculate ByteRange values to replace them.
@@ -29,17 +31,23 @@ func (context *SignContext) updateByteRange() error {
// Make sure our ByteRange string didn't shrink in length.
new_byte_range += strings.Repeat(" ", len(signatureByteRangePlaceholder)-len(new_byte_range))
context.OutputBuffer.Seek(0, 0)
if _, err := context.OutputBuffer.Seek(0, 0); err != nil {
return err
}
file_content := context.OutputBuffer.Buff.Bytes()
context.OutputBuffer.Write(file_content[:context.ByteRangeStartByte])
if _, err := context.OutputBuffer.Write(file_content[:context.ByteRangeStartByte]); err != nil {
return err
}
// Write new ByteRange.
if _, err := context.OutputBuffer.Write([]byte(new_byte_range)); err != nil {
return err
}
context.OutputBuffer.Write(file_content[context.ByteRangeStartByte+int64(len(new_byte_range)):])
if _, err := context.OutputBuffer.Write(file_content[context.ByteRangeStartByte+int64(len(new_byte_range)):]); err != nil {
return err
}
return nil
}

View File

@@ -11,7 +11,9 @@ func (context *SignContext) writeTrailer() error {
trailer_length := context.PDFReader.XrefInformation.IncludingTrailerEndPos - context.PDFReader.XrefInformation.EndPos
// Read the trailer so we can replace the size.
context.InputFile.Seek(context.PDFReader.XrefInformation.EndPos+1, 0)
if _, err := context.InputFile.Seek(context.PDFReader.XrefInformation.EndPos+1, 0); err != nil {
return err
}
trailer_buf := make([]byte, trailer_length)
if _, err := context.InputFile.Read(trailer_buf); err != nil {
return err

View File

@@ -84,8 +84,8 @@ func (context *SignContext) writeXrefStream() error {
predictor := context.PDFReader.Trailer().Key("DecodeParms").Key("Predictor").Int64()
streamBytes := []byte{}
err := errors.New("")
var streamBytes []byte
var err error
writeXrefStreamLine(buffer, 1, int(context.Filesize), 0)
writeXrefStreamLine(buffer, 1, int(context.Filesize+context.VisualSignData.Length), 0)
@@ -171,7 +171,9 @@ func EncodePNGSUBBytes(columns int, data []byte) ([]byte, error) {
var b bytes.Buffer
w := zlib.NewWriter(&b)
w.Write(data)
if _, err := w.Write(data); err != nil {
return nil, err
}
w.Close()
return b.Bytes(), nil
@@ -209,7 +211,9 @@ func EncodePNGUPBytes(columns int, data []byte) ([]byte, error) {
var b bytes.Buffer
w := zlib.NewWriter(&b)
w.Write(data)
if _, err := w.Write(data); err != nil {
return nil, err
}
w.Close()
return b.Bytes(), nil

View File

@@ -4,6 +4,7 @@ import (
"crypto"
"crypto/x509"
"encoding/hex"
"fmt"
"io"
"os"
"time"
@@ -164,7 +165,10 @@ func (context *SignContext) SignPDF() error {
context.OutputBuffer = filebuffer.New([]byte{})
// Copy old file into new file.
context.InputFile.Seek(0, 0)
_, err := context.InputFile.Seek(0, 0)
if err != nil {
return err
}
if _, err := io.Copy(context.OutputBuffer, context.InputFile); err != nil {
return err
}
@@ -182,26 +186,22 @@ func (context *SignContext) SignPDF() error {
case "ECDSA-SHA1":
case "DSA-SHA1":
context.SignatureMaxLength += uint32(hex.EncodedLen(128))
break
case "SHA256-RSA":
case "ECDSA-SHA256":
case "DSA-SHA256":
context.SignatureMaxLength += uint32(hex.EncodedLen(256))
break
case "SHA384-RSA":
case "ECDSA-SHA384":
context.SignatureMaxLength += uint32(hex.EncodedLen(384))
break
case "SHA512-RSA":
case "ECDSA-SHA512":
context.SignatureMaxLength += uint32(hex.EncodedLen(512))
break
}
// Add size for my certificate.
degenerated, err := pkcs7.DegenerateCertificate(context.SignData.Certificate.Raw)
if err != nil {
return err
return fmt.Errorf("failed to degenerate certificate: %w", err)
}
context.SignatureMaxLength += uint32(hex.EncodedLen(len(degenerated)))
@@ -216,7 +216,7 @@ func (context *SignContext) SignPDF() error {
for _, cert := range certificate_chain {
degenerated, err := pkcs7.DegenerateCertificate(cert.Raw)
if err != nil {
return err
return fmt.Errorf("failed to degenerate certificate in chain: %w", err)
}
context.SignatureMaxLength += uint32(hex.EncodedLen(len(degenerated)))
@@ -225,17 +225,22 @@ func (context *SignContext) SignPDF() error {
// Add estimated size for TSA.
// We can't kow actual size of TSA until after signing.
//
// Different TSA servers provide different response sizes, we
// might need to make this configurable or detect and store.
if context.SignData.TSA.URL != "" {
context.SignatureMaxLength += uint32(hex.EncodedLen(6000))
context.SignatureMaxLength += uint32(hex.EncodedLen(9000))
}
// Fetch revocation data before adding signature placeholder.
// Revocation data can be quite large and we need to create enough space in the placeholder.
context.fetchRevocationData()
if err := context.fetchRevocationData(); err != nil {
return fmt.Errorf("failed to fetch revocation data: %w", err)
}
visual_signature, err := context.createVisualSignature()
if err != nil {
return err
return fmt.Errorf("failed to create visual signature: %w", err)
}
context.VisualSignData.Length = int64(len(visual_signature))
@@ -247,14 +252,14 @@ func (context *SignContext) SignPDF() error {
catalog, err := context.createCatalog()
if err != nil {
return err
return fmt.Errorf("failed to create catalog: %w", err)
}
context.CatalogData.Length = int64(len(catalog))
// Write the new catalog object.
if _, err := context.OutputBuffer.Write([]byte(catalog)); err != nil {
return err
return fmt.Errorf("failed to write catalog: %w", err)
}
// Create the signature object
@@ -262,14 +267,14 @@ func (context *SignContext) SignPDF() error {
info, err := context.createInfo()
if err != nil {
return err
return fmt.Errorf("failed to create info: %w", err)
}
context.InfoData.Length = int64(len(info))
// Write the new catalog object.
if _, err := context.OutputBuffer.Write([]byte(info)); err != nil {
return err
return fmt.Errorf("failed to write info: %w", err)
}
appended_bytes := context.Filesize + int64(len(catalog)) + int64(len(visual_signature)) + int64(len(info))
@@ -283,32 +288,36 @@ func (context *SignContext) SignPDF() error {
// Write the new signature object.
if _, err := context.OutputBuffer.Write([]byte(signature_object)); err != nil {
return err
return fmt.Errorf("failed to create the new signature object: %w", err)
}
// Calculate the new start position of the xref table.
context.NewXrefStart = appended_bytes + int64(len(signature_object))
if err := context.writeXref(); err != nil {
return err
return fmt.Errorf("failed to write xref: %w", err)
}
if err := context.writeTrailer(); err != nil {
return err
return fmt.Errorf("failed to write trailer: %w", err)
}
if err := context.updateByteRange(); err != nil {
return err
return fmt.Errorf("failed to update byte range: %w", err)
}
if err := context.replaceSignature(); err != nil {
return err
return fmt.Errorf("failed to replace signature: %w", err)
}
context.OutputBuffer.Seek(0, 0)
if _, err := context.OutputBuffer.Seek(0, 0); err != nil {
return err
}
file_content := context.OutputBuffer.Buff.Bytes()
context.OutputFile.Write(file_content)
if _, err := context.OutputFile.Write(file_content); err != nil {
return fmt.Errorf("failed to write to output file: %w", err)
}
return nil
}

View File

@@ -65,7 +65,6 @@ func TestReaderCanReadPDF(t *testing.T) {
for _, f := range files {
ext := filepath.Ext(f.Name())
if ext != ".pdf" {
t.Log("Skipping file", f.Name())
continue
}
@@ -100,8 +99,8 @@ func TestReaderCanReadPDF(t *testing.T) {
}
func TestSignPDF(t *testing.T) {
os.RemoveAll("../testfiles/failed/")
os.MkdirAll("../testfiles/failed/", 0777)
_ = os.RemoveAll("../testfiles/failed/")
_ = os.MkdirAll("../testfiles/failed/", 0777)
files, err := ioutil.ReadDir("../testfiles")
if err != nil {
@@ -140,7 +139,6 @@ func TestSignPDF(t *testing.T) {
ext := filepath.Ext(f.Name())
if ext != ".pdf" {
t.Log("Skipping file", f.Name())
continue
}
@@ -171,6 +169,10 @@ func TestSignPDF(t *testing.T) {
}
outputFile, err := ioutil.TempFile("", "pdfsign_test")
if err != nil {
t.Errorf("%s", err.Error())
return
}
err = Sign(input_file, outputFile, rdr, size, SignData{
Signature: SignDataSignature{
@@ -196,7 +198,7 @@ func TestSignPDF(t *testing.T) {
if err != nil {
input_file.Close()
os.Remove(outputFile.Name())
_ = os.Remove(outputFile.Name())
st.Errorf("%s: %s", f.Name(), err.Error())
return
}
@@ -244,6 +246,10 @@ func TestSignPDFFile(t *testing.T) {
certificate_chains := make([][]*x509.Certificate, 0)
tmpfile, err := ioutil.TempFile("", "pdfsign_test")
if err != nil {
t.Errorf("%s", err.Error())
return
}
err = SignFile("../testfiles/testfile20.pdf", tmpfile.Name(), SignData{
Signature: SignDataSignature{
@@ -322,7 +328,10 @@ func BenchmarkSignPDF(b *testing.B) {
}
for n := 0; n < b.N; n++ {
input_file.Seek(0, 0)
if _, err := input_file.Seek(0, 0); err != nil {
b.Errorf("%s: %s", "testfile20.pdf", err.Error())
return
}
err = Sign(input_file, ioutil.Discard, rdr, size, SignData{
Signature: SignDataSignature{

View File

@@ -71,7 +71,9 @@ type DocumentInfo struct {
func File(file *os.File) (apiResp *Response, err error) {
finfo, _ := file.Stat()
file.Seek(0, 0)
if _, err := file.Seek(0, 0); err != nil {
return nil, err
}
return Reader(file, finfo.Size())
}
@@ -155,9 +157,9 @@ func Reader(file io.ReaderAt, size int64) (apiResp *Response, err error) {
// Signer certificate
// http://www.alvestrand.no/objectid/1.2.840.113549.1.9.html
// http://www.alvestrand.no/objectid/1.2.840.113583.1.1.8.html
var isn []byte
//var isn []byte
for _, s := range p7.Signers {
isn = s.IssuerAndSerialNumber.IssuerName.FullBytes
//isn = s.IssuerAndSerialNumber.IssuerName.FullBytes
//for _, a := range s.AuthenticatedAttributes {
//fmt.Printf("A: %v, %#v\n", s.IssuerAndSerialNumber.SerialNumber, a.Type)
//}
@@ -199,13 +201,9 @@ func Reader(file io.ReaderAt, size int64) (apiResp *Response, err error) {
}
// Directory of certificates, including OCSP
//var ica *x509.Certificate
certPool := x509.NewCertPool()
for _, cert := range p7.Certificates {
certPool.AddCert(cert)
if bytes.Equal(isn, cert.RawSubject) {
//ica = cert
}
}
// Verify the digital signature of the pdf file.
@@ -225,7 +223,7 @@ func Reader(file io.ReaderAt, size int64) (apiResp *Response, err error) {
// PDF signature certificate revocation information attribute (1.2.840.113583.1.1.8)
var revInfo revocation.InfoArchival
p7.UnmarshalSignedAttribute(asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 8}, &revInfo)
_ = p7.UnmarshalSignedAttribute(asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 8}, &revInfo)
// Parse OCSP response
var ocspStatus = make(map[string]*ocsp.Response)