/** * Encrypt all files in a directory * @param string $dirPath the directory whose files will be encrypted * @param null $legacyPassphrase * @param null $newPassphrase * @return bool * @note Encryption is recursive */ public function encryptAll($dirPath, $legacyPassphrase = null, $newPassphrase = null) { $result = true; $found = $this->findEncFiles($dirPath); // Disable proxy to prevent file being encrypted twice \OC_FileProxy::$enabled = false; $versionStatus = \OCP\App::isEnabled('files_versions'); \OC_App::disable('files_versions'); $encryptedFiles = array(); // Encrypt unencrypted files foreach ($found['plain'] as $plainFile) { //get file info $fileInfo = \OC\Files\Filesystem::getFileInfo($plainFile['path']); //relative to data/<user>/file $relPath = $plainFile['path']; //relative to /data $rawPath = '/' . $this->userId . '/files/' . $plainFile['path']; // keep timestamp $timestamp = $fileInfo['mtime']; // Open plain file handle for binary reading $plainHandle = $this->view->fopen($rawPath, 'rb'); // Open enc file handle for binary writing, with same filename as original plain file $encHandle = fopen('crypt://' . $rawPath . '.part', 'wb'); if (is_resource($encHandle) && is_resource($plainHandle)) { // Move plain file to a temporary location $size = stream_copy_to_stream($plainHandle, $encHandle); fclose($encHandle); fclose($plainHandle); $fakeRoot = $this->view->getRoot(); $this->view->chroot('/' . $this->userId . '/files'); $this->view->rename($relPath . '.part', $relPath); // set timestamp $this->view->touch($relPath, $timestamp); $encSize = $this->view->filesize($relPath); $this->view->chroot($fakeRoot); // Add the file to the cache \OC\Files\Filesystem::putFileInfo($relPath, array('encrypted' => true, 'size' => $encSize, 'unencrypted_size' => $size, 'etag' => $fileInfo['etag'])); $encryptedFiles[] = $relPath; } else { \OCP\Util::writeLog('files_encryption', 'initial encryption: could not encrypt ' . $rawPath, \OCP\Util::FATAL); $result = false; } } // Encrypt legacy encrypted files if (!empty($legacyPassphrase) && !empty($newPassphrase)) { foreach ($found['legacy'] as $legacyFile) { // Fetch data from file $legacyData = $this->view->file_get_contents($legacyFile['path']); // decrypt data, generate catfile $decrypted = Crypt::legacyBlockDecrypt($legacyData, $legacyPassphrase); $rawPath = $legacyFile['path']; // enable proxy the ensure encryption is handled \OC_FileProxy::$enabled = true; // Open enc file handle for binary writing, with same filename as original plain file $encHandle = $this->view->fopen($rawPath, 'wb'); if (is_resource($encHandle)) { // write data to stream fwrite($encHandle, $decrypted); // close stream fclose($encHandle); } else { \OCP\Util::writeLog('files_encryption', 'initial encryption: could not encrypt legacy file ' . $rawPath, \OCP\Util::FATAL); $result = false; } // disable proxy to prevent file being encrypted twice \OC_FileProxy::$enabled = false; } } \OC_FileProxy::$enabled = true; if ($versionStatus) { \OC_App::enable('files_versions'); } $result = $result && $this->encryptVersions($encryptedFiles); return $result; }
/** * @medium * @brief test decryption using legacy blowfish method */ function testLegacyDecryptLong() { $crypted = $this->legacyEncrypt($this->dataLong, $this->pass); $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass); $this->assertEquals($this->dataLong, $decrypted); }
/** * @brief test generation of legacy encryption key * @depends testLegacyDecryptShort */ function testLegacyCreateKey() { // Create encrypted key $encKey = Encryption\Crypt::legacyCreateKey($this->pass); // Decrypt key $key = Encryption\Crypt::legacyBlockDecrypt($encKey, $this->pass); $this->assertTrue(is_numeric($key)); // Check that key is correct length $this->assertEquals(20, strlen($key)); }