crypt.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>, and
  4. * Robin Appelman <icewind@owncloud.com>
  5. * This file is licensed under the Affero General Public License version 3 or
  6. * later.
  7. * See the COPYING-README file.
  8. */
  9. require_once realpath(dirname(__FILE__) . '/../3rdparty/Crypt_Blowfish/Blowfish.php');
  10. require_once realpath(dirname(__FILE__) . '/../../../lib/base.php');
  11. require_once realpath(dirname(__FILE__) . '/../lib/crypt.php');
  12. require_once realpath(dirname(__FILE__) . '/../lib/keymanager.php');
  13. require_once realpath(dirname(__FILE__) . '/../lib/proxy.php');
  14. require_once realpath(dirname(__FILE__) . '/../lib/stream.php');
  15. require_once realpath(dirname(__FILE__) . '/../lib/util.php');
  16. require_once realpath(dirname(__FILE__) . '/../lib/helper.php');
  17. require_once realpath(dirname(__FILE__) . '/../appinfo/app.php');
  18. require_once realpath(dirname(__FILE__) . '/util.php');
  19. use OCA\Encryption;
  20. /**
  21. * Class Test_Encryption_Crypt
  22. */
  23. class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
  24. const TEST_ENCRYPTION_CRYPT_USER1 = "test-crypt-user1";
  25. public $userId;
  26. public $pass;
  27. public $stateFilesTrashbin;
  28. public $dataLong;
  29. public $dataUrl;
  30. public $dataShort;
  31. /**
  32. * @var OC_FilesystemView
  33. */
  34. public $view;
  35. public $legacyEncryptedData;
  36. public $genPrivateKey;
  37. public $genPublicKey;
  38. public static function setUpBeforeClass() {
  39. // reset backend
  40. \OC_User::clearBackends();
  41. \OC_User::useBackend('database');
  42. // Filesystem related hooks
  43. \OCA\Encryption\Helper::registerFilesystemHooks();
  44. // Filesystem related hooks
  45. \OCA\Encryption\Helper::registerUserHooks();
  46. // clear and register hooks
  47. \OC_FileProxy::clearProxies();
  48. \OC_FileProxy::register(new OCA\Encryption\Proxy());
  49. // create test user
  50. \Test_Encryption_Util::loginHelper(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1, true);
  51. }
  52. function setUp() {
  53. // set user id
  54. \OC_User::setUserId(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1);
  55. $this->userId = \Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1;
  56. $this->pass = \Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1;
  57. // set content for encrypting / decrypting in tests
  58. $this->dataLong = file_get_contents(realpath(dirname(__FILE__) . '/../lib/crypt.php'));
  59. $this->dataShort = 'hats';
  60. $this->dataUrl = realpath(dirname(__FILE__) . '/../lib/crypt.php');
  61. $this->legacyData = realpath(dirname(__FILE__) . '/legacy-text.txt');
  62. $this->legacyEncryptedData = realpath(dirname(__FILE__) . '/legacy-encrypted-text.txt');
  63. $this->legacyEncryptedDataKey = realpath(dirname(__FILE__) . '/encryption.key');
  64. $this->randomKey = Encryption\Crypt::generateKey();
  65. $keypair = Encryption\Crypt::createKeypair();
  66. $this->genPublicKey = $keypair['publicKey'];
  67. $this->genPrivateKey = $keypair['privateKey'];
  68. $this->view = new \OC_FilesystemView('/');
  69. // remember files_trashbin state
  70. $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
  71. // we don't want to tests with app files_trashbin enabled
  72. \OC_App::disable('files_trashbin');
  73. }
  74. function tearDown() {
  75. // reset app files_trashbin
  76. if ($this->stateFilesTrashbin) {
  77. OC_App::enable('files_trashbin');
  78. } else {
  79. OC_App::disable('files_trashbin');
  80. }
  81. }
  82. public static function tearDownAfterClass() {
  83. // cleanup test user
  84. \OC_User::deleteUser(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1);
  85. }
  86. /**
  87. * @medium
  88. */
  89. function testGenerateKey() {
  90. # TODO: use more accurate (larger) string length for test confirmation
  91. $key = Encryption\Crypt::generateKey();
  92. $this->assertTrue(strlen($key) > 16);
  93. }
  94. /**
  95. * @large
  96. * @return String
  97. */
  98. function testGenerateIv() {
  99. $iv = Encryption\Crypt::generateIv();
  100. $this->assertEquals(16, strlen($iv));
  101. return $iv;
  102. }
  103. /**
  104. * @large
  105. * @depends testGenerateIv
  106. */
  107. function testConcatIv($iv) {
  108. $catFile = Encryption\Crypt::concatIv($this->dataLong, $iv);
  109. // Fetch encryption metadata from end of file
  110. $meta = substr($catFile, -22);
  111. $identifier = substr($meta, 0, 6);
  112. // Fetch IV from end of file
  113. $foundIv = substr($meta, 6);
  114. $this->assertEquals('00iv00', $identifier);
  115. $this->assertEquals($iv, $foundIv);
  116. // Remove IV and IV identifier text to expose encrypted content
  117. $data = substr($catFile, 0, -22);
  118. $this->assertEquals($this->dataLong, $data);
  119. return array(
  120. 'iv' => $iv
  121. ,
  122. 'catfile' => $catFile
  123. );
  124. }
  125. /**
  126. * @medium
  127. * @depends testConcatIv
  128. */
  129. function testSplitIv($testConcatIv) {
  130. // Split catfile into components
  131. $splitCatfile = Encryption\Crypt::splitIv($testConcatIv['catfile']);
  132. // Check that original IV and split IV match
  133. $this->assertEquals($testConcatIv['iv'], $splitCatfile['iv']);
  134. // Check that original data and split data match
  135. $this->assertEquals($this->dataLong, $splitCatfile['encrypted']);
  136. }
  137. /**
  138. * @medium
  139. * @return string padded
  140. */
  141. function testAddPadding() {
  142. $padded = Encryption\Crypt::addPadding($this->dataLong);
  143. $padding = substr($padded, -2);
  144. $this->assertEquals('xx', $padding);
  145. return $padded;
  146. }
  147. /**
  148. * @medium
  149. * @depends testAddPadding
  150. */
  151. function testRemovePadding($padded) {
  152. $noPadding = Encryption\Crypt::RemovePadding($padded);
  153. $this->assertEquals($this->dataLong, $noPadding);
  154. }
  155. /**
  156. * @medium
  157. */
  158. function testEncrypt() {
  159. $random = openssl_random_pseudo_bytes(13);
  160. $iv = substr(base64_encode($random), 0, -4); // i.e. E5IG033j+mRNKrht
  161. $crypted = Encryption\Crypt::encrypt($this->dataUrl, $iv, 'hat');
  162. $this->assertNotEquals($this->dataUrl, $crypted);
  163. }
  164. /**
  165. * @medium
  166. */
  167. function testDecrypt() {
  168. $random = openssl_random_pseudo_bytes(13);
  169. $iv = substr(base64_encode($random), 0, -4); // i.e. E5IG033j+mRNKrht
  170. $crypted = Encryption\Crypt::encrypt($this->dataUrl, $iv, 'hat');
  171. $decrypt = Encryption\Crypt::decrypt($crypted, $iv, 'hat');
  172. $this->assertEquals($this->dataUrl, $decrypt);
  173. }
  174. function testDecryptPrivateKey() {
  175. // test successful decrypt
  176. $crypted = Encryption\Crypt::symmetricEncryptFileContent($this->genPrivateKey, 'hat');
  177. $decrypted = Encryption\Crypt::decryptPrivateKey($crypted, 'hat');
  178. $this->assertEquals($this->genPrivateKey, $decrypted);
  179. //test private key decrypt with wrong password
  180. $wrongPasswd = Encryption\Crypt::decryptPrivateKey($crypted, 'hat2');
  181. $this->assertEquals(false, $wrongPasswd);
  182. }
  183. /**
  184. * @medium
  185. */
  186. function testSymmetricEncryptFileContent() {
  187. # TODO: search in keyfile for actual content as IV will ensure this test always passes
  188. $crypted = Encryption\Crypt::symmetricEncryptFileContent($this->dataShort, 'hat');
  189. $this->assertNotEquals($this->dataShort, $crypted);
  190. $decrypt = Encryption\Crypt::symmetricDecryptFileContent($crypted, 'hat');
  191. $this->assertEquals($this->dataShort, $decrypt);
  192. }
  193. /**
  194. * @medium
  195. */
  196. function testSymmetricStreamEncryptShortFileContent() {
  197. $filename = 'tmp-' . time() . '.test';
  198. $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataShort);
  199. // Test that data was successfully written
  200. $this->assertTrue(is_int($cryptedFile));
  201. // Disable encryption proxy to prevent recursive calls
  202. $proxyStatus = \OC_FileProxy::$enabled;
  203. \OC_FileProxy::$enabled = false;
  204. // Get file contents without using any wrapper to get it's actual contents on disk
  205. $retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
  206. // Re-enable proxy - our work is done
  207. \OC_FileProxy::$enabled = $proxyStatus;
  208. // Check that the file was encrypted before being written to disk
  209. $this->assertNotEquals($this->dataShort, $retreivedCryptedFile);
  210. // Get the encrypted keyfile
  211. $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename);
  212. // Attempt to fetch the user's shareKey
  213. $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename);
  214. // get session
  215. $session = new \OCA\Encryption\Session($this->view);
  216. // get private key
  217. $privateKey = $session->getPrivateKey($this->userId);
  218. // Decrypt keyfile with shareKey
  219. $plainKeyfile = Encryption\Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
  220. // Manually decrypt
  221. $manualDecrypt = Encryption\Crypt::symmetricDecryptFileContent($retreivedCryptedFile, $plainKeyfile);
  222. // Check that decrypted data matches
  223. $this->assertEquals($this->dataShort, $manualDecrypt);
  224. // Teardown
  225. $this->view->unlink($this->userId . '/files/' . $filename);
  226. Encryption\Keymanager::deleteFileKey($this->view, $this->userId, $filename);
  227. }
  228. /**
  229. * @medium
  230. * @brief Test that data that is written by the crypto stream wrapper
  231. * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
  232. * @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
  233. * reassembly of its data
  234. */
  235. function testSymmetricStreamEncryptLongFileContent() {
  236. // Generate a a random filename
  237. $filename = 'tmp-' . time() . '.test';
  238. // Save long data as encrypted file using stream wrapper
  239. $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong . $this->dataLong);
  240. // Test that data was successfully written
  241. $this->assertTrue(is_int($cryptedFile));
  242. // Disable encryption proxy to prevent recursive calls
  243. $proxyStatus = \OC_FileProxy::$enabled;
  244. \OC_FileProxy::$enabled = false;
  245. // Get file contents without using any wrapper to get it's actual contents on disk
  246. $retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
  247. // Re-enable proxy - our work is done
  248. \OC_FileProxy::$enabled = $proxyStatus;
  249. // Check that the file was encrypted before being written to disk
  250. $this->assertNotEquals($this->dataLong . $this->dataLong, $retreivedCryptedFile);
  251. // Manuallly split saved file into separate IVs and encrypted chunks
  252. $r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
  253. //print_r($r);
  254. // Join IVs and their respective data chunks
  255. $e = array(
  256. $r[0] . $r[1],
  257. $r[2] . $r[3],
  258. $r[4] . $r[5],
  259. $r[6] . $r[7],
  260. $r[8] . $r[9],
  261. $r[10] . $r[11]
  262. ); //.$r[11], $r[12].$r[13], $r[14] );
  263. //print_r($e);
  264. // Get the encrypted keyfile
  265. $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename);
  266. // Attempt to fetch the user's shareKey
  267. $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename);
  268. // get session
  269. $session = new \OCA\Encryption\Session($this->view);
  270. // get private key
  271. $privateKey = $session->getPrivateKey($this->userId);
  272. // Decrypt keyfile with shareKey
  273. $plainKeyfile = Encryption\Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
  274. // Set var for reassembling decrypted content
  275. $decrypt = '';
  276. // Manually decrypt chunk
  277. foreach ($e as $chunk) {
  278. $chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent($chunk, $plainKeyfile);
  279. // Assemble decrypted chunks
  280. $decrypt .= $chunkDecrypt;
  281. }
  282. $this->assertEquals($this->dataLong . $this->dataLong, $decrypt);
  283. // Teardown
  284. $this->view->unlink($this->userId . '/files/' . $filename);
  285. Encryption\Keymanager::deleteFileKey($this->view, $this->userId, $filename);
  286. }
  287. /**
  288. * @medium
  289. * @brief Test that data that is read by the crypto stream wrapper
  290. */
  291. function testSymmetricStreamDecryptShortFileContent() {
  292. $filename = 'tmp-' . time();
  293. // Save long data as encrypted file using stream wrapper
  294. $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataShort);
  295. // Test that data was successfully written
  296. $this->assertTrue(is_int($cryptedFile));
  297. // Disable encryption proxy to prevent recursive calls
  298. $proxyStatus = \OC_FileProxy::$enabled;
  299. \OC_FileProxy::$enabled = false;
  300. $this->assertTrue(Encryption\Crypt::isEncryptedMeta($filename));
  301. \OC_FileProxy::$enabled = $proxyStatus;
  302. // Get file decrypted contents
  303. $decrypt = file_get_contents('crypt://' . $filename);
  304. $this->assertEquals($this->dataShort, $decrypt);
  305. // tear down
  306. $this->view->unlink($this->userId . '/files/' . $filename);
  307. }
  308. /**
  309. * @medium
  310. */
  311. function testSymmetricStreamDecryptLongFileContent() {
  312. $filename = 'tmp-' . time();
  313. // Save long data as encrypted file using stream wrapper
  314. $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
  315. // Test that data was successfully written
  316. $this->assertTrue(is_int($cryptedFile));
  317. // Get file decrypted contents
  318. $decrypt = file_get_contents('crypt://' . $filename);
  319. $this->assertEquals($this->dataLong, $decrypt);
  320. // tear down
  321. $this->view->unlink($this->userId . '/files/' . $filename);
  322. }
  323. /**
  324. * @medium
  325. */
  326. function testSymmetricEncryptFileContentKeyfile() {
  327. # TODO: search in keyfile for actual content as IV will ensure this test always passes
  328. $crypted = Encryption\Crypt::symmetricEncryptFileContentKeyfile($this->dataUrl);
  329. $this->assertNotEquals($this->dataUrl, $crypted['encrypted']);
  330. $decrypt = Encryption\Crypt::symmetricDecryptFileContent($crypted['encrypted'], $crypted['key']);
  331. $this->assertEquals($this->dataUrl, $decrypt);
  332. }
  333. /**
  334. * @medium
  335. */
  336. function testIsEncryptedContent() {
  337. $this->assertFalse(Encryption\Crypt::isCatfileContent($this->dataUrl));
  338. $this->assertFalse(Encryption\Crypt::isCatfileContent($this->legacyEncryptedData));
  339. $keyfileContent = Encryption\Crypt::symmetricEncryptFileContent($this->dataUrl, 'hat');
  340. $this->assertTrue(Encryption\Crypt::isCatfileContent($keyfileContent));
  341. }
  342. /**
  343. * @large
  344. */
  345. function testMultiKeyEncrypt() {
  346. # TODO: search in keyfile for actual content as IV will ensure this test always passes
  347. $pair1 = Encryption\Crypt::createKeypair();
  348. $this->assertEquals(2, count($pair1));
  349. $this->assertTrue(strlen($pair1['publicKey']) > 1);
  350. $this->assertTrue(strlen($pair1['privateKey']) > 1);
  351. $crypted = Encryption\Crypt::multiKeyEncrypt($this->dataShort, array($pair1['publicKey']));
  352. $this->assertNotEquals($this->dataShort, $crypted['data']);
  353. $decrypt = Encryption\Crypt::multiKeyDecrypt($crypted['data'], $crypted['keys'][0], $pair1['privateKey']);
  354. $this->assertEquals($this->dataShort, $decrypt);
  355. }
  356. /**
  357. * @medium
  358. */
  359. function testKeyEncrypt() {
  360. // Generate keypair
  361. $pair1 = Encryption\Crypt::createKeypair();
  362. // Encrypt data
  363. $crypted = Encryption\Crypt::keyEncrypt($this->dataUrl, $pair1['publicKey']);
  364. $this->assertNotEquals($this->dataUrl, $crypted);
  365. // Decrypt data
  366. $decrypt = Encryption\Crypt::keyDecrypt($crypted, $pair1['privateKey']);
  367. $this->assertEquals($this->dataUrl, $decrypt);
  368. }
  369. /**
  370. * @medium
  371. * @brief test encryption using legacy blowfish method
  372. */
  373. function testLegacyEncryptShort() {
  374. $crypted = Encryption\Crypt::legacyEncrypt($this->dataShort, $this->pass);
  375. $this->assertNotEquals($this->dataShort, $crypted);
  376. # TODO: search inencrypted text for actual content to ensure it
  377. # genuine transformation
  378. return $crypted;
  379. }
  380. /**
  381. * @medium
  382. * @brief test decryption using legacy blowfish method
  383. * @depends testLegacyEncryptShort
  384. */
  385. function testLegacyDecryptShort($crypted) {
  386. $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass);
  387. $this->assertEquals($this->dataShort, $decrypted);
  388. }
  389. /**
  390. * @medium
  391. * @brief test encryption using legacy blowfish method
  392. */
  393. function testLegacyEncryptLong() {
  394. $crypted = Encryption\Crypt::legacyEncrypt($this->dataLong, $this->pass);
  395. $this->assertNotEquals($this->dataLong, $crypted);
  396. # TODO: search inencrypted text for actual content to ensure it
  397. # genuine transformation
  398. return $crypted;
  399. }
  400. /**
  401. * @medium
  402. * @brief test decryption using legacy blowfish method
  403. * @depends testLegacyEncryptLong
  404. */
  405. function testLegacyDecryptLong($crypted) {
  406. $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass);
  407. $this->assertEquals($this->dataLong, $decrypted);
  408. $this->assertFalse(Encryption\Crypt::getBlowfish(''));
  409. }
  410. /**
  411. * @medium
  412. * @brief test generation of legacy encryption key
  413. * @depends testLegacyDecryptShort
  414. */
  415. function testLegacyCreateKey() {
  416. // Create encrypted key
  417. $encKey = Encryption\Crypt::legacyCreateKey($this->pass);
  418. // Decrypt key
  419. $key = Encryption\Crypt::legacyBlockDecrypt($encKey, $this->pass);
  420. $this->assertTrue(is_numeric($key));
  421. // Check that key is correct length
  422. $this->assertEquals(20, strlen($key));
  423. }
  424. /**
  425. * @medium
  426. */
  427. function testRenameFile() {
  428. $filename = 'tmp-' . time();
  429. // Save long data as encrypted file using stream wrapper
  430. $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
  431. // Test that data was successfully written
  432. $this->assertTrue(is_int($cryptedFile));
  433. // Get file decrypted contents
  434. $decrypt = file_get_contents('crypt://' . $filename);
  435. $this->assertEquals($this->dataLong, $decrypt);
  436. $newFilename = 'tmp-new-' . time();
  437. $view = new \OC\Files\View('/' . $this->userId . '/files');
  438. $view->rename($filename, $newFilename);
  439. // Get file decrypted contents
  440. $newDecrypt = file_get_contents('crypt://' . $newFilename);
  441. $this->assertEquals($this->dataLong, $newDecrypt);
  442. // tear down
  443. $view->unlink($newFilename);
  444. }
  445. /**
  446. * @medium
  447. */
  448. function testMoveFileIntoFolder() {
  449. $filename = 'tmp-' . time();
  450. // Save long data as encrypted file using stream wrapper
  451. $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
  452. // Test that data was successfully written
  453. $this->assertTrue(is_int($cryptedFile));
  454. // Get file decrypted contents
  455. $decrypt = file_get_contents('crypt://' . $filename);
  456. $this->assertEquals($this->dataLong, $decrypt);
  457. $newFolder = '/newfolder' . time();
  458. $newFilename = 'tmp-new-' . time();
  459. $view = new \OC\Files\View('/' . $this->userId . '/files');
  460. $view->mkdir($newFolder);
  461. $view->rename($filename, $newFolder . '/' . $newFilename);
  462. // Get file decrypted contents
  463. $newDecrypt = file_get_contents('crypt://' . $newFolder . '/' . $newFilename);
  464. $this->assertEquals($this->dataLong, $newDecrypt);
  465. // tear down
  466. $view->unlink($newFolder);
  467. }
  468. /**
  469. * @medium
  470. */
  471. function testMoveFolder() {
  472. $view = new \OC\Files\View('/' . $this->userId . '/files');
  473. $filename = '/tmp-' . time();
  474. $folder = '/folder' . time();
  475. $view->mkdir($folder);
  476. // Save long data as encrypted file using stream wrapper
  477. $cryptedFile = file_put_contents('crypt://' . $folder . $filename, $this->dataLong);
  478. // Test that data was successfully written
  479. $this->assertTrue(is_int($cryptedFile));
  480. // Get file decrypted contents
  481. $decrypt = file_get_contents('crypt://' . $folder . $filename);
  482. $this->assertEquals($this->dataLong, $decrypt);
  483. $newFolder = '/newfolder/subfolder' . time();
  484. $view->mkdir('/newfolder');
  485. $view->rename($folder, $newFolder);
  486. // Get file decrypted contents
  487. $newDecrypt = file_get_contents('crypt://' . $newFolder . $filename);
  488. $this->assertEquals($this->dataLong, $newDecrypt);
  489. // tear down
  490. $view->unlink($newFolder);
  491. $view->unlink('/newfolder');
  492. }
  493. /**
  494. * @medium
  495. */
  496. function testChangePassphrase() {
  497. $filename = 'tmp-' . time();
  498. // Save long data as encrypted file using stream wrapper
  499. $cryptedFile = file_put_contents('crypt://' . $filename, $this->dataLong);
  500. // Test that data was successfully written
  501. $this->assertTrue(is_int($cryptedFile));
  502. // Get file decrypted contents
  503. $decrypt = file_get_contents('crypt://' . $filename);
  504. $this->assertEquals($this->dataLong, $decrypt);
  505. // change password
  506. \OC_User::setPassword($this->userId, 'test', null);
  507. // relogin
  508. $params['uid'] = $this->userId;
  509. $params['password'] = 'test';
  510. OCA\Encryption\Hooks::login($params);
  511. // Get file decrypted contents
  512. $newDecrypt = file_get_contents('crypt://' . $filename);
  513. $this->assertEquals($this->dataLong, $newDecrypt);
  514. // tear down
  515. // change password back
  516. \OC_User::setPassword($this->userId, $this->pass);
  517. $view = new \OC\Files\View('/' . $this->userId . '/files');
  518. $view->unlink($filename);
  519. }
  520. /**
  521. * @medium
  522. */
  523. function testViewFilePutAndGetContents() {
  524. $filename = '/tmp-' . time();
  525. $view = new \OC\Files\View('/' . $this->userId . '/files');
  526. // Save short data as encrypted file using stream wrapper
  527. $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
  528. // Test that data was successfully written
  529. $this->assertTrue(is_int($cryptedFile));
  530. // Get file decrypted contents
  531. $decrypt = $view->file_get_contents($filename);
  532. $this->assertEquals($this->dataShort, $decrypt);
  533. // Save long data as encrypted file using stream wrapper
  534. $cryptedFileLong = $view->file_put_contents($filename, $this->dataLong);
  535. // Test that data was successfully written
  536. $this->assertTrue(is_int($cryptedFileLong));
  537. // Get file decrypted contents
  538. $decryptLong = $view->file_get_contents($filename);
  539. $this->assertEquals($this->dataLong, $decryptLong);
  540. // tear down
  541. $view->unlink($filename);
  542. }
  543. /**
  544. * @large
  545. */
  546. function testTouchExistingFile() {
  547. $filename = '/tmp-' . time();
  548. $view = new \OC\Files\View('/' . $this->userId . '/files');
  549. // Save short data as encrypted file using stream wrapper
  550. $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
  551. // Test that data was successfully written
  552. $this->assertTrue(is_int($cryptedFile));
  553. $view->touch($filename);
  554. // Get file decrypted contents
  555. $decrypt = $view->file_get_contents($filename);
  556. $this->assertEquals($this->dataShort, $decrypt);
  557. // tear down
  558. $view->unlink($filename);
  559. }
  560. /**
  561. * @medium
  562. */
  563. function testTouchFile() {
  564. $filename = '/tmp-' . time();
  565. $view = new \OC\Files\View('/' . $this->userId . '/files');
  566. $view->touch($filename);
  567. // Save short data as encrypted file using stream wrapper
  568. $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
  569. // Test that data was successfully written
  570. $this->assertTrue(is_int($cryptedFile));
  571. // Get file decrypted contents
  572. $decrypt = $view->file_get_contents($filename);
  573. $this->assertEquals($this->dataShort, $decrypt);
  574. // tear down
  575. $view->unlink($filename);
  576. }
  577. /**
  578. * @medium
  579. */
  580. function testFopenFile() {
  581. $filename = '/tmp-' . time();
  582. $view = new \OC\Files\View('/' . $this->userId . '/files');
  583. // Save short data as encrypted file using stream wrapper
  584. $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
  585. // Test that data was successfully written
  586. $this->assertTrue(is_int($cryptedFile));
  587. $handle = $view->fopen($filename, 'r');
  588. // Get file decrypted contents
  589. $decrypt = fgets($handle);
  590. $this->assertEquals($this->dataShort, $decrypt);
  591. // tear down
  592. $view->unlink($filename);
  593. }
  594. }