예제 #1
0
 /**
  * @param $path raw path relative to data/
  * @param $mode
  * @param $options
  * @param $opened_path
  * @return bool
  */
 public function stream_open($path, $mode, $options, &$opened_path)
 {
     // assume that the file already exist before we decide it finally in getKey()
     $this->newFile = false;
     if (!isset($this->rootView)) {
         $this->rootView = new \OC_FilesystemView('/');
     }
     $this->session = new \OCA\Encryption\Session($this->rootView);
     $this->privateKey = $this->session->getPrivateKey();
     // rawPath is relative to the data directory
     $this->rawPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
     $this->userId = Helper::getUser($this->rawPath);
     $util = new Util($this->rootView, $this->userId);
     // get the key ID which we want to use, can be the users key or the
     // public share key
     $this->keyId = $util->getKeyId();
     // Strip identifier text from path, this gives us the path relative to data/<user>/files
     $this->relPath = Helper::stripUserFilesPath($this->rawPath);
     // if raw path doesn't point to a real file, check if it is a version or a file in the trash bin
     if ($this->relPath === false) {
         $this->relPath = Helper::getPathToRealFile($this->rawPath);
     }
     if ($this->relPath === false) {
         \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '" expecting a path to "files", "files_versions" or "cache"', \OCP\Util::ERROR);
         return false;
     }
     // Disable fileproxies so we can get the file size and open the source file without recursive encryption
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     if ($mode === 'w' or $mode === 'w+' or $mode === 'wb' or $mode === 'wb+') {
         // We're writing a new file so start write counter with 0 bytes
         $this->size = 0;
         $this->unencryptedSize = 0;
     } else {
         if ($this->privateKey === false) {
             // if private key is not valid redirect user to a error page
             \OCA\Encryption\Helper::redirectToErrorPage($this->session);
         }
         $this->size = $this->rootView->filesize($this->rawPath, $mode);
     }
     $this->handle = $this->rootView->fopen($this->rawPath, $mode);
     \OC_FileProxy::$enabled = $proxyStatus;
     if (!is_resource($this->handle)) {
         \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
     } else {
         $this->meta = stream_get_meta_data($this->handle);
     }
     return is_resource($this->handle);
 }
예제 #2
0
 /**
  * Change a user's encryption passphrase
  *
  * @param array $params keys: uid, password
  * @return boolean|null
  */
 public function setPassphrase($params)
 {
     // Get existing decrypted private key
     $privateKey = $this->session->getPrivateKey();
     $user = $this->user->getUser();
     // current logged in user changes his own password
     if ($user && $params['uid'] === $user->getUID() && $privateKey) {
         // Encrypt private key with new user pwd as passphrase
         $encryptedPrivateKey = $this->crypt->encryptPrivateKey($privateKey, $params['password'], $params['uid']);
         // Save private key
         if ($encryptedPrivateKey) {
             $this->keyManager->setPrivateKey($this->user->getUser()->getUID(), $this->crypt->generateHeader() . $encryptedPrivateKey);
         } else {
             $this->logger->error('Encryption could not update users encryption password');
         }
         // NOTE: Session does not need to be updated as the
         // private key has not changed, only the passphrase
         // used to decrypt it has changed
     } else {
         // admin changed the password for a different user, create new keys and re-encrypt file keys
         $user = $params['uid'];
         $this->initMountPoints($user);
         $recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null;
         // we generate new keys if...
         // ...we have a recovery password and the user enabled the recovery key
         // ...encryption was activated for the first time (no keys exists)
         // ...the user doesn't have any files
         if ($this->recovery->isRecoveryEnabledForUser($user) && $recoveryPassword || !$this->keyManager->userHasKeys($user) || !$this->util->userHasFiles($user)) {
             // backup old keys
             //$this->backupAllKeys('recovery');
             $newUserPassword = $params['password'];
             $keyPair = $this->crypt->createKeyPair();
             // Save public key
             $this->keyManager->setPublicKey($user, $keyPair['publicKey']);
             // Encrypt private key with new password
             $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $newUserPassword, $user);
             if ($encryptedKey) {
                 $this->keyManager->setPrivateKey($user, $this->crypt->generateHeader() . $encryptedKey);
                 if ($recoveryPassword) {
                     // if recovery key is set we can re-encrypt the key files
                     $this->recovery->recoverUsersFiles($recoveryPassword, $user);
                 }
             } else {
                 $this->logger->error('Encryption Could not update users encryption password');
             }
         }
     }
 }
예제 #3
0
 /**
  * @param $path
  * @param $uid
  * @return string
  */
 public function getFileKey($path, $uid)
 {
     $encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId, Encryption::ID);
     if (is_null($uid)) {
         $uid = $this->getPublicShareKeyId();
         $shareKey = $this->getShareKey($path, $uid);
         $privateKey = $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.privateKey', Encryption::ID);
         $privateKey = $this->crypt->decryptPrivateKey($privateKey);
     } else {
         $shareKey = $this->getShareKey($path, $uid);
         $privateKey = $this->session->getPrivateKey();
     }
     if ($encryptedFileKey && $shareKey && $privateKey) {
         return $this->crypt->multiKeyDecrypt($encryptedFileKey, $shareKey, $privateKey);
     }
     return '';
 }
예제 #4
0
 /**
  * @param $path
  * @param $mode
  * @param $options
  * @param $opened_path
  * @return bool
  */
 public function stream_open($path, $mode, $options, &$opened_path)
 {
     if (!isset($this->rootView)) {
         $this->rootView = new \OC_FilesystemView('/');
     }
     $this->session = new \OCA\Encryption\Session($this->rootView);
     $this->privateKey = $this->session->getPrivateKey($this->userId);
     $util = new Util($this->rootView, \OCP\USER::getUser());
     $this->userId = $util->getUserId();
     // Strip identifier text from path, this gives us the path relative to data/<user>/files
     $this->relPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
     // rawPath is relative to the data directory
     $this->rawPath = $util->getUserFilesDir() . $this->relPath;
     // Disable fileproxies so we can get the file size and open the source file without recursive encryption
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     if ($mode === 'w' or $mode === 'w+' or $mode === 'wb' or $mode === 'wb+') {
         // We're writing a new file so start write counter with 0 bytes
         $this->size = 0;
         $this->unencryptedSize = 0;
     } else {
         if ($this->privateKey === false) {
             // if private key is not valid redirect user to a error page
             \OCA\Encryption\Helper::redirectToErrorPage();
         }
         $this->size = $this->rootView->filesize($this->rawPath, $mode);
     }
     $this->handle = $this->rootView->fopen($this->rawPath, $mode);
     \OC_FileProxy::$enabled = $proxyStatus;
     if (!is_resource($this->handle)) {
         \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
     } else {
         $this->meta = stream_get_meta_data($this->handle);
     }
     return is_resource($this->handle);
 }
예제 #5
0
 /**
  * @depends testThatGetPrivateKeyThrowsExceptionWhenNotSet
  */
 public function testSetAndGetPrivateKey()
 {
     $this->instance->setPrivateKey('dummyPrivateKey');
     $this->assertEquals('dummyPrivateKey', $this->instance->getPrivateKey());
 }
예제 #6
0
 /**
  * Encrypt keyfile to multiple users
  * @param Session $session
  * @param array $users list of users which should be able to access the file
  * @param string $filePath path of the file to be shared
  * @return bool
  */
 public function setSharedFileKeyfiles(Session $session, array $users, $filePath)
 {
     // Make sure users are capable of sharing
     $filteredUids = $this->filterShareReadyUsers($users);
     // If we're attempting to share to unready users
     if (!empty($filteredUids['unready'])) {
         \OCP\Util::writeLog('Encryption library', 'Sharing to these user(s) failed as they are unready for encryption:"' . print_r($filteredUids['unready'], 1), \OCP\Util::WARN);
         return false;
     }
     // Get public keys for each user, ready for generating sharekeys
     $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']);
     // Note proxy status then disable it
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // Get the current users's private key for decrypting existing keyfile
     $privateKey = $session->getPrivateKey();
     try {
         // Decrypt keyfile
         $plainKeyfile = $this->decryptKeyfile($filePath, $privateKey);
         // Re-enc keyfile to (additional) sharekeys
         $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys);
     } catch (Exceptions\EncryptionException $e) {
         $msg = 'set shareFileKeyFailed (code: ' . $e->getCode() . '): ' . $e->getMessage();
         \OCP\Util::writeLog('files_encryption', $msg, \OCP\Util::FATAL);
         return false;
     } catch (\Exception $e) {
         $msg = 'set shareFileKeyFailed (unknown error): ' . $e->getMessage();
         \OCP\Util::writeLog('files_encryption', $msg, \OCP\Util::FATAL);
         return false;
     }
     // Save the recrypted key to it's owner's keyfiles directory
     // Save new sharekeys to all necessary user directory
     if (!Keymanager::setFileKey($this->view, $this, $filePath, $multiEncKey['data']) || !Keymanager::setShareKeys($this->view, $this, $filePath, $multiEncKey['keys'])) {
         \OCP\Util::writeLog('Encryption library', 'Keyfiles could not be saved for users sharing ' . $filePath, \OCP\Util::ERROR);
         return false;
     }
     // Return proxy to original status
     \OC_FileProxy::$enabled = $proxyStatus;
     return true;
 }