summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile26
-rw-r--r--include/mupdf/helpers/pkcs7-check.h12
-rw-r--r--include/mupdf/helpers/pkcs7-openssl.h24
-rw-r--r--include/mupdf/pdf.h2
-rw-r--r--include/mupdf/pdf/crypt.h7
-rw-r--r--include/mupdf/pdf/document.h47
-rw-r--r--include/mupdf/pdf/field.h1
-rw-r--r--include/mupdf/pdf/pdf-pkcs7.h56
-rw-r--r--platform/win32/libmupdf.vcproj8
-rw-r--r--platform/win32/mupdf.vcproj308
-rw-r--r--platform/x11/pdfapp.c5
-rw-r--r--source/helpers/pkcs7/pkcs7-check.c128
-rw-r--r--source/helpers/pkcs7/pkcs7-openssl.c (renamed from source/pdf/pdf-pkcs7.c)318
-rw-r--r--source/pdf/pdf-signature.c136
-rw-r--r--source/pdf/pdf-write.c2
-rw-r--r--source/pdf/pdf-xref.c4
-rw-r--r--source/tools/pdfsign.c5
17 files changed, 699 insertions, 390 deletions
diff --git a/Makefile b/Makefile
index 3959ccf4..acf559fe 100644
--- a/Makefile
+++ b/Makefile
@@ -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)