/** * Set document protection * Remark: the protection against modification is for people who have the full Acrobat product. * If you don't set any password, the document will open as usual. If you set a user password, the PDF viewer will ask for it before displaying the document. The master password, if different from the user one, can be used to get full access. * Note: protecting a document requires to encrypt it, which increases the processing time a lot. This can cause a PHP time-out in some cases, especially if the document contains images or fonts. * @param $permissions (Array) the set of permissions (specify the ones you want to block):<ul><li>print : Print the document;</li><li>modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';</li><li>copy : Copy or otherwise extract text and graphics from the document;</li><li>annot-forms : Add or modify text annotations, fill in interactive form fields, and, if 'modify' is also set, create or modify interactive form fields (including signature fields);</li><li>fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;</li><li>extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);</li><li>assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;</li><li>print-high : Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this is not set, printing is limited to a low-level representation of the appearance, possibly of degraded quality.</li><li>owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.</li></ul> * @param $user_pass (String) user password. Empty by default. * @param $owner_pass (String) owner password. If not specified, a random value is used. * @param $mode (int) encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit. * @param $pubkeys (String) array of recipients containing public-key certificates ('c') and permissions ('p'). For example: array(array('c' => 'file://../examples/data/cert/tcpdf.crt', 'p' => array('print'))) * @public * @since 2.0.000 (2008-01-02) * @author Nicola Asuni */ public function SetProtection($permissions = array('print', 'modify', 'copy', 'annot-forms', 'fill-forms', 'extract', 'assemble', 'print-high'), $user_pass = '', $owner_pass = null, $mode = 0, $pubkeys = null) { if ($this->pdfa_mode) { // encryption is not allowed in PDF/A mode return; } $this->encryptdata['protection'] = TCPDF_STATIC::getUserPermissionCode($permissions, $mode); if ($pubkeys !== null and is_array($pubkeys)) { // public-key mode $this->encryptdata['pubkeys'] = $pubkeys; if ($mode == 0) { // public-Key Security requires at least 128 bit $mode = 1; } if (!function_exists('openssl_pkcs7_encrypt')) { $this->Error('Public-Key Security requires openssl library.'); } // Set Public-Key filter (availabe are: Entrust.PPKEF, Adobe.PPKLite, Adobe.PubSec) $this->encryptdata['pubkey'] = true; $this->encryptdata['Filter'] = 'Adobe.PubSec'; $this->encryptdata['StmF'] = 'DefaultCryptFilter'; $this->encryptdata['StrF'] = 'DefaultCryptFilter'; } else { // standard mode (password mode) $this->encryptdata['pubkey'] = false; $this->encryptdata['Filter'] = 'Standard'; $this->encryptdata['StmF'] = 'StdCF'; $this->encryptdata['StrF'] = 'StdCF'; } if ($mode > 1) { // AES if (!extension_loaded('mcrypt')) { $this->Error('AES encryption requires mcrypt library (http://www.php.net/manual/en/mcrypt.requirements.php).'); } if (mcrypt_get_cipher_name(MCRYPT_RIJNDAEL_128) === false) { $this->Error('AES encryption requires MCRYPT_RIJNDAEL_128 cypher.'); } if ($mode == 3 and !function_exists('hash')) { // the Hash extension requires no external libraries and is enabled by default as of PHP 5.1.2. $this->Error('AES 256 encryption requires HASH Message Digest Framework (http://www.php.net/manual/en/book.hash.php).'); } } if ($owner_pass === null) { $owner_pass = md5(TCPDF_STATIC::getRandomSeed()); } $this->encryptdata['user_password'] = $user_pass; $this->encryptdata['owner_password'] = $owner_pass; $this->encryptdata['mode'] = $mode; switch ($mode) { case 0: // RC4 40 bit $this->encryptdata['V'] = 1; $this->encryptdata['Length'] = 40; $this->encryptdata['CF']['CFM'] = 'V2'; break; case 1: // RC4 128 bit $this->encryptdata['V'] = 2; $this->encryptdata['Length'] = 128; $this->encryptdata['CF']['CFM'] = 'V2'; if ($this->encryptdata['pubkey']) { $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s4'; $this->encryptdata['Recipients'] = array(); } break; case 2: // AES 128 bit $this->encryptdata['V'] = 4; $this->encryptdata['Length'] = 128; $this->encryptdata['CF']['CFM'] = 'AESV2'; $this->encryptdata['CF']['Length'] = 128; if ($this->encryptdata['pubkey']) { $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5'; $this->encryptdata['Recipients'] = array(); } break; case 3: // AES 256 bit $this->encryptdata['V'] = 5; $this->encryptdata['Length'] = 256; $this->encryptdata['CF']['CFM'] = 'AESV3'; $this->encryptdata['CF']['Length'] = 256; if ($this->encryptdata['pubkey']) { $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5'; $this->encryptdata['Recipients'] = array(); } break; } $this->encrypted = true; $this->encryptdata['fileid'] = TCPDF_STATIC::convertHexStringToString($this->file_id); $this->_generateencryptionkey(); }