summaryrefslogtreecommitdiffstats
path: root/apps/files_encryption/lib/keymanager.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_encryption/lib/keymanager.php')
-rw-r--r--apps/files_encryption/lib/keymanager.php500
1 files changed, 0 insertions, 500 deletions
diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
deleted file mode 100644
index 5e33372e9c6..00000000000
--- a/apps/files_encryption/lib/keymanager.php
+++ /dev/null
@@ -1,500 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Christopher Schäpers <kondou@ts.unde.re>
- * @author Florin Peter <github@florin-peter.de>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
- * @author Sam Tuke <mail@samtuke.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Encryption;
-
-/**
- * Class to manage storage and retrieval of encryption keys
- * @note Where a method requires a view object, it's root must be '/'
- */
-class Keymanager {
-
- // base dir where all the file related keys are stored
- private static $keys_base_dir = '/files_encryption/keys/';
- private static $encryption_base_dir = '/files_encryption';
- private static $public_key_dir = '/files_encryption/public_keys';
-
- private static $key_cache = array(); // cache keys
-
- /**
- * read key from hard disk
- *
- * @param string $path to key
- * @param \OC\Files\View $view
- * @return string|bool either the key or false
- */
- private static function getKey($path, $view) {
-
- $key = false;
-
- if (isset(self::$key_cache[$path])) {
- $key = self::$key_cache[$path];
- } else {
-
- /** @var \OCP\Files\Storage $storage */
- list($storage, $internalPath) = $view->resolvePath($path);
-
- if ($storage->file_exists($internalPath)) {
- $key = $storage->file_get_contents($internalPath);
- self::$key_cache[$path] = $key;
- }
-
- }
-
- return $key;
- }
-
- /**
- * write key to disk
- *
- *
- * @param string $path path to key directory
- * @param string $name key name
- * @param string $key key
- * @param \OC\Files\View $view
- * @return bool
- */
- private static function setKey($path, $name, $key, $view) {
- self::keySetPreparation($view, $path);
-
- /** @var \OCP\Files\Storage $storage */
- $pathToKey = \OC\Files\Filesystem::normalizePath($path . '/' . $name);
- list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($pathToKey);
- $result = $storage->file_put_contents($internalPath, $key);
-
- if (is_int($result) && $result > 0) {
- self::$key_cache[$pathToKey] = $key;
- return true;
- }
-
- return false;
- }
-
- /**
- * retrieve the ENCRYPTED private key from a user
- *
- * @param \OC\Files\View $view
- * @param string $user
- * @return string private key or false (hopefully)
- * @note the key returned by this method must be decrypted before use
- */
- public static function getPrivateKey(\OC\Files\View $view, $user) {
- $path = '/' . $user . '/' . 'files_encryption' . '/' . $user . '.privateKey';
- return self::getKey($path, $view);
- }
-
- /**
- * retrieve public key for a specified user
- * @param \OC\Files\View $view
- * @param string $userId
- * @return string public key or false
- */
- public static function getPublicKey(\OC\Files\View $view, $userId) {
- $path = self::$public_key_dir . '/' . $userId . '.publicKey';
- return self::getKey($path, $view);
- }
-
- public static function getPublicKeyPath() {
- return self::$public_key_dir;
- }
-
- /**
- * Retrieve a user's public and private key
- * @param \OC\Files\View $view
- * @param string $userId
- * @return array keys: privateKey, publicKey
- */
- public static function getUserKeys(\OC\Files\View $view, $userId) {
-
- return array(
- 'publicKey' => self::getPublicKey($view, $userId),
- 'privateKey' => self::getPrivateKey($view, $userId)
- );
-
- }
-
- /**
- * Retrieve public keys for given users
- * @param \OC\Files\View $view
- * @param array $userIds
- * @return array of public keys for the specified users
- */
- public static function getPublicKeys(\OC\Files\View $view, array $userIds) {
-
- $keys = array();
- foreach ($userIds as $userId) {
- $keys[$userId] = self::getPublicKey($view, $userId);
- }
-
- return $keys;
-
- }
-
- /**
- * store file encryption key
- *
- * @param \OC\Files\View $view
- * @param \OCA\Files_Encryption\Util $util
- * @param string $path relative path of the file, including filename
- * @param string $catfile keyfile content
- * @return bool true/false
- * @note The keyfile is not encrypted here. Client code must
- * asymmetrically encrypt the keyfile before passing it to this method
- */
- public static function setFileKey(\OC\Files\View $view, $util, $path, $catfile) {
- $path = self::getKeyPath($view, $util, $path);
- return self::setKey($path, 'fileKey', $catfile, $view);
-
- }
-
- /**
- * get path to key folder for a given file
- *
- * @param \OC\Files\View $view relative to data directory
- * @param \OCA\Files_Encryption\Util $util
- * @param string $path path to the file, relative to the users file directory
- * @return string
- */
- public static function getKeyPath($view, $util, $path) {
-
- if ($view->is_dir('/' . \OCP\User::getUser() . '/' . $path)) {
- throw new Exception\EncryptionException('file was expected but directoy was given', Exception\EncryptionException::GENERIC);
- }
-
- list($owner, $filename) = $util->getUidAndFilename($path);
- $filename = Helper::stripPartialFileExtension($filename);
- $filePath_f = ltrim($filename, '/');
-
- // in case of system wide mount points the keys are stored directly in the data directory
- if ($util->isSystemWideMountPoint($filename)) {
- $keyPath = self::$keys_base_dir . $filePath_f . '/';
- } else {
- $keyPath = '/' . $owner . self::$keys_base_dir . $filePath_f . '/';
- }
-
- return $keyPath;
- }
-
- /**
- * get path to file key for a given file
- *
- * @param \OC\Files\View $view relative to data directory
- * @param \OCA\Files_Encryption\Util $util
- * @param string $path path to the file, relative to the users file directory
- * @return string
- */
- public static function getFileKeyPath($view, $util, $path) {
- $keyDir = self::getKeyPath($view, $util, $path);
- return $keyDir . 'fileKey';
- }
-
- /**
- * get path to share key for a given user
- *
- * @param \OC\Files\View $view relateive to data directory
- * @param \OCA\Files_Encryption\Util $util
- * @param string $path path to file relative to the users files directoy
- * @param string $uid user for whom we want the share-key path
- * @retrun string
- */
- public static function getShareKeyPath($view, $util, $path, $uid) {
- $keyDir = self::getKeyPath($view, $util, $path);
- return $keyDir . $uid . '.shareKey';
- }
-
- /**
- * delete key
- *
- * @param \OC\Files\View $view
- * @param string $path
- * @return boolean
- */
- private static function deleteKey($view, $path) {
- $normalizedPath = \OC\Files\Filesystem::normalizePath($path);
- $result = $view->unlink($normalizedPath);
-
- if ($result) {
- unset(self::$key_cache[$normalizedPath]);
- return true;
- }
-
- return false;
- }
-
- /**
- * delete public key from a given user
- *
- * @param \OC\Files\View $view
- * @param string $uid user
- * @return bool
- */
- public static function deletePublicKey($view, $uid) {
-
- $result = false;
-
- if (!\OCP\User::userExists($uid)) {
- $publicKey = self::$public_key_dir . '/' . $uid . '.publicKey';
- self::deleteKey($view, $publicKey);
- }
-
- return $result;
- }
-
- /**
- * check if public key for user exists
- *
- * @param \OC\Files\View $view
- * @param string $uid
- */
- public static function publicKeyExists($view, $uid) {
- return $view->file_exists(self::$public_key_dir . '/'. $uid . '.publicKey');
- }
-
-
-
- /**
- * retrieve keyfile for an encrypted file
- * @param \OC\Files\View $view
- * @param \OCA\Files_Encryption\Util $util
- * @param string|false $filePath
- * @return string file key or false
- * @note The keyfile returned is asymmetrically encrypted. Decryption
- * of the keyfile must be performed by client code
- */
- public static function getFileKey($view, $util, $filePath) {
- $path = self::getFileKeyPath($view, $util, $filePath);
- return self::getKey($path, $view);
- }
-
- /**
- * store private key from the user
- * @param string $key
- * @return bool
- * @note Encryption of the private key must be performed by client code
- * as no encryption takes place here
- */
- public static function setPrivateKey($key, $user = '') {
-
- $user = $user === '' ? \OCP\User::getUser() : $user;
- $path = '/' . $user . '/files_encryption';
- $header = Crypt::generateHeader();
-
- return self::setKey($path, $user . '.privateKey', $header . $key, new \OC\Files\View());
-
- }
-
- /**
- * check if recovery key exists
- *
- * @param \OC\Files\View $view
- * @return bool
- */
- public static function recoveryKeyExists($view) {
-
- $result = false;
-
- $recoveryKeyId = Helper::getRecoveryKeyId();
- if ($recoveryKeyId) {
- $result = ($view->file_exists(self::$public_key_dir . '/' . $recoveryKeyId . ".publicKey")
- && $view->file_exists(self::$encryption_base_dir . '/' . $recoveryKeyId . ".privateKey"));
- }
-
- return $result;
- }
-
- public static function publicShareKeyExists($view) {
- $result = false;
-
- $publicShareKeyId = Helper::getPublicShareKeyId();
- if ($publicShareKeyId) {
- $result = ($view->file_exists(self::$public_key_dir . '/' . $publicShareKeyId . ".publicKey")
- && $view->file_exists(self::$encryption_base_dir . '/' . $publicShareKeyId . ".privateKey"));
-
- }
-
- return $result;
- }
-
- /**
- * store public key from the user
- * @param string $key
- * @param string $user
- *
- * @return bool
- */
- public static function setPublicKey($key, $user = '') {
-
- $user = $user === '' ? \OCP\User::getUser() : $user;
-
- return self::setKey(self::$public_key_dir, $user . '.publicKey', $key, new \OC\Files\View('/'));
- }
-
- /**
- * write private system key (recovery and public share key) to disk
- *
- * @param string $key encrypted key
- * @param string $keyName name of the key
- * @return boolean
- */
- public static function setPrivateSystemKey($key, $keyName) {
-
- $keyName = $keyName . '.privateKey';
- $header = Crypt::generateHeader();
-
- return self::setKey(self::$encryption_base_dir, $keyName,$header . $key, new \OC\Files\View());
- }
-
- /**
- * read private system key (recovery and public share key) from disk
- *
- * @param string $keyName name of the key
- * @return string|boolean private system key or false
- */
- public static function getPrivateSystemKey($keyName) {
- $path = $keyName . '.privateKey';
- return self::getKey($path, new \OC\Files\View(self::$encryption_base_dir));
- }
-
- /**
- * store multiple share keys for a single file
- * @param \OC\Files\View $view
- * @param \OCA\Files_Encryption\Util $util
- * @param string $path
- * @param array $shareKeys
- * @return bool
- */
- public static function setShareKeys($view, $util, $path, array $shareKeys) {
-
- // in case of system wide mount points the keys are stored directly in the data directory
- $basePath = Keymanager::getKeyPath($view, $util, $path);
-
- self::keySetPreparation($view, $basePath);
-
- $result = true;
-
- foreach ($shareKeys as $userId => $shareKey) {
- if (!self::setKey($basePath, $userId . '.shareKey', $shareKey, $view)) {
- // If any of the keys are not set, flag false
- $result = false;
- }
- }
-
- // Returns false if any of the keys weren't set
- return $result;
- }
-
- /**
- * retrieve shareKey for an encrypted file
- * @param \OC\Files\View $view
- * @param string $userId
- * @param \OCA\Files_Encryption\Util $util
- * @param string $filePath
- * @return string file key or false
- * @note The sharekey returned is encrypted. Decryption
- * of the keyfile must be performed by client code
- */
- public static function getShareKey($view, $userId, $util, $filePath) {
- $path = self::getShareKeyPath($view, $util, $filePath, $userId);
- return self::getKey($path, $view);
- }
-
- /**
- * Delete a single user's shareKey for a single file
- *
- * @param \OC\Files\View $view relative to data/
- * @param array $userIds list of users we want to remove
- * @param string $keyPath
- * @param string $owner the owner of the file
- * @param string $ownerPath the owners name of the file for which we want to remove the users relative to data/user/files
- */
- public static function delShareKey($view, $userIds, $keysPath, $owner, $ownerPath) {
-
- $key = array_search($owner, $userIds, true);
- if ($key !== false && $view->file_exists('/' . $owner . '/files/' . $ownerPath)) {
- unset($userIds[$key]);
- }
-
- self::recursiveDelShareKeys($keysPath, $userIds, $view);
-
- }
-
- /**
- * recursively delete share keys from given users
- *
- * @param string $dir directory
- * @param array $userIds user ids for which the share keys should be deleted
- * @param \OC\Files\View $view view relative to data/
- */
- private static function recursiveDelShareKeys($dir, $userIds, $view) {
-
- $dirContent = $view->opendir($dir);
-
- if (is_resource($dirContent)) {
- while (($file = readdir($dirContent)) !== false) {
- if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
- if ($view->is_dir($dir . '/' . $file)) {
- self::recursiveDelShareKeys($dir . '/' . $file, $userIds, $view);
- } else {
- foreach ($userIds as $userId) {
- if ($userId . '.shareKey' === $file) {
- \OCP\Util::writeLog('files_encryption', 'recursiveDelShareKey: delete share key: ' . $file, \OCP\Util::DEBUG);
- self::deleteKey($view, $dir . '/' . $file);
- }
- }
- }
- }
- }
- closedir($dirContent);
- }
- }
-
- /**
- * Make preparations to vars and filesystem for saving a keyfile
- *
- * @param \OC\Files\View $view
- * @param string $path relatvie to the views root
- * @param string $basePath
- */
- protected static function keySetPreparation($view, $path) {
- // If the file resides within a subdirectory, create it
- if (!$view->file_exists($path)) {
- $sub_dirs = explode('/', $path);
- $dir = '';
- foreach ($sub_dirs as $sub_dir) {
- $dir .= '/' . $sub_dir;
- if (!$view->is_dir($dir)) {
- $view->mkdir($dir);
- }
- }
- }
- }
-
-}