diff options
-rw-r--r-- | apps/win_main.c | 12 | ||||
-rw-r--r-- | pdf/mupdf.h | 99 | ||||
-rw-r--r-- | pdf/pdf_crypt.c | 82 | ||||
-rw-r--r-- | pdf/pdf_stream.c | 17 |
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; } |