Comment 38 for bug 1085526

Revision history for this message
In , Weibo3721 (weibo3721) wrote :

Comment on attachment 37425
Initial patch for parsing digitally signed PDFs

>diff --git a/poppler/Form.cc b/poppler/Form.cc
>index 4df8a7d..1da9776 100644
>--- a/poppler/Form.cc
>+++ b/poppler/Form.cc
>@@ -1107,11 +1107,28 @@ void FormFieldChoice::_createChoicesTab ()
> FormFieldSignature::FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref)
> : FormField(xrefA, dict, ref, formSignature)
> {
>+ Object v, contents;
>+
>+ if (dict->dictLookup("V", &v)->isDict()) {
>+ if (v.dictLookup("Contents", &contents)->isString()) {
>+ this->contents = contents.getString()->copy();
>+ v.dictLookup("ByteRange", &byteRange);
>+ v.dictLookup("Filter", &filter);
>+ v.dictLookup("SubFilter", &subFilter);
>+ }
>+ contents.free();
>+ }
>+ v.free();
> }
>
> FormFieldSignature::~FormFieldSignature()
> {
>-
>+ if(contents) {
>+ delete contents;
>+}
>+ byteRange.free();
>+ filter.free();
>+ subFilter.free();
> }
>
> //------------------------------------------------------------------------
>diff --git a/poppler/Form.h b/poppler/Form.h
>index 35d66af..e5d1a1f 100644
>--- a/poppler/Form.h
>+++ b/poppler/Form.h
>@@ -418,6 +418,18 @@ public:
> FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref);
>
> virtual ~FormFieldSignature();
>+
>+ Array* GetByteRange() { return byteRange.getArray(); }
>+ GooString* GetContents() const { return contents; }
>+ char* GetFilter() { return filter.getName(); }
>+ char* GetSubFilter() { return subFilter.getName();}
>+
>+protected:
>+ GooString* contents;
>+ Object byteRange;
>+ Object filter;
>+ Object subFilter;
>+
> };
>
> //------------------------------------------------------------------------
>diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
>index ade5fe4..80b5f6c 100644
>--- a/poppler/PDFDoc.cc
>+++ b/poppler/PDFDoc.cc
>@@ -358,6 +358,25 @@ GBool PDFDoc::checkEncryption(GooString *ownerPassword, GooString *userPassword)
> return ret;
> }
>
>+#define SIGFLAGS_SIGNATURES_EXIST 0x1
>+#define SIGFLAGS_APPEND_ONLY 0x2
>+
>+GBool PDFDoc::isSigned() {
>+ GBool ret;
>+ Object sigFlags;
>+
>+ getCatalog()->getAcroForm()->dictLookup("SigFlags", &sigFlags);
>+
>+ if (sigFlags.isInt()) {
>+ ret = sigFlags.getInt() & SIGFLAGS_SIGNATURES_EXIST;
>+ } else {
>+ ret = gFalse;
>+ }
>+ sigFlags.free();
>+
>+ return ret;
>+}
>+
> void PDFDoc::displayPage(OutputDev *out, int page,
> double hDPI, double vDPI, int rotate,
> GBool useMediaBox, GBool crop, GBool printing,
>diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h
>index 6d7dea2..22fdb40 100644
>--- a/poppler/PDFDoc.h
>+++ b/poppler/PDFDoc.h
>@@ -176,6 +176,9 @@ public:
> // Is the file encrypted?
> GBool isEncrypted() { return xref->isEncrypted(); }
>
>+ // Is the file signed?
>+ GBool isSigned();
>+
> // Check various permissions.
> GBool okToPrint(GBool ignoreOwnerPW = gFalse)
> { return xref->okToPrint(ignoreOwnerPW); }
>diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
>index 2abe8b4..b4b2233 100644
>--- a/utils/pdfinfo.cc
>+++ b/utils/pdfinfo.cc
>@@ -49,6 +49,7 @@
> #include "PDFDocEncoding.h"
> #include "Error.h"
> #include "DateInfo.h"
>+#include "Form.h"
>
> static void printInfoString(Dict *infoDict, char *key, char *text,
> UnicodeMap *uMap);
>@@ -111,6 +112,8 @@ int main(int argc, char *argv[]) {
> int exitCode;
> int pg, i;
> GBool multiPage;
>+ Form *form;
>+ FormField *formField;
>
> exitCode = 99;
>
>@@ -225,6 +228,61 @@ int main(int argc, char *argv[]) {
> printf("no\n");
> }
>
>+ // print signature info
>+ printf("Signed: ");
>+ if (doc->isSigned()) {
>+ printf("yes (");
>+
>+ form = doc->getCatalog()->getForm();
>+ int sigCounter = 0;
>+
>+ for (int i = 0; i < form->getNumFields(); i++) {
>+ formField = form->getRootField(i);
>+ if (formField->getType() == formSignature) {
>+ FormFieldSignature* formFieldSig
>+ = static_cast<FormFieldSignature*> (formField);
>+
>+ GooString* contents = formFieldSig->GetContents();
>+
>+ if (i != 0) {
>+ printf("\n ");
>+ }
>+
>+ printf("Signature %d: encoding:%s length:%d",
>+ ++sigCounter,
>+ formFieldSig->GetSubFilter(),
>+ contents->getLength());
>+
>+// for (int i = 0; i < contents->getLength(); i++) {
>+// printf("%x ", contents->getChar(i) & 0xff);
>+// }
>+// printf("\n");
>+
>+ Array *byteRange = formFieldSig->GetByteRange();
>+
>+ for (int i = 0; i < byteRange->getLength(); i+=2) {
>+ Object start, length;
>+ byteRange->get(i, &start);
>+ byteRange->get(i+1, &length);
>+ printf(" bytes: %d-%d",
>+ start.getInt(), start.getInt() + length.getInt());
>+
>+ int oldPos = doc->getBaseStream()->getPos();
>+ doc->getBaseStream()->setPos(start.getInt());
>+// for (int j = 0; j < length.getInt(); j++) {
>+// printf("%x ", doc->getBaseStream()->getChar() & 0xff);
>+// }
>+ doc->getBaseStream()->setPos(oldPos);
>+ start.free();
>+ length.free();
>+ }
>+ }
>+ }
>+ printf(")\n");
>+ } else {
>+ printf("no\n");
>+ }
>+
> // print page size
> for (pg = firstPage; pg <= lastPage; ++pg) {
> w = doc->getPageCropWidth(pg);