summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/win_main.c12
-rw-r--r--pdf/mupdf.h99
-rw-r--r--pdf/pdf_crypt.c82
-rw-r--r--pdf/pdf_stream.c17
4 files changed, 118 insertions, 92 deletions
diff --git a/apps/win_main.c b/apps/win_main.c
index 5e513c89..0054ca17 100644
--- a/apps/win_main.c
+++ b/apps/win_main.c
@@ -171,17 +171,15 @@ dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if (xref->crypt)
{
- sprintf(buf, "Standard %d bit %s", xref->crypt->length,
- xref->crypt->strf.method == PDF_CRYPT_AESV2 ? "AES" : "RC4");
- SetDlgItemTextA(hwnd, 0x12, buf);
+ SetDlgItemTextA(hwnd, 0x12, "Encrypted.");
strcpy(buf, "");
- if (xref->crypt->p & (1 << 2))
+ if (pdf_has_permission(xref, PDF_PERM_PRINT))
strcat(buf, "print, ");
- if (xref->crypt->p & (1 << 3))
+ if (pdf_has_permission(xref, PDF_PERM_CHANGE))
strcat(buf, "modify, ");
- if (xref->crypt->p & (1 << 4))
+ if (pdf_has_permission(xref, PDF_PERM_COPY))
strcat(buf, "copy, ");
- if (xref->crypt->p & (1 << 5))
+ if (pdf_has_permission(xref, PDF_PERM_NOTES))
strcat(buf, "annotate, ");
if (strlen(buf) > 2)
buf[strlen(buf)-2] = 0;
diff --git a/pdf/mupdf.h b/pdf/mupdf.h
index 228cd714..8d3b5ac4 100644
--- a/pdf/mupdf.h
+++ b/pdf/mupdf.h
@@ -42,78 +42,11 @@ fz_obj *pdf_to_utf8_name(fz_obj *src);
char *pdf_from_ucs2(unsigned short *str);
/*
- * Encryption
- */
-
-/* Permission flag bits */
-#define PDF_PERM_PRINT (1<<2)
-#define PDF_PERM_CHANGE (1<<3)
-#define PDF_PERM_COPY (1<<4)
-#define PDF_PERM_NOTES (1<<5)
-#define PDF_PERM_FILL_FORM (1<<8)
-#define PDF_PERM_ACCESSIBILITY (1<<9)
-#define PDF_PERM_ASSEMBLE (1<<10)
-#define PDF_PERM_HIGH_RES_PRINT (1<<11)
-#define PDF_DEFAULT_PERM_FLAGS 0xfffc
-
-typedef struct pdf_crypt_s pdf_crypt;
-typedef struct pdf_crypt_filter_s pdf_crypt_filter;
-
-enum
-{
- PDF_CRYPT_NONE,
- PDF_CRYPT_RC4,
- PDF_CRYPT_AESV2,
- PDF_CRYPT_AESV3,
- PDF_CRYPT_UNKNOWN,
-};
-
-struct pdf_crypt_filter_s
-{
- int method;
- int length;
-};
-
-struct pdf_crypt_s
-{
- unsigned char id_string[32];
- int id_length;
-
- int v;
- int length;
- fz_obj *cf;
- pdf_crypt_filter stmf;
- pdf_crypt_filter strf;
-
- int r;
- unsigned char o[48];
- unsigned char u[48];
- unsigned char oe[32];
- unsigned char ue[32];
- int p;
- int encrypt_metadata;
-
- unsigned char key[32]; /* decryption key generated from password */
-};
-
-/* crypt.c */
-fz_error pdf_new_crypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id);
-void pdf_free_crypt(pdf_crypt *crypt);
-
-fz_error pdf_parse_crypt_filter(pdf_crypt_filter *cf, fz_obj *dict, int defaultlength);
-fz_stream *pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, pdf_crypt_filter *cf, int num, int gen);
-void pdf_crypt_obj(pdf_crypt *crypt, fz_obj *obj, int num, int gen);
-
-int pdf_needs_password(pdf_xref *xref);
-int pdf_authenticate_password(pdf_xref *xref, char *pw);
-
-void pdf_debug_crypt(pdf_crypt *crypt);
-
-/*
* xref and object / stream api
*/
typedef struct pdf_xref_entry_s pdf_xref_entry;
+typedef struct pdf_crypt_s pdf_crypt;
struct pdf_xref_entry_s
{
@@ -170,6 +103,36 @@ void pdf_debug_xref(pdf_xref *);
void pdf_resize_xref(pdf_xref *xref, int newcap);
/*
+ * Encryption
+ */
+
+enum
+{
+ PDF_PERM_PRINT = 1 << 2,
+ PDF_PERM_CHANGE = 1 << 3,
+ PDF_PERM_COPY = 1 << 4,
+ PDF_PERM_NOTES = 1 << 5,
+ PDF_PERM_FILL_FORM = 1 << 8,
+ PDF_PERM_ACCESSIBILITY = 1 << 9,
+ PDF_PERM_ASSEMBLE = 1 << 10,
+ PDF_PERM_HIGH_RES_PRINT = 1 << 11,
+ PDF_DEFAULT_PERM_FLAGS = 0xfffc
+};
+
+fz_error pdf_new_crypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id);
+void pdf_free_crypt(pdf_crypt *crypt);
+
+void pdf_crypt_obj(pdf_crypt *crypt, fz_obj *obj, int num, int gen);
+fz_stream *pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, int num, int gen);
+fz_stream *pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int num, int gen);
+
+int pdf_needs_password(pdf_xref *xref);
+int pdf_authenticate_password(pdf_xref *xref, char *pw);
+int pdf_has_permission(pdf_xref *xref, int p);
+
+void pdf_debug_crypt(pdf_crypt *crypt);
+
+/*
* Resource store
*/
diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c
index d29e756d..edd3e985 100644
--- a/pdf/pdf_crypt.c
+++ b/pdf/pdf_crypt.c
@@ -1,6 +1,47 @@
#include "fitz.h"
#include "mupdf.h"
+enum
+{
+ PDF_CRYPT_NONE,
+ PDF_CRYPT_RC4,
+ PDF_CRYPT_AESV2,
+ PDF_CRYPT_AESV3,
+ PDF_CRYPT_UNKNOWN,
+};
+
+typedef struct pdf_crypt_filter_s pdf_crypt_filter;
+
+struct pdf_crypt_filter_s
+{
+ int method;
+ int length;
+};
+
+struct pdf_crypt_s
+{
+ unsigned char id_string[32];
+ int id_length;
+
+ int v;
+ int length;
+ fz_obj *cf;
+ pdf_crypt_filter stmf;
+ pdf_crypt_filter strf;
+
+ int r;
+ unsigned char o[48];
+ unsigned char u[48];
+ unsigned char oe[32];
+ unsigned char ue[32];
+ int p;
+ int encrypt_metadata;
+
+ unsigned char key[32]; /* decryption key generated from password */
+};
+
+static fz_error pdf_parse_crypt_filter(pdf_crypt_filter *cf, fz_obj *dict, int defaultlength);
+
/*
* Create crypt object for decrypting strings and streams
* given the Encryption and ID objects.
@@ -228,7 +269,7 @@ pdf_free_crypt(pdf_crypt *crypt)
* Parse a CF dictionary entry (PDF 1.7 table 3.22)
*/
-fz_error
+static fz_error
pdf_parse_crypt_filter(pdf_crypt_filter *cf, fz_obj *dict, int defaultlength)
{
fz_obj *obj;
@@ -560,6 +601,14 @@ pdf_needs_password(pdf_xref *xref)
return 1;
}
+int
+pdf_has_permission(pdf_xref *xref, int p)
+{
+ if (!xref->crypt)
+ return 1;
+ return xref->crypt->p & p;
+}
+
/*
* PDF 1.7 algorithm 3.1 and ExtensionLevel 3 algorithm 3.1a
*
@@ -679,8 +728,8 @@ pdf_crypt_obj(pdf_crypt *crypt, fz_obj *obj, int num, int gen)
*
* Create filter suitable for de/encrypting a stream.
*/
-fz_stream *
-pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, pdf_crypt_filter *stmf, int num, int gen)
+static fz_stream *
+pdf_open_crypt_imp(fz_stream *chain, pdf_crypt *crypt, pdf_crypt_filter *stmf, int num, int gen)
{
unsigned char key[32];
int len;
@@ -696,6 +745,33 @@ pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, pdf_crypt_filter *stmf, int n
return fz_open_copy(chain);
}
+fz_stream *
+pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, int num, int gen)
+{
+ return pdf_open_crypt_imp(chain, crypt, &crypt->stmf, num, gen);
+}
+
+fz_stream *
+pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int num, int gen)
+{
+ fz_error error;
+ pdf_crypt_filter cf;
+
+ if (strcmp(name, "Identity"))
+ {
+ fz_obj *obj = fz_dict_gets(crypt->cf, name);
+ if (fz_is_dict(obj))
+ {
+ error = pdf_parse_crypt_filter(&cf, obj, crypt->length);
+ if (error)
+ fz_catch(error, "cannot parse crypt filter (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ else
+ return pdf_open_crypt_imp(chain, crypt, &cf, num, gen);
+ }
+ }
+ return chain;
+}
+
void pdf_debug_crypt(pdf_crypt *crypt)
{
int i;
diff --git a/pdf/pdf_stream.c b/pdf/pdf_stream.c
index 79b39d07..c2dd8578 100644
--- a/pdf/pdf_stream.c
+++ b/pdf/pdf_stream.c
@@ -113,7 +113,6 @@ build_filter(fz_stream *chain, pdf_xref * xref, fz_obj * f, fz_obj * p, int num,
else if (!strcmp(s, "Crypt"))
{
- pdf_crypt_filter cf;
fz_obj *name;
if (!xref->crypt)
@@ -123,18 +122,8 @@ build_filter(fz_stream *chain, pdf_xref * xref, fz_obj * f, fz_obj * p, int num,
}
name = fz_dict_gets(p, "Name");
- if (fz_is_name(name) && strcmp(fz_to_name(name), "Identity") != 0)
- {
- fz_obj *obj = fz_dict_get(xref->crypt->cf, name);
- if (fz_is_dict(obj))
- {
- error = pdf_parse_crypt_filter(&cf, obj, xref->crypt->length);
- if (error)
- fz_catch(error, "cannot parse crypt filter (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
- else
- return pdf_open_crypt(chain, xref->crypt, &cf, num, gen);
- }
- }
+ if (fz_is_name(name))
+ return pdf_open_crypt_with_filter(chain, xref->crypt, fz_to_name(name), num, gen);
return chain;
}
@@ -184,7 +173,7 @@ pdf_open_raw_filter(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int num, i
hascrypt = pdf_stream_has_crypt(stmobj);
if (xref->crypt && !hascrypt)
- chain = pdf_open_crypt(chain, xref->crypt, &xref->crypt->stmf, num, gen);
+ chain = pdf_open_crypt(chain, xref->crypt, num, gen);
return chain;
}