|
|
|
|
@ -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;
|
|
|
|
|
|