Beispiel #1
1
 /**
  * Convert the loaded image to a JPEG and then return a structure for the PDF creator.
  * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
  * @param $image (image) Image object.
  * @param $quality (int) JPEG quality.
  * return image JPEG image object.
  * @public static
  */
 public static function _toJPEG($image, $quality)
 {
     $tempname = TCPDF_STATIC::getObjFilename('img');
     imagejpeg($image, $tempname, $quality);
     imagedestroy($image);
     $retvars = self::_parsejpeg($tempname);
     // tidy up by removing temporary image
     unlink($tempname);
     return $retvars;
 }
Beispiel #2
0
 /**
  * Set font buffer content.
  * @param $font (string) font key
  * @param $data (array) font data
  * @protected
  * @since 4.5.000 (2009-01-02)
  */
 protected function setFontBuffer($font, $data)
 {
     if ($this->diskcache) {
         if (!isset($this->fonts[$font])) {
             $this->fonts[$font] = TCPDF_STATIC::getObjFilename('font');
         }
         $this->writeDiskCache($this->fonts[$font], serialize($data));
     } else {
         $this->fonts[$font] = $data;
     }
     if (!in_array($font, $this->fontkeys)) {
         $this->fontkeys[] = $font;
         // store object ID for current font
         ++$this->n;
         $this->font_obj_ids[$font] = $this->n;
         $this->setFontSubBuffer($font, 'n', $this->n);
     }
 }
 /**
  * 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);
         }
     }
 }
Beispiel #4
0
 /**
  * Overriden to allow unicode in filenames
  * @see http://sourceforge.net/p/tcpdf/feature-requests/184/
  *
  * Send the document to a given destination: string, local file or browser.
  * In the last case, the plug-in may be used (if present) or a download ("Save as" dialog box) may be forced.<br />
  * The method first calls Close() if necessary to terminate the document.
  * @param $name (string) The name of the file when saved. Note that special characters are removed and blanks characters are replaced with the underscore character.
  * @param $dest (string) Destination where to send the document. It can take one of the following values:<ul><li>I: send the file inline to the browser (default). The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.</li><li>D: send to the browser and force a file download with the name given by name.</li><li>F: save to a local server file with the name given by name.</li><li>S: return the document as a string (name is ignored).</li><li>FI: equivalent to F + I option</li><li>FD: equivalent to F + D option</li><li>E: return the document as base64 mime multi-part email attachment (RFC 2045)</li></ul>
  * @public
  * @since 1.0
  * @see Close()
  */
 public function Output($name = 'doc.pdf', $dest = 'I')
 {
     //Output PDF to some destination
     //Finish document if necessary
     if ($this->state < 3) {
         $this->Close();
     }
     //Normalize parameters
     if (is_bool($dest)) {
         $dest = $dest ? 'D' : 'F';
     }
     $dest = strtoupper($dest);
     if ($dest[0] != 'F') {
         $name = preg_replace('/[\\s]+/', '_', $name);
         $name = preg_replace('/[^\\p{L}\\p{N}_\\.-]/u', '', $name);
     }
     if ($this->sign) {
         // *** apply digital signature to the document ***
         // get the document content
         $pdfdoc = $this->getBuffer();
         // remove last newline
         $pdfdoc = substr($pdfdoc, 0, -1);
         // Remove the original buffer
         if (isset($this->diskcache) and $this->diskcache) {
             // remove buffer file from cache
             unlink($this->buffer);
         }
         unset($this->buffer);
         // remove filler space
         $byterange_string_len = strlen(TCPDF_STATIC::$byterange_string);
         // define the ByteRange
         $byte_range = array();
         $byte_range[0] = 0;
         $byte_range[1] = strpos($pdfdoc, TCPDF_STATIC::$byterange_string) + $byterange_string_len + 10;
         $byte_range[2] = $byte_range[1] + $this->signature_max_length + 2;
         $byte_range[3] = strlen($pdfdoc) - $byte_range[2];
         $pdfdoc = substr($pdfdoc, 0, $byte_range[1]) . substr($pdfdoc, $byte_range[2]);
         // replace the ByteRange
         $byterange = sprintf('/ByteRange[0 %u %u %u]', $byte_range[1], $byte_range[2], $byte_range[3]);
         $byterange .= str_repeat(' ', $byterange_string_len - strlen($byterange));
         $pdfdoc = str_replace(TCPDF_STATIC::$byterange_string, $byterange, $pdfdoc);
         // write the document to a temporary folder
         $tempdoc = TCPDF_STATIC::getObjFilename('doc');
         $f = fopen($tempdoc, 'wb');
         if (!$f) {
             $this->Error('Unable to create temporary file: ' . $tempdoc);
         }
         $pdfdoc_length = strlen($pdfdoc);
         fwrite($f, $pdfdoc, $pdfdoc_length);
         fclose($f);
         // get digital signature via openssl library
         $tempsign = TCPDF_STATIC::getObjFilename('sig');
         if (empty($this->signature_data['extracerts'])) {
             openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED);
         } else {
             openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']);
         }
         unlink($tempdoc);
         // read signature
         $signature = file_get_contents($tempsign);
         unlink($tempsign);
         // extract signature
         $signature = substr($signature, $pdfdoc_length);
         $signature = substr($signature, strpos($signature, "%%EOF\n\n------") + 13);
         $tmparr = explode("\n\n", $signature);
         $signature = $tmparr[1];
         unset($tmparr);
         // decode signature
         $signature = base64_decode(trim($signature));
         // convert signature to hex
         $signature = current(unpack('H*', $signature));
         $signature = str_pad($signature, $this->signature_max_length, '0');
         // disable disk caching
         $this->diskcache = false;
         // Add signature to the document
         $this->buffer = substr($pdfdoc, 0, $byte_range[1]) . '<' . $signature . '>' . substr($pdfdoc, $byte_range[1]);
         $this->bufferlen = strlen($this->buffer);
     }
     switch ($dest) {
         case 'I':
             // Send PDF to the standard output
             if (ob_get_contents()) {
                 $this->Error('Some data has already been output, can\'t send PDF file');
             }
             if (php_sapi_name() != 'cli') {
                 // send output to a browser
                 header('Content-Type: application/pdf');
                 if (headers_sent()) {
                     $this->Error('Some data has already been output to browser, can\'t send PDF file');
                 }
                 header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
                 //header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
                 header('Pragma: public');
                 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
                 // Date in the past
                 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
                 header('Content-Disposition: inline; filename="' . basename($name) . '"');
                 TCPDF_STATIC::sendOutputData($this->getBuffer(), $this->bufferlen);
             } else {
                 echo $this->getBuffer();
             }
             break;
         case 'D':
             // download PDF as file
             if (ob_get_contents()) {
                 $this->Error('Some data has already been output, can\'t send PDF file');
             }
             header('Content-Description: File Transfer');
             if (headers_sent()) {
                 $this->Error('Some data has already been output to browser, can\'t send PDF file');
             }
             header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
             //header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
             header('Pragma: public');
             header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
             // Date in the past
             header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
             // force download dialog
             if (strpos(php_sapi_name(), 'cgi') === false) {
                 header('Content-Type: application/force-download');
                 header('Content-Type: application/octet-stream', false);
                 header('Content-Type: application/download', false);
                 header('Content-Type: application/pdf', false);
             } else {
                 header('Content-Type: application/pdf');
             }
             // use the Content-Disposition header to supply a recommended filename
             header('Content-Disposition: attachment; filename="' . basename($name) . '"');
             header('Content-Transfer-Encoding: binary');
             TCPDF_STATIC::sendOutputData($this->getBuffer(), $this->bufferlen);
             break;
         case 'F':
         case 'FI':
         case 'FD':
             // save PDF to a local file
             if ($this->diskcache) {
                 copy($this->buffer, $name);
             } else {
                 $f = fopen($name, 'wb');
                 if (!$f) {
                     $this->Error('Unable to create output file: ' . $name);
                 }
                 fwrite($f, $this->getBuffer(), $this->bufferlen);
                 fclose($f);
             }
             if ($dest == 'FI') {
                 // send headers to browser
                 header('Content-Type: application/pdf');
                 header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
                 //header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
                 header('Pragma: public');
                 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
                 // Date in the past
                 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
                 header('Content-Disposition: inline; filename="' . basename($name) . '"');
                 TCPDF_STATIC::sendOutputData(file_get_contents($name), filesize($name));
             } elseif ($dest == 'FD') {
                 // send headers to browser
                 if (ob_get_contents()) {
                     $this->Error('Some data has already been output, can\'t send PDF file');
                 }
                 header('Content-Description: File Transfer');
                 if (headers_sent()) {
                     $this->Error('Some data has already been output to browser, can\'t send PDF file');
                 }
                 header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
                 header('Pragma: public');
                 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
                 // Date in the past
                 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
                 // force download dialog
                 if (strpos(php_sapi_name(), 'cgi') === false) {
                     header('Content-Type: application/force-download');
                     header('Content-Type: application/octet-stream', false);
                     header('Content-Type: application/download', false);
                     header('Content-Type: application/pdf', false);
                 } else {
                     header('Content-Type: application/pdf');
                 }
                 // use the Content-Disposition header to supply a recommended filename
                 header('Content-Disposition: attachment; filename="' . basename($name) . '"');
                 header('Content-Transfer-Encoding: binary');
                 TCPDF_STATIC::sendOutputData(file_get_contents($name), filesize($name));
             }
             break;
         case 'E':
             // return PDF as base64 mime multi-part email attachment (RFC 2045)
             $retval = 'Content-Type: application/pdf;' . "\r\n";
             $retval .= ' name="' . $name . '"' . "\r\n";
             $retval .= 'Content-Transfer-Encoding: base64' . "\r\n";
             $retval .= 'Content-Disposition: attachment;' . "\r\n";
             $retval .= ' filename="' . $name . '"' . "\r\n\r\n";
             $retval .= chunk_split(base64_encode($this->getBuffer()), 76, "\r\n");
             return $retval;
         case 'S':
             // returns PDF as a string
             return $this->getBuffer();
         default:
             $this->Error('Incorrect output destination: ' . $dest);
     }
     return '';
 }