* indirect references.
*/
+static int is_signature(fz_context *ctx, pdf_obj *obj)
+{
+ if (pdf_dict_get(ctx, obj, PDF_NAME(Type)) == PDF_NAME(Sig))
+ if (pdf_dict_get(ctx, obj, PDF_NAME(Contents)) && pdf_dict_get(ctx, obj, PDF_NAME(ByteRange)) && pdf_dict_get(ctx, obj, PDF_NAME(Filter)))
+ return 1;
+ return 0;
+}
+
static void
pdf_crypt_obj_imp(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, unsigned char *key, int keylen)
{
int n = pdf_dict_len(ctx, obj);
for (i = 0; i < n; i++)
{
+ if (pdf_dict_get_key(ctx, obj, i) == PDF_NAME(Contents) && is_signature(ctx, obj))
+ continue;
+
pdf_crypt_obj_imp(ctx, crypt, pdf_dict_get_val(ctx, obj, i), key, keylen);
}
}
}
}
+static int is_signature(fz_context *ctx, pdf_obj *obj)
+{
+ if (pdf_dict_get(ctx, obj, PDF_NAME(Type)) == PDF_NAME(Sig))
+ if (pdf_dict_get(ctx, obj, PDF_NAME(Contents)) && pdf_dict_get(ctx, obj, PDF_NAME(ByteRange)) && pdf_dict_get(ctx, obj, PDF_NAME(Filter)))
+ return 1;
+ return 0;
+}
+
static void fmt_dict(fz_context *ctx, struct fmt *fmt, pdf_obj *obj)
{
int i, n;
if (fmt->tight) {
fmt_puts(ctx, fmt, "<<");
for (i = 0; i < n; i++) {
- fmt_obj(ctx, fmt, pdf_dict_get_key(ctx, obj, i));
+ key = pdf_dict_get_key(ctx, obj, i);
+ val = pdf_dict_get_val(ctx, obj, i);
+ fmt_obj(ctx, fmt, key);
fmt_sep(ctx, fmt);
- fmt_obj(ctx, fmt, pdf_dict_get_val(ctx, obj, i));
+ if (key == PDF_NAME(Contents) && is_signature(ctx, obj))
+ {
+ pdf_crypt *crypt = fmt->crypt;
+ fz_try(ctx)
+ {
+ fmt->crypt = NULL;
+ fmt_obj(ctx, fmt, val);
+ }
+ fz_always(ctx)
+ fmt->crypt = crypt;
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+ else
+ fmt_obj(ctx, fmt, val);
fmt_sep(ctx, fmt);
}
fmt_puts(ctx, fmt, ">>");
fmt_putc(ctx, fmt, ' ');
if (!pdf_is_indirect(ctx, val) && pdf_is_array(ctx, val))
fmt->indent ++;
- fmt_obj(ctx, fmt, val);
+ if (key == PDF_NAME(Contents) && is_signature(ctx, obj))
+ {
+ pdf_crypt *crypt = fmt->crypt;
+ fz_try(ctx)
+ {
+ fmt->crypt = NULL;
+ fmt_obj(ctx, fmt, val);
+ }
+ fz_always(ctx)
+ fmt->crypt = crypt;
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ }
+ else
+ fmt_obj(ctx, fmt, val);
fmt_putc(ctx, fmt, '\n');
if (!pdf_is_indirect(ctx, val) && pdf_is_array(ctx, val))
fmt->indent --;
unsigned char *digest = NULL;
size_t digest_len;
pdf_obj *v = pdf_dict_get(ctx, field, PDF_NAME(V));
- pdf_obj *c = pdf_dict_get(ctx, v, PDF_NAME(Contents));
size_t len;
- const char *s = pdf_to_string(ctx, c, &len);
char *cstr = NULL;
fz_var(stm);
if (hexdigest_length < 4)
fz_throw(ctx, FZ_ERROR_GENERIC, "Bad parameters to pdf_write_digest");
- digest_len = (hexdigest_length - 2) / 2;
- if (len < digest_len)
- fz_throw(ctx, FZ_ERROR_GENERIC, "Signature contents array smaller than digest");
+ len = (hexdigest_length - 2) / 2;
fz_try(ctx)
{
stm = fz_stream_from_output(ctx, out);
in = fz_open_range_filter(ctx, stm, brange, brange_len);
- digest = fz_malloc(ctx, digest_len);
- digest_len = signer->create_digest(ctx, signer, in, digest, digest_len);
+ digest = fz_malloc(ctx, len);
+ digest_len = signer->create_digest(ctx, signer, in, digest, len);
+ if (digest_len == 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "signer provided no signature digest");
+ if (digest_len > len)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "signature digest larger than space for digest");
fz_drop_stream(ctx, in);
in = NULL;
stm = NULL;
fz_seek_output(ctx, out, (int64_t)hexdigest_offset+1, SEEK_SET);
-
cstr = fz_malloc(ctx, len);
- for (z = 0; z < digest_len; z++)
- fz_write_printf(ctx, out, "%02x", digest[z]);
- memcpy(cstr, digest, digest_len);
- memcpy(cstr + digest_len, s + digest_len, len - digest_len);
+ for (z = 0; z < len; z++)
+ {
+ int val = z < digest_len ? digest[z] : 0;
+ fz_write_printf(ctx, out, "%02x", val);
+ cstr[z] = val;
+ }
pdf_dict_put_string(ctx, v, PDF_NAME(Contents), cstr, len);
}