diff options
author | Vincent Petry <pvince81@owncloud.com> | 2014-10-30 18:06:25 +0100 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2014-10-30 18:06:25 +0100 |
commit | 146c46b73a5b780fafd400dfa1881c14457cb4a2 (patch) | |
tree | 46f855dc1f7beee9714e23178e3386064a407ea2 /apps | |
parent | 9b293537a67fd7c85f8b0647eebfbaeea11b487b (diff) | |
parent | 4faee4011d2e6918d46384f6eaf86b06222eaf3c (diff) | |
download | nextcloud-server-146c46b73a5b780fafd400dfa1881c14457cb4a2.tar.gz nextcloud-server-146c46b73a5b780fafd400dfa1881c14457cb4a2.zip |
Merge pull request #11659 from jknockaert/master
rework getFileSize
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files_encryption/lib/util.php | 92 |
1 files changed, 54 insertions, 38 deletions
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 33c2f88b0fd..ce5e8c8b54c 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -385,55 +385,71 @@ class Util { && $this->isEncryptedPath($path) ) { - $offset = 0; - if ($this->containHeader($path)) { - $offset = Crypt::BLOCKSIZE; - } - - // get the size from filesystem if the file contains a encryption header we - // we substract it - $size = $this->view->filesize($path) - $offset; + $cipher = 'AES-128-CFB'; + $realSize = 0; - // fast path, else the calculation for $lastChunkNr is bogus - if ($size === 0) { - \OC_FileProxy::$enabled = $proxyStatus; - return 0; - } - - // 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); + // get the size from filesystem + $size = $this->view->filesize($path); // open stream - $stream = fopen('crypt://' . $path, "r"); + $stream = $this->view->fopen($path, "r"); if (is_resource($stream)) { - // calculate last chunk position - $lastChunckPos = ($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; - } + // if the file contains a encryption header we + // we set the cipher + // and we update the size + if ($this->containHeader($path)) { + $data = fread($stream,Crypt::BLOCKSIZE); + $header = Crypt::parseHeader($data); + $cipher = Crypt::getCipher($header); + $size -= Crypt::BLOCKSIZE; } + // fast path, else the calculation for $lastChunkNr is bogus + if ($size === 0) { + \OC_FileProxy::$enabled = $proxyStatus; + return 0; + } + + // 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; + + // calculate last chunk position + $lastChunkPos = ($lastChunkNr * Crypt::BLOCKSIZE); + // get the content of the last chunk - $lastChunkContent = fread($stream, $lastChunkSize); + if (@fseek($stream, $lastChunkPos, SEEK_CUR) === 0) { + $realSize+=$lastChunkNr*6126; + } + $lastChunkContentEncrypted=''; + $count=Crypt::BLOCKSIZE; + while ($count>0) { + $data=fread($stream,Crypt::BLOCKSIZE); + $count=strlen($data); + $lastChunkContentEncrypted.=$data; + if(strlen($lastChunkContentEncrypted)>Crypt::BLOCKSIZE) { + $realSize+=6126; + $lastChunkContentEncrypted=substr($lastChunkContentEncrypted,Crypt::BLOCKSIZE); + } + } + fclose($stream); + $relPath = \OCA\Encryption\Helper::stripUserFilesPath($path); + $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $relPath); + if($shareKey===false) { + \OC_FileProxy::$enabled = $proxyStatus; + return $result; + } + $session = new \OCA\Encryption\Session($this->view); + $privateKey = $session->getPrivateKey(); + $plainKeyfile = $this->decryptKeyfile($relPath, $privateKey); + $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; |