Example #1
0
 /**
  * Compute encryption key
  * @protected
  * @since 2.0.000 (2008-01-02)
  * @author Nicola Asuni
  */
 protected function _generateencryptionkey()
 {
     $keybytelen = $this->encryptdata['Length'] / 8;
     if (!$this->encryptdata['pubkey']) {
         // standard mode
         if ($this->encryptdata['mode'] == 3) {
             // AES-256
             // generate 256 bit random key
             $this->encryptdata['key'] = substr(hash('sha256', TCPDF_STATIC::getRandomSeed(), true), 0, $keybytelen);
             // truncate passwords
             $this->encryptdata['user_password'] = $this->_fixAES256Password($this->encryptdata['user_password']);
             $this->encryptdata['owner_password'] = $this->_fixAES256Password($this->encryptdata['owner_password']);
             // Compute U value
             $this->encryptdata['U'] = $this->_Uvalue();
             // Compute UE value
             $this->encryptdata['UE'] = $this->_UEvalue();
             // Compute O value
             $this->encryptdata['O'] = $this->_Ovalue();
             // Compute OE value
             $this->encryptdata['OE'] = $this->_OEvalue();
             // Compute P value
             $this->encryptdata['P'] = $this->encryptdata['protection'];
             // Computing the encryption dictionary's Perms (permissions) value
             $perms = TCPDF_STATIC::getEncPermissionsString($this->encryptdata['protection']);
             // bytes 0-3
             $perms .= chr(255) . chr(255) . chr(255) . chr(255);
             // bytes 4-7
             if (isset($this->encryptdata['CF']['EncryptMetadata']) and !$this->encryptdata['CF']['EncryptMetadata']) {
                 // byte 8
                 $perms .= 'F';
             } else {
                 $perms .= 'T';
             }
             $perms .= 'adb';
             // bytes 9-11
             $perms .= 'nick';
             // bytes 12-15
             $this->encryptdata['perms'] = TCPDF_STATIC::_AESnopad($this->encryptdata['key'], $perms);
         } else {
             // RC4-40, RC4-128, AES-128
             // Pad passwords
             $this->encryptdata['user_password'] = substr($this->encryptdata['user_password'] . TCPDF_STATIC::$enc_padding, 0, 32);
             $this->encryptdata['owner_password'] = substr($this->encryptdata['owner_password'] . TCPDF_STATIC::$enc_padding, 0, 32);
             // Compute O value
             $this->encryptdata['O'] = $this->_Ovalue();
             // get default permissions (reverse byte order)
             $permissions = TCPDF_STATIC::getEncPermissionsString($this->encryptdata['protection']);
             // Compute encryption key
             $tmp = TCPDF_STATIC::_md5_16($this->encryptdata['user_password'] . $this->encryptdata['O'] . $permissions . $this->encryptdata['fileid']);
             if ($this->encryptdata['mode'] > 0) {
                 for ($i = 0; $i < 50; ++$i) {
                     $tmp = TCPDF_STATIC::_md5_16(substr($tmp, 0, $keybytelen));
                 }
             }
             $this->encryptdata['key'] = substr($tmp, 0, $keybytelen);
             // Compute U value
             $this->encryptdata['U'] = $this->_Uvalue();
             // Compute P value
             $this->encryptdata['P'] = $this->encryptdata['protection'];
         }
     } else {
         // Public-Key mode
         // random 20-byte seed
         $seed = sha1(TCPDF_STATIC::getRandomSeed(), true);
         $recipient_bytes = '';
         foreach ($this->encryptdata['pubkeys'] as $pubkey) {
             // for each public certificate
             if (isset($pubkey['p'])) {
                 $pkprotection = TCPDF_STATIC::getUserPermissionCode($pubkey['p'], $this->encryptdata['mode']);
             } else {
                 $pkprotection = $this->encryptdata['protection'];
             }
             // get default permissions (reverse byte order)
             $pkpermissions = TCPDF_STATIC::getEncPermissionsString($pkprotection);
             // envelope data
             $envelope = $seed . $pkpermissions;
             // write the envelope data to a temporary file
             $tempkeyfile = TCPDF_STATIC::getObjFilename('key', $this->file_id);
             $f = TCPDF_STATIC::fopenLocal($tempkeyfile, 'wb');
             if (!$f) {
                 $this->Error('Unable to create temporary key file: ' . $tempkeyfile);
             }
             $envelope_length = strlen($envelope);
             fwrite($f, $envelope, $envelope_length);
             fclose($f);
             $tempencfile = TCPDF_STATIC::getObjFilename('enc', $this->file_id);
             if (!openssl_pkcs7_encrypt($tempkeyfile, $tempencfile, $pubkey['c'], array(), PKCS7_BINARY | PKCS7_DETACHED)) {
                 $this->Error('Unable to encrypt the file: ' . $tempkeyfile);
             }
             // read encryption signature
             $signature = file_get_contents($tempencfile, false, null, $envelope_length);
             // extract signature
             $signature = substr($signature, strpos($signature, 'Content-Disposition'));
             $tmparr = explode("\n\n", $signature);
             $signature = trim($tmparr[1]);
             unset($tmparr);
             // decode signature
             $signature = base64_decode($signature);
             // convert signature to hex
             $hexsignature = current(unpack('H*', $signature));
             // store signature on recipients array
             $this->encryptdata['Recipients'][] = $hexsignature;
             // The bytes of each item in the Recipients array of PKCS#7 objects in the order in which they appear in the array
             $recipient_bytes .= $signature;
         }
         // calculate encryption key
         if ($this->encryptdata['mode'] == 3) {
             // AES-256
             $this->encryptdata['key'] = substr(hash('sha256', $seed . $recipient_bytes, true), 0, $keybytelen);
         } else {
             // RC4-40, RC4-128, AES-128
             $this->encryptdata['key'] = substr(sha1($seed . $recipient_bytes, true), 0, $keybytelen);
         }
     }
 }