diff options
Diffstat (limited to 'lib/private/files')
-rw-r--r-- | lib/private/files/cache/cache.php | 9 | ||||
-rw-r--r-- | lib/private/files/fileinfo.php | 9 | ||||
-rw-r--r-- | lib/private/files/storage/wrapper/encryption.php | 16 | ||||
-rw-r--r-- | lib/private/files/stream/encryption.php | 31 |
4 files changed, 50 insertions, 15 deletions
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 22b9f49e528..b30666d48d2 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -145,6 +145,7 @@ class Cache implements ICache { $data['size'] = 0 + $data['size']; $data['mtime'] = (int)$data['mtime']; $data['storage_mtime'] = (int)$data['storage_mtime']; + $data['encryptedVersion'] = (int)$data['encrypted']; $data['encrypted'] = (bool)$data['encrypted']; $data['storage'] = $this->storageId; $data['mimetype'] = $this->mimetypeLoader->getMimetypeById($data['mimetype']); @@ -345,8 +346,12 @@ class Cache implements ICache { $queryParts[] = '`mtime`'; } } elseif ($name === 'encrypted') { - // Boolean to integer conversion - $value = $value ? 1 : 0; + if(isset($data['encryptedVersion'])) { + $value = $data['encryptedVersion']; + } else { + // Boolean to integer conversion + $value = $value ? 1 : 0; + } } $params[] = $value; $queryParts[] = '`' . $name . '`'; diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php index f22e1099e26..1d722a46735 100644 --- a/lib/private/files/fileinfo.php +++ b/lib/private/files/fileinfo.php @@ -194,6 +194,15 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { } /** + * Return the currently version used for the HMAC in the encryption app + * + * @return int + */ + public function getEncryptedVersion() { + return isset($this->data['encryptedVersion']) ? (int) $this->data['encryptedVersion'] : 1; + } + + /** * @return int */ public function getPermissions() { diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index f358bd59239..14d3b15bbae 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -39,6 +39,7 @@ use OCP\Encryption\Keys\IStorage; use OCP\Files\Mount\IMountPoint; use OCP\Files\Storage; use OCP\ILogger; +use OCP\Files\Cache\ICacheEntry; class Encryption extends Wrapper { @@ -129,13 +130,16 @@ class Encryption extends Wrapper { if (isset($this->unencryptedSize[$fullPath])) { $size = $this->unencryptedSize[$fullPath]; // update file cache - if ($info) { + if ($info instanceof ICacheEntry) { $info = $info->getData(); + $info['encrypted'] = $info['encryptedVersion']; } else { - $info = []; + if (!is_array($info)) { + $info = []; + } + $info['encrypted'] = true; } - $info['encrypted'] = true; $info['size'] = $size; $this->getCache()->put($path, $info); @@ -343,6 +347,7 @@ class Encryption extends Wrapper { $shouldEncrypt = false; $encryptionModule = null; $header = $this->getHeader($path); + $signed = (isset($header['signed']) && $header['signed'] === 'true') ? true : false; $fullPath = $this->getFullPath($path); $encryptionModuleId = $this->util->getEncryptionModuleId($header); @@ -377,7 +382,7 @@ class Encryption extends Wrapper { || $mode === 'wb' || $mode === 'wb+' ) { - // don't overwrite encrypted files if encyption is not enabled + // don't overwrite encrypted files if encryption is not enabled if ($targetIsEncrypted && $encryptionEnabled === false) { throw new GenericEncryptionException('Tried to access encrypted file but encryption is not enabled'); } @@ -385,6 +390,7 @@ class Encryption extends Wrapper { // if $encryptionModuleId is empty, the default module will be used $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId); $shouldEncrypt = $encryptionModule->shouldEncrypt($fullPath); + $signed = true; } } else { $info = $this->getCache()->get($path); @@ -422,7 +428,7 @@ class Encryption extends Wrapper { } $handle = \OC\Files\Stream\Encryption::wrap($source, $path, $fullPath, $header, $this->uid, $encryptionModule, $this->storage, $this, $this->util, $this->fileHelper, $mode, - $size, $unencryptedSize, $headerSize); + $size, $unencryptedSize, $headerSize, $signed); return $handle; } diff --git a/lib/private/files/stream/encryption.php b/lib/private/files/stream/encryption.php index c884cd8fa07..63949035b5a 100644 --- a/lib/private/files/stream/encryption.php +++ b/lib/private/files/stream/encryption.php @@ -72,6 +72,9 @@ class Encryption extends Wrapper { /** @var string */ protected $fullPath; + /** @var bool */ + protected $signed; + /** * header data returned by the encryption module, will be written to the file * in case of a write operation @@ -110,7 +113,8 @@ class Encryption extends Wrapper { 'size', 'unencryptedSize', 'encryptionStorage', - 'headerSize' + 'headerSize', + 'signed' ); } @@ -132,6 +136,7 @@ class Encryption extends Wrapper { * @param int $size * @param int $unencryptedSize * @param int $headerSize + * @param bool $signed * @param string $wrapper stream wrapper class * @return resource * @@ -148,6 +153,7 @@ class Encryption extends Wrapper { $size, $unencryptedSize, $headerSize, + $signed, $wrapper = 'OC\Files\Stream\Encryption') { $context = stream_context_create(array( @@ -164,7 +170,8 @@ class Encryption extends Wrapper { 'size' => $size, 'unencryptedSize' => $unencryptedSize, 'encryptionStorage' => $encStorage, - 'headerSize' => $headerSize + 'headerSize' => $headerSize, + 'signed' => $signed ) )); @@ -225,7 +232,7 @@ class Encryption extends Wrapper { $this->position = 0; $this->cache = ''; $this->writeFlag = false; - $this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize(); + $this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed); if ( $mode === 'w' @@ -392,8 +399,9 @@ class Encryption extends Wrapper { } public function stream_close() { - $this->flush(); - $remainingData = $this->encryptionModule->end($this->fullPath); + $this->flush('end'); + $position = (int)floor($this->position/$this->unencryptedBlockSize); + $remainingData = $this->encryptionModule->end($this->fullPath, $position . 'end'); if ($this->readOnly === false) { if(!empty($remainingData)) { parent::stream_write($remainingData); @@ -405,15 +413,17 @@ class Encryption extends Wrapper { /** * write block to file + * @param string $positionPrefix */ - protected function flush() { + protected function flush($positionPrefix = '') { // write to disk only when writeFlag was set to 1 if ($this->writeFlag) { // Disable the file proxies so that encryption is not // automatically attempted when the file is written to disk - // we are handling that separately here and we don't want to // get into an infinite loop - $encrypted = $this->encryptionModule->encrypt($this->cache); + $position = (int)floor($this->position/$this->unencryptedBlockSize); + $encrypted = $this->encryptionModule->encrypt($this->cache, $position . $positionPrefix); $bytesWritten = parent::stream_write($encrypted); $this->writeFlag = false; // Check whether the write concerns the last block @@ -440,7 +450,12 @@ class Encryption extends Wrapper { if ($this->cache === '' && !($this->position === $this->unencryptedSize && ($this->position % $this->unencryptedBlockSize) === 0)) { // Get the data from the file handle $data = parent::stream_read($this->util->getBlockSize()); - $this->cache = $this->encryptionModule->decrypt($data); + $position = (int)floor($this->position/$this->unencryptedBlockSize); + $numberOfChunks = (int)($this->unencryptedSize / $this->unencryptedBlockSize); + if($numberOfChunks === $position) { + $position .= 'end'; + } + $this->cache = $this->encryptionModule->decrypt($data, $position); } } |