]> source.dussan.org Git - nextcloud-server.git/commitdiff
Added IV for ext storage password encryption
authorVincent Petry <pvince81@owncloud.com>
Wed, 19 Mar 2014 10:42:22 +0000 (11:42 +0100)
committerVincent Petry <pvince81@owncloud.com>
Wed, 19 Mar 2014 10:42:22 +0000 (11:42 +0100)
apps/files_external/lib/config.php
lib/public/util.php

index 05cc88c5d579e8e92d8de136e40201272fcd931b..0a68de1cdb17981816268218bf52c490a7ddc13c 100755 (executable)
@@ -39,9 +39,6 @@ class OC_Mount_Config {
        // whether to skip backend test (for unit tests, as this static class is not mockable)
        public static $skipTest = false;
 
-       // password encryption cipher
-       private static $cipher;
-
        /**
        * Get details on each of the external storage backends, used for the mount config UI
        * If a custom UI is needed, add the key 'custom' and a javascript file with that name will be loaded
@@ -555,7 +552,7 @@ class OC_Mount_Config {
         */
        private static function encryptPasswords($options) {
                if (isset($options['password'])) {
-                       $options['password_encrypted'] = base64_encode(self::getCipher()->encrypt($options['password']));
+                       $options['password_encrypted'] = self::encryptPassword($options['password']);
                        unset($options['password']);
                }
                return $options;
@@ -569,20 +566,46 @@ class OC_Mount_Config {
        private static function decryptPasswords($options) {
                // note: legacy options might still have the unencrypted password in the "password" field
                if (isset($options['password_encrypted'])) {
-                       $options['password'] = self::getCipher()->decrypt(base64_decode($options['password_encrypted']));
+                       $options['password'] = self::decryptPassword($options['password_encrypted']);
                        unset($options['password_encrypted']);
                }
                return $options;
        }
 
+       /**
+        * Encrypt a single password
+        * @param string $password plain text password
+        * @return encrypted password
+        */
+       private static function encryptPassword($password) {
+               $cipher = self::getCipher();
+               $iv = \OCP\Util::generateRandomBytes(16);
+               $cipher->setIV($iv);
+               return base64_encode($iv . $cipher->encrypt($password));
+       }
+
+       /**
+        * Decrypts a single password
+        * @param string $encryptedPassword encrypted password
+        * @return plain text password
+        */
+       private static function decryptPassword($encryptedPassword) {
+               $cipher = self::getCipher();
+               $binaryPassword = base64_decode($encryptedPassword);
+               $iv = substr($binaryPassword, 0, 16);
+               $cipher->setIV($iv);
+               $binaryPassword = substr($binaryPassword, 16);
+               return $cipher->decrypt($binaryPassword);
+       }
+
        /**
         * Returns the encryption cipher
         */
        private static function getCipher() {
-               if (!isset(self::$cipher)) {
-                       self::$cipher = new Crypt_AES(CRYPT_AES_MODE_CBC);
-                       self::$cipher->setKey(\OCP\Config::getSystemValue('passwordsalt'));
-               }
-               return self::$cipher;
+               // note: not caching this to make it thread safe as we'll use
+               // a different IV for each password
+               $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC);
+               $cipher->setKey(\OCP\Config::getSystemValue('passwordsalt'));
+               return $cipher;
        }
 }
index 585c5d226341785dea867c33fb91e0e0310f521f..f4d749c104b3b878d93911497e938de05dacc4a2 100644 (file)
@@ -495,4 +495,13 @@ class Util {
        public static function isValidFileName($file) {
                return \OC_Util::isValidFileName($file);
        }
+
+       /**
+        * @brief Generates a cryptographic secure pseudo-random string
+        * @param Int $length of the random string
+        * @return String
+        */
+       public static function generateRandomBytes($length = 30) {
+               return \OC_Util::generateRandomBytes($length);
+       }
 }