improve cryptstream fro writing non-chunksized data

This commit is contained in:
Robin Appelman 2012-05-05 16:48:28 +02:00
parent d875191777
commit 70cb053e6b
2 changed files with 36 additions and 3 deletions

View File

@ -34,6 +34,7 @@ class OC_CryptStream{
private $readBuffer;//for streams that dont support seeking
private $meta=array();//header/meta for source stream
private $count;
private $writeCache;
public function stream_open($path, $mode, $options, &$opened_path){
$path=str_replace('crypt://','',$path);
@ -57,6 +58,7 @@ class OC_CryptStream{
}
public function stream_seek($offset, $whence=SEEK_SET){
$this->flush();
fseek($this->source,$offset,$whence);
}
@ -67,6 +69,7 @@ class OC_CryptStream{
public function stream_read($count){
//$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->writeCache='';
if($count!=8192){
OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL);
die();
@ -84,6 +87,10 @@ class OC_CryptStream{
$length=strlen($data);
$written=0;
$currentPos=ftell($this->source);
if($this->writeCache){
$data=$this->writeCache.$data;
$this->writeCache='';
}
if($currentPos%8192!=0){
//make sure we always start on a block start
fseek($this->source,-($currentPos%8192),SEEK_CUR);
@ -91,11 +98,17 @@ class OC_CryptStream{
fseek($this->source,-($currentPos%8192),SEEK_CUR);
$block=OC_Crypt::decrypt($encryptedBlock);
$data=substr($block,0,$currentPos%8192).$data;
fseek($this->source,-($currentPos%8192),SEEK_CUR);
}
while(strlen($data)>0){
$encrypted=OC_Crypt::encrypt(substr($data,0,8192));
fwrite($this->source,$encrypted);
$data=substr($data,8192);
if(strlen($data)<8192){
$this->writeCache=$data;
$data='';
}else{
$encrypted=OC_Crypt::encrypt(substr($data,0,8192));
fwrite($this->source,$encrypted);
$data=substr($data,8192);
}
}
return $length;
}
@ -129,7 +142,16 @@ class OC_CryptStream{
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(){
$this->flush();
if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){
OC_FileCache::put($this->path,array('encrypted'=>true));
}

View File

@ -38,5 +38,16 @@ class Test_Encryption extends UnitTestCase {
OC_Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key);
$decrypted=file_get_contents($tmpFileDecrypted);
$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);
}
}