summaryrefslogtreecommitdiffstats
path: root/apps/files_encryption/test
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_encryption/test')
-rw-r--r--apps/files_encryption/test/binarybin0 -> 9734 bytes
-rwxr-xr-xapps/files_encryption/test/crypt.php667
-rw-r--r--apps/files_encryption/test/keymanager.php132
-rw-r--r--apps/files_encryption/test/legacy-encrypted-text.txtbin0 -> 3360 bytes
-rw-r--r--apps/files_encryption/test/proxy.php220
-rw-r--r--apps/files_encryption/test/stream.php226
-rwxr-xr-xapps/files_encryption/test/util.php210
-rw-r--r--apps/files_encryption/test/zerosbin0 -> 10238 bytes
8 files changed, 1455 insertions, 0 deletions
diff --git a/apps/files_encryption/test/binary b/apps/files_encryption/test/binary
new file mode 100644
index 00000000000..79bc99479da
--- /dev/null
+++ b/apps/files_encryption/test/binary
Binary files differ
diff --git a/apps/files_encryption/test/crypt.php b/apps/files_encryption/test/crypt.php
new file mode 100755
index 00000000000..5a7820dc9da
--- /dev/null
+++ b/apps/files_encryption/test/crypt.php
@@ -0,0 +1,667 @@
+<?php
+/**
+ * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>, and
+ * Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+//require_once "PHPUnit/Framework/TestCase.php";
+require_once realpath( dirname(__FILE__).'/../../../3rdparty/Crypt_Blowfish/Blowfish.php' );
+require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
+require_once realpath( dirname(__FILE__).'/../lib/crypt.php' );
+require_once realpath( dirname(__FILE__).'/../lib/keymanager.php' );
+require_once realpath( dirname(__FILE__).'/../lib/proxy.php' );
+require_once realpath( dirname(__FILE__).'/../lib/stream.php' );
+require_once realpath( dirname(__FILE__).'/../lib/util.php' );
+require_once realpath( dirname(__FILE__).'/../appinfo/app.php' );
+
+use OCA\Encryption;
+
+// This has to go here because otherwise session errors arise, and the private
+// encryption key needs to be saved in the session
+\OC_User::login( 'admin', 'admin' );
+
+/**
+ * @note It would be better to use Mockery here for mocking out the session
+ * handling process, and isolate calls to session class and data from the unit
+ * tests relating to them (stream etc.). However getting mockery to work and
+ * overload classes whilst also using the OC autoloader is difficult due to
+ * load order Pear errors.
+ */
+
+class Test_Crypt extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+
+ // set content for encrypting / decrypting in tests
+ $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
+ $this->dataShort = 'hats';
+ $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' );
+ $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' );
+ $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' );
+ $this->randomKey = Encryption\Crypt::generateKey();
+
+ $keypair = Encryption\Crypt::createKeypair();
+ $this->genPublicKey = $keypair['publicKey'];
+ $this->genPrivateKey = $keypair['privateKey'];
+
+ $this->view = new \OC_FilesystemView( '/' );
+
+ \OC_User::setUserId( 'admin' );
+ $this->userId = 'admin';
+ $this->pass = 'admin';
+
+ \OC_Filesystem::init( '/' );
+ \OC_Filesystem::mount( 'OC_Filestorage_Local', array('datadir' => \OC_User::getHome($this->userId)), '/' );
+
+ }
+
+ function tearDown() {
+
+ }
+
+ function testGenerateKey() {
+
+ # TODO: use more accurate (larger) string length for test confirmation
+
+ $key = Encryption\Crypt::generateKey();
+
+ $this->assertTrue( strlen( $key ) > 16 );
+
+ }
+
+ function testGenerateIv() {
+
+ $iv = Encryption\Crypt::generateIv();
+
+ $this->assertEquals( 16, strlen( $iv ) );
+
+ return $iv;
+
+ }
+
+ /**
+ * @depends testGenerateIv
+ */
+ function testConcatIv( $iv ) {
+
+ $catFile = Encryption\Crypt::concatIv( $this->dataLong, $iv );
+
+ // Fetch encryption metadata from end of file
+ $meta = substr( $catFile, -22 );
+
+ $identifier = substr( $meta, 0, 6);
+
+ // Fetch IV from end of file
+ $foundIv = substr( $meta, 6 );
+
+ $this->assertEquals( '00iv00', $identifier );
+
+ $this->assertEquals( $iv, $foundIv );
+
+ // Remove IV and IV identifier text to expose encrypted content
+ $data = substr( $catFile, 0, -22 );
+
+ $this->assertEquals( $this->dataLong, $data );
+
+ return array(
+ 'iv' => $iv
+ , 'catfile' => $catFile
+ );
+
+ }
+
+ /**
+ * @depends testConcatIv
+ */
+ function testSplitIv( $testConcatIv ) {
+
+ // Split catfile into components
+ $splitCatfile = Encryption\Crypt::splitIv( $testConcatIv['catfile'] );
+
+ // Check that original IV and split IV match
+ $this->assertEquals( $testConcatIv['iv'], $splitCatfile['iv'] );
+
+ // Check that original data and split data match
+ $this->assertEquals( $this->dataLong, $splitCatfile['encrypted'] );
+
+ }
+
+ function testAddPadding() {
+
+ $padded = Encryption\Crypt::addPadding( $this->dataLong );
+
+ $padding = substr( $padded, -2 );
+
+ $this->assertEquals( 'xx' , $padding );
+
+ return $padded;
+
+ }
+
+ /**
+ * @depends testAddPadding
+ */
+ function testRemovePadding( $padded ) {
+
+ $noPadding = Encryption\Crypt::RemovePadding( $padded );
+
+ $this->assertEquals( $this->dataLong, $noPadding );
+
+ }
+
+ function testEncrypt() {
+
+ $random = openssl_random_pseudo_bytes( 13 );
+
+ $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht
+
+ $crypted = Encryption\Crypt::encrypt( $this->dataUrl, $iv, 'hat' );
+
+ $this->assertNotEquals( $this->dataUrl, $crypted );
+
+ }
+
+ function testDecrypt() {
+
+ $random = openssl_random_pseudo_bytes( 13 );
+
+ $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht
+
+ $crypted = Encryption\Crypt::encrypt( $this->dataUrl, $iv, 'hat' );
+
+ $decrypt = Encryption\Crypt::decrypt( $crypted, $iv, 'hat' );
+
+ $this->assertEquals( $this->dataUrl, $decrypt );
+
+ }
+
+ function testSymmetricEncryptFileContent() {
+
+ # TODO: search in keyfile for actual content as IV will ensure this test always passes
+
+ $crypted = Encryption\Crypt::symmetricEncryptFileContent( $this->dataShort, 'hat' );
+
+ $this->assertNotEquals( $this->dataShort, $crypted );
+
+
+ $decrypt = Encryption\Crypt::symmetricDecryptFileContent( $crypted, 'hat' );
+
+ $this->assertEquals( $this->dataShort, $decrypt );
+
+ }
+
+ // These aren't used for now
+// function testSymmetricBlockEncryptShortFileContent() {
+//
+// $crypted = Encryption\Crypt::symmetricBlockEncryptFileContent( $this->dataShort, $this->randomKey );
+//
+// $this->assertNotEquals( $this->dataShort, $crypted );
+//
+//
+// $decrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $crypted, $this->randomKey );
+//
+// $this->assertEquals( $this->dataShort, $decrypt );
+//
+// }
+//
+// function testSymmetricBlockEncryptLongFileContent() {
+//
+// $crypted = Encryption\Crypt::symmetricBlockEncryptFileContent( $this->dataLong, $this->randomKey );
+//
+// $this->assertNotEquals( $this->dataLong, $crypted );
+//
+//
+// $decrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $crypted, $this->randomKey );
+//
+// $this->assertEquals( $this->dataLong, $decrypt );
+//
+// }
+
+ function testSymmetricStreamEncryptShortFileContent() {
+
+ $filename = 'tmp-'.time();
+
+ $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataShort );
+
+ // Test that data was successfully written
+ $this->assertTrue( is_int( $cryptedFile ) );
+
+
+ // Get file contents without using any wrapper to get it's actual contents on disk
+ $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
+
+ // Check that the file was encrypted before being written to disk
+ $this->assertNotEquals( $this->dataShort, $retreivedCryptedFile );
+
+ // Get private key
+ $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
+
+ $decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
+
+
+ // Get keyfile
+ $encryptedKeyfile = Encryption\Keymanager::getFileKey( $this->view, $this->userId, $filename );
+
+ $decryptedKeyfile = Encryption\Crypt::keyDecrypt( $encryptedKeyfile, $decryptedPrivateKey );
+
+
+ // Manually decrypt
+ $manualDecrypt = Encryption\Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $decryptedKeyfile );
+
+ // Check that decrypted data matches
+ $this->assertEquals( $this->dataShort, $manualDecrypt );
+
+ }
+
+ /**
+ * @brief Test that data that is written by the crypto stream wrapper
+ * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
+ * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
+ * reassembly of its data
+ */
+ function testSymmetricStreamEncryptLongFileContent() {
+
+ // Generate a a random filename
+ $filename = 'tmp-'.time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong.$this->dataLong );
+
+ // Test that data was successfully written
+ $this->assertTrue( is_int( $cryptedFile ) );
+
+ // Get file contents without using any wrapper to get it's actual contents on disk
+ $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
+
+// echo "\n\n\$retreivedCryptedFile = $retreivedCryptedFile\n\n";
+
+ // Check that the file was encrypted before being written to disk
+ $this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile );
+
+ // Manuallly split saved file into separate IVs and encrypted chunks
+ $r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
+
+ //print_r($r);
+
+ // Join IVs and their respective data chunks
+ $e = array( $r[0].$r[1], $r[2].$r[3], $r[4].$r[5], $r[6].$r[7], $r[8].$r[9], $r[10].$r[11], $r[12].$r[13] );//.$r[11], $r[12].$r[13], $r[14] );
+
+ //print_r($e);
+
+
+ // Get private key
+ $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
+
+ $decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
+
+
+ // Get keyfile
+ $encryptedKeyfile = Encryption\Keymanager::getFileKey( $this->view, $this->userId, $filename );
+
+ $decryptedKeyfile = Encryption\Crypt::keyDecrypt( $encryptedKeyfile, $decryptedPrivateKey );
+
+
+ // Set var for reassembling decrypted content
+ $decrypt = '';
+
+ // Manually decrypt chunk
+ foreach ($e as $e) {
+
+// echo "\n\$e = $e";
+
+ $chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent( $e, $decryptedKeyfile );
+
+ // Assemble decrypted chunks
+ $decrypt .= $chunkDecrypt;
+
+// echo "\n\$chunkDecrypt = $chunkDecrypt";
+
+ }
+
+// echo "\n\$decrypt = $decrypt";
+
+ $this->assertEquals( $this->dataLong.$this->dataLong, $decrypt );
+
+ // Teardown
+
+ $this->view->unlink( $filename );
+
+ Encryption\Keymanager::deleteFileKey( $filename );
+
+ }
+
+ /**
+ * @brief Test that data that is read by the crypto stream wrapper
+ */
+ function testSymmetricStreamDecryptShortFileContent() {
+
+ $filename = 'tmp-'.time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataShort );
+
+ // Test that data was successfully written
+ $this->assertTrue( is_int( $cryptedFile ) );
+
+
+ // Get file contents without using any wrapper to get it's actual contents on disk
+ $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
+
+ $decrypt = file_get_contents( 'crypt://' . $filename );
+
+ $this->assertEquals( $this->dataShort, $decrypt );
+
+ }
+
+ function testSymmetricStreamDecryptLongFileContent() {
+
+ $filename = 'tmp-'.time();
+
+ // Save long data as encrypted file using stream wrapper
+ $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong );
+
+ // Test that data was successfully written
+ $this->assertTrue( is_int( $cryptedFile ) );
+
+
+ // Get file contents without using any wrapper to get it's actual contents on disk
+ $retreivedCryptedFile = $this->view->file_get_contents( $this->userId . '/files/' . $filename );
+
+ $decrypt = file_get_contents( 'crypt://' . $filename );
+
+ $this->assertEquals( $this->dataLong, $decrypt );
+
+ }
+
+ // Is this test still necessary?
+// function testSymmetricBlockStreamDecryptFileContent() {
+//
+// \OC_User::setUserId( 'admin' );
+//
+// // Disable encryption proxy to prevent unwanted en/decryption
+// \OC_FileProxy::$enabled = false;
+//
+// $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $this->dataUrl );
+//
+// // Disable encryption proxy to prevent unwanted en/decryption
+// \OC_FileProxy::$enabled = false;
+//
+// echo "\n\n\$cryptedFile = " . $this->view->file_get_contents( '/blockEncrypt' );
+//
+// $retreivedCryptedFile = file_get_contents( 'crypt://' . '/blockEncrypt' );
+//
+// $this->assertEquals( $this->dataUrl, $retreivedCryptedFile );
+//
+// \OC_FileProxy::$enabled = false;
+//
+// }
+
+ function testSymmetricEncryptFileContentKeyfile() {
+
+ # TODO: search in keyfile for actual content as IV will ensure this test always passes
+
+ $crypted = Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->dataUrl );
+
+ $this->assertNotEquals( $this->dataUrl, $crypted['encrypted'] );
+
+
+ $decrypt = Encryption\Crypt::symmetricDecryptFileContent( $crypted['encrypted'], $crypted['key'] );
+
+ $this->assertEquals( $this->dataUrl, $decrypt );
+
+ }
+
+ function testIsEncryptedContent() {
+
+ $this->assertFalse( Encryption\Crypt::isEncryptedContent( $this->dataUrl ) );
+
+ $this->assertFalse( Encryption\Crypt::isEncryptedContent( $this->legacyEncryptedData ) );
+
+ $keyfileContent = Encryption\Crypt::symmetricEncryptFileContent( $this->dataUrl, 'hat' );
+
+ $this->assertTrue( Encryption\Crypt::isEncryptedContent( $keyfileContent ) );
+
+ }
+
+ function testMultiKeyEncrypt() {
+
+ # TODO: search in keyfile for actual content as IV will ensure this test always passes
+
+ $pair1 = Encryption\Crypt::createKeypair();
+
+ $this->assertEquals( 2, count( $pair1 ) );
+
+ $this->assertTrue( strlen( $pair1['publicKey'] ) > 1 );
+
+ $this->assertTrue( strlen( $pair1['privateKey'] ) > 1 );
+
+
+ $crypted = Encryption\Crypt::multiKeyEncrypt( $this->dataUrl, array( $pair1['publicKey'] ) );
+
+ $this->assertNotEquals( $this->dataUrl, $crypted['encrypted'] );
+
+
+ $decrypt = Encryption\Crypt::multiKeyDecrypt( $crypted['encrypted'], $crypted['keys'][0], $pair1['privateKey'] );
+
+ $this->assertEquals( $this->dataUrl, $decrypt );
+
+ }
+
+ function testKeyEncrypt() {
+
+ // Generate keypair
+ $pair1 = Encryption\Crypt::createKeypair();
+
+ // Encrypt data
+ $crypted = Encryption\Crypt::keyEncrypt( $this->dataUrl, $pair1['publicKey'] );
+
+ $this->assertNotEquals( $this->dataUrl, $crypted );
+
+ // Decrypt data
+ $decrypt = Encryption\Crypt::keyDecrypt( $crypted, $pair1['privateKey'] );
+
+ $this->assertEquals( $this->dataUrl, $decrypt );
+
+ }
+
+ // What is the point of this test? It doesn't use keyEncryptKeyfile()
+ function testKeyEncryptKeyfile() {
+
+ # TODO: Don't repeat encryption from previous tests, use PHPUnit test interdependency instead
+
+ // Generate keypair
+ $pair1 = Encryption\Crypt::createKeypair();
+
+ // Encrypt plain data, generate keyfile & encrypted file
+ $cryptedData = Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->dataUrl );
+
+ // Encrypt keyfile
+ $cryptedKey = Encryption\Crypt::keyEncrypt( $cryptedData['key'], $pair1['publicKey'] );
+
+ // Decrypt keyfile
+ $decryptKey = Encryption\Crypt::keyDecrypt( $cryptedKey, $pair1['privateKey'] );
+
+ // Decrypt encrypted file
+ $decryptData = Encryption\Crypt::symmetricDecryptFileContent( $cryptedData['encrypted'], $decryptKey );
+
+ $this->assertEquals( $this->dataUrl, $decryptData );
+
+ }
+
+ /**
+ * @brief test functionality of keyEncryptKeyfile() and
+ * keyDecryptKeyfile()
+ */
+ function testKeyDecryptKeyfile() {
+
+ $encrypted = Encryption\Crypt::keyEncryptKeyfile( $this->dataShort, $this->genPublicKey );
+
+ $this->assertNotEquals( $encrypted['data'], $this->dataShort );
+
+ $decrypted = Encryption\Crypt::keyDecryptKeyfile( $encrypted['data'], $encrypted['key'], $this->genPrivateKey );
+
+ $this->assertEquals( $decrypted, $this->dataShort );
+
+ }
+
+
+ /**
+ * @brief test encryption using legacy blowfish method
+ */
+ function testLegacyEncryptShort() {
+
+ $crypted = Encryption\Crypt::legacyEncrypt( $this->dataShort, $this->pass );
+
+ $this->assertNotEquals( $this->dataShort, $crypted );
+
+ # TODO: search inencrypted text for actual content to ensure it
+ # genuine transformation
+
+ return $crypted;
+
+ }
+
+ /**
+ * @brief test decryption using legacy blowfish method
+ * @depends testLegacyEncryptShort
+ */
+ function testLegacyDecryptShort( $crypted ) {
+
+ $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
+
+ $this->assertEquals( $this->dataShort, $decrypted );
+
+ }
+
+ /**
+ * @brief test encryption using legacy blowfish method
+ */
+ function testLegacyEncryptLong() {
+
+ $crypted = Encryption\Crypt::legacyEncrypt( $this->dataLong, $this->pass );
+
+ $this->assertNotEquals( $this->dataLong, $crypted );
+
+ # TODO: search inencrypted text for actual content to ensure it
+ # genuine transformation
+
+ return $crypted;
+
+ }
+
+ /**
+ * @brief test decryption using legacy blowfish method
+ * @depends testLegacyEncryptLong
+ */
+ function testLegacyDecryptLong( $crypted ) {
+
+ $decrypted = Encryption\Crypt::legacyDecrypt( $crypted, $this->pass );
+
+ $this->assertEquals( $this->dataLong, $decrypted );
+
+ }
+
+ /**
+ * @brief test generation of legacy encryption key
+ * @depends testLegacyDecryptShort
+ */
+ function testLegacyCreateKey() {
+
+ // Create encrypted key
+ $encKey = Encryption\Crypt::legacyCreateKey( $this->pass );
+
+ // Decrypt key
+ $key = Encryption\Crypt::legacyDecrypt( $encKey, $this->pass );
+
+ $this->assertTrue( is_numeric( $key ) );
+
+ // Check that key is correct length
+ $this->assertEquals( 20, strlen( $key ) );
+
+ }
+
+ /**
+ * @brief test decryption using legacy blowfish method
+ * @depends testLegacyEncryptLong
+ */
+ function testLegacyKeyRecryptKeyfileEncrypt( $crypted ) {
+
+ $recrypted = Encryption\Crypt::LegacyKeyRecryptKeyfile( $crypted, $this->pass, $this->genPublicKey, $this->pass );
+
+ $this->assertNotEquals( $this->dataLong, $recrypted['data'] );
+
+ return $recrypted;
+
+ # TODO: search inencrypted text for actual content to ensure it
+ # genuine transformation
+
+ }
+
+// function testEncryption(){
+//
+// $key=uniqid();
+// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
+// $source=file_get_contents($file); //nice large text file
+// $encrypted=OC_Encryption\Crypt::encrypt($source,$key);
+// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
+// $decrypted=rtrim($decrypted, "\0");
+// $this->assertNotEquals($encrypted,$source);
+// $this->assertEqual($decrypted,$source);
+//
+// $chunk=substr($source,0,8192);
+// $encrypted=OC_Encryption\Crypt::encrypt($chunk,$key);
+// $this->assertEqual(strlen($chunk),strlen($encrypted));
+// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
+// $decrypted=rtrim($decrypted, "\0");
+// $this->assertEqual($decrypted,$chunk);
+//
+// $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key);
+// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key);
+// $this->assertNotEquals($encrypted,$source);
+// $this->assertEqual($decrypted,$source);
+//
+// $tmpFileEncrypted=OCP\Files::tmpFile();
+// OC_Encryption\Crypt::encryptfile($file,$tmpFileEncrypted,$key);
+// $encrypted=file_get_contents($tmpFileEncrypted);
+// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key);
+// $this->assertNotEquals($encrypted,$source);
+// $this->assertEqual($decrypted,$source);
+//
+// $tmpFileDecrypted=OCP\Files::tmpFile();
+// OC_Encryption\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_Encryption\Crypt::encrypt($source,$key);
+// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
+// $decrypted=rtrim($decrypted, "\0");
+// $this->assertEqual($decrypted,$source);
+//
+// $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key);
+// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key);
+// $this->assertEqual($decrypted,$source);
+//
+// }
+//
+// function testBinary(){
+// $key=uniqid();
+//
+// $file=__DIR__.'/binary';
+// $source=file_get_contents($file); //binary file
+// $encrypted=OC_Encryption\Crypt::encrypt($source,$key);
+// $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key);
+//
+// $decrypted=rtrim($decrypted, "\0");
+// $this->assertEqual($decrypted,$source);
+//
+// $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key);
+// $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key,strlen($source));
+// $this->assertEqual($decrypted,$source);
+// }
+
+}
diff --git a/apps/files_encryption/test/keymanager.php b/apps/files_encryption/test/keymanager.php
new file mode 100644
index 00000000000..f02d6eb5f7a
--- /dev/null
+++ b/apps/files_encryption/test/keymanager.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+//require_once "PHPUnit/Framework/TestCase.php";
+require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
+require_once realpath( dirname(__FILE__).'/../lib/crypt.php' );
+require_once realpath( dirname(__FILE__).'/../lib/keymanager.php' );
+require_once realpath( dirname(__FILE__).'/../lib/proxy.php' );
+require_once realpath( dirname(__FILE__).'/../lib/stream.php' );
+require_once realpath( dirname(__FILE__).'/../lib/util.php' );
+require_once realpath( dirname(__FILE__).'/../appinfo/app.php' );
+
+use OCA\Encryption;
+
+// This has to go here because otherwise session errors arise, and the private
+// encryption key needs to be saved in the session
+\OC_User::login( 'admin', 'admin' );
+
+class Test_Keymanager extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+
+ \OC_FileProxy::$enabled = false;
+
+ // set content for encrypting / decrypting in tests
+ $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
+ $this->dataShort = 'hats';
+ $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' );
+ $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' );
+ $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' );
+ $this->randomKey = Encryption\Crypt::generateKey();
+
+ $keypair = Encryption\Crypt::createKeypair();
+ $this->genPublicKey = $keypair['publicKey'];
+ $this->genPrivateKey = $keypair['privateKey'];
+
+ $this->view = new \OC_FilesystemView( '/' );
+
+ \OC_User::setUserId( 'admin' );
+ $this->userId = 'admin';
+ $this->pass = 'admin';
+
+ \OC_Filesystem::init( '/' );
+ \OC_Filesystem::mount( 'OC_Filestorage_Local', array('datadir' => \OC_User::getHome($this->userId)), '/' );
+
+ }
+
+ function tearDown(){
+
+ \OC_FileProxy::$enabled = true;
+
+ }
+
+ function testGetPrivateKey() {
+
+ $key = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
+
+ // Will this length vary? Perhaps we should use a range instead
+ $this->assertEquals( 2296, strlen( $key ) );
+
+ }
+
+ function testGetPublicKey() {
+
+ $key = Encryption\Keymanager::getPublicKey( $this->view, $this->userId );
+
+ $this->assertEquals( 451, strlen( $key ) );
+
+ $this->assertEquals( '-----BEGIN PUBLIC KEY-----', substr( $key, 0, 26 ) );
+ }
+
+ function testSetFileKey() {
+
+ # NOTE: This cannot be tested until we are able to break out
+ # of the FileSystemView data directory root
+
+// $key = Crypt::symmetricEncryptFileContentKeyfile( $this->data, 'hat' );
+//
+// $tmpPath = sys_get_temp_dir(). '/' . 'testSetFileKey';
+//
+// $view = new \OC_FilesystemView( '/tmp/' );
+//
+// //$view = new \OC_FilesystemView( '/' . $this->userId . '/files_encryption/keyfiles' );
+//
+// Encryption\Keymanager::setFileKey( $tmpPath, $key['key'], $view );
+
+ }
+
+// /**
+// * @depends testGetPrivateKey
+// */
+// function testGetPrivateKey_decrypt() {
+//
+// $key = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
+//
+// # TODO: replace call to Crypt with a mock object?
+// $decrypted = Encryption\Crypt::symmetricDecryptFileContent( $key, $this->passphrase );
+//
+// $this->assertEquals( 1704, strlen( $decrypted ) );
+//
+// $this->assertEquals( '-----BEGIN PRIVATE KEY-----', substr( $decrypted, 0, 27 ) );
+//
+// }
+
+ function testGetUserKeys() {
+
+ $keys = Encryption\Keymanager::getUserKeys( $this->view, $this->userId );
+
+ $this->assertEquals( 451, strlen( $keys['publicKey'] ) );
+ $this->assertEquals( '-----BEGIN PUBLIC KEY-----', substr( $keys['publicKey'], 0, 26 ) );
+ $this->assertEquals( 2296, strlen( $keys['privateKey'] ) );
+
+ }
+
+ function testGetPublicKeys() {
+
+ # TODO: write me
+
+ }
+
+ function testGetFileKey() {
+
+// Encryption\Keymanager::getFileKey( $this->view, $this->userId, $this->filePath );
+
+ }
+
+}
diff --git a/apps/files_encryption/test/legacy-encrypted-text.txt b/apps/files_encryption/test/legacy-encrypted-text.txt
new file mode 100644
index 00000000000..cb5bf50550d
--- /dev/null
+++ b/apps/files_encryption/test/legacy-encrypted-text.txt
Binary files differ
diff --git a/apps/files_encryption/test/proxy.php b/apps/files_encryption/test/proxy.php
new file mode 100644
index 00000000000..51e77100baa
--- /dev/null
+++ b/apps/files_encryption/test/proxy.php
@@ -0,0 +1,220 @@
+<?php
+/**
+ * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>,
+ * and Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+// require_once "PHPUnit/Framework/TestCase.php";
+// require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Generator.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/MockInterface.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Mock.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Container.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Configuration.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CompositeExpectation.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/ExpectationDirector.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Expectation.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Exception.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/CountValidatorAbstract.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/Exception.php' );
+// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/Exact.php' );
+//
+// use \Mockery as m;
+// use OCA\Encryption;
+
+// class Test_Util extends \PHPUnit_Framework_TestCase {
+//
+// public function setUp() {
+//
+// $this->proxy = new Encryption\Proxy();
+//
+// $this->tmpFileName = "tmpFile-".time();
+//
+// $this->privateKey = file_get_contents( realpath( dirname(__FILE__).'/data/admin.public.key' ) );
+// $this->publicKey = file_get_contents( realpath( dirname(__FILE__).'/data/admin.private.key' ) );
+// $this->encDataShort = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester-enc' ) );
+// $this->encDataShortKey = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester.key' ) );
+//
+// $this->dataShort = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester' ) );
+// $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
+// $this->longDataPath = realpath( dirname(__FILE__).'/../lib/crypt.php' );
+//
+// $this->data1 = file_get_contents( realpath( dirname(__FILE__).'/../../../data/admin/files/enc-test.txt' ) );
+//
+// \OC_FileProxy::$enabled = false;
+// $this->Encdata1 = file_get_contents( realpath( dirname(__FILE__).'/../../../data/admin/files/enc-test.txt' ) );
+// \OC_FileProxy::$enabled = true;
+//
+// $this->userId = 'admin';
+// $this->pass = 'admin';
+//
+// $this->session = new Encryption\Session();
+//
+// $this->session->setPrivateKey(
+// '-----BEGIN PRIVATE KEY-----
+// MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDiH3EA4EpFA7Fx
+// s2dyyfL5jwXeYXrTqQJ6DqKgGn8VsbT3eu8R9KzM2XitVwZe8c8L52DvJ06o5vg0
+// GqPYxilFdOFJe/ggac5Tq8UmJiZS4EqYEMwxBIfIyWTxeGV06/0HOwnVAkqHMcBz
+// 64qldtgi5O8kZMEM2/gKBgU0kMLJzM+8oEWhL1+gsUWQhxd8cKLXypS6iWgqFJrz
+// f/X0hJsJR+gyYxNpahtnjzd/LxLAETrOMsl2tue+BAxmjbAM0aG0NEM0div+b59s
+// 2uz/iWbxImp5pOdYVKcVW89D4XBMyGegR40trV2VwiuX1blKCfdjMsJhiaL9pymp
+// ug1wzyQFAgMBAAECggEAK6c+PZkPPXuVCgpEcliiW6NM0r2m5K3AGKgypQ34csu3
+// z/8foCvIIFPrhCtEw5eTDQ1CHWlNOjY8vHJYJ0U6Onpx86nHIRrMBkMm8FJ1G5LJ
+// U8oKYXwqaozWu/cuPwA//OFc6I5krOzh5n8WaRMkbrgbor8AtebRX74By0AXGrXe
+// cswJI7zR96oFn4Dm7Pgvpg5Zhk1vFJ+w6QtH+4DDJ6PBvlZsRkGxYBLGVd/3qhAI
+// sBAyjFlSzuP4eCRhHOhHC/e4gmAH9evFVXB88jFyRZm3K+jQ5W5CwrVRBCV2lph6
+// 2B6P7CBJN+IjGKMhy+75y13UvvKPv9IwH8Fzl2x1gQKBgQD8qQOr7a6KhSj16wQE
+// jim2xqt9gQ2jH5No405NrKs/PFQQZnzD4YseQsiK//NUjOJiUhaT+L5jhIpzINHt
+// RJpt3bGkEZmLyjdjgTpB3GwZdXa28DNK9VdXZ19qIl/ZH0qAjKmJCRahUDASMnVi
+// M4Pkk9yx9ZIKkri4TcuMWqc0DQKBgQDlHKBTITZq/arYPD6Nl3NsoOdqVRqJrGay
+// 0TjXAVbBXe46+z5lnMsqwXb79nx14hdmSEsZULrw/3f+MnQbdjMTYLFP24visZg9
+// MN8vAiALiiiR1a+Crz+DTA1Q8sGOMVCMqMDmD7QBys3ZuWxuapm0txAiIYUtsjJZ
+// XN76T4nZ2QKBgQCHaT3igzwsWTmesxowJtEMeGWomeXpKx8h89EfqA8PkRGsyIDN
+// qq+YxEoe1RZgljEuaLhZDdNcGsjo8woPk9kAUPTH7fbRCMuutK+4ZJ469s1tNkcH
+// QX5SBcEJbOrZvv967ehe3VQXmJZq6kgnHVzuwKBjcC2ZJRGDFY6l5l/+cQKBgCqh
+// +Adf/8NK7paMJ0urqfPFwSodKfICXZ3apswDWMRkmSbqh4La+Uc8dsqN5Dz/VEFZ
+// JHhSeGbN8uMfOlG93eU2MehdPxtw1pZUWMNjjtj23XO9ooob2CKzbSrp8TBnZsi1
+// widNNr66oTFpeo7VUUK6acsgF6sYJJxSVr+XO1yJAoGAEhvitq8shNKcEY0xCipS
+// k1kbgyS7KKB7opVxI5+ChEqyUDijS3Y9FZixrRIWE6i2uGu86UG+v2lbKvSbM4Qm
+// xvbOcX9OVMnlRb7n8woOP10UMY+ZE2x+YEUXQTLtPYq7F66e1OfxltstMxLQA+3d
+// Y1d5piFV8PXK3Fg2F+Cj5qg=
+// -----END PRIVATE KEY-----
+// '
+// , $this->userId
+// );
+//
+// \OC_User::setUserId( $this->userId );
+//
+// }
+//
+// public function testpreFile_get_contents() {
+//
+// // This won't work for now because mocking of the static keymanager class isn't working :(
+//
+// // $mock = m::mock( 'alias:OCA\Encryption\Keymanager' );
+// //
+// // $mock->shouldReceive( 'getFileKey' )->times(2)->andReturn( $this->encDataShort );
+// //
+// // $encrypted = $this->proxy->postFile_get_contents( 'data/'.$this->tmpFileName, $this->encDataShortKey );
+// //
+// // $this->assertNotEquals( $this->dataShort, $encrypted );
+//
+// $decrypted = $this->proxy->postFile_get_contents( 'data/admin/files/enc-test.txt', $this->data1 );
+//
+// }
+//
+// }
+
+// class Test_CryptProxy extends UnitTestCase {
+// private $oldConfig;
+// private $oldKey;
+//
+// public function setUp(){
+// $user=OC_User::getUser();
+//
+// $this->oldConfig=OCP\Config::getAppValue('files_encryption','enable_encryption','true');
+// OCP\Config::setAppValue('files_encryption','enable_encryption','true');
+// $this->oldKey=isset($_SESSION['privateKey'])?$_SESSION['privateKey']:null;
+//
+//
+// //set testing key
+// $_SESSION['privateKey']=md5(time());
+//
+// //clear all proxies and hooks so we can do clean testing
+// OC_FileProxy::clearProxies();
+// OC_Hook::clear('OC_Filesystem');
+//
+// //enable only the encryption hook
+// OC_FileProxy::register(new OC_FileProxy_Encryption());
+//
+// //set up temporary storage
+// OC_Filesystem::clearMounts();
+// OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/');
+//
+// OC_Filesystem::init('/'.$user.'/files');
+//
+// //set up the users home folder in the temp storage
+// $rootView=new OC_FilesystemView('');
+// $rootView->mkdir('/'.$user);
+// $rootView->mkdir('/'.$user.'/files');
+// }
+//
+// public function tearDown(){
+// OCP\Config::setAppValue('files_encryption','enable_encryption',$this->oldConfig);
+// if(!is_null($this->oldKey)){
+// $_SESSION['privateKey']=$this->oldKey;
+// }
+// }
+//
+// public function testSimple(){
+// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
+// $original=file_get_contents($file);
+//
+// OC_Filesystem::file_put_contents('/file',$original);
+//
+// OC_FileProxy::$enabled=false;
+// $stored=OC_Filesystem::file_get_contents('/file');
+// OC_FileProxy::$enabled=true;
+//
+// $fromFile=OC_Filesystem::file_get_contents('/file');
+// $this->assertNotEqual($original,$stored);
+// $this->assertEqual(strlen($original),strlen($fromFile));
+// $this->assertEqual($original,$fromFile);
+//
+// }
+//
+// public function testView(){
+// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
+// $original=file_get_contents($file);
+//
+// $rootView=new OC_FilesystemView('');
+// $view=new OC_FilesystemView('/'.OC_User::getUser());
+// $userDir='/'.OC_User::getUser().'/files';
+//
+// $rootView->file_put_contents($userDir.'/file',$original);
+//
+// OC_FileProxy::$enabled=false;
+// $stored=$rootView->file_get_contents($userDir.'/file');
+// OC_FileProxy::$enabled=true;
+//
+// $this->assertNotEqual($original,$stored);
+// $fromFile=$rootView->file_get_contents($userDir.'/file');
+// $this->assertEqual($original,$fromFile);
+//
+// $fromFile=$view->file_get_contents('files/file');
+// $this->assertEqual($original,$fromFile);
+// }
+//
+// public function testBinary(){
+// $file=__DIR__.'/binary';
+// $original=file_get_contents($file);
+//
+// OC_Filesystem::file_put_contents('/file',$original);
+//
+// OC_FileProxy::$enabled=false;
+// $stored=OC_Filesystem::file_get_contents('/file');
+// OC_FileProxy::$enabled=true;
+//
+// $fromFile=OC_Filesystem::file_get_contents('/file');
+// $this->assertNotEqual($original,$stored);
+// $this->assertEqual(strlen($original),strlen($fromFile));
+// $this->assertEqual($original,$fromFile);
+//
+// $file=__DIR__.'/zeros';
+// $original=file_get_contents($file);
+//
+// OC_Filesystem::file_put_contents('/file',$original);
+//
+// OC_FileProxy::$enabled=false;
+// $stored=OC_Filesystem::file_get_contents('/file');
+// OC_FileProxy::$enabled=true;
+//
+// $fromFile=OC_Filesystem::file_get_contents('/file');
+// $this->assertNotEqual($original,$stored);
+// $this->assertEqual(strlen($original),strlen($fromFile));
+// }
+// }
diff --git a/apps/files_encryption/test/stream.php b/apps/files_encryption/test/stream.php
new file mode 100644
index 00000000000..4211cab3104
--- /dev/null
+++ b/apps/files_encryption/test/stream.php
@@ -0,0 +1,226 @@
+// <?php
+// /**
+// * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+// * This file is licensed under the Affero General Public License version 3 or
+// * later.
+// * See the COPYING-README file.
+// */
+//
+// namespace OCA\Encryption;
+//
+// class Test_Stream extends \PHPUnit_Framework_TestCase {
+//
+// function setUp() {
+//
+// \OC_Filesystem::mount( 'OC_Filestorage_Local', array(), '/' );
+//
+// $this->empty = '';
+//
+// $this->stream = new Stream();
+//
+// $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
+// $this->dataShort = 'hats';
+//
+// $this->emptyTmpFilePath = \OCP\Files::tmpFile();
+//
+// $this->dataTmpFilePath = \OCP\Files::tmpFile();
+//
+// file_put_contents( $this->dataTmpFilePath, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est." );
+//
+// }
+//
+// function testStreamOpen() {
+//
+// $stream1 = new Stream();
+//
+// $handle1 = $stream1->stream_open( $this->emptyTmpFilePath, 'wb', array(), $this->empty );
+//
+// // Test that resource was returned successfully
+// $this->assertTrue( $handle1 );
+//
+// // Test that file has correct size
+// $this->assertEquals( 0, $stream1->size );
+//
+// // Test that path is correct
+// $this->assertEquals( $this->emptyTmpFilePath, $stream1->rawPath );
+//
+// $stream2 = new Stream();
+//
+// $handle2 = $stream2->stream_open( 'crypt://' . $this->emptyTmpFilePath, 'wb', array(), $this->empty );
+//
+// // Test that protocol identifier is removed from path
+// $this->assertEquals( $this->emptyTmpFilePath, $stream2->rawPath );
+//
+// // "Stat failed error" prevents this test from executing
+// // $stream3 = new Stream();
+// //
+// // $handle3 = $stream3->stream_open( $this->dataTmpFilePath, 'r', array(), $this->empty );
+// //
+// // $this->assertEquals( 0, $stream3->size );
+//
+// }
+//
+// function testStreamWrite() {
+//
+// $stream1 = new Stream();
+//
+// $handle1 = $stream1->stream_open( $this->emptyTmpFilePath, 'r+b', array(), $this->empty );
+//
+// # what about the keymanager? there is no key for the newly created temporary file!
+//
+// $stream1->stream_write( $this->dataShort );
+//
+// }
+//
+// // function getStream( $id, $mode, $size ) {
+// //
+// // if ( $id === '' ) {
+// //
+// // $id = uniqid();
+// // }
+// //
+// //
+// // if ( !isset( $this->tmpFiles[$id] ) ) {
+// //
+// // // If tempfile with given name does not already exist, create it
+// //
+// // $file = OCP\Files::tmpFile();
+// //
+// // $this->tmpFiles[$id] = $file;
+// //
+// // } else {
+// //
+// // $file = $this->tmpFiles[$id];
+// //
+// // }
+// //
+// // $stream = fopen( $file, $mode );
+// //
+// // Stream::$sourceStreams[$id] = array( 'path' => 'dummy' . $id, 'stream' => $stream, 'size' => $size );
+// //
+// // return fopen( 'crypt://streams/'.$id, $mode );
+// //
+// // }
+// //
+// // function testStream( ){
+// //
+// // $stream = $this->getStream( 'test1', 'w', strlen( 'foobar' ) );
+// //
+// // fwrite( $stream, 'foobar' );
+// //
+// // fclose( $stream );
+// //
+// //
+// // $stream = $this->getStream( 'test1', 'r', strlen( 'foobar' ) );
+// //
+// // $data = fread( $stream, 6 );
+// //
+// // fclose( $stream );
+// //
+// // $this->assertEqual( 'foobar', $data );
+// //
+// //
+// // $file = OC::$SERVERROOT.'/3rdparty/MDB2.php';
+// //
+// // $source = fopen( $file, 'r' );
+// //
+// // $target = $this->getStream( 'test2', 'w', 0 );
+// //
+// // OCP\Files::streamCopy( $source, $target );
+// //
+// // fclose( $target );
+// //
+// // fclose( $source );
+// //
+// //
+// // $stream = $this->getStream( 'test2', 'r', filesize( $file ) );
+// //
+// // $data = stream_get_contents( $stream );
+// //
+// // $original = file_get_contents( $file );
+// //
+// // $this->assertEqual( strlen( $original ), strlen( $data ) );
+// //
+// // $this->assertEqual( $original, $data );
+// //
+// // }
+//
+// }
+//
+// // class Test_CryptStream extends UnitTestCase {
+// // private $tmpFiles=array();
+// //
+// // function testStream(){
+// // $stream=$this->getStream('test1','w',strlen('foobar'));
+// // fwrite($stream,'foobar');
+// // fclose($stream);
+// //
+// // $stream=$this->getStream('test1','r',strlen('foobar'));
+// // $data=fread($stream,6);
+// // fclose($stream);
+// // $this->assertEqual('foobar',$data);
+// //
+// // $file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
+// // $source=fopen($file,'r');
+// // $target=$this->getStream('test2','w',0);
+// // OCP\Files::streamCopy($source,$target);
+// // fclose($target);
+// // fclose($source);
+// //
+// // $stream=$this->getStream('test2','r',filesize($file));
+// // $data=stream_get_contents($stream);
+// // $original=file_get_contents($file);
+// // $this->assertEqual(strlen($original),strlen($data));
+// // $this->assertEqual($original,$data);
+// // }
+// //
+// // /**
+// // * get a cryptstream to a temporary file
+// // * @param string $id
+// // * @param string $mode
+// // * @param int size
+// // * @return resource
+// // */
+// // function getStream($id,$mode,$size){
+// // if($id===''){
+// // $id=uniqid();
+// // }
+// // if(!isset($this->tmpFiles[$id])){
+// // $file=OCP\Files::tmpFile();
+// // $this->tmpFiles[$id]=$file;
+// // }else{
+// // $file=$this->tmpFiles[$id];
+// // }
+// // $stream=fopen($file,$mode);
+// // OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy'.$id,'stream'=>$stream,'size'=>$size);
+// // return fopen('crypt://streams/'.$id,$mode);
+// // }
+// //
+// // function testBinary(){
+// // $file=__DIR__.'/binary';
+// // $source=file_get_contents($file);
+// //
+// // $stream=$this->getStream('test','w',strlen($source));
+// // fwrite($stream,$source);
+// // fclose($stream);
+// //
+// // $stream=$this->getStream('test','r',strlen($source));
+// // $data=stream_get_contents($stream);
+// // fclose($stream);
+// // $this->assertEqual(strlen($data),strlen($source));
+// // $this->assertEqual($source,$data);
+// //
+// // $file=__DIR__.'/zeros';
+// // $source=file_get_contents($file);
+// //
+// // $stream=$this->getStream('test2','w',strlen($source));
+// // fwrite($stream,$source);
+// // fclose($stream);
+// //
+// // $stream=$this->getStream('test2','r',strlen($source));
+// // $data=stream_get_contents($stream);
+// // fclose($stream);
+// // $this->assertEqual(strlen($data),strlen($source));
+// // $this->assertEqual($source,$data);
+// // }
+// // }
diff --git a/apps/files_encryption/test/util.php b/apps/files_encryption/test/util.php
new file mode 100755
index 00000000000..016787fbfba
--- /dev/null
+++ b/apps/files_encryption/test/util.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+//require_once "PHPUnit/Framework/TestCase.php";
+require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
+require_once realpath( dirname(__FILE__).'/../lib/crypt.php' );
+require_once realpath( dirname(__FILE__).'/../lib/keymanager.php' );
+require_once realpath( dirname(__FILE__).'/../lib/proxy.php' );
+require_once realpath( dirname(__FILE__).'/../lib/stream.php' );
+require_once realpath( dirname(__FILE__).'/../lib/util.php' );
+require_once realpath( dirname(__FILE__).'/../appinfo/app.php' );
+
+// Load mockery files
+require_once 'Mockery/Loader.php';
+require_once 'Hamcrest/Hamcrest.php';
+$loader = new \Mockery\Loader;
+$loader->register();
+
+use \Mockery as m;
+use OCA\Encryption;
+
+class Test_Enc_Util extends \PHPUnit_Framework_TestCase {
+
+ function setUp() {
+
+ \OC_Filesystem::mount( 'OC_Filestorage_Local', array(), '/' );
+
+ // set content for encrypting / decrypting in tests
+ $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' );
+ $this->dataShort = 'hats';
+ $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
+ $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' );
+ $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' );
+
+ $this->userId = 'admin';
+ $this->pass = 'admin';
+
+ $keypair = Encryption\Crypt::createKeypair();
+
+ $this->genPublicKey = $keypair['publicKey'];
+ $this->genPrivateKey = $keypair['privateKey'];
+
+ $this->publicKeyDir = '/' . 'public-keys';
+ $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
+ $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
+ $this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
+ $this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
+
+ $this->view = new OC_FilesystemView( '/admin' );
+
+ $this->mockView = m::mock('OC_FilesystemView');
+ $this->util = new Encryption\Util( $this->mockView, $this->userId );
+
+ }
+
+ function tearDown(){
+
+ m::close();
+
+ }
+
+ /**
+ * @brief test that paths set during User construction are correct
+ */
+ function testKeyPaths() {
+
+ $mockView = m::mock('OC_FilesystemView');
+
+ $util = new Encryption\Util( $mockView, $this->userId );
+
+ $this->assertEquals( $this->publicKeyDir, $util->getPath( 'publicKeyDir' ) );
+ $this->assertEquals( $this->encryptionDir, $util->getPath( 'encryptionDir' ) );
+ $this->assertEquals( $this->keyfilesPath, $util->getPath( 'keyfilesPath' ) );
+ $this->assertEquals( $this->publicKeyPath, $util->getPath( 'publicKeyPath' ) );
+ $this->assertEquals( $this->privateKeyPath, $util->getPath( 'privateKeyPath' ) );
+
+ }
+
+ /**
+ * @brief test setup of encryption directories when they don't yet exist
+ */
+ function testSetupServerSideNotSetup() {
+
+ $mockView = m::mock('OC_FilesystemView');
+
+ $mockView->shouldReceive( 'file_exists' )->times(4)->andReturn( false );
+ $mockView->shouldReceive( 'mkdir' )->times(3)->andReturn( true );
+ $mockView->shouldReceive( 'file_put_contents' )->withAnyArgs();
+
+ $util = new Encryption\Util( $mockView, $this->userId );
+
+ $this->assertEquals( true, $util->setupServerSide( $this->pass ) );
+
+ }
+
+ /**
+ * @brief test setup of encryption directories when they already exist
+ */
+ function testSetupServerSideIsSetup() {
+
+ $mockView = m::mock('OC_FilesystemView');
+
+ $mockView->shouldReceive( 'file_exists' )->times(5)->andReturn( true );
+ $mockView->shouldReceive( 'file_put_contents' )->withAnyArgs();
+
+ $util = new Encryption\Util( $mockView, $this->userId );
+
+ $this->assertEquals( true, $util->setupServerSide( $this->pass ) );
+
+ }
+
+ /**
+ * @brief test checking whether account is ready for encryption, when it isn't ready
+ */
+ function testReadyNotReady() {
+
+ $mockView = m::mock('OC_FilesystemView');
+
+ $mockView->shouldReceive( 'file_exists' )->times(1)->andReturn( false );
+
+ $util = new Encryption\Util( $mockView, $this->userId );
+
+ $this->assertEquals( false, $util->ready() );
+
+ # TODO: Add more tests here to check that if any of the dirs are
+ # then false will be returned. Use strict ordering?
+
+ }
+
+ /**
+ * @brief test checking whether account is ready for encryption, when it is ready
+ */
+ function testReadyIsReady() {
+
+ $mockView = m::mock('OC_FilesystemView');
+
+ $mockView->shouldReceive( 'file_exists' )->times(3)->andReturn( true );
+
+ $util = new Encryption\Util( $mockView, $this->userId );
+
+ $this->assertEquals( true, $util->ready() );
+
+ # TODO: Add more tests here to check that if any of the dirs are
+ # then false will be returned. Use strict ordering?
+
+ }
+
+// /**
+// * @brief test decryption using legacy blowfish method
+// * @depends testLegacyEncryptLong
+// */
+// function testLegacyKeyRecryptKeyfileDecrypt( $recrypted ) {
+//
+// $decrypted = Encryption\Crypt::keyDecryptKeyfile( $recrypted['data'], $recrypted['key'], $this->genPrivateKey );
+//
+// $this->assertEquals( $this->dataLong, $decrypted );
+//
+// }
+
+// // Cannot use this test for now due to hidden dependencies in OC_FileCache
+// function testIsLegacyEncryptedContent() {
+//
+// $keyfileContent = OCA\Encryption\Crypt::symmetricEncryptFileContent( $this->legacyEncryptedData, 'hat' );
+//
+// $this->assertFalse( OCA\Encryption\Crypt::isLegacyEncryptedContent( $keyfileContent, '/files/admin/test.txt' ) );
+//
+// OC_FileCache::put( '/admin/files/legacy-encrypted-test.txt', $this->legacyEncryptedData );
+//
+// $this->assertTrue( OCA\Encryption\Crypt::isLegacyEncryptedContent( $this->legacyEncryptedData, '/files/admin/test.txt' ) );
+//
+// }
+
+// // Cannot use this test for now due to need for different root in OC_Filesystem_view class
+// function testGetLegacyKey() {
+//
+// $c = new \OCA\Encryption\Util( $view, false );
+//
+// $bool = $c->getLegacyKey( 'admin' );
+//
+// $this->assertTrue( $bool );
+//
+// $this->assertTrue( $c->legacyKey );
+//
+// $this->assertTrue( is_int( $c->legacyKey ) );
+//
+// $this->assertTrue( strlen( $c->legacyKey ) == 20 );
+//
+// }
+
+// // Cannot use this test for now due to need for different root in OC_Filesystem_view class
+// function testLegacyDecrypt() {
+//
+// $c = new OCA\Encryption\Util( $this->view, false );
+//
+// $bool = $c->getLegacyKey( 'admin' );
+//
+// $encrypted = $c->legacyEncrypt( $this->data, $c->legacyKey );
+//
+// $decrypted = $c->legacyDecrypt( $encrypted, $c->legacyKey );
+//
+// $this->assertEqual( $decrypted, $this->data );
+//
+// }
+
+} \ No newline at end of file
diff --git a/apps/files_encryption/test/zeros b/apps/files_encryption/test/zeros
new file mode 100644
index 00000000000..ff982acf423
--- /dev/null
+++ b/apps/files_encryption/test/zeros
Binary files differ