From e318858152683b23bac6bc646c557c2420bee2cf Mon Sep 17 00:00:00 2001 From: jknockaert Date: Sun, 19 Oct 2014 22:27:15 +0200 Subject: [PATCH 1/6] rework getFileSize --- apps/files_encryption/lib/util.php | 75 ++++++++++++++++++------------ 1 file changed, 46 insertions(+), 29 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,14 +385,23 @@ class Util { && $this->isEncryptedPath($path) ) { - $offset = 0; - if ($this->containHeader($path)) { - $offset = Crypt::BLOCKSIZE; - } + $cipher = Helper::getCipher(); + $realSize = 0; - // get the size from filesystem if the file contains a encryption header we - // we substract it - $size = $this->view->filesize($path) - $offset; + // 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)) { + $header = fread($stream,Crypt::BLOCKSIZE); + $cipher = Crypt::getCipher($header); + $size -= Crypt::BLOCKSIZE; + } // fast path, else the calculation for $lastChunkNr is bogus if ($size === 0) { @@ -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; From 3be57d0169eaa2bc95f25c3ed070bdc9940a1531 Mon Sep 17 00:00:00 2001 From: jknockaert Date: Sun, 19 Oct 2014 22:54:34 +0200 Subject: [PATCH 2/6] small fix --- apps/files_encryption/lib/util.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 3cf83703295..410d3dd1255 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -398,7 +398,8 @@ class Util { // we set the cipher // and we update the size if ($this->containHeader($path)) { - $header = fread($stream,Crypt::BLOCKSIZE); + $data = fread($stream,Crypt::BLOCKSIZE); + $header = Crypt::parseHeader($data); $cipher = Crypt::getCipher($header); $size -= Crypt::BLOCKSIZE; } From 1b7e9d66b31553f6a257638c868fd16f1a8e8e4b Mon Sep 17 00:00:00 2001 From: jknockaert Date: Mon, 20 Oct 2014 00:28:41 +0200 Subject: [PATCH 3/6] ok; still some bugs that had to be fixed --- apps/files_encryption/lib/util.php | 76 ++++++++++++++---------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 410d3dd1255..75cf78c5f94 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -392,59 +392,55 @@ class Util { $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)) { - $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; + $stream = $this->view->fopen($path, "r"); if (is_resource($stream)) { + + // 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 - $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; + } + $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); } } + $relPath = \OCA\Encryption\Helper::stripUserFilesPath($path); $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); + $plainKeyfile = $this->decryptKeyfile($relPath, $privateKey); + $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $relPath); $plainKey = Crypt::multiKeyDecrypt($plainKeyfile, $shareKey, $privateKey); From d277ef6ac265a108a19ca725c4eea68b29e0e472 Mon Sep 17 00:00:00 2001 From: jknockaert Date: Mon, 20 Oct 2014 23:04:11 +0200 Subject: [PATCH 4/6] bugfixes --- apps/files_encryption/lib/util.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 75cf78c5f94..fcfcbb83f7f 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -435,15 +435,16 @@ class Util { $lastChunkContentEncrypted=substr($lastChunkContentEncrypted,Crypt::BLOCKSIZE); } } - + fclose($stream); $relPath = \OCA\Encryption\Helper::stripUserFilesPath($path); - $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); + $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $relPath); + if($shareKey===false) { + return $result; + } + $session = new \OCA\Encryption\Session($this->view); $privateKey = $session->getPrivateKey(); $plainKeyfile = $this->decryptKeyfile($relPath, $privateKey); - $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $relPath); - $plainKey = Crypt::multiKeyDecrypt($plainKeyfile, $shareKey, $privateKey); - $lastChunkContent=Crypt::symmetricDecryptFileContent($lastChunkContentEncrypted, $plainKey, $cipher); // calc the real file size with the size of the last chunk From da44150a1584d4684eced96f7757016c0e27944b Mon Sep 17 00:00:00 2001 From: jknockaert Date: Mon, 20 Oct 2014 23:25:54 +0200 Subject: [PATCH 5/6] small fix --- apps/files_encryption/lib/util.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index fcfcbb83f7f..c98e21cdcb7 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -439,6 +439,7 @@ class Util { $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); From 4faee4011d2e6918d46384f6eaf86b06222eaf3c Mon Sep 17 00:00:00 2001 From: jknockaert Date: Tue, 28 Oct 2014 19:19:10 +0100 Subject: [PATCH 6/6] initialisation of cipher --- apps/files_encryption/lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index c98e21cdcb7..ce5e8c8b54c 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -385,7 +385,7 @@ class Util { && $this->isEncryptedPath($path) ) { - $cipher = Helper::getCipher(); + $cipher = 'AES-128-CFB'; $realSize = 0; // get the size from filesystem