]> source.dussan.org Git - nextcloud-server.git/commitdiff
Development snapshot
authorSam Tuke <samtuke@owncloud.com>
Sat, 5 Jan 2013 17:12:23 +0000 (17:12 +0000)
committerSam Tuke <samtuke@owncloud.com>
Sat, 5 Jan 2013 17:12:23 +0000 (17:12 +0000)
Crypt{} & Util{} unit tests now passing locally
Added keymanager unit tests

apps/files_encryption/hooks/hooks.php
apps/files_encryption/lib/crypt.php
apps/files_encryption/lib/keymanager.php
apps/files_encryption/lib/proxy.php
apps/files_encryption/lib/stream.php
apps/files_encryption/tests/crypt.php
apps/files_encryption/tests/keymanager.php

index 7545520fa7833d79b6442e83e4c5d060f8efb571..59bf4921913d4605572cb9200b565d60aad920b3 100644 (file)
@@ -54,7 +54,7 @@ class Hooks {
                \r
                        \OC_FileProxy::$enabled = false;\r
                        \r
-                       $encryptedKey = Keymanager::getPrivateKey( $params['uid'], $view );\r
+                       $encryptedKey = Keymanager::getPrivateKey( $view, $params['uid'] );\r
                        \r
                        \OC_FileProxy::$enabled = true;\r
                        \r
index 7895a5dd7b04334159fde85b08edf570c73b1ac7..4e2128e89f498f474e776e944e183a76e16d73b7 100755 (executable)
@@ -628,7 +628,7 @@ class Crypt {
        public static function changekeypasscode($oldPassword, $newPassword) {\r
 \r
                if(\OCP\User::isLoggedIn()){\r
-                       $key = Keymanager::getPrivateKey();\r
+                       $key = Keymanager::getPrivateKey( $user, $view );\r
                        if ( ($key = Crypt::symmetricDecryptFileContent($key,$oldpasswd)) ) {\r
                                if ( ($key = Crypt::symmetricEncryptFileContent($key, $newpasswd)) ) {\r
                                        Keymanager::setPrivateKey($key);\r
index d3be166add2ab516792468e195f4fa7fcfd9e3b4..818cd1a154d635e76a740e8b468aad712b10aafa 100755 (executable)
@@ -23,7 +23,8 @@
 namespace OCA\Encryption;\r
 \r
 /**\r
- * This class provides basic operations to read/write encryption keys from/to the filesystem \r
+ * @brief Class to manage storage and retrieval of encryption keys\r
+ * @note Where a method requires a view object, it's root must be '/'\r
  */\r
 class Keymanager {\r
        \r
@@ -35,60 +36,46 @@ class Keymanager {
         * @return string private key or false\r
         * @note the key returned by this method must be decrypted before use\r
         */\r
-       public static function getPrivateKey( $user, $view ) {\r
+       public static function getPrivateKey( $view, $user ) {\r
        \r
-               $view->chroot( '/' . $user . '/' . 'files_encryption' );\r
-               return $view->file_get_contents( '/' . $user.'.private.key' );\r
-               \r
+               return $view->file_get_contents( '/' . $user . '/' . 'files_encryption' . '/' . $user.'.private.key' );\r
        }\r
 \r
        /**\r
         * @brief retrieve public key for a specified user\r
         * @return string public key or false\r
         */\r
-       public static function getPublicKey( $userId = NULL ) {\r
-       \r
-               // If the username wasn't specified, fetch it\r
-               if ( ! $userId ) {\r
-               \r
-                       $userId = \OCP\User::getUser(); \r
-               \r
-               }\r
+       public static function getPublicKey( $view, $userId ) {\r
                \r
-               // Create new view with the right\r
-               $view = new \OC_FilesystemView( '/public-keys/' );\r
-               \r
-               return $view->file_get_contents( '/' . $userId . '.public.key' );\r
+               return $view->file_get_contents( '/public-keys/' . '/' . $userId . '.public.key' );\r
                \r
        }\r
        \r
        /**\r
         * @brief retrieve both keys from a user (private and public)\r
-        *\r
-        * @return string private key or false\r
+        * @return array keys: privateKey, publicKey\r
         */\r
-       public static function getUserKeys() {\r
+       public static function getUserKeys( $view, $userId ) {\r
        \r
-       return array(\r
-                       'privatekey' => self::getPrivateKey(),\r
-                       'publickey' => self::getPublicKey(),\r
+               return array(\r
+                       'publicKey' => self::getPublicKey( $view, $userId )\r
+                       , 'privateKey' => self::getPrivateKey( $view, $userId )\r
                );\r
        \r
        }\r
        \r
        /**\r
-        * @brief retrieve a list of the public key from all users with access to the file\r
-        *\r
-        * @param string path to file\r
+        * @brief Retrieve public keys of all users with access to a file\r
+        * @param string $path Path to file\r
         * @return array of public keys for the given file\r
+        * @note Checks that the sharing app is enabled should be performed \r
+        * by client code, that isn't checked here\r
         */\r
-       public static function getPublicKeys( $path ) {\r
-       \r
-               $userId = \OCP\User::getUser();\r
+       public static function getPublicKeys( $view, $userId, $filePath ) {\r
                \r
                $path = ltrim( $path, '/' );\r
                \r
-               $filepath = '/'.$userId.'/files/'.$path;\r
+               $filepath = '/' . $userId . '/files/' . $filePath;\r
                \r
                // Check if sharing is enabled\r
                if ( OC_App::isEnabled( 'files_sharing' ) ) {\r
@@ -157,34 +144,30 @@ class Keymanager {
        \r
        /**\r
         * @brief retrieve keyfile for an encrypted file\r
-        *\r
         * @param string file name\r
         * @return string file key or false\r
         * @note The keyfile returned is asymmetrically encrypted. Decryption\r
         * of the keyfile must be performed by client code\r
         */\r
-       public static function getFileKey( $path, $staticUserClass = 'OCP\User' ) {\r
+       public static function getFileKey( $view, $userId, $filePath ) {\r
                \r
-               $keypath = ltrim( $path, '/' );\r
-               $user = $staticUserClass::getUser();\r
+               $filePath_f = ltrim( $filePath, '/' );\r
 \r
-//             // update $keypath and $user if path point to a file shared by someone else\r
+//             // update $keypath and $userId if path point to a file shared by someone else\r
 //             $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" );\r
 //             \r
-//             $result = $query->execute( array ('/'.$user.'/files/'.$keypath, $user));\r
+//             $result = $query->execute( array ('/'.$userId.'/files/'.$keypath, $userId));\r
 //             \r
 //             if ($row = $result->fetchRow()) {\r
 //             \r
 //                     $keypath = $row['source'];\r
 //                     $keypath_parts = explode( '/', $keypath );\r
-//                     $user = $keypath_parts[1];\r
-//                     $keypath = str_replace( '/' . $user . '/files/', '', $keypath );\r
+//                     $userId = $keypath_parts[1];\r
+//                     $keypath = str_replace( '/' . $userId . '/files/', '', $keypath );\r
 //                     \r
 //             }\r
                \r
-               $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/');\r
-               \r
-               return $view->file_get_contents( $keypath . '.key' );\r
+               return $this->view->file_get_contents( '/' . $userId . '/files_encryption/keyfiles/' . $filePath_f );\r
                \r
        }\r
        \r
index 9c7b5f01afc9ca79e19ea9e3090fff7f1196c89f..272d0a5509fd30c84bf8d7a8877b6297d7e30639 100644 (file)
@@ -91,6 +91,10 @@ class Proxy extends \OC_FileProxy {
                
                        if ( !is_resource( $data ) ) { //stream put contents should have been converted to fopen
                        
+                               $userId = \OCP\USER::getUser();
+                               
+                               $rootView = new \OC_FilesystemView( '/' );
+                       
                                // Set the filesize for userland, before encrypting
                                $size = strlen( $data );
                                
@@ -98,7 +102,7 @@ class Proxy extends \OC_FileProxy {
                                \OC_FileProxy::$enabled = false;
                                
                                // Encrypt plain data and fetch key
-                               $encrypted = Crypt::keyEncryptKeyfile( $data, Keymanager::getPublicKey() );
+                               $encrypted = Crypt::keyEncryptKeyfile( $data, Keymanager::getPublicKey( $rootView, $userId ) );
                                
                                // Replace plain content with encrypted content by reference
                                $data = $encrypted['data'];
@@ -110,7 +114,7 @@ class Proxy extends \OC_FileProxy {
                                $filePath = '/' . implode( '/', $filePath );
                                
                                # TODO: make keyfile dir dynamic from app config
-                               $view = new \OC_FilesystemView( '/' . \OCP\USER::getUser() . '/files_encryption/keyfiles' );
+                               $view = new \OC_FilesystemView( '/' . $userId . '/files_encryption/keyfiles' );
                                
                                // Save keyfile for newly encrypted file in parallel directory tree
                                Keymanager::setFileKey( $filePath, $encrypted['key'], $view, '\OC_DB' );
index dcdad7ee5612e62fd42b2f418c257304e3d0572d..fc1b9808cc5af594dbc216c8e756a1a406ace7b3 100644 (file)
@@ -63,7 +63,8 @@ class Stream {
        private $publicKey;
        private $keyfile;
        private $encKeyfile;
-       private static $view;
+       private static $view; // a fsview object set to user dir
+       private $rootView; // a fsview object set to '/'
 
        public function stream_open( $path, $mode, $options, &$opened_path ) {
        
@@ -76,6 +77,13 @@ class Stream {
 
                }
                
+               // Set rootview object if necessary
+               if ( ! $this->rootView ) {
+
+                       $this->rootView = new \OC_FilesystemView( $this->userId . '/' );
+
+               }
+               
                $this->userId = \OCP\User::getUser();
                
                // Get the bare file path
@@ -332,7 +340,7 @@ class Stream {
                
                        $this->keyfile = Crypt::generateKey();
                        
-                       $this->publicKey = Keymanager::getPublicKey( $this->userId );
+                       $this->publicKey = Keymanager::getPublicKey( $this->rootView, $this->userId );
                        
                        $this->encKeyfile = Crypt::keyEncrypt( $this->keyfile, $this->publicKey );
                        
index e64ec15c82f14416355ebae9afddd47fbbab5699..446af7cfa09c26e77e24288b387bcde120f00a6d 100755 (executable)
@@ -7,21 +7,6 @@
  * See the COPYING-README file.
  */
 
-// Load mockery files
-require_once 'Mockery/Loader.php';
-require_once 'Hamcrest/Hamcrest.php';
-$loader = new \Mockery\Loader;
-$loader->register();
-
-use \Mockery as m;
-
-// Overload Session{} with a mock object before it is included
-$adminEncPriKey = realpath( dirname(__FILE__).'/../../../data/admin/files_encryption/admin.private.key' );
-$adminDePriKey = OCA\Encryption\Crypt::symmetricDecryptFileContent( $adminEncPriKey, 'admin' );
-
-$mockSession = m::mock('overload:OCA\Encryption\Session');
-$mockSession->shouldReceive( 'getPrivateKey' )->andReturn( file_get_contents( $adminDePriKey ) );
-
 //require_once "PHPUnit/Framework/TestCase.php";
 require_once realpath( dirname(__FILE__).'/../../../3rdparty/Crypt_Blowfish/Blowfish.php' );
 require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
@@ -38,7 +23,13 @@ use OCA\Encryption;
 // encryption key needs to be saved in the session
 \OC_User::login( 'admin', 'admin' );
 
-//trigger_error("session = ".var_export($_SESSION, 1));
+/**
+ * @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 {
        
@@ -66,8 +57,6 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
        
        function tearDown() {
        
-               m::close();
-       
        }
 
        function testGenerateKey() {
@@ -247,7 +236,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
                $this->assertNotEquals( $this->dataShort, $retreivedCryptedFile );
                
                // Get private key
-               $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->userId, $this->view );
+               $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
                
                $decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
                
@@ -303,7 +292,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
                
                
                // Get private key
-               $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->userId, $this->view );
+               $encryptedPrivateKey = Encryption\Keymanager::getPrivateKey( $this->view, $this->userId );
                
                $decryptedPrivateKey = Encryption\Crypt::symmetricDecryptFileContent( $encryptedPrivateKey, $this->pass );
                
index c762310dcc51952c335fe10d041dd1736a0bbd34..e31bbe2ab27518810480b5dec6e10b21a4bb8500 100644 (file)
@@ -25,10 +25,14 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase {
                $this->data = realpath( dirname(__FILE__).'/../lib/crypt.php' );
                $this->user = 'admin';
                $this->passphrase = 'admin';
+               $this->filePath = '/testing';
                $this->view = new \OC_FilesystemView( '' );
                
                // Disable encryption proxy to prevent recursive calls
                \OC_FileProxy::$enabled = false;
+               
+               // Notify system which iser is logged in etc.
+               \OC_User::setUserId( 'admin' );
        
        }
        
@@ -38,17 +42,29 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase {
                
        }
 
-       function testGetEncryptedPrivateKey() {
+       function testGetPrivateKey() {
        
-               $key = Encryption\Keymanager::getPrivateKey( $this->user, $this->view );
-               
-               $this->assertEquals( 2302, strlen( $key ) );
+               $key = Encryption\Keymanager::getPrivateKey( $this->view, $this->user );
+                
+                
+                // 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->user );
+               
+               $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
+               # NOTE: This cannot be tested until we are able to break out 
+               # of the FileSystemView data directory root
        
 //             $key = Crypt::symmetricEncryptFileContentKeyfile( $this->data, 'hat' );
 //             
@@ -62,21 +78,39 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase {
        
        }
        
-       function testGetDecryptedPrivateKey() {
+       function testGetPrivateKey_decrypt() {
        
-               $key = Encryption\Keymanager::getPrivateKey( $this->user, $this->view );
+               $key = Encryption\Keymanager::getPrivateKey( $this->view, $this->user );
                
                # TODO: replace call to Crypt with a mock object?
                $decrypted = Encryption\Crypt::symmetricDecryptFileContent( $key, $this->passphrase );
                
-               var_dump($decrypted);
-               
-               $this->assertEquals( 1708, strlen( $decrypted ) );
+               $this->assertEquals( 1704, strlen( $decrypted ) );
                
                $this->assertEquals( '-----BEGIN PRIVATE KEY-----', substr( $decrypted, 0, 27 ) );
        
        }
        
+       function testGetUserKeys() {
+       
+               $keys = Encryption\Keymanager::getUserKeys( $this->view, $this->user );
+               
+               $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->user, $this->filePath );
+       
+       }
        
 }