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 (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);