summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2013-03-04 13:56:54 +0100
committerRobin Watts <robin.watts@artifex.com>2013-04-11 13:58:58 +0100
commitb302892a8c302aee9ca6d2abab2f32afbee3a8a5 (patch)
tree38479155f5b62933d6e7bbc4826494a6ed548fc8
parent5ff123aed2b3853a4765a0d85de18d7074c2e1ec (diff)
downloadmupdf-b302892a8c302aee9ca6d2abab2f32afbee3a8a5.tar.xz
Convert UTF-8 passwords to correct encoding.
PDFDocEncoding for crypt revisions <= 4, UTF-8 for newer.
-rw-r--r--pdf/data_encodings.h7
-rw-r--r--pdf/mupdf.h2
-rw-r--r--pdf/pdf_crypt.c40
3 files changed, 42 insertions, 7 deletions
diff --git a/pdf/data_encodings.h b/pdf/data_encodings.h
index 96b06769..025e9d03 100644
--- a/pdf/data_encodings.h
+++ b/pdf/data_encodings.h
@@ -2,9 +2,10 @@
const unsigned short pdf_doc_encoding[256] =
{
- 0x0, ' ', ' ', ' ', ' ', ' ', ' ', ' ',
- ' ', 0x9, 0xA, ' ', ' ', 0xD, ' ', ' ',
- ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ /* 0x0 to 0x17 except \t, \n and \r are really undefined */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
diff --git a/pdf/mupdf.h b/pdf/mupdf.h
index 9dbafc91..301f8a8a 100644
--- a/pdf/mupdf.h
+++ b/pdf/mupdf.h
@@ -193,7 +193,7 @@ pdf_document *pdf_open_document_with_stream(fz_context *ctx, fz_stream *file);
void pdf_close_document(pdf_document *doc);
int pdf_needs_password(pdf_document *doc);
-int pdf_authenticate_password(pdf_document *doc, char *pw);
+int pdf_authenticate_password(pdf_document *doc, const char *pw);
enum
{
diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c
index 82295af2..54579570 100644
--- a/pdf/pdf_crypt.c
+++ b/pdf/pdf_crypt.c
@@ -699,13 +699,47 @@ pdf_authenticate_owner_password(fz_context *ctx, pdf_crypt *crypt, unsigned char
return pdf_authenticate_user_password(ctx, crypt, userpass, 32);
}
+static void pdf_docenc_from_utf8(char *password, const char *utf8, int n)
+{
+ int i = 0, k, c;
+ while (*utf8 && i + 1 < n)
+ {
+ utf8 += fz_chartorune(&c, utf8);
+ for (k = 0; k < 256; k++)
+ {
+ if (c == pdf_doc_encoding[k])
+ {
+ password[i++] = k;
+ break;
+ }
+ }
+ /* FIXME: drop characters that can't be encoded or return an error? */
+ }
+ password[i] = 0;
+}
+
+static void pdf_saslprep_from_utf8(char *password, const char *utf8, int n)
+{
+ /* TODO: stringprep with SALSprep profile */
+ fz_strlcpy(password, utf8, n);
+}
+
int
-pdf_authenticate_password(pdf_document *xref, char *password)
+pdf_authenticate_password(pdf_document *xref, const char *pwd_utf8)
{
+ char password[2048];
+
if (xref->crypt)
{
- if (!password)
- password = "";
+ password[0] = 0;
+ if (pwd_utf8)
+ {
+ if (xref->crypt->r <= 4)
+ pdf_docenc_from_utf8(password, pwd_utf8, sizeof password);
+ else
+ pdf_saslprep_from_utf8(password, pwd_utf8, sizeof password);
+ }
+
if (pdf_authenticate_user_password(xref->ctx, xref->crypt, (unsigned char *)password, strlen(password)))
return 1;
if (pdf_authenticate_owner_password(xref->ctx, xref->crypt, (unsigned char *)password, strlen(password)))