Back to index

texmacs  1.0.7.15
pdfencrypt.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/pdfencrypt.c,v 1.14 2010/02/07 12:58:48 chofchof Exp $
00002  
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
00006     the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
00007     
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012     
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017     
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00021 */
00022 
00023 #if HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <time.h>
00031 
00032 #ifdef WIN32
00033 #include <conio.h>
00034 #define getch _getch
00035 #else  /* !WIN32 */
00036 #include <unistd.h>
00037 #endif /* WIN32 */
00038 
00039 #include "system.h"
00040 #include "mem.h"
00041 #include "error.h"
00042 #include "pdfobj.h"
00043 #include "dpxcrypt.h"
00044 
00045 #include "pdfencrypt.h"
00046 
00047 #define MAX_KEY_LEN 16
00048 #define MAX_STR_LEN 32
00049 #define MAX_PWD_LEN 128
00050 
00051 static unsigned char algorithm, revision, key_size;
00052 static long permission;
00053 
00054 static unsigned char key_data[MAX_KEY_LEN], id_string[MAX_KEY_LEN];
00055 static unsigned char opwd_string[MAX_STR_LEN], upwd_string[MAX_STR_LEN];
00056 
00057 static unsigned long current_label = 0;
00058 static unsigned current_generation = 0;
00059 
00060 static ARC4_KEY key;
00061 static MD5_CONTEXT md5_ctx;
00062 
00063 static unsigned char md5_buf[MAX_KEY_LEN], key_buf[MAX_KEY_LEN];
00064 static unsigned char in_buf[MAX_STR_LEN], out_buf[MAX_STR_LEN];
00065 
00066 static const unsigned char padding_string[MAX_STR_LEN] = {
00067   0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
00068   0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
00069   0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
00070   0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
00071 };
00072 
00073 static char owner_passwd[MAX_PWD_LEN], user_passwd[MAX_PWD_LEN];
00074 
00075 static unsigned char verbose = 0;
00076 
00077 void pdf_enc_set_verbose (void)
00078 {
00079   if (verbose < 255) verbose++;
00080 }
00081 
00082 #define PRODUCER "%s-%s, Copyright \251 2002-2010 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata"
00083 void pdf_enc_compute_id_string (char *dviname, char *pdfname)
00084 {
00085   char *date_string, *producer;
00086   time_t current_time;
00087   struct tm *bd_time;
00088 
00089   MD5_init(&md5_ctx);
00090 
00091   date_string = NEW (15, char);
00092   time(&current_time);
00093   bd_time = localtime(&current_time);
00094   sprintf (date_string, "%04d%02d%02d%02d%02d%02d",
00095           bd_time -> tm_year+1900, bd_time -> tm_mon+1, bd_time -> tm_mday,
00096           bd_time -> tm_hour, bd_time -> tm_min, bd_time -> tm_sec);
00097   MD5_write(&md5_ctx, (unsigned char *)date_string, strlen(date_string));
00098   RELEASE (date_string);
00099 
00100   producer = NEW (strlen(PRODUCER)+strlen(PACKAGE)+strlen(VERSION), char);
00101   sprintf(producer, PRODUCER, PACKAGE, VERSION);
00102   MD5_write(&md5_ctx, (unsigned char *)producer, strlen(producer));
00103   RELEASE (producer);
00104 
00105   MD5_write(&md5_ctx, (unsigned char *)dviname, strlen(dviname));
00106   MD5_write(&md5_ctx, (unsigned char *)pdfname, strlen(pdfname));
00107   MD5_final(id_string, &md5_ctx);
00108 }
00109 
00110 static void passwd_padding (unsigned char *src, unsigned char *dst)
00111 {
00112   register int len = strlen((char *)src);
00113 
00114   if (len > MAX_STR_LEN)
00115     len = MAX_STR_LEN;
00116 
00117   memcpy(dst, src, len);
00118   memcpy(dst+len, padding_string, MAX_STR_LEN-len);
00119 }
00120 
00121 static void compute_owner_password (void)
00122 {
00123   register unsigned char i, j;
00124   /*
00125    * Algorithm 3.3 Computing the encryption dictionary's O (owner password)
00126    *               value
00127    *
00128    * 1. Pad or truncate the owner password string as described in step 1
00129    *    of Algorithm 3.2. If there is no owner password, use the user
00130    *    password instead. (See implementation note 17 in Appendix H.)
00131    */
00132   passwd_padding((unsigned char *)(strlen(owner_passwd) > 0 ? owner_passwd : user_passwd), in_buf);
00133   /*
00134    * 2. Initialize the MD5 hash function and pass the result of step 1
00135    *    as input to this function.
00136    */
00137   MD5_init(&md5_ctx);
00138   MD5_write(&md5_ctx, in_buf, MAX_STR_LEN);
00139   MD5_final(md5_buf, &md5_ctx);
00140   /*
00141    * 3. (Revision 3 only) Do the following 50 times: Take the output
00142    *    from the previous MD5 hash and pass it as input into a new
00143    *    MD5 hash.
00144    */
00145   if (revision == 3)
00146     for (i = 0; i < 50; i++) {
00147       /*
00148        * NOTE: We truncate each MD5 hash as in the following step.
00149        *       Otherwise Adobe Reader won't decrypt the PDF file.
00150        */
00151       MD5_init(&md5_ctx);
00152       MD5_write(&md5_ctx, md5_buf, key_size);
00153       MD5_final(md5_buf, &md5_ctx);
00154     }
00155   /*
00156    * 4. Create an RC4 encryption key using the first n bytes of the output
00157    *    from the final MD5 hash, where n is always 5 for revision 2 but
00158    *    for revision 3 depends on the value of the encryption dictionary's
00159    *    Length entry.
00160    */
00161   ARC4_set_key(&key, key_size, md5_buf);
00162   /*
00163    * 5. Pad or truncate the user password string as described in step 1
00164    *    of Algorithm 3.2.
00165    */
00166   passwd_padding((unsigned char *)user_passwd, in_buf);
00167   /*
00168    * 6. Encrypt the result of step 5, using an RC4 encryption function
00169    *    with the encryption key obtained in step 4.
00170    */
00171   ARC4(&key, MAX_STR_LEN, in_buf, out_buf);
00172   /*
00173    * 7. (Revision 3 only) Do the following 19 times: Take the output
00174    *    from the previous invocation of the RC4 function and pass it
00175    *    as input to a new invocation of the function; use an encryption
00176    *    key generated by taking each byte of the encryption key obtained
00177    *    in step 4 and performing an XOR (exclusive or) operation between
00178    *    that byte and the single-byte value of the iteration counter
00179    *    (from 1 to 19).
00180    */
00181   if (revision == 3)
00182     for (i = 1; i <= 19; i++) {
00183       memcpy(in_buf, out_buf, MAX_STR_LEN);
00184       for (j = 0; j < key_size; j++)
00185         key_buf[j] = md5_buf[j] ^ i;
00186       ARC4_set_key(&key, key_size, key_buf);
00187       ARC4(&key, MAX_STR_LEN, in_buf, out_buf);
00188     }
00189   /*
00190    * 8. Store the output from the final invocation of the RC4 function
00191    *    as the value of the O entry in the encryption dictionary.
00192    */
00193   memcpy(opwd_string, out_buf, MAX_STR_LEN);
00194 }
00195 
00196 static void compute_encryption_key (unsigned char *pwd)
00197 {
00198   register unsigned char i;
00199   /*
00200    * Algorithm 3.2 Computing an encryption key
00201    *
00202    * 1. Pad or truncate the password string to exactly 32 bytes. If the
00203    *    password string is more than 32 bytes long, use only its first
00204    *    32 bytes; if it is less than 32 bytes long, pad it by appending
00205    *    the required number of additional bytes from the beginning of
00206    *    the following padding string:
00207    *
00208    *    < 28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08
00209    *      2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A >
00210    *
00211    *    That is, if the password string is n bytes long, append the
00212    *    first 32 - n bytes of the padding string to the end of the
00213    *    password string. If the password string is empty (zero-length),
00214    *   meaning there is no user password, substitute the entire
00215    *   padding string in its place.
00216    */
00217   passwd_padding(pwd, in_buf);
00218   /*
00219    * 2. Initialize the MD5 hash function and pass the result of step 1
00220    *    as input to this fuction.
00221    */
00222   MD5_init(&md5_ctx);
00223   MD5_write(&md5_ctx, in_buf, MAX_STR_LEN);
00224   /*
00225    * 3. Pass the value of the encryption dictionary's O entry to the
00226    *    MD5 hash function. (Algorithm 3.3 shows how the O value is
00227    *    computed.)
00228    */
00229   MD5_write(&md5_ctx, opwd_string, MAX_STR_LEN);
00230   /*
00231    * 4. Treat the value of the P entry as an unsigned 4-byte integer
00232    *    and pass these bytes to the MD5 hash function, low-order byte
00233    *    first.
00234    */
00235   in_buf[0] = (unsigned char)(permission) & 0xFF;
00236   in_buf[1] = (unsigned char)(permission >> 8) & 0xFF;
00237   in_buf[2] = (unsigned char)(permission >> 16) & 0xFF;
00238   in_buf[3] = (unsigned char)(permission >> 24) & 0xFF;
00239   MD5_write(&md5_ctx, in_buf, 4);
00240   /*
00241    * 5. Pass the first element of the file's file identifier array
00242    *    (the value of the ID entry in the document's trailer dictionary;
00243    *    see Table 3.12 on page 68) to the MD5 hash function and
00244    *    finish the hash.
00245    */
00246   MD5_write(&md5_ctx, id_string, MAX_KEY_LEN);
00247   MD5_final(md5_buf, &md5_ctx);
00248   /*
00249    * 6. (Revision 3 only) Do the following 50 times; Take the output from
00250    *    the previous MD5 hash and pass it as input into a new MD5 hash.
00251    */
00252   if (revision == 3)
00253     for (i = 0; i < 50; i++) {
00254       /*
00255        * NOTE: We truncate each MD5 hash as in the following step.
00256        *       Otherwise Adobe Reader won't decrypt the PDF file.
00257        */
00258       MD5_init(&md5_ctx);
00259       MD5_write(&md5_ctx, md5_buf, key_size);
00260       MD5_final(md5_buf, &md5_ctx);
00261     }
00262   /*
00263    * 7. Set the encryption key to the first n bytes of the output from
00264    *    the final MD5 hash, where n is always 5 for revision 2 but for
00265    *    revision 3 depends on the value of the encryption dictionary's
00266    *    Length entry.
00267    */
00268   memcpy(key_data, md5_buf, key_size);
00269 }
00270 
00271 static void compute_user_password (void)
00272 {
00273   register unsigned char i, j;
00274   /*
00275    * Algorithm 3.4 Computing the encryption dictionary's U (user password)
00276    *               value (Revision 2)
00277    *
00278    * 1. Create an encryption key based on the user password string, as
00279    *    described in Algorithm 3.2.
00280    *
00281    * 2. Encrypt the 32-byte padding string shown in step 1 of Algorithm
00282    *    3.2, using an RC4 encryption fuction with the encryption key from
00283    *    the preceeding step.
00284    *
00285    * 3. Store the result of step 2 as the value of the U entry in the
00286    *    encryption dictionary.
00287    */
00288   /*
00289    * Algorithm 3.5 Computing the encryption dictionary's U (user password)
00290    *               value (Revision 3)
00291    *
00292    * 1. Create an encryption key based on the user password string, as
00293    *    described in Algorithm 3.2.
00294    *
00295    * 2. Initialize the MD5 hash function and pass the 32-byte padding
00296    *    string shown in step 1 of Algorithm 3.2 as input to this function.
00297    *
00298    * 3. Pass the first element of the file's file identifier array (the
00299    *    value of the ID entry in the document's trailer dictionary; see
00300    *    Table 3.12 on page 68) to the hash function and finish the hash.
00301    *
00302    * 4. Encrypt the 16-byte result of the hash, using an RC4 encryption
00303    *    function with the encryption key from step 1.
00304    *
00305    * 5. Do the following 19 times: Take the output from the previous
00306    *    invocation of the RC4 function and pass it as input to a new
00307    *    invocation of the function; use an encryption key generated by
00308    *    taking each byte of the original encryption key (obtained in
00309    *    step 1) and performing an XOR (exclusive or) operation between
00310    *    that byte and the single-byte value of the iteration counter
00311    *    (from 1 to 19).
00312    *
00313    * 6. Append 16 bytes of arbitrary padding to the output from the
00314    *    final invocation of the RC4 function and store the 32-byte
00315    *    result as the value of the U entry in the encryption dictionary.
00316    */
00317   compute_encryption_key((unsigned char *)user_passwd);
00318 
00319   switch (revision) {
00320   case 2:
00321     ARC4_set_key(&key, key_size, key_data);
00322     ARC4(&key, MAX_STR_LEN, padding_string, out_buf);
00323     break;
00324   case 3:
00325     MD5_init(&md5_ctx);
00326     MD5_write(&md5_ctx, (unsigned char *)padding_string, MAX_STR_LEN);
00327 
00328     MD5_write(&md5_ctx, id_string, MAX_KEY_LEN);
00329     MD5_final(md5_buf, &md5_ctx);
00330 
00331     ARC4_set_key(&key, key_size, key_data);
00332     ARC4(&key, MAX_KEY_LEN, md5_buf, out_buf);
00333 
00334     for (i = 1; i <= 19; i++) {
00335       memcpy(in_buf, out_buf, MAX_KEY_LEN);
00336       for (j = 0; j < key_size; j++)
00337         key_buf[j] = key_data[j] ^ i;
00338       ARC4_set_key(&key, key_size, key_buf);
00339       ARC4(&key, MAX_KEY_LEN, in_buf, out_buf);
00340     }
00341     break;
00342   default:
00343     ERROR("Invalid revision number.\n");
00344   }
00345 
00346   memcpy(upwd_string, out_buf, MAX_STR_LEN);
00347 }
00348 
00349 #ifdef WIN32
00350 static char *getpass (const char *prompt)
00351 {
00352   static char pwd_buf[128];
00353   size_t i;
00354 
00355   fputs(prompt, stderr);
00356   fflush(stderr);
00357   for (i = 0; i < sizeof(pwd_buf)-1; i++) {
00358     pwd_buf[i] = getch();
00359     if (pwd_buf[i] == '\r')
00360       break;
00361   }
00362   pwd_buf[i] = '\0';
00363   fputs("\n", stderr);
00364   return pwd_buf;
00365 }
00366 #endif
00367 
00368 void pdf_enc_set_passwd (unsigned bits, unsigned perm, char *dviname, char *pdfname)
00369 {
00370   register char *retry_passwd;
00371 
00372   while (1) {
00373     strcpy(owner_passwd, getpass("Owner password: "));
00374     retry_passwd = getpass("Re-enter owner password: ");
00375     if (!strcmp(owner_passwd, retry_passwd))
00376       break;
00377     fputs("Password is not identical.\nTry again.\n", stderr);
00378     fflush(stderr);
00379   }
00380 
00381   while (1) {
00382     strcpy(user_passwd, getpass("User password: "));
00383     retry_passwd = getpass("Re-enter user password: ");
00384     if (!strcmp(user_passwd, retry_passwd))
00385       break;
00386     fputs("Password is not identical.\nTry again.\n", stderr);
00387     fflush(stderr);
00388   }
00389 
00390   key_size = (unsigned char)(bits / 8);
00391   algorithm = (key_size == 5 ? 1 : 2);
00392   permission = (long) (perm | 0xC0U);
00393   revision = ((algorithm == 1 && permission < 0x100L) ? 2 : 3);
00394   if (revision == 3)
00395     permission |= ~0xFFFL;
00396 
00397   compute_owner_password();
00398   compute_user_password();
00399 }
00400 
00401 void pdf_encrypt_data (unsigned char *data, unsigned long len)
00402 {
00403   unsigned char *result;
00404 
00405   memcpy(in_buf, key_data, key_size);
00406   in_buf[key_size]   = (unsigned char)(current_label) & 0xFF;
00407   in_buf[key_size+1] = (unsigned char)(current_label >> 8) & 0xFF;
00408   in_buf[key_size+2] = (unsigned char)(current_label >> 16) & 0xFF;
00409   in_buf[key_size+3] = (unsigned char)(current_generation) & 0xFF;
00410   in_buf[key_size+4] = (unsigned char)(current_generation >> 8) & 0xFF;
00411 
00412   MD5_init(&md5_ctx);
00413   MD5_write(&md5_ctx, in_buf, key_size+5);
00414   MD5_final(md5_buf, &md5_ctx);
00415   
00416   result = NEW (len, unsigned char);
00417   ARC4_set_key(&key, (key_size > 10 ? MAX_KEY_LEN : key_size+5), md5_buf);
00418   ARC4(&key, len, data, result);
00419   memcpy(data, result, len);
00420   RELEASE (result);
00421 }
00422 
00423 pdf_obj *pdf_encrypt_obj (void)
00424 {
00425   pdf_obj *doc_encrypt;
00426 
00427 #ifdef DEBUG
00428   fprintf (stderr, "(pdf_encrypt_obj)");
00429 #endif
00430 
00431   doc_encrypt = pdf_new_dict ();
00432 
00433   /* KEY  : Filter
00434    * TYPE : name
00435    * VALUE: (Required) The name of the security handler for this document;
00436    *        see below. Default value: Standard, for the built-in security
00437    *        handler.
00438    */
00439   pdf_add_dict (doc_encrypt, 
00440               pdf_new_name ("Filter"),
00441               pdf_new_name ("Standard"));
00442   /* KEY  : V
00443    * TYPE : number
00444    * VALUE: (Optional but strongly recommended) A code specifying the
00445    *        algorithm to be used in encrypting and decrypting the document:
00446    *        0  An algorithm that is undocumented and no longer supported,
00447    *           and whose use is strongly discouraged.
00448    *        1  Algorithm 3.1 on page 73, with an encryption key length
00449    *           of 40 bits; see below.
00450    *        2  (PDF 1.4) Algorithm 3.1 on page 73, but allowing encryption
00451    *           key lengths greater than 40 bits.
00452    *        3  (PDF 1.4) An unpublished algorithm allowing encryption key
00453    *           lengths ranging from 40 to 128 bits. (This algorithm is
00454    *           unpublished as an export requirement of the U.S. Department
00455    *           of Commerce.)
00456    *        The default value if this entry is omitted is 0, but a value
00457    *        of 1 or greater is strongly recommended.
00458    */
00459   pdf_add_dict (doc_encrypt, 
00460               pdf_new_name ("V"),
00461               pdf_new_number (algorithm));
00462   /* KEY  : Length
00463    * TYPE : integer
00464    * VALUE: (Optional; PDF 1.4; only if V is 2 or 3) The length of the
00465    *        encryption key, in bits. The value must be a multiple of 8,
00466    *        in the range 40 to 128. Default value: 40.
00467    */
00468   if (algorithm > 1)
00469     pdf_add_dict (doc_encrypt, 
00470                 pdf_new_name ("Length"),
00471                 pdf_new_number (key_size * 8));
00472   /* KEY  : R
00473    * TYPE : number
00474    * VALUE: (Required) A number specifying which revision of the standard
00475    *        security handler should be used to interpret this dictionary.
00476    *        The revison number should be 2 if the document is encrypted
00477    *        with a V value less than 2; otherwise this value should be 3.
00478    */
00479   pdf_add_dict (doc_encrypt, 
00480               pdf_new_name ("R"),
00481               pdf_new_number (revision));
00482   /* KEY  : O
00483    * TYPE : string
00484    * VALUE: (Required) A 32-byte string, based on both the owner and
00485    *        user passwords, that is used in computing the encryption
00486    *        key and in determining whether a valid owner password was
00487    *        entered.
00488    */
00489   pdf_add_dict (doc_encrypt, 
00490               pdf_new_name ("O"),
00491               pdf_new_string (opwd_string, 32));
00492   /* KEY  : U
00493    * TYPE : string
00494    * VALUE: (Required) A 32-byte string, based on the user password,
00495    *        that is used in determining whether to prompt the user
00496    *        for a password and, if so, whether a valid user or owner
00497    *        password was entered.
00498    */
00499   pdf_add_dict (doc_encrypt, 
00500               pdf_new_name ("U"),
00501               pdf_new_string (upwd_string, 32));
00502   /* KEY  : P
00503    * TYPE : (signed 32 bit) integer
00504    * VALUE: (Required) A set of flags specifying which operations are
00505    *        permitted when the document is opened with user access.
00506    */
00507   pdf_add_dict (doc_encrypt, 
00508               pdf_new_name ("P"),
00509               pdf_new_number (permission));
00510 
00511   return doc_encrypt;
00512 }
00513 
00514 pdf_obj *pdf_enc_id_array (void)
00515 {
00516   pdf_obj *id = pdf_new_array();
00517   pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN));
00518   pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN));
00519   return id;
00520 }
00521 
00522 void pdf_enc_set_label (unsigned long label)
00523 {
00524   current_label = label;
00525 }
00526 
00527 void pdf_enc_set_generation (unsigned generation)
00528 {
00529   current_generation = generation;
00530 }