make it backward compatible to work with signed and un-signed files

This commit is contained in:
Björn Schießle 2016-01-05 15:29:44 +01:00 committed by Lukas Reschke
parent 40a5ba72fc
commit cf3a8f274f
5 changed files with 34 additions and 18 deletions

View File

@ -462,7 +462,7 @@ class Crypt {
*/ */
private function checkSignature($data, $passPhrase, $expectedSignature) { private function checkSignature($data, $passPhrase, $expectedSignature) {
$signature = $this->createSignature($data, $passPhrase); $signature = $this->createSignature($data, $passPhrase);
if (hash_equals($expectedSignature, $signature)) { if (!hash_equals($expectedSignature, $signature)) {
throw new HintException('Bad Signature', $this->l->t('Bad Signature')); throw new HintException('Bad Signature', $this->l->t('Bad Signature'));
} }
} }
@ -517,7 +517,7 @@ class Crypt {
$meta = substr($catFile, -22); $meta = substr($catFile, -22);
$iv = substr($meta, -16); $iv = substr($meta, -16);
$sig = false; $sig = false;
$encrypted = substr($catFile, 0, -93); $encrypted = substr($catFile, 0, -22);
} }
return [ return [

View File

@ -94,8 +94,12 @@ class Encryption implements IEncryptionModule {
/** @var DecryptAll */ /** @var DecryptAll */
private $decryptAll; private $decryptAll;
/** @var int unencrypted block size if block contains signature */
private $unencryptedBlockSizeSigned = 6072;
/** @var int unencrypted block size */ /** @var int unencrypted block size */
private $unencryptedBlockSize = 6072; private $unencryptedBlockSize = 6126;
/** /**
* *
@ -198,7 +202,7 @@ class Encryption implements IEncryptionModule {
$this->cipher = $this->crypt->getLegacyCipher(); $this->cipher = $this->crypt->getLegacyCipher();
} }
return array('cipher' => $this->cipher); return array('cipher' => $this->cipher, 'signed' => 'true');
} }
/** /**
@ -278,7 +282,7 @@ class Encryption implements IEncryptionModule {
// If data remaining to be written is less than the // If data remaining to be written is less than the
// size of 1 6126 byte block // size of 1 6126 byte block
if ($remainingLength < $this->unencryptedBlockSize) { if ($remainingLength < $this->unencryptedBlockSizeSigned) {
// Set writeCache to contents of $data // Set writeCache to contents of $data
// The writeCache will be carried over to the // The writeCache will be carried over to the
@ -296,14 +300,14 @@ class Encryption implements IEncryptionModule {
} else { } else {
// Read the chunk from the start of $data // Read the chunk from the start of $data
$chunk = substr($data, 0, $this->unencryptedBlockSize); $chunk = substr($data, 0, $this->unencryptedBlockSizeSigned);
$encrypted .= $this->crypt->symmetricEncryptFileContent($chunk, $this->fileKey); $encrypted .= $this->crypt->symmetricEncryptFileContent($chunk, $this->fileKey);
// Remove the chunk we just processed from // Remove the chunk we just processed from
// $data, leaving only unprocessed data in $data // $data, leaving only unprocessed data in $data
// var, for handling on the next round // var, for handling on the next round
$data = substr($data, $this->unencryptedBlockSize); $data = substr($data, $this->unencryptedBlockSizeSigned);
} }
@ -410,10 +414,15 @@ class Encryption implements IEncryptionModule {
* get size of the unencrypted payload per block. * get size of the unencrypted payload per block.
* ownCloud read/write files with a block size of 8192 byte * ownCloud read/write files with a block size of 8192 byte
* *
* @return integer * @param bool $signed
* @return int
*/ */
public function getUnencryptedBlockSize() { public function getUnencryptedBlockSize($signed = false) {
return $this->unencryptedBlockSize; if ($signed === false) {
return $this->unencryptedBlockSize;
}
return $this->unencryptedBlockSizeSigned;
} }
/** /**

View File

@ -343,6 +343,7 @@ class Encryption extends Wrapper {
$shouldEncrypt = false; $shouldEncrypt = false;
$encryptionModule = null; $encryptionModule = null;
$header = $this->getHeader($path); $header = $this->getHeader($path);
$signed = (isset($header['signed']) && $header['signed'] === 'true') ? true : false;
$fullPath = $this->getFullPath($path); $fullPath = $this->getFullPath($path);
$encryptionModuleId = $this->util->getEncryptionModuleId($header); $encryptionModuleId = $this->util->getEncryptionModuleId($header);
@ -377,7 +378,7 @@ class Encryption extends Wrapper {
|| $mode === 'wb' || $mode === 'wb'
|| $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) { if ($targetIsEncrypted && $encryptionEnabled === false) {
throw new GenericEncryptionException('Tried to access encrypted file but encryption is not enabled'); throw new GenericEncryptionException('Tried to access encrypted file but encryption is not enabled');
} }
@ -385,6 +386,7 @@ class Encryption extends Wrapper {
// if $encryptionModuleId is empty, the default module will be used // if $encryptionModuleId is empty, the default module will be used
$encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId); $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
$shouldEncrypt = $encryptionModule->shouldEncrypt($fullPath); $shouldEncrypt = $encryptionModule->shouldEncrypt($fullPath);
$signed = true;
} }
} else { } else {
$info = $this->getCache()->get($path); $info = $this->getCache()->get($path);
@ -422,7 +424,7 @@ class Encryption extends Wrapper {
} }
$handle = \OC\Files\Stream\Encryption::wrap($source, $path, $fullPath, $header, $handle = \OC\Files\Stream\Encryption::wrap($source, $path, $fullPath, $header,
$this->uid, $encryptionModule, $this->storage, $this, $this->util, $this->fileHelper, $mode, $this->uid, $encryptionModule, $this->storage, $this, $this->util, $this->fileHelper, $mode,
$size, $unencryptedSize, $headerSize); $size, $unencryptedSize, $headerSize, $signed);
return $handle; return $handle;
} }

View File

@ -110,7 +110,8 @@ class Encryption extends Wrapper {
'size', 'size',
'unencryptedSize', 'unencryptedSize',
'encryptionStorage', 'encryptionStorage',
'headerSize' 'headerSize',
'signed'
); );
} }
@ -132,6 +133,7 @@ class Encryption extends Wrapper {
* @param int $size * @param int $size
* @param int $unencryptedSize * @param int $unencryptedSize
* @param int $headerSize * @param int $headerSize
* @param bool $signed
* @param string $wrapper stream wrapper class * @param string $wrapper stream wrapper class
* @return resource * @return resource
* *
@ -148,6 +150,7 @@ class Encryption extends Wrapper {
$size, $size,
$unencryptedSize, $unencryptedSize,
$headerSize, $headerSize,
$signed,
$wrapper = 'OC\Files\Stream\Encryption') { $wrapper = 'OC\Files\Stream\Encryption') {
$context = stream_context_create(array( $context = stream_context_create(array(
@ -164,7 +167,8 @@ class Encryption extends Wrapper {
'size' => $size, 'size' => $size,
'unencryptedSize' => $unencryptedSize, 'unencryptedSize' => $unencryptedSize,
'encryptionStorage' => $encStorage, 'encryptionStorage' => $encStorage,
'headerSize' => $headerSize 'headerSize' => $headerSize,
'signed' => $signed
) )
)); ));
@ -225,7 +229,7 @@ class Encryption extends Wrapper {
$this->position = 0; $this->position = 0;
$this->cache = ''; $this->cache = '';
$this->writeFlag = false; $this->writeFlag = false;
$this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize(); $this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
if ( if (
$mode === 'w' $mode === 'w'

View File

@ -119,10 +119,11 @@ interface IEncryptionModule {
* get size of the unencrypted payload per block. * get size of the unencrypted payload per block.
* ownCloud read/write files with a block size of 8192 byte * ownCloud read/write files with a block size of 8192 byte
* *
* @return integer * @param bool $signed
* @since 8.1.0 * @return int
* @since 8.1.0 optional parameter $signed was added in 9.0.0
*/ */
public function getUnencryptedBlockSize(); public function getUnencryptedBlockSize($signed = false);
/** /**
* check if the encryption module is able to read the file, * check if the encryption module is able to read the file,