[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/lib/fpdf/ -> fpdfprotection.php (source)

   1  <?php
   2  /****************************************************************************
   3  * Software: FPDF_Protection                                                 *
   4  * Version:  1.02                                                            *
   5  * Date:     2005/05/08                                                      *
   6  * Author:   Klemen VODOPIVEC                                                *
   7  * License:  Freeware                                                        *
   8  *                                                                           *
   9  * You may use and modify this software as you wish as stated in original    *
  10  * FPDF package.                                                             *
  11  *                                                                           *
  12  * Thanks: Cpdf (http://www.ros.co.nz/pdf) was my working sample of how to   *
  13  * implement protection in pdf.                                              *
  14  ****************************************************************************/
  15  
  16  require_once ('fpdf.php');
  17  
  18  class FPDF_Protection extends FPDF
  19  {
  20      var $encrypted;          //whether document is protected
  21      var $Uvalue;             //U entry in pdf document
  22      var $Ovalue;             //O entry in pdf document
  23      var $Pvalue;             //P entry in pdf document
  24      var $enc_obj_id;         //encryption object id
  25      var $last_rc4_key;       //last RC4 key encrypted (cached for optimisation)
  26      var $last_rc4_key_c;     //last RC4 computed key
  27  
  28      function FPDF_Protection($orientation='P',$unit='mm',$format='A4') {
  29          parent::FPDF($orientation,$unit,$format);
  30  
  31          $this->encrypted=false;
  32          $this->last_rc4_key='';
  33          $this->padding="\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
  34                          "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
  35      }
  36  
  37      /**
  38      * Function to set permissions as well as user and owner passwords
  39      *
  40      * - permissions is an array with values taken from the following list:
  41      *   copy, print, modify, annot-forms
  42      *   If a value is present it means that the permission is granted
  43      * - If a user password is set, user will be prompted before document is opened
  44      * - If an owner password is set, document can be opened in privilege mode with no
  45      *   restriction if that password is entered
  46      */
  47      function SetProtection($permissions=array(),$user_pass='',$owner_pass=null) {
  48          $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32 );
  49          $protection = 192;
  50          foreach($permissions as $permission){
  51              if (!isset($options[$permission]))
  52                  $this->Error('Incorrect permission: '.$permission);
  53              $protection += $options[$permission];
  54          }
  55          if ($owner_pass === null)
  56              $owner_pass = uniqid(rand());
  57          $this->encrypted = true;
  58          $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
  59      }
  60  
  61  /****************************************************************************
  62  *                                                                           *
  63  *                              Private methods                              *
  64  *                                                                           *
  65  ****************************************************************************/
  66  
  67      function _putstream($s) {
  68          if ($this->encrypted) {
  69              $s = $this->_RC4($this->_objectkey($this->n), $s);
  70          }
  71          parent::_putstream($s);
  72      }
  73  
  74      function _textstring($s) {
  75          if ($this->encrypted) {
  76              $s = $this->_RC4($this->_objectkey($this->n), $s);
  77          }
  78          return parent::_textstring($s);
  79      }
  80  
  81      /**
  82      * Compute key depending on object number where the encrypted data is stored
  83      */
  84      function _objectkey($n) {
  85          return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,10);
  86      }
  87  
  88      /**
  89      * Escape special characters
  90      */
  91      function _escape($s) {
  92          $s=str_replace('\\','\\\\',$s);
  93          $s=str_replace(')','\\)',$s);
  94          $s=str_replace('(','\\(',$s);
  95          $s=str_replace("\r",'\\r',$s);
  96          return $s;
  97      }
  98  
  99      function _putresources() {
 100          parent::_putresources();
 101          if ($this->encrypted) {
 102              $this->_newobj();
 103              $this->enc_obj_id = $this->n;
 104              $this->_out('<<');
 105              $this->_putencryption();
 106              $this->_out('>>');
 107              $this->_out('endobj');
 108          }
 109      }
 110  
 111      function _putencryption() {
 112          $this->_out('/Filter /Standard');
 113          $this->_out('/V 1');
 114          $this->_out('/R 2');
 115          $this->_out('/O ('.$this->_escape($this->Ovalue).')');
 116          $this->_out('/U ('.$this->_escape($this->Uvalue).')');
 117          $this->_out('/P '.$this->Pvalue);
 118      }
 119  
 120      function _puttrailer() {
 121          parent::_puttrailer();
 122          if ($this->encrypted) {
 123              $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
 124              $this->_out('/ID [()()]');
 125          }
 126      }
 127  
 128      /**
 129      * RC4 is the standard encryption algorithm used in PDF format
 130      */
 131      function _RC4($key, $text) {
 132          if ($this->last_rc4_key != $key) {
 133              $k = str_repeat($key, 256/strlen($key)+1);
 134              $rc4 = range(0,255);
 135              $j = 0;
 136              for ($i=0; $i<256; $i++){
 137                  $t = $rc4[$i];
 138                  $j = ($j + $t + ord($k{$i})) % 256;
 139                  $rc4[$i] = $rc4[$j];
 140                  $rc4[$j] = $t;
 141              }
 142              $this->last_rc4_key = $key;
 143              $this->last_rc4_key_c = $rc4;
 144          } else {
 145              $rc4 = $this->last_rc4_key_c;
 146          }
 147  
 148          $len = strlen($text);
 149          $a = 0;
 150          $b = 0;
 151          $out = '';
 152          for ($i=0; $i<$len; $i++){
 153              $a = ($a+1)%256;
 154              $t= $rc4[$a];
 155              $b = ($b+$t)%256;
 156              $rc4[$a] = $rc4[$b];
 157              $rc4[$b] = $t;
 158              $k = $rc4[($rc4[$a]+$rc4[$b])%256];
 159              $out.=chr(ord($text{$i}) ^ $k);
 160          }
 161  
 162          return $out;
 163      }
 164  
 165      /**
 166      * Get MD5 as binary string
 167      */
 168      function _md5_16($string) {
 169          return pack('H*',md5($string));
 170      }
 171  
 172      /**
 173      * Compute O value
 174      */
 175      function _Ovalue($user_pass, $owner_pass) {
 176          $tmp = $this->_md5_16($owner_pass);
 177          $owner_RC4_key = substr($tmp,0,5);
 178          return $this->_RC4($owner_RC4_key, $user_pass);
 179      }
 180  
 181      /**
 182      * Compute U value
 183      */
 184      function _Uvalue() {
 185          return $this->_RC4($this->encryption_key, $this->padding);
 186      }
 187  
 188      /**
 189      * Compute encryption key
 190      */
 191      function _generateencryptionkey($user_pass, $owner_pass, $protection) {
 192          // Pad passwords
 193          $user_pass = substr($user_pass.$this->padding,0,32);
 194          $owner_pass = substr($owner_pass.$this->padding,0,32);
 195          // Compute O value
 196          $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
 197          // Compute encyption key
 198          $tmp = $this->_md5_16($user_pass.$this->Ovalue.chr($protection)."\xFF\xFF\xFF");
 199          $this->encryption_key = substr($tmp,0,5);
 200          // Compute U value
 201          $this->Uvalue = $this->_Uvalue();
 202          // Compute P value
 203          $this->Pvalue = -(($protection^255)+1);
 204      }
 205  }
 206  
 207  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7