Пример #1
0
 function _Load_Decryption_Cipher($validate_key = true)
 {
     // If legacy, switch to legacy mode
     if ($this->job['legacy']) {
         return $this->_Legacy_Load_Decryption_Cipher($validate_key);
     }
     // Attempt to open the cipher module
     if ($this->job['header']['version'] >= 3) {
         list($module, $module_str, $key_size) = $this->_Get_Cipher($this->progress['config']['enc_type']);
     } else {
         list($module, $module_str, $key_size) = $this->_Get_Cipher_NonStandard($this->progress['config']['enc_type']);
     }
     if (false === ($this->cipher = @mcrypt_module_open($module, '', MCRYPT_MODE_CBC, ''))) {
         return 'Failed to open encryption module: ' . OBFW_Exception();
     }
     if ($validate_key) {
         // Get the IV size
         $iv_size = mcrypt_enc_get_iv_size($this->cipher);
         // Check header IV size - if incorrect it normally means wrong encryption type selected
         if ($iv_size != $this->job['header']['iv_size']) {
             return false;
         }
         $extra = 0;
         // Generate the encryption key and password authentication value - allow $extra parameter to use a different section of the key
         $dk = WPOnlineBackup_Functions::PBKDF2($this->progress['config']['enc_key'], $this->job['header']['iv'], 1148, $key_size * (2 + $extra) + 2);
         $this->job['key'] = substr($dk, $extra ? $key_size * (1 + $extra) + 2 : 0, $key_size);
         $pass_auth = substr($dk, $key_size * 2, 2);
         $check_pass_auth = chr($this->job['header']['pass_auth1']) . chr($this->job['header']['pass_auth2']);
         // While - so we can jump out
         while ($pass_auth != $check_pass_auth) {
             // Try the broken PBKDF2 call if this is a version 1 file
             if ($this->job['header']['version'] == 1) {
                 $dk = WPOnlineBackup_Functions::PBKDF2_Broken($this->progress['config']['enc_key'], $this->job['header']['iv'], 1148, $key_size * (2 + $extra) + 2);
                 $this->job['key'] = substr($dk, $extra ? $key_size * (1 + $extra) + 2 : 0, $key_size);
                 $pass_auth = substr($dk, $key_size * 2, 2);
                 if ($pass_auth == $check_pass_auth) {
                     break;
                 }
             }
             // Password authentication didn't match
             return false;
         }
     }
     // Now initialise the cipher so we can start decrypting. Returns -2/-3 on errors, false on incorrect parameters
     if (false === ($ret = @mcrypt_generic_init($this->cipher, $this->job['key'], $this->job['current_iv'])) || $ret < 0) {
         return 'Failed to initialise encryption. PHP: ' . OBFW_Exception();
     }
     // Flag the cipher as initialised so we deinit it
     $this->cipher_init = true;
     return true;
 }
    function Open(&$disk, $cipher_spec, $key, $extra = 0, $rjct_intention = false)
    {
        // ASSERTION - The file is closed
        // First thing first, check we actually have encryption available... If not, server configuration has changed
        if (!$this->WPOnlineBackup->Get_Env('encryption_available') || !array_key_exists($cipher_spec, $this->WPOnlineBackup->Get_Env('encryption_types'))) {
            return __('The selected encryption type is no longer available on the server. The server configuration must have changed since encryption was configured. Please change the encryption details and run the backup again. If this was an online backup you may need to contact your host about this as your encryption details cannot be changed.', 'wponlinebackup');
        }
        // Store the cipher specification and key
        $this->cipher_spec = $cipher_spec;
        $this->key = $key;
        // Store the file handle
        $this->disk =& $disk;
        // Attempt to open the cipher module
        list($module, $module_str, $key_size) = $this->Get_Cipher($this->cipher_spec);
        if (($this->cipher = @mcrypt_module_open($module, '', MCRYPT_MODE_CBC, '')) === false) {
            return 'Failed to open encryption module. PHP: ' . OBFW_Exception();
        }
        // Get the IV size
        $iv_size = mcrypt_enc_get_iv_size($this->cipher);
        // Randomly generate an IV - the IV will be stored in the file
        $this->iv = '';
        mt_srand(time());
        for ($i = 0; $i < $iv_size; $i++) {
            $this->iv .= chr(rand(0, 255));
        }
        // Generate the encryption key and password authentication value - allow $extra parameter to use a different section of the key
        $dk = WPOnlineBackup_Functions::PBKDF2($this->key, $this->iv, 1148, $key_size * (2 + $extra) + 2);
        $this->key = substr($dk, $extra ? $key_size * (1 + $extra) + 2 : 0, $key_size);
        $pass_auth = substr($dk, $key_size * 2, 2);
        // Now initialise the cipher so we can start encrypting. Returns -2/-3 on errors, false on incorrect parameters
        if (($ret = @mcrypt_generic_init($this->cipher, $this->key, $this->iv)) === false || $ret < 0) {
            $e = 'Failed to initialise encryption. PHP: ' . OBFW_Exception();
            @mcrypt_module_close($this->cipher);
            return $e;
        }
        // Is the caller intending to write a rejection header through this writer?
        // If so, we'll have to write our own since the one we get given will be encrypted and mangled
        if ($rjct_intention) {
            // We don't need to store this, the disk itself will keep track of positioning, much like it will with our header
            // Decryption is not an issue since it will search for the OBFWEN descriptor in the first 1024 bytes
            $header = <<<HEADER
<?php
/*Rejection header*/
__halt_compiler();
}
HEADER;
            if (($ret = $this->disk->Write($header)) !== true) {
                @mcrypt_generic_deinit($this->cipher);
                @mcrypt_module_close($this->cipher);
                return $ret;
            }
        }
        // This must be called AFTER we write rejection header otherwise we'll fail to adjust the header during Close()
        $this->header_pos = $this->disk->Pos();
        // Write the file header
        // We used to encrypt the header but we don't any more so we can get the actual backup file size without needing the key
        // We'll set an unencrypted size of 0 and fill it in as we close
        $fields = array(array('a6', 'OBFWEN'), array('v', 3), array('v', 0), array('C', ord($pass_auth[0])), array('C', ord($pass_auth[1])), array('V', $iv_size), array('V', 0), array('V', 0), array('V', 0));
        $fields = WPOnlineBackup_Functions::Pack_Fields($fields) . $this->iv;
        if (($ret = $this->disk->Write($fields)) !== true) {
            @mcrypt_generic_deinit($this->cipher);
            @mcrypt_module_close($this->cipher);
            return $ret;
        }
        // Grab the real block size and adjust the configured block size to ensure it is an exact divisor
        $this->real_blocksize = mcrypt_enc_get_block_size($this->cipher);
        if (($rem = $this->WPOnlineBackup->Get_Setting('encryption_block_size') % $this->real_blocksize) != 0) {
            $this->blocksize = $this->WPOnlineBackup->Get_Setting('encryption_block_size') + ($this->real_blocksize - $rem);
        } else {
            $this->blocksize = $this->WPOnlineBackup->Get_Setting('encryption_block_size');
        }
        // Prepare the counters
        $this->data = '';
        $this->data_len = 0;
        if ($this->WPOnlineBackup->Get_Env('inc_hash_available')) {
            $this->hash_ctx = hash_init('crc32b');
        } else {
            $this->hash_ctx = false;
        }
        $this->hash_len = 0;
        $this->crc = false;
        $this->last_cipher = null;
        $this->totalsize = 0;
        $this->encsize = strlen($fields);
        $this->volatile = false;
        $this->volatile_len = 0;
        $this->buffer_disk = false;
        // Open() called so set status
        $this->status = 1;
        return true;
    }