dealfonso / sapp

Simple and Agnostic PDF Document Parser in PHP - sign PDF docs using PHP
GNU Lesser General Public License v3.0
110 stars 29 forks source link

Extracting all signatures #58

Open henrywood opened 9 months ago

henrywood commented 9 months ago

How can I extract all signatures from a PDF (to validate them one by one) ?

Please help !

Thanks !

dealfonso commented 9 months ago

Do you need the signatures? Or the signed documents at each version?

Please check method get_signatures

henrywood commented 9 months ago

@dealfonso Thanks ! I don't know how I was able to overlook that method :)

henrywood commented 9 months ago

This line:

https://github.com/dealfonso/sapp/blob/main/src/PDFDoc.php#L1076C1-L1076C60

throws a TypeError on some signed PDFs:

PHP Warning: Undefined array key 0 in /tmp/sapp/vendor/ddn/sapp/src/PDFDoc.php on line 1076 PHP Fatal error: Uncaught TypeError: Unsupported operand types: array + bool in /tmp/sapp/vendor/ddn/sapp/src/PDFDoc.php:1076 Stack trace:

0 /tmp/sapp/vendor/ddn/sapp/src/PDFDoc.php(1090): ddn\sapp\PDFDoc->get_signatures()

1 /tmp/sapp/test_verify.php(19): ddn\sapp\PDFDoc->get_signature_count()

2 {main}

thrown in /tmp/sapp/vendor/ddn/sapp/src/PDFDoc.php on line 1076

(I am running PHP 8.2)

Apparently $cert[0] is not set such cases ?

I tested using this script:

<?php

use ddn\sapp\PDFDoc;

require_once('vendor/autoload.php');

if (($argc < 2) || ($argc > 3))
        fwrite(STDERR, sprintf("usage: %s <filename> [<output>]", $argv[0]));
else {
        if (!file_exists($argv[1]))
                fwrite(STDERR, "failed to open file " . $argv[1]);
        else {
                $obj = PDFDoc::from_string(file_get_contents($argv[1]));

                if ($obj === false)
                        fwrite(STDERR, "failed to parse file " . $argv[1]);
                else {

                        $sigCount = $obj->get_signature_count();

                        if ($sigCount > 0) {

                                $signatures = $obj->get_signatures();

                                $okCount = 0;

                                var_dump($signatures);

                                foreach($signatures as $signature) {

                                        // TODO

                                }

                        } else {

                                // Document does not have a digital signature
                                throw new Exception('This document contains no digital signatures');
                        }
                }
        }
}
henrywood commented 9 months ago

Works: pdf_digital_signature_timestamp.pdf Produces the typeError above: sample01.pdf

erikn69 commented 9 months ago

59 avoids the TypeError