diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2017-09-26 16:24:07 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2017-10-12 15:18:07 +0200 |
commit | a8ccc764d8ef30625fbc90eeff2c659063b3c67f (patch) | |
tree | 7d901e267e89356bc36f80295322d055cf9f7041 /source | |
parent | 72618d242a5fc908e6902cf2a9ad1132084b2a79 (diff) | |
download | mupdf-a8ccc764d8ef30625fbc90eeff2c659063b3c67f.tar.xz |
Add 'mutool sign' tool for verifying digital PDF signatures.
Diffstat (limited to 'source')
-rw-r--r-- | source/tools/mutool.c | 2 | ||||
-rw-r--r-- | source/tools/pdfsign.c | 91 |
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; +} |