From e318858152683b23bac6bc646c557c2420bee2cf Mon Sep 17 00:00:00 2001 From: jknockaert Date: Sun, 19 Oct 2014 22:27:15 +0200 Subject: [PATCH] rework getFileSize --- apps/files_encryption/lib/util.php | 73 ++++++++++++++++++------------ 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 33c2f88b0fd..3cf83703295 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -385,15 +385,24 @@ class Util { && $this->isEncryptedPath($path) ) { - $offset = 0; + $cipher = Helper::getCipher(); + $realSize = 0; + + // get the size from filesystem + $size = $this->view->filesize($path); + + // open stream + $stream = fopen($path, "r"); + + // if the file contains a encryption header we + // we set the cipher + // and we update the size if ($this->containHeader($path)) { - $offset = Crypt::BLOCKSIZE; + $header = fread($stream,Crypt::BLOCKSIZE); + $cipher = Crypt::getCipher($header); + $size -= Crypt::BLOCKSIZE; } - // get the size from filesystem if the file contains a encryption header we - // we substract it - $size = $this->view->filesize($path) - $offset; - // fast path, else the calculation for $lastChunkNr is bogus if ($size === 0) { \OC_FileProxy::$enabled = $proxyStatus; @@ -403,37 +412,45 @@ class Util { // calculate last chunk nr // next highest is end of chunks, one subtracted is last one // we have to read the last chunk, we can't just calculate it (because of padding etc) - $lastChunkNr = ceil($size/ Crypt::BLOCKSIZE) - 1; - $lastChunkSize = $size - ($lastChunkNr * Crypt::BLOCKSIZE); - - // open stream - $stream = fopen('crypt://' . $path, "r"); + $lastChunkNr = ceil($size/Crypt::BLOCKSIZE)-1; if (is_resource($stream)) { // calculate last chunk position - $lastChunckPos = ($lastChunkNr * Crypt::BLOCKSIZE); + $lastChunkPos = ($lastChunkNr * Crypt::BLOCKSIZE); - // seek to end - if (@fseek($stream, $lastChunckPos) === -1) { - // storage doesn't support fseek, we need a local copy - fclose($stream); - $localFile = $this->view->getLocalFile($path); - Helper::addTmpFileToMapper($localFile, $path); - $stream = fopen('crypt://' . $localFile, "r"); - if (fseek($stream, $lastChunckPos) === -1) { - // if fseek also fails on the local storage, than - // there is nothing we can do - fclose($stream); - \OCP\Util::writeLog('Encryption library', 'couldn\'t determine size of "' . $path, \OCP\Util::ERROR); - return $result; + // get the content of the last chunk + $lastChunkContentEncrypted=''; + $count=Crypt::BLOCKSIZE; + if (@fseek($stream, $lastChunkPos, SEEK_CUR) === 0) { + $realSize+=$lastChunkNr*6126; + while ($count>0) { + $data=fread($stream,Crypt::BLOCKSIZE); + $count=strlen($data); + $lastChunkContentEncrypted.=$data; + } + } else { + while ($count>0) { + if(strlen($lastChunkContentEncrypted)>Crypt::BLOCKSIZE) { + $realSize+=6126; + $lastChunkContentEncrypted=substr($lastChunkContentEncrypted,Crypt::BLOCKSIZE); + } + $data=fread($stream,Crypt::BLOCKSIZE); + $count=strlen($data); + $lastChunkContentEncrypted.=$data; } } - // get the content of the last chunk - $lastChunkContent = fread($stream, $lastChunkSize); + $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); + $privateKey = $session->getPrivateKey(); + $plainKeyfile = $this->decryptKeyfile($path, $privateKey); + $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $path); + + $plainKey = Crypt::multiKeyDecrypt($plainKeyfile, $shareKey, $privateKey); + + $lastChunkContent=Crypt::symmetricDecryptFileContent($lastChunkContentEncrypted, $plainKey, $cipher); // calc the real file size with the size of the last chunk - $realSize = (($lastChunkNr * 6126) + strlen($lastChunkContent)); + $realSize += strlen($lastChunkContent); // store file size $result = $realSize; -- 2.39.5