diff --git a/poppler/Form.cc b/poppler/Form.cc index 11b16c91..646dcd81 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -454,6 +454,11 @@ FormWidgetSignature::FormWidgetSignature(PDFDoc *docA, Object *aobj, unsigned nu type = formSignature; } +GooString *FormWidgetSignature::getSignature() +{ + return static_cast(field)->getSignature(); +} + SignatureInfo *FormWidgetSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime) { return static_cast(field)->validateSignature(doVerifyCert, forceRevalidation, validationTime); diff --git a/poppler/Form.h b/poppler/Form.h index 8f7cb377..15a486d2 100644 --- a/poppler/Form.h +++ b/poppler/Form.h @@ -280,6 +280,8 @@ public: // if the check passed (and the checked file size as output parameter in checkedFileSize) // otherwise a nullptr is returned GooString* getCheckedSignature(Goffset *checkedFileSize); + + GooString *getSignature(); }; //------------------------------------------------------------------------ diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 34d96475..3ce90c2c 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -99,6 +99,14 @@ if (ENABLE_NSS3) target_link_libraries(pdfsig ${common_libs}) install(TARGETS pdfsig DESTINATION bin) install(FILES pdfsig.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + + # sigdump + set(sigdump_SOURCES ${common_srcs} + sigdump.cc + ) + add_executable(sigdump ${sigdump_SOURCES}) + target_link_libraries(sigdump ${common_libs}) + install(TARGETS sigdump DESTINATION bin) endif () # pdftops diff --git a/utils/pdfsig.h b/utils/pdfsig.h new file mode 100644 index 00000000..446e587c --- /dev/null +++ b/utils/pdfsig.h @@ -0,0 +1,50 @@ +#include +#include "Object.h" +#include "PDFDoc.h" +#include "GlobalParams.h" +#include "SignatureInfo.h" + +class PDFSignature { + public: + PDFSignature(std::string input) + { + // This is shared state for all poppler usage. + if (!globalParams) { + globalParams = new GlobalParams(); + + // Keep Quiet + globalParams->setErrQuiet(true); + } + + doc = new PDFDoc(new MemStream(const_cast(input.data()), 0, input.size(), Object(objNull)), NULL, NULL); + + if (doc->isOk()) { + widgets = doc->getSignatureWidgets(); + } + } + + ~PDFSignature() + { + delete doc; + } + + size_t getSignatureCount() + { + return widgets.size(); + } + + std::string getSignature(size_t n) + { + GooString *signature = widgets.at(n)->getSignature(); + + if (signature) { + return std::string(signature->getCString(), signature->getLength()); + } else { + return std::string(); + } + } + private: + std::vector widgets; + PDFDoc *doc; +}; + diff --git a/utils/sigdump.cc b/utils/sigdump.cc new file mode 100644 index 00000000..511d492e --- /dev/null +++ b/utils/sigdump.cc @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include +#include +#include "pdfsig.h" + +int main(int argc, char *argv[]) +{ + std::ifstream t(argv[1]); + std::string input((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + + PDFSignature *doc = new PDFSignature(input); + + printf("%zu Signatures\n", doc->getSignatureCount()); + + for (int i = 0; i < doc->getSignatureCount(); i++) { + char buf[1024]; + snprintf(buf, sizeof buf, "%s.sig%02u", basename(argv[1]), i); + std::ofstream outfile (buf, std::ofstream::binary); + printf("Signature #%d (%lu bytes) => %s\n", i, doc->getSignature(i).size(), buf); + outfile.write(doc->getSignature(i).data(), doc->getSignature(i).size()); + outfile.close(); + } + + delete doc; + return 0; +}