summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2017-09-26 16:24:07 +0200
committerTor Andersson <tor.andersson@artifex.com>2017-10-12 15:18:07 +0200
commita8ccc764d8ef30625fbc90eeff2c659063b3c67f (patch)
tree7d901e267e89356bc36f80295322d055cf9f7041 /source
parent72618d242a5fc908e6902cf2a9ad1132084b2a79 (diff)
downloadmupdf-a8ccc764d8ef30625fbc90eeff2c659063b3c67f.tar.xz
Add 'mutool sign' tool for verifying digital PDF signatures.
Diffstat (limited to 'source')
-rw-r--r--source/tools/mutool.c2
-rw-r--r--source/tools/pdfsign.c91
2 files changed, 93 insertions, 0 deletions
diff --git a/source/tools/mutool.c b/source/tools/mutool.c
index 3e4cbf09..c6b33330 100644
--- a/source/tools/mutool.c
+++ b/source/tools/mutool.c
@@ -25,6 +25,7 @@ int pdfpages_main(int argc, char *argv[]);
int pdfcreate_main(int argc, char *argv[]);
int pdfmerge_main(int argc, char *argv[]);
int pdfportfolio_main(int argc, char *argv[]);
+int pdfsign_main(int argc, char *argv[]);
static struct {
int (*func)(int argc, char *argv[]);
@@ -49,6 +50,7 @@ static struct {
{ pdfpages_main, "pages", "show information about pdf pages" },
{ pdfportfolio_main, "portfolio", "manipulate PDF portfolios" },
{ pdfposter_main, "poster", "split large page into many tiles" },
+ { pdfsign_main, "sign", "manipulate PDF digital signatures" },
#endif
#if FZ_ENABLE_JS
{ murun_main, "run", "run javascript" },
diff --git a/source/tools/pdfsign.c b/source/tools/pdfsign.c
new file mode 100644
index 00000000..81b78ab7
--- /dev/null
+++ b/source/tools/pdfsign.c
@@ -0,0 +1,91 @@
+/*
+ * PDF signature tool: verify and sign digital signatures in PDF files.
+ */
+
+#include "mupdf/fitz.h"
+#include "mupdf/pdf.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static char *filename = NULL;
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "usage: mutool sign input.pdf\n"
+ "\t-p -\tpassword\n"
+ );
+ exit(1);
+}
+
+void verify_signature(fz_context *ctx, pdf_document *doc, int n, pdf_widget *widget)
+{
+ char msg[256];
+ printf("verifying signature on page %d\n", n+1);
+ pdf_check_signature(ctx, doc, widget, filename, msg, sizeof msg);
+ printf(" result: '%s'\n", msg);
+}
+
+void verify_page(fz_context *ctx, pdf_document *doc, int n, pdf_page *page)
+{
+ pdf_annot *annot;
+ for (annot = pdf_first_annot(ctx, page); annot; annot = pdf_next_annot(ctx, annot))
+ if (pdf_annot_type(ctx, annot) == PDF_ANNOT_WIDGET)
+ if (pdf_widget_type(ctx, annot) == PDF_WIDGET_TYPE_SIGNATURE)
+ verify_signature(ctx, doc, n, annot);
+}
+
+int pdfsign_main(int argc, char **argv)
+{
+ fz_context *ctx = NULL;
+ pdf_document *doc = NULL;
+ char *password = "";
+ int i, n, c;
+
+ while ((c = fz_getopt(argc, argv, "p:")) != -1)
+ {
+ switch (c)
+ {
+ case 'p': password = fz_optarg; break;
+ default: usage(); break;
+ }
+ }
+
+ if (argc - fz_optind < 1)
+ usage();
+
+ filename = argv[fz_optind++];
+
+ ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
+ if (!ctx)
+ {
+ fprintf(stderr, "cannot initialize context\n");
+ exit(1);
+ }
+
+ fz_try(ctx)
+ {
+ doc = pdf_open_document(ctx, filename);
+ if (pdf_needs_password(ctx, doc))
+ if (!pdf_authenticate_password(ctx, doc, password))
+ fz_warn(ctx, "cannot authenticate password: %s", filename);
+
+ n = pdf_count_pages(ctx, doc);
+ for (i = 0; i < n; ++i)
+ {
+ pdf_page *page = pdf_load_page(ctx, doc, i);
+ verify_page(ctx, doc, i, page);
+ fz_drop_page(ctx, (fz_page*)page);
+ }
+ }
+ fz_catch(ctx)
+ {
+ }
+
+ pdf_drop_document(ctx, doc);
+ fz_flush_warnings(ctx);
+ fz_drop_context(ctx);
+ return 0;
+}