Commit ba311960 authored by Albert Astals Cid's avatar Albert Astals Cid Committed by Albert Astals Cid

pdfsig: Show also signatures that aren't attached to any page

Move two methods from FormWidgetSignature to FormFieldSignature where
they actually belong

Rename PDFDoc::getSignatureWidgets to getSignatureFields, making it go
through the FormsFields instead of the Page FormWidgets

Remove the gotos from pdfsig code

Add a few const here and there

Fixes part of #895
parent 84657591
This diff is collapsed.
......@@ -268,13 +268,13 @@ public:
FormWidgetSignature(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p);
void updateWidgetAppearance() override;
FormSignatureType signatureType();
FormSignatureType signatureType() const;
// Use -1 for now as validationTime
SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime);
// returns a list with the boundaries of the signed ranges
// the elements of the list are of type Goffset
std::vector<Goffset> getSignedRangeBounds();
std::vector<Goffset> getSignedRangeBounds() const;
// checks the length encoding of the signature and returns the hex encoded signature
// if the check passed (and the checked file size as output parameter in checkedFileSize)
......@@ -318,8 +318,10 @@ public:
GooString *getFullyQualifiedName();
FormWidget* findWidgetByRef (Ref aref);
int getNumWidgets() { return terminal ? numChildren : 0; }
FormWidget *getWidget(int i) { return terminal ? widgets[i] : nullptr; }
int getNumWidgets() const { return terminal ? numChildren : 0; }
FormWidget *getWidget(int i) const { return terminal ? widgets[i] : nullptr; }
int getNumChildren() const { return !terminal ? numChildren : 0; }
FormField *getChildren(int i) const { return children[i]; }
// only implemented in FormFieldButton
virtual void fillChildrenSiblingsID ();
......@@ -528,16 +530,25 @@ protected:
//------------------------------------------------------------------------
class FormFieldSignature: public FormField {
friend class FormWidgetSignature;
public:
FormFieldSignature(PDFDoc *docA, Object &&dict, const Ref ref, FormField *parent, std::set<int> *usedParents);
// Use -1 for now as validationTime
SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime);
// returns a list with the boundaries of the signed ranges
// the elements of the list are of type Goffset
std::vector<Goffset> getSignedRangeBounds() const;
// checks the length encoding of the signature and returns the hex encoded signature
// if the check passed (and the checked file size as output parameter in checkedFileSize)
// otherwise a nullptr is returned
GooString* getCheckedSignature(Goffset *checkedFileSize);
~FormFieldSignature() override;
Object* getByteRange() { return &byte_range; }
const GooString* getSignature() const { return signature; }
FormSignatureType getSignatureType() const { return signature_type; }
private:
void parseInfo();
......
......@@ -597,25 +597,32 @@ void PDFDoc::extractPDFSubtype() {
delete pdfSubtypeVersion;
}
std::vector<FormWidgetSignature*> PDFDoc::getSignatureWidgets()
static void addSignatureFieldsToVector(FormField *ff, std::vector<FormFieldSignature*> &res)
{
int num_pages = getNumPages();
FormPageWidgets *page_widgets = nullptr;
std::vector<FormWidgetSignature*> widget_vector;
for (int i = 1; i <= num_pages; i++) {
Page *p = getCatalog()->getPage(i);
if (p) {
page_widgets = p->getFormWidgets();
for (int j = 0; page_widgets != nullptr && j < page_widgets->getNumWidgets(); j++) {
if (page_widgets->getWidget(j)->getType() == formSignature) {
widget_vector.push_back(static_cast<FormWidgetSignature*>(page_widgets->getWidget(j)));
}
}
delete page_widgets;
if (ff->getNumChildren() == 0) {
if (ff->getType() == formSignature) {
res.push_back(static_cast<FormFieldSignature*>(ff));
}
} else {
for (int i = 0; i < ff->getNumChildren(); ++i) {
FormField *children = ff->getChildren(i);
addSignatureFieldsToVector(children, res);
}
}
}
std::vector<FormFieldSignature*> PDFDoc::getSignatureFields()
{
// const int num_pages = getNumPages();
std::vector<FormFieldSignature*> res;
const Form *f = catalog->getForm();
const int nRootFields = f->getNumFields();
for (int i = 0; i < nRootFields; ++i) {
FormField *ff = f->getRootField(i);
addSignatureFieldsToVector(ff, res);
}
return widget_vector;
return res;
}
void PDFDoc::displayPage(OutputDev *out, int page,
......
......@@ -239,7 +239,7 @@ public:
// Is the file encrypted?
bool isEncrypted() { return xref->isEncrypted(); }
std::vector<FormWidgetSignature*> getSignatureWidgets();
std::vector<FormFieldSignature*> getSignatureFields();
// Check various permissions.
bool okToPrint(bool ignoreOwnerPW = false)
......
......@@ -362,6 +362,7 @@ void Page::replaceXRef(XRef *xrefA) {
/* Loads standalone fields into Page, should be called once per page only */
void Page::loadStandaloneFields(Annots *annotations, Form *form) {
const int numAnnots = annotations ? annotations->getNumAnnots() : 0;
if (numAnnots < 1)
return;
......
......@@ -67,22 +67,22 @@ SignatureInfo::~SignatureInfo()
/* GETTERS */
SignatureValidationStatus SignatureInfo::getSignatureValStatus()
SignatureValidationStatus SignatureInfo::getSignatureValStatus() const
{
return sig_status;
}
CertificateValidationStatus SignatureInfo::getCertificateValStatus()
CertificateValidationStatus SignatureInfo::getCertificateValStatus() const
{
return cert_status;
}
const char *SignatureInfo::getSignerName()
const char *SignatureInfo::getSignerName() const
{
return signer_name;
}
const char *SignatureInfo::getSubjectDN()
const char *SignatureInfo::getSubjectDN() const
{
return subject_dn;
}
......@@ -97,12 +97,12 @@ const char *SignatureInfo::getReason() const
return reason;
}
int SignatureInfo::getHashAlgorithm()
int SignatureInfo::getHashAlgorithm() const
{
return hash_type;
}
time_t SignatureInfo::getSigningTime()
time_t SignatureInfo::getSigningTime() const
{
return signing_time;
}
......
......@@ -53,15 +53,15 @@ public:
SignatureInfo& operator=(const SignatureInfo &) = delete;
/* GETTERS */
SignatureValidationStatus getSignatureValStatus();
CertificateValidationStatus getCertificateValStatus();
const char *getSignerName();
const char *getSubjectDN();
SignatureValidationStatus getSignatureValStatus() const;
CertificateValidationStatus getCertificateValStatus() const;
const char *getSignerName() const;
const char *getSubjectDN() const;
const char *getLocation() const;
const char *getReason() const;
int getHashAlgorithm(); // Returns a NSS3 HASH_HashType or -1 if compiled without NSS3
time_t getSigningTime();
bool isSubfilterSupported() { return sig_subfilter_supported; }
int getHashAlgorithm() const; // Returns a NSS3 HASH_HashType or -1 if compiled without NSS3
time_t getSigningTime() const;
bool isSubfilterSupported() const { return sig_subfilter_supported; }
const X509CertificateInfo *getCertificateInfo() const;
/* SETTERS */
......
......@@ -97,9 +97,9 @@ static char *getReadableTime(time_t unix_time)
return time_str;
}
static bool dumpSignature(int sig_num, int sigCount, FormWidgetSignature *sig_widget, const char *filename)
static bool dumpSignature(int sig_num, int sigCount, FormFieldSignature *s, const char *filename)
{
const GooString *signature = sig_widget->getSignature();
const GooString *signature = s->getSignature();
if (!signature) {
printf("Cannot dump signature #%d\n", sig_num);
return false;
......@@ -149,19 +149,12 @@ static const ArgDesc argDesc[] = {
int main(int argc, char *argv[])
{
PDFDoc *doc = nullptr;
unsigned int sigCount;
GooString * fileName = nullptr;
SignatureInfo *sig_info = nullptr;
char *time_str = nullptr;
std::vector<FormWidgetSignature*> sig_widgets;
globalParams = std::make_unique<GlobalParams>();
Win32Console win32Console(&argc, &argv);
int exitCode = 99;
bool ok;
ok = parseArgs(argDesc, &argc, argv);
const bool ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc != 2 || printVersion || printHelp) {
fprintf(stderr, "pdfsig version %s\n", PACKAGE_VERSION);
......@@ -171,47 +164,44 @@ int main(int argc, char *argv[])
printUsage("pdfsig", "<PDF-file>", argDesc);
}
if (printVersion || printHelp)
exitCode = 0;
goto end;
return 0;
return 99;
}
fileName = new GooString(argv[argc - 1]);
std::unique_ptr<GooString> fileName = std::make_unique<GooString>(argv[argc - 1]);
SignatureHandler::setNSSDir(nssDir);
// open PDF file
doc = PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr);
std::unique_ptr<PDFDoc> doc(PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr));
if (!doc->isOk()) {
exitCode = 1;
goto end;
return 1;
}
sig_widgets = doc->getSignatureWidgets();
sigCount = sig_widgets.size();
const std::vector<FormFieldSignature*> signatures = doc->getSignatureFields();
const unsigned int sigCount = signatures.size();
if (sigCount >= 1) {
if (dumpSignatures) {
exitCode = 0;
printf("Dumping Signatures: %u\n", sigCount);
for (unsigned int i = 0; i < sigCount; i++) {
const bool dumpingOk = dumpSignature(i, sigCount, sig_widgets.at(i), fileName->c_str());
const bool dumpingOk = dumpSignature(i, sigCount, signatures.at(i), fileName->c_str());
if (!dumpingOk) {
exitCode = 3;
return 3;
}
}
goto end;
return 0;
} else {
printf("Digital Signature Info of: %s\n", fileName->c_str());
}
} else {
printf("File '%s' does not contain any signatures\n", fileName->c_str());
exitCode = 2;
goto end;
return 2;
}
for (unsigned int i = 0; i < sigCount; i++) {
sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */);
const SignatureInfo *sig_info = signatures.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */);
printf("Signature #%u:\n", i+1);
printf(" - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
printf(" - Signer full Distinguished Name: %s\n", sig_info->getSubjectDN());
......@@ -244,7 +234,7 @@ int main(int argc, char *argv[])
printf("unknown\n");
}
printf(" - Signature Type: ");
switch (sig_widgets.at(i)->signatureType())
switch (signatures.at(i)->getSignatureType())
{
case adbe_pkcs7_sha1:
printf("adbe.pkcs7.sha1\n");
......@@ -258,13 +248,13 @@ int main(int argc, char *argv[])
default:
printf("unknown\n");
}
std::vector<Goffset> ranges = sig_widgets.at(i)->getSignedRangeBounds();
std::vector<Goffset> ranges = signatures.at(i)->getSignedRangeBounds();
if (ranges.size() == 4)
{
printf(" - Signed Ranges: [%lld - %lld], [%lld - %lld]\n",
ranges[0], ranges[1], ranges[2], ranges[3]);
Goffset checked_file_size;
GooString* signature = sig_widgets.at(i)->getCheckedSignature(&checked_file_size);
GooString* signature = signatures.at(i)->getCheckedSignature(&checked_file_size);
if (signature && checked_file_size == ranges[3]) {
printf(" - Total document signed\n");
} else {
......@@ -280,11 +270,5 @@ int main(int argc, char *argv[])
printf(" - Certificate Validation: %s\n", getReadableCertState(sig_info->getCertificateValStatus()));
}
exitCode = 0;
end:
delete fileName;
delete doc;
return exitCode;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment