diff options
-rw-r--r-- | Makefile | 26 | ||||
-rw-r--r-- | include/mupdf/helpers/pkcs7-check.h | 12 | ||||
-rw-r--r-- | include/mupdf/helpers/pkcs7-openssl.h | 24 | ||||
-rw-r--r-- | include/mupdf/pdf.h | 2 | ||||
-rw-r--r-- | include/mupdf/pdf/crypt.h | 7 | ||||
-rw-r--r-- | include/mupdf/pdf/document.h | 47 | ||||
-rw-r--r-- | include/mupdf/pdf/field.h | 1 | ||||
-rw-r--r-- | include/mupdf/pdf/pdf-pkcs7.h | 56 | ||||
-rw-r--r-- | platform/win32/libmupdf.vcproj | 8 | ||||
-rw-r--r-- | platform/win32/mupdf.vcproj | 308 | ||||
-rw-r--r-- | platform/x11/pdfapp.c | 5 | ||||
-rw-r--r-- | source/helpers/pkcs7/pkcs7-check.c | 128 | ||||
-rw-r--r-- | source/helpers/pkcs7/pkcs7-openssl.c (renamed from source/pdf/pdf-pkcs7.c) | 318 | ||||
-rw-r--r-- | source/pdf/pdf-signature.c | 136 | ||||
-rw-r--r-- | source/pdf/pdf-write.c | 2 | ||||
-rw-r--r-- | source/pdf/pdf-xref.c | 4 | ||||
-rw-r--r-- | source/tools/pdfsign.c | 5 |
17 files changed, 699 insertions, 390 deletions
@@ -53,6 +53,7 @@ ALL_DIR += $(OUT)/source/gprf ALL_DIR += $(OUT)/source/tools ALL_DIR += $(OUT)/source/helpers ALL_DIR += $(OUT)/source/helpers/mu-threads +ALL_DIR += $(OUT)/source/helpers/pkcs7 ALL_DIR += $(OUT)/platform/x11 ALL_DIR += $(OUT)/platform/x11/curl ALL_DIR += $(OUT)/platform/gl @@ -93,9 +94,12 @@ $(OUT)/%.a : $(OUT)/%.exe: $(OUT)/%.o | $(ALL_DIR) $(LINK_CMD) -$(OUT)/source/helpers/%.o : source/helpers/%.c | $(ALL_DIR) +$(OUT)/source/helpers/mu-threads/%.o : source/helpers/mu-threads/%.c | $(ALL_DIR) $(CC_CMD) $(THREADING_CFLAGS) +$(OUT)/source/helpers/pkcs7/%.o : source/helpers/pkcs7/%.c | $(ALL_DIR) + $(CC_CMD) + $(OUT)/source/tools/%.o : source/tools/%.c | $(ALL_DIR) $(CC_CMD) $(THREADING_CFLAGS) @@ -127,6 +131,7 @@ $(OUT)/%.o : %.cpp | $(ALL_DIR) FITZ_HDR := include/mupdf/fitz.h $(wildcard include/mupdf/fitz/*.h) PDF_HDR := include/mupdf/pdf.h $(wildcard include/mupdf/pdf/*.h) THREAD_HDR := include/mupdf/helpers/mu-threads.h +PKCS7_HDR := $(sort $(wildcard include/mupdf/helpers/pkcs7-*.h)) FITZ_SRC := $(sort $(wildcard source/fitz/*.c)) PDF_SRC := $(sort $(wildcard source/pdf/*.c)) @@ -136,6 +141,7 @@ CBZ_SRC := $(sort $(wildcard source/cbz/*.c)) HTML_SRC := $(sort $(wildcard source/html/*.c)) GPRF_SRC := $(sort $(wildcard source/gprf/*.c)) THREAD_SRC := $(sort $(wildcard source/helpers/mu-threads/*.c)) +PKCS7_SRC := $(sort $(wildcard source/helpers/pkcs7/*.c)) FITZ_SRC_HDR := $(wildcard source/fitz/*.h) PDF_SRC_HDR := $(wildcard source/pdf/*.h) source/pdf/pdf-name-table.h @@ -152,6 +158,8 @@ CBZ_OBJ := $(CBZ_SRC:%.c=$(OUT)/%.o) HTML_OBJ := $(HTML_SRC:%.c=$(OUT)/%.o) GPRF_OBJ := $(GPRF_SRC:%.c=$(OUT)/%.o) THREAD_OBJ := $(THREAD_SRC:%.c=$(OUT)/%.o) +PKCS7_OBJ := $(PKCS7_SRC:%.c=$(OUT)/%.o) +SIGNATURE_OBJ := $(OUT)/platform/x11/pdfapp.o $(OUT)/source/tools/pdfsign.o $(FITZ_OBJ) : $(FITZ_HDR) $(FITZ_SRC_HDR) $(PDF_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR) @@ -163,6 +171,8 @@ $(CBZ_OBJ) : $(FITZ_HDR) $(CBZ_HDR) $(CBZ_SRC_HDR) $(HTML_OBJ) : $(FITZ_HDR) $(HTML_HDR) $(HTML_SRC_HDR) $(GPRF_OBJ) : $(FITZ_HDR) $(GPRF_HDR) $(GPRF_SRC_HDR) $(THREAD_OBJ) : $(THREAD_HDR) +$(PKCS7_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PKCS7_HDR) +$(SIGNATURE_OBJ) : $(PKCS7_HDR) # --- Generated PDF name tables --- @@ -315,6 +325,9 @@ generate: $(JAVASCRIPT_GEN) MUPDF_LIB = $(OUT)/libmupdf.a THIRD_LIB = $(OUT)/libmupdfthird.a THREAD_LIB = $(OUT)/libmuthreads.a +ifeq "$(HAVE_LIBCRYPTO)" "yes" +PKCS7_LIB = $(OUT)/libmupkcs7.a +endif MUPDF_OBJ := \ $(FITZ_OBJ) \ @@ -341,11 +354,12 @@ THIRD_OBJ := \ $(ZLIB_OBJ) \ $(LCMS2_OBJ) -THREAD_OBJ := $(THREAD_OBJ) - $(MUPDF_LIB) : $(MUPDF_OBJ) $(THIRD_LIB) : $(THIRD_OBJ) $(THREAD_LIB) : $(THREAD_OBJ) +ifeq "$(HAVE_LIBCRYPTO)" "yes" +$(PKCS7_LIB) : $(PKCS7_OBJ) +endif INSTALL_LIBS := $(MUPDF_LIB) $(THIRD_LIB) @@ -356,7 +370,7 @@ MUTOOL_SRC := source/tools/mutool.c source/tools/muconvert.c source/tools/mudraw MUTOOL_SRC += $(sort $(wildcard source/tools/pdf*.c)) MUTOOL_OBJ := $(MUTOOL_SRC:%.c=$(OUT)/%.o) $(MUTOOL_OBJ) : $(FITZ_HDR) $(PDF_HDR) -$(MUTOOL_EXE) : $(MUTOOL_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(THREAD_LIB) +$(MUTOOL_EXE) : $(MUTOOL_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(THREAD_LIB) $(PKCS7_LIB) $(LINK_CMD) $(THREADING_LIBS) MURASTER_EXE := $(OUT)/muraster @@ -381,14 +395,14 @@ ifeq "$(HAVE_X11)" "yes" MUVIEW_X11_EXE := $(OUT)/mupdf-x11 MUVIEW_X11_OBJ := $(addprefix $(OUT)/platform/x11/, x11_main.o x11_image.o pdfapp.o) $(MUVIEW_X11_OBJ) : $(FITZ_HDR) $(PDF_HDR) -$(MUVIEW_X11_EXE) : $(MUVIEW_X11_OBJ) $(MUPDF_LIB) $(THIRD_LIB) +$(MUVIEW_X11_EXE) : $(MUVIEW_X11_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(PKCS7_LIB) $(LINK_CMD) $(X11_LIBS) ifeq "$(HAVE_CURL)" "yes" MUVIEW_X11_CURL_EXE := $(OUT)/mupdf-x11-curl MUVIEW_X11_CURL_OBJ := $(addprefix $(OUT)/platform/x11/curl/, x11_main.o x11_image.o pdfapp.o curl_stream.o) $(MUVIEW_X11_CURL_OBJ) : $(FITZ_HDR) $(PDF_HDR) -$(MUVIEW_X11_CURL_EXE) : $(MUVIEW_X11_CURL_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(CURL_LIB) +$(MUVIEW_X11_CURL_EXE) : $(MUVIEW_X11_CURL_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(CURL_LIB) $(PKCS7_LIB) $(LINK_CMD) $(X11_LIBS) $(CURL_LIBS) $(SYS_CURL_DEPS) endif endif diff --git a/include/mupdf/helpers/pkcs7-check.h b/include/mupdf/helpers/pkcs7-check.h new file mode 100644 index 00000000..3ff529d7 --- /dev/null +++ b/include/mupdf/helpers/pkcs7-check.h @@ -0,0 +1,12 @@ +#ifndef MUPDF_PKCS7_CHECK_H +#define MUPDF_PKCS7_CHECK_H + +/* + pdf_check_signature: check a signature's certificate chain and digest + + This is a helper function defined to provide compatibility with older + versions of mupdf +*/ +int pdf_check_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, char *ebuf, int ebufsize); + +#endif diff --git a/include/mupdf/helpers/pkcs7-openssl.h b/include/mupdf/helpers/pkcs7-openssl.h new file mode 100644 index 00000000..a6268839 --- /dev/null +++ b/include/mupdf/helpers/pkcs7-openssl.h @@ -0,0 +1,24 @@ +#ifndef MUPDF_PKCS7_OPENSSL_H +#define MUPDF_PKCS7_OPENSSL_H + +/* This an example pkcs7 implementation using openssl. These are the types of functions that you + * will likely need to sign documents and check signatures within documents. In particular, to + * sign a document, you need a function that derives a pdf_pkcs7_signer object from a certificate + * stored by the operating system or within a file. */ + +/* Check a signature's digest against ranges of bytes drawn from a stream */ +SignatureError pkcs7_openssl_check_digest(fz_context *ctx, fz_stream *stm, char *sig, int sig_len); + +/* Check a singature's certificate is trusted */ +SignatureError pkcs7_openssl_check_certificate(char *sig, int sig_len); + +/* Obtain the designated name information from signature's certificate */ +pdf_pkcs7_designated_name *pkcs7_openssl_designated_name(fz_context *ctx, char *sig, int sig_len); + +/* Free the resources associated with designated name information */ +void pkcs7_opensll_drop_designated_name(fz_context *ctx, pdf_pkcs7_designated_name *dn); + +/* Read the certificate and private key from a pfx file, holding it as an opaque structure */ +pdf_pkcs7_signer *pkcs7_openssl_read_pfx(fz_context *ctx, const char *pfile, const char *pw); + +#endif diff --git a/include/mupdf/pdf.h b/include/mupdf/pdf.h index f593e680..eab70ee9 100644 --- a/include/mupdf/pdf.h +++ b/include/mupdf/pdf.h @@ -31,8 +31,6 @@ extern "C" { #include "mupdf/pdf/clean.h" -#include "mupdf/pdf/pdf-pkcs7.h" - #ifdef __cplusplus } #endif diff --git a/include/mupdf/pdf/crypt.h b/include/mupdf/pdf/crypt.h index 846ed5bb..c01d3978 100644 --- a/include/mupdf/pdf/crypt.h +++ b/include/mupdf/pdf/crypt.h @@ -39,14 +39,9 @@ fz_stream *pdf_signature_widget_hash_bytes(fz_context *ctx, pdf_document *doc, p int pdf_signature_widget_contents(fz_context *ctx, pdf_document *doc, pdf_widget *widget, char **contents); /* - pdf_check_signature: check a signature's certificate chain and digest -*/ -int pdf_check_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, char *ebuf, int ebufsize); - -/* pdf_sign_signature: sign a signature form field */ -void pdf_sign_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, const char *sigfile, const char *password); +void pdf_sign_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, pdf_pkcs7_signer *signer); void pdf_encrypt_data(fz_context *ctx, pdf_crypt *crypt, int num, int gen, void (*fmt_str_out)(fz_context *, void *, const unsigned char *, int), void *arg, const unsigned char *s, int n); diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h index ef861145..124de254 100644 --- a/include/mupdf/pdf/document.h +++ b/include/mupdf/pdf/document.h @@ -535,8 +535,55 @@ void pdf_update_page(fz_context *ctx, pdf_page *page); */ int pdf_has_unsaved_changes(fz_context *ctx, pdf_document *doc); +typedef enum +{ + SignatureError_Okay, + SignatureError_NoSignatures, + SignatureError_NoCertificate, + SignatureError_DocumentChanged, + SignatureError_SelfSigned, + SignatureError_SelfSignedInChain, + SignatureError_NotTrusted, + SignatureError_Unknown +} SignatureError; + +typedef struct pdf_pkcs7_designated_name_s +{ + char *cn; + char *o; + char *ou; + char *email; + char *c; +} +pdf_pkcs7_designated_name; + +/* Object that can perform the cryptographic operation necessary for document signing */ typedef struct pdf_pkcs7_signer_s pdf_pkcs7_signer; +/* Increment the reference count for a signer object */ +typedef pdf_pkcs7_signer *(pdf_pkcs7_keep_fn)(pdf_pkcs7_signer *signer); + +/* Drop a reference for a signer object */ +typedef void (pdf_pkcs7_drop_fn)(pdf_pkcs7_signer *signer); + +/* Obtain the designated name information from a signer object */ +typedef pdf_pkcs7_designated_name *(pdf_pkcs7_designated_name_fn)(pdf_pkcs7_signer *signer); + +/* Free the resources associated with previously obtained designated name information */ +typedef void (pdf_pkcs7_drop_designated_name_fn)(pdf_pkcs7_signer *signer, pdf_pkcs7_designated_name *name); + +/* Create a signature based on ranges of bytes drawn from a steam */ +typedef int (pdf_pkcs7_create_digest_fn)(pdf_pkcs7_signer *signer, fz_stream *in, unsigned char *digest, int *digest_len); + +struct pdf_pkcs7_signer_s +{ + pdf_pkcs7_keep_fn *keep; + pdf_pkcs7_drop_fn *drop; + pdf_pkcs7_designated_name_fn *designated_name; + pdf_pkcs7_drop_designated_name_fn *drop_designated_name; + pdf_pkcs7_create_digest_fn *create_digest; +}; + /* Unsaved signature fields */ typedef struct pdf_unsaved_sig_s pdf_unsaved_sig; diff --git a/include/mupdf/pdf/field.h b/include/mupdf/pdf/field.h index c3509938..5b25dc3f 100644 --- a/include/mupdf/pdf/field.h +++ b/include/mupdf/pdf/field.h @@ -51,6 +51,5 @@ char *pdf_field_name(fz_context *ctx, pdf_document *doc, pdf_obj *field); void pdf_field_set_display(fz_context *ctx, pdf_document *doc, pdf_obj *field, int d); pdf_obj *pdf_lookup_field(fz_context *ctx, pdf_obj *form, char *name); void pdf_field_reset(fz_context *ctx, pdf_document *doc, pdf_obj *field); -int pdf_signatures_supported(fz_context *ctx); #endif diff --git a/include/mupdf/pdf/pdf-pkcs7.h b/include/mupdf/pdf/pdf-pkcs7.h deleted file mode 100644 index 237a036d..00000000 --- a/include/mupdf/pdf/pdf-pkcs7.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef MUPDF_PDF_PKCS7_H -#define MUPDF_PDF_PKCS7_H - -typedef enum -{ - SignatureError_Okay, - SignatureError_NoSignatures, - SignatureError_NoCertificate, - SignatureError_DocumentChanged, - SignatureError_SelfSigned, - SignatureError_SelfSignedInChain, - SignatureError_NotTrusted, - SignatureError_Unknown -} SignatureError; - -typedef struct pdf_pkcs7_designated_name_s -{ - char *cn; - char *o; - char *ou; - char *email; - char *c; -} -pdf_pkcs7_designated_name; - -/* Check a signature's digest against ranges of bytes drawn from a stream */ -SignatureError pdf_pkcs7_check_digest(fz_context *ctx, fz_stream *stm, char *sig, int sig_len); - -/* Check a singature's certificate is trusted */ -SignatureError pdf_pkcs7_check_certificate(char *sig, int sig_len); - -/* Obtain the designated name information from signature's certificate */ -pdf_pkcs7_designated_name *pdf_cert_designated_name(fz_context *ctx, char *sig, int sig_len); - -/* Free the resources associated with designated name information */ -void pdf_pkcs7_drop_designated_name(fz_context *ctx, pdf_pkcs7_designated_name *dn); - -/* Read the certificate and private key from a pfx file, holding it as an opaque structure */ -pdf_pkcs7_signer *pdf_pkcs7_read_pfx(fz_context *ctx, const char *pfile, const char *pw); - -/* Increment the reference count for a signer object */ -pdf_pkcs7_signer *pdf_pkcs7_keep_signer(fz_context *ctx, pdf_pkcs7_signer *signer); - -/* Drop a reference for a signer object */ -void pdf_pkcs7_drop_signer(fz_context *ctx, pdf_pkcs7_signer *signer); - -/* Obtain the designated name information from a signer object */ -pdf_pkcs7_designated_name *pdf_pkcs7_signer_designated_name(fz_context *ctx, pdf_pkcs7_signer *signer); - -/* Create a signature based on ranges of bytes drawn from a steam */ -int pdf_pkcs7_create_digest(fz_context *ctx, fz_stream *in, pdf_pkcs7_signer *signer, unsigned char *digest, int *digest_len); - -/* Report whether pkcs7 is supported in the current build */ -int pdf_pkcs7_supported(fz_context *ctx); - -#endif diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj index 17217a68..0af5d4df 100644 --- a/platform/win32/libmupdf.vcproj +++ b/platform/win32/libmupdf.vcproj @@ -2137,10 +2137,6 @@ > </File> <File - RelativePath="..\..\source\pdf\pdf-pkcs7.c" - > - </File> - <File RelativePath="..\..\source\pdf\pdf-portfolio.c" > </File> @@ -2288,10 +2284,6 @@ > </File> <File - RelativePath="..\..\include\mupdf\pdf\pdf-pkcs7.h" - > - </File> - <File RelativePath="..\..\include\mupdf\pdf\resource.h" > </File> diff --git a/platform/win32/mupdf.vcproj b/platform/win32/mupdf.vcproj index a85fe1ee..d9d3b765 100644 --- a/platform/win32/mupdf.vcproj +++ b/platform/win32/mupdf.vcproj @@ -1352,6 +1352,314 @@ <References> </References> <Files> + <Filter + Name="pkcs7" + > + <File + RelativePath="..\..\source\helpers\pkcs7\pkcs7-check.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Memento|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Memento|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugOpenssl|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugOpenssl|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseOpenssl|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseOpenssl|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugGProof|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugGProof|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="MementoCommercial|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="MementoCommercial|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugCommercial|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugCommercial|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseCommercial|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseCommercial|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\..\include\mupdf\helpers\pkcs7-check.h" + > + </File> + <File + RelativePath="..\..\source\helpers\pkcs7\pkcs7-openssl.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Memento|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Memento|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugOpenssl|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugOpenssl|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseOpenssl|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseOpenssl|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugGProof|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugGProof|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="MementoCommercial|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="MementoCommercial|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugCommercial|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="DebugCommercial|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseCommercial|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="ReleaseCommercial|x64" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\..\include\mupdf\helpers\pkcs7-openssl.h" + > + </File> + </Filter> <File RelativePath="..\..\platform\x11\pdfapp.c" > diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 6b04720d..ca869f16 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -1,5 +1,6 @@ #include "pdfapp.h" #include "curl_stream.h" +#include "mupdf/helpers/pkcs7-check.h" #include <string.h> #include <limits.h> @@ -1713,6 +1714,7 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta break; case PDF_WIDGET_TYPE_SIGNATURE: +#ifdef HAVE_LIBCRYPTO if (state == -1) { char ebuf[256]; @@ -1730,6 +1732,9 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta winwarn(app, ebuf); } } +#else + winwarn(app, "No support for signatures in this build"); +#endif break; } } diff --git a/source/helpers/pkcs7/pkcs7-check.c b/source/helpers/pkcs7/pkcs7-check.c new file mode 100644 index 00000000..72b6af90 --- /dev/null +++ b/source/helpers/pkcs7/pkcs7-check.c @@ -0,0 +1,128 @@ +#include "mupdf/fitz.h" +#include "mupdf/pdf.h" +#include "mupdf/helpers/pkcs7-openssl.h" +#include "mupdf/helpers/pkcs7-check.h" + +#include <string.h> + + +static void pdf_print_designated_name(pdf_pkcs7_designated_name *name, char *buf, int buflen) +{ + int i, n; + const char *part[] = { + "/CN=", name->cn, + "/O=", name->o, + "/OU=", name->ou, + "/emailAddress=", name->email, + "/C=", name->c}; + + if (buflen) + buf[0] = 0; + + n = sizeof(part)/sizeof(*part); + for (i = 0; i < n; i++) + if (part[i]) + fz_strlcat(buf, part[i], buflen); +} + +int pdf_check_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, char *ebuf, int ebufsize) +{ + fz_stream *bytes = NULL; + char *contents = NULL; + int contents_len; + int res = 0; + + if (pdf_xref_obj_is_unsaved_signature(doc, ((pdf_annot *)widget)->obj)) + { + fz_strlcpy(ebuf, "Signed but document yet to be saved", ebufsize); + if (ebufsize > 0) + ebuf[ebufsize-1] = 0; + return 0; + } + + fz_var(bytes); + fz_var(res); + fz_try(ctx) + { + contents_len = pdf_signature_widget_contents(ctx, doc, widget, &contents); + if (contents) + { + SignatureError err; + + bytes = pdf_signature_widget_hash_bytes(ctx, doc, widget); + err = pkcs7_openssl_check_digest(ctx, bytes, contents, contents_len); + if (err == SignatureError_Okay) + err = pkcs7_openssl_check_certificate(contents, contents_len); + switch (err) + { + case SignatureError_Okay: + ebuf[0] = 0; + res = 1; + break; + case SignatureError_NoSignatures: + fz_strlcpy(ebuf, "No signatures", ebufsize); + break; + case SignatureError_NoCertificate: + fz_strlcpy(ebuf, "No certificate", ebufsize); + break; + case SignatureError_DocumentChanged: + fz_strlcpy(ebuf, "Document changed since signing", ebufsize); + break; + case SignatureError_SelfSigned: + fz_strlcpy(ebuf, "Self-signed certificate", ebufsize); + break; + case SignatureError_SelfSignedInChain: + fz_strlcpy(ebuf, "Self-signed certificate in chain", ebufsize); + break; + case SignatureError_NotTrusted: + fz_strlcpy(ebuf, "Certificate not trusted", ebufsize); + break; + default: + case SignatureError_Unknown: + fz_strlcpy(ebuf, "Unknown error", ebufsize); + break; + } + + switch (err) + { + case SignatureError_SelfSigned: + case SignatureError_SelfSignedInChain: + case SignatureError_NotTrusted: + { + pdf_pkcs7_designated_name *name = pkcs7_openssl_designated_name(ctx, contents, contents_len); + if (name) + { + int len; + + fz_strlcat(ebuf, ": ", ebufsize); + len = strlen(ebuf); + pdf_print_designated_name(name, ebuf + len, ebufsize - len); + pkcs7_opensll_drop_designated_name(ctx, name); + } + } + break; + default: + break; + } + } + else + { + res = 0; + fz_strlcpy(ebuf, "Not signed", ebufsize); + } + } + fz_always(ctx) + { + fz_drop_stream(ctx, bytes); + } + fz_catch(ctx) + { + res = 0; + fz_strlcpy(ebuf, fz_caught_message(ctx), ebufsize); + } + + if (ebufsize > 0) + ebuf[ebufsize-1] = 0; + + return res; +} diff --git a/source/pdf/pdf-pkcs7.c b/source/helpers/pkcs7/pkcs7-openssl.c index 7f4e15b1..c0ca9093 100644 --- a/source/pdf/pdf-pkcs7.c +++ b/source/helpers/pkcs7/pkcs7-openssl.c @@ -1,11 +1,10 @@ #include "mupdf/fitz.h" #include "mupdf/pdf.h" -#include "../fitz/fitz-imp.h" +#include "../../fitz/fitz-imp.h" +#include "mupdf/helpers/pkcs7-openssl.h" #include <string.h> -#ifdef HAVE_LIBCRYPTO - /* Generated from resources/certs/AdobeCA.p7c */ static const char AdobeCA_p7c[] = { 48,130,4,208,6,9,42,134,72,134,247,13,1,7,2,160,130,4,193,48,130,4,189,2, @@ -285,12 +284,14 @@ exit: static SignatureError pk7_verify_cert(X509_STORE *cert_store, PKCS7 *p7) { - int res = SignatureError_Unknown; + int res = SignatureError_Okay; int i; STACK_OF(PKCS7_SIGNER_INFO) *sk; X509_STORE_CTX *ctx; ctx = X509_STORE_CTX_new(); + if (!ctx) + return SignatureError_Unknown; ERR_clear_error(); @@ -333,31 +334,35 @@ static SignatureError pk7_verify_cert(X509_STORE *cert_store, PKCS7 *p7) if (!X509_STORE_CTX_init(ctx, cert_store, cert, certs)) { - res = 0; - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); + res = SignatureError_Unknown; goto exit; } - X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); + if (!X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN)) + { + res = SignatureError_Unknown; + goto exit; + } + /* X509_verify_cert may return an error, but in all such cases + * it sets a context error */ X509_verify_cert(ctx); X509_STORE_CTX_cleanup(ctx); ctx_err = X509_STORE_CTX_get_error(ctx); switch (ctx_err) { case X509_V_OK: - res = SignatureError_Okay; break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: res = SignatureError_SelfSigned; - break; + goto exit; case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: res = SignatureError_SelfSignedInChain; - break; + goto exit; default: - break; + res = SignatureError_Unknown; + goto exit; } - goto exit; } exit: @@ -367,12 +372,11 @@ exit: return res; } -SignatureError pdf_pkcs7_check_digest(fz_context *ctx, fz_stream *stm, char *sig, int sig_len) +SignatureError pkcs7_openssl_check_digest(fz_context *ctx, fz_stream *stm, char *sig, int sig_len) { PKCS7 *pk7sig = NULL; BIO *bsig = NULL; BIO *bdata = NULL; - STACK_OF(X509) *certs = NULL; int res = SignatureError_Unknown; bsig = BIO_new_mem_buf(sig, sig_len); @@ -394,7 +398,7 @@ exit: return res; } -SignatureError pdf_pkcs7_check_certificate(char *sig, int sig_len) +SignatureError pkcs7_openssl_check_certificate(char *sig, int sig_len) { PKCS7 *pk7sig = NULL; PKCS7 *pk7cert = NULL; @@ -451,16 +455,24 @@ typedef struct pdf_pkcs7_designated_name_openssl_s char buf[8192]; } pdf_pkcs7_designated_name_openssl; -struct pdf_pkcs7_signer_s +void pkcs7_opensll_drop_designated_name(fz_context *ctx, pdf_pkcs7_designated_name *dn) { + fz_free(ctx, dn); +} + +typedef struct +{ + pdf_pkcs7_signer base; + fz_context *ctx; int refs; X509 *x509; EVP_PKEY *pkey; -}; +} openssl_signer; -void pdf_pkcs7_drop_designated_name(fz_context *ctx, pdf_pkcs7_designated_name *dn) +static void signer_drop_designated_name(pdf_pkcs7_signer *signer, pdf_pkcs7_designated_name *dn) { - fz_free(ctx, dn); + openssl_signer *osigner = (openssl_signer *)signer; + fz_free(osigner->ctx, dn); } static void add_from_bags(X509 **pX509, EVP_PKEY **pPkey, const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pw); @@ -524,104 +536,20 @@ static void add_from_bags(X509 **pX509, EVP_PKEY **pPkey, const STACK_OF(PKCS12_ add_from_bag(pX509, pPkey, sk_PKCS12_SAFEBAG_value(bags, i), pw); } -pdf_pkcs7_signer *pdf_pkcs7_read_pfx(fz_context *ctx, const char *pfile, const char *pw) +static pdf_pkcs7_signer *keep_signer(pdf_pkcs7_signer *signer) { - BIO *pfxbio = NULL; - PKCS12 *p12 = NULL; - STACK_OF(PKCS7) *asafes; - pdf_pkcs7_signer *signer = NULL; - int i; - - fz_var(pfxbio); - fz_var(p12); - fz_var(signer); - fz_try(ctx) - { - signer = fz_malloc_struct(ctx, pdf_pkcs7_signer); - signer->refs = 1; - - OpenSSL_add_all_algorithms(); - - EVP_add_digest(EVP_md5()); - EVP_add_digest(EVP_sha1()); - - ERR_load_crypto_strings(); - - ERR_clear_error(); - - pfxbio = BIO_new_file(pfile, "rb"); - if (pfxbio == NULL) - fz_throw(ctx, FZ_ERROR_GENERIC, "Can't open pfx file: %s", pfile); - - p12 = d2i_PKCS12_bio(pfxbio, NULL); - if (p12 == NULL) - fz_throw(ctx, FZ_ERROR_GENERIC, "Invalid pfx file: %s", pfile); - - asafes = PKCS12_unpack_authsafes(p12); - if (asafes == NULL) - fz_throw(ctx, FZ_ERROR_GENERIC, "Invalid pfx file: %s", pfile); - - /* Nothing in this for loop can fz_throw */ - for (i = 0; i < sk_PKCS7_num(asafes); i++) - { - PKCS7 *p7; - STACK_OF(PKCS12_SAFEBAG) *bags; - int bagnid; - - p7 = sk_PKCS7_value(asafes, i); - bagnid = OBJ_obj2nid(p7->type); - switch (bagnid) - { - case NID_pkcs7_data: - bags = PKCS12_unpack_p7data(p7); - break; - case NID_pkcs7_encrypted: - bags = PKCS12_unpack_p7encdata(p7, pw, (int)strlen(pw)); - break; - default: - continue; - } - - if (bags) - { - add_from_bags(&signer->x509, &signer->pkey, bags, pw); - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - } - } - sk_PKCS7_pop_free (asafes, PKCS7_free); - - if (signer->pkey == NULL) - fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to obtain public key"); - - if (signer->x509 == NULL) - fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to obtain certificate"); - } - fz_always(ctx) - { - BIO_free(pfxbio); - PKCS12_free(p12); - } - fz_catch(ctx) - { - pdf_pkcs7_drop_signer(ctx, signer); - fz_rethrow(ctx); - } - - return signer; + openssl_signer *osigner = (openssl_signer *)signer; + return fz_keep_imp(osigner->ctx, osigner, &osigner->refs); } -pdf_pkcs7_signer *pdf_pkcs7_keep_signer(fz_context *ctx, pdf_pkcs7_signer *signer) +static void drop_signer(pdf_pkcs7_signer *signer) { - return fz_keep_imp(ctx, signer, &signer->refs); -} - -void pdf_pkcs7_drop_signer(fz_context *ctx, pdf_pkcs7_signer *signer) -{ - if (fz_drop_imp(ctx, signer, &signer->refs)) + openssl_signer *osigner = (openssl_signer *)signer; + if (fz_drop_imp(osigner->ctx, osigner, &osigner->refs)) { - X509_free(signer->x509); - EVP_PKEY_free(signer->pkey); - fz_free(ctx, signer); + X509_free(osigner->x509); + EVP_PKEY_free(osigner->pkey); + fz_free(osigner->ctx, osigner); } } @@ -649,13 +577,16 @@ static pdf_pkcs7_designated_name *x509_designated_name(fz_context *ctx, X509 *x5 return (pdf_pkcs7_designated_name *)dn; } -pdf_pkcs7_designated_name *pdf_pkcs7_signer_designated_name(fz_context *ctx, pdf_pkcs7_signer *signer) +static pdf_pkcs7_designated_name *signer_designated_name(pdf_pkcs7_signer *signer) { - return x509_designated_name(ctx, signer->x509); + openssl_signer *osigner = (openssl_signer *)signer; + return x509_designated_name(osigner->ctx, osigner->x509); } -int pdf_pkcs7_create_digest(fz_context *ctx, fz_stream *in, pdf_pkcs7_signer *signer, unsigned char *digest, int *digest_len) +static int signer_create_digest(pdf_pkcs7_signer *signer, fz_stream *in, unsigned char *digest, int *digest_len) { + openssl_signer *osigner = (openssl_signer *)signer; + fz_context *ctx = osigner->ctx; int res = 0; BIO *bdata = NULL; BIO *bp7in = NULL; @@ -676,12 +607,12 @@ int pdf_pkcs7_create_digest(fz_context *ctx, fz_stream *in, pdf_pkcs7_signer *si goto exit; PKCS7_set_type(p7, NID_pkcs7_signed); - si = PKCS7_add_signature(p7, signer->x509, signer->pkey, EVP_sha1()); + si = PKCS7_add_signature(p7, osigner->x509, osigner->pkey, EVP_sha1()); if (si == NULL) goto exit; PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)); - PKCS7_add_certificate(p7, signer->x509); + PKCS7_add_certificate(p7, osigner->x509); PKCS7_content_new(p7, NID_pkcs7_data); PKCS7_set_detached(p7, 1); @@ -725,7 +656,100 @@ exit: return res; } -pdf_pkcs7_designated_name *pdf_cert_designated_name(fz_context *ctx, char *sig, int sig_len) +pdf_pkcs7_signer *pkcs7_openssl_read_pfx(fz_context *ctx, const char *pfile, const char *pw) +{ + BIO *pfxbio = NULL; + PKCS12 *p12 = NULL; + STACK_OF(PKCS7) *asafes; + openssl_signer *signer = NULL; + int i; + + fz_var(pfxbio); + fz_var(p12); + fz_var(signer); + fz_try(ctx) + { + signer = fz_malloc_struct(ctx, openssl_signer); + signer->refs = 1; + + OpenSSL_add_all_algorithms(); + + EVP_add_digest(EVP_md5()); + EVP_add_digest(EVP_sha1()); + + ERR_load_crypto_strings(); + + ERR_clear_error(); + + pfxbio = BIO_new_file(pfile, "rb"); + if (pfxbio == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Can't open pfx file: %s", pfile); + + p12 = d2i_PKCS12_bio(pfxbio, NULL); + if (p12 == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Invalid pfx file: %s", pfile); + + asafes = PKCS12_unpack_authsafes(p12); + if (asafes == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Invalid pfx file: %s", pfile); + + /* Nothing in this for loop can fz_throw */ + for (i = 0; i < sk_PKCS7_num(asafes); i++) + { + PKCS7 *p7; + STACK_OF(PKCS12_SAFEBAG) *bags; + int bagnid; + + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + switch (bagnid) + { + case NID_pkcs7_data: + bags = PKCS12_unpack_p7data(p7); + break; + case NID_pkcs7_encrypted: + bags = PKCS12_unpack_p7encdata(p7, pw, (int)strlen(pw)); + break; + default: + continue; + } + + if (bags) + { + add_from_bags(&signer->x509, &signer->pkey, bags, pw); + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + } + } + sk_PKCS7_pop_free (asafes, PKCS7_free); + + if (signer->pkey == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to obtain public key"); + + if (signer->x509 == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to obtain certificate"); + + signer->ctx = ctx; + signer->base.keep = keep_signer; + signer->base.drop = drop_signer; + signer->base.designated_name = signer_designated_name; + signer->base.drop_designated_name = signer_drop_designated_name; + signer->base.create_digest = signer_create_digest; + } + fz_always(ctx) + { + BIO_free(pfxbio); + PKCS12_free(p12); + } + fz_catch(ctx) + { + drop_signer(&signer->base); + fz_rethrow(ctx); + } + + return &signer->base; +} + +pdf_pkcs7_designated_name *pkcs7_openssl_designated_name(fz_context *ctx, char *sig, int sig_len) { pdf_pkcs7_designated_name *name = NULL; PKCS7 *pk7sig = NULL; @@ -752,61 +776,3 @@ exit: return name; } - - -int pdf_pkcs7_supported(fz_context *ctx) -{ - return 1; -} - -#else /* HAVE_LIBCRYPTO */ - -SignatureError pdf_pkcs7_check_digest(fz_context *ctx, fz_stream *stm, char *sig, int sig_len) -{ - return SignatureError_Unknown; -} - -SignatureError pdf_pkcs7_check_certificate(char *sig, int sig_len) -{ - return SignatureError_Unknown; -} - -pdf_pkcs7_designated_name *pdf_cert_designated_name(fz_context *ctx, char *sig, int sig_len) -{ - return NULL; -} - -void pdf_pkcs7_drop_designated_name(fz_context *ctx, pdf_pkcs7_designated_name *dn) -{ -} - -pdf_pkcs7_signer *pdf_pkcs7_read_pfx(fz_context *ctx, const char *pfile, const char *pw) -{ - return NULL; -} - -pdf_pkcs7_signer *pdf_pkcs7_keep_signer(fz_context *ctx, pdf_pkcs7_signer *signer) -{ - return NULL; -} - -void pdf_pkcs7_drop_signer(fz_context *ctx, pdf_pkcs7_signer *signer) -{ -} - -pdf_pkcs7_designated_name *pdf_pkcs7_signer_designated_name(fz_context *ctx, pdf_pkcs7_signer *signer) -{ - return NULL; -} - -int pdf_pkcs7_create_digest(fz_context *ctx, fz_stream *in, pdf_pkcs7_signer *signer, unsigned char *digest, int *digest_len) -{ - return 0; -} - -int pdf_pkcs7_supported(fz_context *ctx) -{ - return 0; -} - -#endif /* HAVE_LIBCRYPTO */ diff --git a/source/pdf/pdf-signature.c b/source/pdf/pdf-signature.c index 3d96a261..3c882f54 100644 --- a/source/pdf/pdf-signature.c +++ b/source/pdf/pdf-signature.c @@ -5,25 +5,6 @@ #include <string.h> -static void pdf_print_designated_name(pdf_pkcs7_designated_name *name, char *buf, int buflen) -{ - int i, n; - const char *part[] = { - "/CN=", name->cn, - "/O=", name->o, - "/OU=", name->ou, - "/emailAddress=", name->email, - "/C=", name->c}; - - if (buflen) - buf[0] = 0; - - n = sizeof(part)/sizeof(*part); - for (i = 0; i < n; i++) - if (part[i]) - fz_strlcat(buf, part[i], buflen); -} - void pdf_write_digest(fz_context *ctx, fz_output *out, pdf_obj *byte_range, int hexdigest_offset, int hexdigest_length, pdf_pkcs7_signer *signer) { fz_stream *in = NULL; @@ -53,7 +34,7 @@ void pdf_write_digest(fz_context *ctx, fz_output *out, pdf_obj *byte_range, int digest_len = (hexdigest_length - 2) / 2; digest = fz_malloc(ctx, digest_len); - res = pdf_pkcs7_create_digest(ctx, in, signer, digest, &digest_len); + res = signer->create_digest(signer, in, digest, &digest_len); if (!res) fz_throw(ctx, FZ_ERROR_GENERIC, "pdf_pkcs7_create_digest failed"); @@ -77,111 +58,8 @@ void pdf_write_digest(fz_context *ctx, fz_output *out, pdf_obj *byte_range, int } } -int pdf_check_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, char *ebuf, int ebufsize) -{ - fz_stream *bytes = NULL; - char *contents = NULL; - int contents_len; - int res = 0; - - if (pdf_xref_obj_is_unsaved_signature(doc, ((pdf_annot *)widget)->obj)) - { - fz_strlcpy(ebuf, "Signed but document yet to be saved", ebufsize); - if (ebufsize > 0) - ebuf[ebufsize-1] = 0; - return 0; - } - - fz_var(bytes); - fz_var(res); - fz_try(ctx) - { - contents_len = pdf_signature_widget_contents(ctx, doc, widget, &contents); - if (contents) - { - SignatureError err; - - bytes = pdf_signature_widget_hash_bytes(ctx, doc, widget); - err = pdf_pkcs7_check_digest(ctx, bytes, contents, contents_len); - if (err == SignatureError_Okay) - err = pdf_pkcs7_check_certificate(contents, contents_len); - switch (err) - { - case SignatureError_Okay: - ebuf[0] = 0; - res = 1; - break; - case SignatureError_NoSignatures: - fz_strlcpy(ebuf, "No signatures", ebufsize); - break; - case SignatureError_NoCertificate: - fz_strlcpy(ebuf, "No certificate", ebufsize); - break; - case SignatureError_DocumentChanged: - fz_strlcpy(ebuf, "Document changed since signing", ebufsize); - break; - case SignatureError_SelfSigned: - fz_strlcpy(ebuf, "Self-signed certificate", ebufsize); - break; - case SignatureError_SelfSignedInChain: - fz_strlcpy(ebuf, "Self-signed certificate in chain", ebufsize); - break; - case SignatureError_NotTrusted: - fz_strlcpy(ebuf, "Certificate not trusted", ebufsize); - break; - default: - case SignatureError_Unknown: - fz_strlcpy(ebuf, "Unknown error", ebufsize); - break; - } - - switch (err) - { - case SignatureError_SelfSigned: - case SignatureError_SelfSignedInChain: - case SignatureError_NotTrusted: - { - pdf_pkcs7_designated_name *name = pdf_cert_designated_name(ctx, contents, contents_len); - if (name) - { - int len; - - fz_strlcat(ebuf, ": ", ebufsize); - len = strlen(ebuf); - pdf_print_designated_name(name, ebuf + len, ebufsize - len); - pdf_pkcs7_drop_designated_name(ctx, name); - } - } - break; - default: - break; - } - } - else - { - res = 0; - fz_strlcpy(ebuf, "Not signed", ebufsize); - } - } - fz_always(ctx) - { - fz_drop_stream(ctx, bytes); - } - fz_catch(ctx) - { - res = 0; - fz_strlcpy(ebuf, fz_caught_message(ctx), ebufsize); - } - - if (ebufsize > 0) - ebuf[ebufsize-1] = 0; - - return res; -} - -void pdf_sign_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, const char *sigfile, const char *password) +void pdf_sign_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, pdf_pkcs7_signer *signer) { - pdf_pkcs7_signer *signer = pdf_pkcs7_read_pfx(ctx, sigfile, password); pdf_pkcs7_designated_name *dn = NULL; fz_buffer *fzbuf = NULL; @@ -197,7 +75,7 @@ void pdf_sign_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, /* Create an appearance stream only if the signature is intended to be visible */ if (!fz_is_empty_rect(&rect)) { - dn = pdf_pkcs7_signer_designated_name(ctx, signer); + dn = signer->designated_name(signer); fzbuf = fz_new_buffer(ctx, 256); if (!dn->cn) fz_throw(ctx, FZ_ERROR_GENERIC, "Certificate has no common name"); @@ -222,8 +100,7 @@ void pdf_sign_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, } fz_always(ctx) { - pdf_pkcs7_drop_signer(ctx, signer); - pdf_pkcs7_drop_designated_name(ctx, dn); + signer->drop_designated_name(signer, dn); fz_drop_buffer(ctx, fzbuf); } fz_catch(ctx) @@ -231,8 +108,3 @@ void pdf_sign_signature(fz_context *ctx, pdf_document *doc, pdf_widget *widget, fz_rethrow(ctx); } } - -int pdf_signatures_supported(fz_context *ctx) -{ - return pdf_pkcs7_supported(ctx); -} diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c index 0ab76a35..7b163813 100644 --- a/source/pdf/pdf-write.c +++ b/source/pdf/pdf-write.c @@ -2708,7 +2708,7 @@ static void complete_signatures(fz_context *ctx, pdf_document *doc, pdf_write_st { xref->unsaved_sigs = usig->next; pdf_drop_obj(ctx, usig->field); - pdf_pkcs7_drop_signer(ctx, usig->signer); + usig->signer->drop(usig->signer); fz_free(ctx, usig); } } diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index 1dc3b7d8..7e38706b 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -59,7 +59,7 @@ static void pdf_drop_xref_sections_imp(fz_context *ctx, pdf_document *doc, pdf_x { xref->unsaved_sigs = usig->next; pdf_drop_obj(ctx, usig->field); - pdf_pkcs7_drop_signer(ctx, usig->signer); + usig->signer->drop(usig->signer); fz_free(ctx, usig); } } @@ -418,7 +418,7 @@ void pdf_xref_store_unsaved_signature(fz_context *ctx, pdf_document *doc, pdf_ob * saving time */ unsaved_sig = fz_malloc_struct(ctx, pdf_unsaved_sig); unsaved_sig->field = pdf_keep_obj(ctx, field); - unsaved_sig->signer = pdf_pkcs7_keep_signer(ctx, signer); + unsaved_sig->signer = signer->keep(signer); unsaved_sig->next = NULL; if (xref->unsaved_sigs_end == NULL) xref->unsaved_sigs_end = &xref->unsaved_sigs; diff --git a/source/tools/pdfsign.c b/source/tools/pdfsign.c index bc14be41..434c9332 100644 --- a/source/tools/pdfsign.c +++ b/source/tools/pdfsign.c @@ -4,6 +4,7 @@ #include "mupdf/fitz.h" #include "mupdf/pdf.h" +#include "mupdf/helpers/pkcs7-check.h" #include <string.h> #include <stdlib.h> @@ -22,10 +23,14 @@ static void usage(void) void verify_signature(fz_context *ctx, pdf_document *doc, int n, pdf_widget *widget) { +#ifdef HAVE_LIBCRYPTO char msg[256]; printf("verifying signature on page %d\n", n+1); pdf_check_signature(ctx, doc, widget, msg, sizeof msg); printf(" result: '%s'\n", msg); +#else + printf("No signature support in this build\n"); +#endif } void verify_page(fz_context *ctx, pdf_document *doc, int n, pdf_page *page) |