Skip to content
Snippets Groups Projects
Commit 70cb053e authored by Robin Appelman's avatar Robin Appelman
Browse files

improve cryptstream fro writing non-chunksized data

parent d8751917
Branches
No related tags found
No related merge requests found
...@@ -34,6 +34,7 @@ class OC_CryptStream{ ...@@ -34,6 +34,7 @@ class OC_CryptStream{
private $readBuffer;//for streams that dont support seeking private $readBuffer;//for streams that dont support seeking
private $meta=array();//header/meta for source stream private $meta=array();//header/meta for source stream
private $count; private $count;
private $writeCache;
public function stream_open($path, $mode, $options, &$opened_path){ public function stream_open($path, $mode, $options, &$opened_path){
$path=str_replace('crypt://','',$path); $path=str_replace('crypt://','',$path);
...@@ -57,6 +58,7 @@ class OC_CryptStream{ ...@@ -57,6 +58,7 @@ class OC_CryptStream{
} }
public function stream_seek($offset, $whence=SEEK_SET){ public function stream_seek($offset, $whence=SEEK_SET){
$this->flush();
fseek($this->source,$offset,$whence); fseek($this->source,$offset,$whence);
} }
...@@ -67,6 +69,7 @@ class OC_CryptStream{ ...@@ -67,6 +69,7 @@ class OC_CryptStream{
public function stream_read($count){ public function stream_read($count){
//$count will always be 8192 https://bugs.php.net/bug.php?id=21641 //$count will always be 8192 https://bugs.php.net/bug.php?id=21641
//This makes this function a lot simpler but will breake everything the moment it's fixed //This makes this function a lot simpler but will breake everything the moment it's fixed
$this->writeCache='';
if($count!=8192){ if($count!=8192){
OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL); OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL);
die(); die();
...@@ -84,6 +87,10 @@ class OC_CryptStream{ ...@@ -84,6 +87,10 @@ class OC_CryptStream{
$length=strlen($data); $length=strlen($data);
$written=0; $written=0;
$currentPos=ftell($this->source); $currentPos=ftell($this->source);
if($this->writeCache){
$data=$this->writeCache.$data;
$this->writeCache='';
}
if($currentPos%8192!=0){ if($currentPos%8192!=0){
//make sure we always start on a block start //make sure we always start on a block start
fseek($this->source,-($currentPos%8192),SEEK_CUR); fseek($this->source,-($currentPos%8192),SEEK_CUR);
...@@ -91,12 +98,18 @@ class OC_CryptStream{ ...@@ -91,12 +98,18 @@ class OC_CryptStream{
fseek($this->source,-($currentPos%8192),SEEK_CUR); fseek($this->source,-($currentPos%8192),SEEK_CUR);
$block=OC_Crypt::decrypt($encryptedBlock); $block=OC_Crypt::decrypt($encryptedBlock);
$data=substr($block,0,$currentPos%8192).$data; $data=substr($block,0,$currentPos%8192).$data;
fseek($this->source,-($currentPos%8192),SEEK_CUR);
} }
while(strlen($data)>0){ while(strlen($data)>0){
if(strlen($data)<8192){
$this->writeCache=$data;
$data='';
}else{
$encrypted=OC_Crypt::encrypt(substr($data,0,8192)); $encrypted=OC_Crypt::encrypt(substr($data,0,8192));
fwrite($this->source,$encrypted); fwrite($this->source,$encrypted);
$data=substr($data,8192); $data=substr($data,8192);
} }
}
return $length; return $length;
} }
...@@ -129,7 +142,16 @@ class OC_CryptStream{ ...@@ -129,7 +142,16 @@ class OC_CryptStream{
return feof($this->source); return feof($this->source);
} }
private function flush(){
if($this->writeCache){
$encrypted=OC_Crypt::encrypt($this->writeCache);
fwrite($this->source,$encrypted);
$this->writeCache='';
}
}
public function stream_close(){ public function stream_close(){
$this->flush();
if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){ if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){
OC_FileCache::put($this->path,array('encrypted'=>true)); OC_FileCache::put($this->path,array('encrypted'=>true));
} }
......
...@@ -38,5 +38,16 @@ class Test_Encryption extends UnitTestCase { ...@@ -38,5 +38,16 @@ class Test_Encryption extends UnitTestCase {
OC_Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key); OC_Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key);
$decrypted=file_get_contents($tmpFileDecrypted); $decrypted=file_get_contents($tmpFileDecrypted);
$this->assertEqual($decrypted,$source); $this->assertEqual($decrypted,$source);
$file=OC::$SERVERROOT.'/core/img/weather-clear.png';
$source=file_get_contents($file); //binary file
$encrypted=OC_Crypt::encrypt($source,$key);
$decrypted=OC_Crypt::decrypt($encrypted,$key);
$this->assertEqual($decrypted,$source);
$encrypted=OC_Crypt::blockEncrypt($source,$key);
$decrypted=OC_Crypt::blockDecrypt($encrypted,$key);
$this->assertEqual($decrypted,$source);
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment