<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - support for digital signatures"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=16770#c34">Comment # 34</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - support for digital signatures"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=16770">bug 16770</a>
              from <span class="vcard"><a class="email" href="mailto:weibo3721@126.com" title="weibo <weibo3721@126.com>"> <span class="fn">weibo</span></a>
</span></b>
        <pre>Comment on <span class=""><a href="attachment.cgi?id=37425" name="attach_37425" title="Initial patch for parsing digitally signed PDFs">attachment 37425</a> <a href="attachment.cgi?id=37425&action=edit" title="Initial patch for parsing digitally signed PDFs">[details]</a></span> <a href='page.cgi?id=splinter.html&bug=16770&attachment=37425'>[review]</a>
Initial patch for parsing digitally signed PDFs

<span class="quote">>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);</span ></pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>