diff options
author | Paul Gardiner <paul.gardiner@artifex.com> | 2018-08-28 14:11:49 +0100 |
---|---|---|
committer | Paul Gardiner <paul.gardiner@artifex.com> | 2018-08-28 15:36:10 +0100 |
commit | e2f757a5c78fce69faeeacb0850b886374c63b5f (patch) | |
tree | 6fdf1962e358bc65ca7b9122f6a899b664d92199 /source/pdf/pdf-write.c | |
parent | 1f279100b292519fa095c576e49ba3e3bb4efbe8 (diff) | |
download | mupdf-e2f757a5c78fce69faeeacb0850b886374c63b5f.tar.xz |
Avoid use of fixed size buffers for the digest when document signing
The signer object now has an extra method that informs the caller of
the maximum size the digest might be. This is used to allocate space for
the digest within the file and to size some of the buffers used in the
code.
The openssl-based inplementation of the signer object has been updated to
perform a test digest generation so as to find the size needed. We
believe that the digest size is indendent of the hashed data.
Diffstat (limited to 'source/pdf/pdf-write.c')
-rw-r--r-- | source/pdf/pdf-write.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c index 26fcd9d1..227258d8 100644 --- a/source/pdf/pdf-write.c +++ b/source/pdf/pdf-write.c @@ -13,6 +13,8 @@ /* #define DEBUG_HEAP_SORT */ /* #define DEBUG_WRITING */ +#define SIG_EXTRAS_SIZE (1024) + typedef struct pdf_write_state_s pdf_write_state; /* @@ -2627,12 +2629,14 @@ static void presize_unsaved_signature_byteranges(fz_context *ctx, pdf_document * static void complete_signatures(fz_context *ctx, pdf_document *doc, pdf_write_state *opts) { pdf_unsaved_sig *usig; - char buf[5120]; + char *buf = NULL; + int buf_size; int s; int i; int last_end; fz_stream *stm = NULL; fz_var(stm); + fz_var(buf); fz_try(ctx) { @@ -2643,6 +2647,18 @@ static void complete_signatures(fz_context *ctx, pdf_document *doc, pdf_write_st if (xref->unsaved_sigs) { pdf_obj *byte_range; + buf_size = 0; + + for (usig = xref->unsaved_sigs; usig; usig = usig->next) + { + int size = usig->signer->max_digest_size(usig->signer); + + buf_size = fz_maxi(buf_size, size); + } + + buf_size = buf_size * 2 + SIG_EXTRAS_SIZE; + + buf = fz_calloc(ctx, buf_size, 1); stm = fz_stream_from_output(ctx, opts->out); /* Locate the byte ranges and contents in the saved file */ @@ -2651,8 +2667,8 @@ static void complete_signatures(fz_context *ctx, pdf_document *doc, pdf_write_st char *bstr, *cstr, *fstr; int pnum = pdf_obj_parent_num(ctx, pdf_dict_getl(ctx, usig->field, PDF_NAME(V), PDF_NAME(ByteRange), NULL)); fz_seek(ctx, stm, opts->ofs_list[pnum], SEEK_SET); - (void)fz_read(ctx, stm, (unsigned char *)buf, sizeof(buf)); - buf[sizeof(buf)-1] = 0; + (void)fz_read(ctx, stm, (unsigned char *)buf, buf_size); + buf[buf_size-1] = 0; bstr = strstr(buf, "/ByteRange"); cstr = strstr(buf, "/Contents"); @@ -2690,8 +2706,8 @@ static void complete_signatures(fz_context *ctx, pdf_document *doc, pdf_write_st pdf_dict_putl_drop(ctx, usig->field, pdf_copy_array(ctx, byte_range), PDF_NAME(V), PDF_NAME(ByteRange), NULL); /* Write the byte range into buf, padding with spaces*/ - i = pdf_sprint_obj(ctx, buf, sizeof(buf), byte_range, 1); - memset(buf+i, ' ', sizeof(buf)-i); + i = pdf_sprint_obj(ctx, buf, buf_size, byte_range, 1); + memset(buf+i, ' ', buf_size-i); /* Write the byte range to the file */ for (usig = xref->unsaved_sigs; usig; usig = usig->next) @@ -2714,12 +2730,16 @@ static void complete_signatures(fz_context *ctx, pdf_document *doc, pdf_write_st } xref->unsaved_sigs_end = NULL; + + fz_free(ctx, buf); + buf = NULL; } } } fz_catch(ctx) { fz_drop_stream(ctx, stm); + fz_free(ctx, buf); fz_rethrow(ctx); } } |