2013-02-05 22:43:55 +04:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ownCloud
|
|
|
|
*
|
2014-11-14 14:20:59 +03:00
|
|
|
* @copyright (C) 2014 ownCloud, Inc.
|
|
|
|
*
|
|
|
|
* @author Bjoern Schiessle <schiessle@owncloud.com>
|
2013-02-05 22:43:55 +04:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 3 of the License, or any later version.
|
|
|
|
*
|
|
|
|
* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2014-12-03 12:57:16 +03:00
|
|
|
namespace OCA\Files_Encryption;
|
2013-02-05 22:43:55 +04:00
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Class to manage storage and retrieval of encryption keys
|
2013-02-05 22:43:55 +04:00
|
|
|
* @note Where a method requires a view object, it's root must be '/'
|
|
|
|
*/
|
2013-05-27 19:26:58 +04:00
|
|
|
class Keymanager {
|
2013-05-20 00:31:00 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
// base dir where all the file related keys are stored
|
2014-11-18 19:25:36 +03:00
|
|
|
private static $keys_base_dir = '/files_encryption/keys/';
|
|
|
|
private static $encryption_base_dir = '/files_encryption';
|
|
|
|
private static $public_key_dir = '/files_encryption/public_keys';
|
2014-11-10 14:40:24 +03:00
|
|
|
|
2014-12-19 13:32:02 +03:00
|
|
|
private static $key_cache = array(); // cache keys
|
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-11-14 19:30:38 +03:00
|
|
|
* read key from hard disk
|
2013-05-20 00:31:00 +04:00
|
|
|
*
|
2014-11-14 19:30:38 +03:00
|
|
|
* @param string $path to key
|
|
|
|
* @return string|bool either the key or false
|
2013-02-05 22:43:55 +04:00
|
|
|
*/
|
2014-11-14 19:30:38 +03:00
|
|
|
private static function getKey($path, $view) {
|
2013-05-15 04:36:23 +04:00
|
|
|
|
2013-09-25 19:44:05 +04:00
|
|
|
$key = false;
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-12-19 13:32:02 +03:00
|
|
|
if (isset(self::$key_cache[$path])) {
|
|
|
|
$key = self::$key_cache[$path];
|
|
|
|
} else {
|
|
|
|
|
|
|
|
$proxyStatus = \OC_FileProxy::$enabled;
|
|
|
|
\OC_FileProxy::$enabled = false;
|
|
|
|
|
|
|
|
if ($view->file_exists($path)) {
|
|
|
|
$key = $view->file_get_contents($path);
|
|
|
|
self::$key_cache[$path] = $key;
|
|
|
|
}
|
|
|
|
|
|
|
|
\OC_FileProxy::$enabled = $proxyStatus;
|
|
|
|
|
|
|
|
}
|
2014-11-14 19:30:38 +03:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
return $key;
|
|
|
|
}
|
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
/**
|
|
|
|
* 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) {
|
|
|
|
$proxyStatus = \OC_FileProxy::$enabled;
|
|
|
|
\OC_FileProxy::$enabled = false;
|
|
|
|
|
|
|
|
self::keySetPreparation($view, $path);
|
2014-12-19 13:32:02 +03:00
|
|
|
$pathToKey = \OC\Files\Filesystem::normalizePath($path . '/' . $name);
|
|
|
|
$result = $view->file_put_contents($pathToKey, $key);
|
2014-11-14 19:30:38 +03:00
|
|
|
|
|
|
|
\OC_FileProxy::$enabled = $proxyStatus;
|
|
|
|
|
2014-12-19 13:32:02 +03:00
|
|
|
if (is_int($result) && $result > 0) {
|
|
|
|
self::$key_cache[$pathToKey] = $key;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2014-11-14 19:30:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* retrieve public key for a specified user
|
2014-05-12 18:30:39 +04:00
|
|
|
* @param \OC\Files\View $view
|
2014-05-13 15:29:25 +04:00
|
|
|
* @param string $userId
|
2013-02-05 22:43:55 +04:00
|
|
|
* @return string public key or false
|
|
|
|
*/
|
2014-05-12 18:30:39 +04:00
|
|
|
public static function getPublicKey(\OC\Files\View $view, $userId) {
|
2014-11-18 19:25:36 +03:00
|
|
|
$path = self::$public_key_dir . '/' . $userId . '.publicKey';
|
2014-11-14 19:30:38 +03:00
|
|
|
return self::getKey($path, $view);
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-18 19:25:36 +03:00
|
|
|
public static function getPublicKeyPath() {
|
|
|
|
return self::$public_key_dir;
|
|
|
|
}
|
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Retrieve a user's public and private key
|
2014-05-12 18:30:39 +04:00
|
|
|
* @param \OC\Files\View $view
|
2014-05-13 15:29:25 +04:00
|
|
|
* @param string $userId
|
2013-02-05 22:43:55 +04:00
|
|
|
* @return array keys: privateKey, publicKey
|
|
|
|
*/
|
2014-05-12 18:30:39 +04:00
|
|
|
public static function getUserKeys(\OC\Files\View $view, $userId) {
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
return array(
|
2013-05-27 22:44:38 +04:00
|
|
|
'publicKey' => self::getPublicKey($view, $userId),
|
2013-05-27 19:26:58 +04:00
|
|
|
'privateKey' => self::getPrivateKey($view, $userId)
|
2013-02-05 22:43:55 +04:00
|
|
|
);
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Retrieve public keys for given users
|
2014-05-12 18:30:39 +04:00
|
|
|
* @param \OC\Files\View $view
|
2013-03-28 21:39:12 +04:00
|
|
|
* @param array $userIds
|
|
|
|
* @return array of public keys for the specified users
|
2013-02-05 22:43:55 +04:00
|
|
|
*/
|
2014-05-12 18:30:39 +04:00
|
|
|
public static function getPublicKeys(\OC\Files\View $view, array $userIds) {
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-03-28 21:39:12 +04:00
|
|
|
$keys = array();
|
2013-05-27 19:26:58 +04:00
|
|
|
foreach ($userIds as $userId) {
|
|
|
|
$keys[$userId] = self::getPublicKey($view, $userId);
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-03-28 21:39:12 +04:00
|
|
|
return $keys;
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* store file encryption key
|
2013-02-05 22:43:55 +04:00
|
|
|
*
|
2014-05-12 18:30:39 +04:00
|
|
|
* @param \OC\Files\View $view
|
2014-12-03 18:52:44 +03:00
|
|
|
* @param \OCA\Files_Encryption\Util $util
|
2013-02-05 22:43:55 +04:00
|
|
|
* @param string $path relative path of the file, including filename
|
2013-11-27 14:46:24 +04:00
|
|
|
* @param string $catfile keyfile content
|
2013-02-05 22:43:55 +04:00
|
|
|
* @return bool true/false
|
2013-05-20 03:24:36 +04:00
|
|
|
* @note The keyfile is not encrypted here. Client code must
|
2013-02-05 22:43:55 +04:00
|
|
|
* asymmetrically encrypt the keyfile before passing it to this method
|
|
|
|
*/
|
2014-05-12 18:30:39 +04:00
|
|
|
public static function setFileKey(\OC\Files\View $view, $util, $path, $catfile) {
|
2014-11-14 19:30:38 +03:00
|
|
|
$path = self::getKeyPath($view, $util, $path);
|
|
|
|
return self::setKey($path, 'fileKey', $catfile, $view);
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-04-27 22:18:57 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-11-10 14:40:24 +03:00
|
|
|
* get path to key folder for a given file
|
|
|
|
*
|
|
|
|
* @param \OC\Files\View $view relative to data directory
|
2014-12-03 18:52:44 +03:00
|
|
|
* @param \OCA\Files_Encryption\Util $util
|
2014-11-10 14:40:24 +03:00
|
|
|
* @param string $path path to the file, relative to the users file directory
|
|
|
|
* @return string
|
2013-02-05 22:43:55 +04:00
|
|
|
*/
|
2014-11-10 14:40:24 +03:00
|
|
|
public static function getKeyPath($view, $util, $path) {
|
2013-04-27 22:18:57 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
if ($view->is_dir('/' . \OCP\User::getUser() . '/' . $path)) {
|
|
|
|
throw new Exception\EncryptionException('file was expected but directoy was given', Exception\EncryptionException::GENERIC);
|
|
|
|
}
|
2013-04-27 22:18:57 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
list($owner, $filename) = $util->getUidAndFilename($path);
|
2013-11-12 19:48:24 +04:00
|
|
|
$filename = Helper::stripPartialFileExtension($filename);
|
2013-05-27 19:26:58 +04:00
|
|
|
$filePath_f = ltrim($filename, '/');
|
2013-05-23 22:30:07 +04:00
|
|
|
|
2013-06-25 14:21:54 +04:00
|
|
|
// in case of system wide mount points the keys are stored directly in the data directory
|
2013-06-25 16:25:00 +04:00
|
|
|
if ($util->isSystemWideMountPoint($filename)) {
|
2014-11-18 19:25:36 +03:00
|
|
|
$keyPath = self::$keys_base_dir . $filePath_f . '/';
|
2013-06-25 14:21:54 +04:00
|
|
|
} else {
|
2014-11-18 19:25:36 +03:00
|
|
|
$keyPath = '/' . $owner . self::$keys_base_dir . $filePath_f . '/';
|
2013-06-25 14:21:54 +04:00
|
|
|
}
|
2013-04-25 16:56:11 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
return $keyPath;
|
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
/**
|
|
|
|
* get path to file key for a given file
|
|
|
|
*
|
|
|
|
* @param \OC\Files\View $view relative to data directory
|
2014-12-03 18:52:44 +03:00
|
|
|
* @param \OCA\Files_Encryption\Util $util
|
2014-11-10 14:40:24 +03:00
|
|
|
* @param string $path path to the file, relative to the users file directory
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function getFileKeyPath($view, $util, $path) {
|
2014-11-14 19:30:38 +03:00
|
|
|
$keyDir = self::getKeyPath($view, $util, $path);
|
|
|
|
return $keyDir . 'fileKey';
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-11-10 14:40:24 +03:00
|
|
|
* get path to share key for a given user
|
2013-02-05 22:43:55 +04:00
|
|
|
*
|
2014-11-10 14:40:24 +03:00
|
|
|
* @param \OC\Files\View $view relateive to data directory
|
2014-12-03 18:52:44 +03:00
|
|
|
* @param \OCA\Files_Encryption\Util $util
|
2014-11-10 14:40:24 +03:00
|
|
|
* @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
|
2013-02-05 22:43:55 +04:00
|
|
|
*/
|
2014-11-10 14:40:24 +03:00
|
|
|
public static function getShareKeyPath($view, $util, $path, $uid) {
|
2014-11-14 19:30:38 +03:00
|
|
|
$keyDir = self::getKeyPath($view, $util, $path);
|
|
|
|
return $keyDir . $uid . '.shareKey';
|
|
|
|
}
|
2013-06-25 18:03:03 +04:00
|
|
|
|
2014-12-19 13:32:02 +03:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
/**
|
|
|
|
* delete public key from a given user
|
|
|
|
*
|
|
|
|
* @param \OC\Files\View $view
|
|
|
|
* @param string $uid user
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function deletePublicKey($view, $uid) {
|
2014-01-31 23:39:11 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
$result = false;
|
2013-06-25 18:03:03 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
if (!\OCP\User::userExists($uid)) {
|
2014-11-18 19:25:36 +03:00
|
|
|
$publicKey = self::$public_key_dir . '/' . $uid . '.publicKey';
|
2014-12-19 13:32:02 +03:00
|
|
|
self::deleteKey($view, $publicKey);
|
2013-06-25 18:03:03 +04:00
|
|
|
}
|
2013-03-28 21:39:12 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* check if public key for user exists
|
|
|
|
*
|
|
|
|
* @param \OC\Files\View $view
|
|
|
|
* @param string $uid
|
|
|
|
*/
|
|
|
|
public static function publicKeyExists($view, $uid) {
|
2014-11-18 19:25:36 +03:00
|
|
|
return $view->file_exists(self::$public_key_dir . '/'. $uid . '.publicKey');
|
2014-11-10 14:40:24 +03:00
|
|
|
}
|
2013-03-28 21:39:12 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
/**
|
|
|
|
* retrieve keyfile for an encrypted file
|
|
|
|
* @param \OC\Files\View $view
|
2014-12-03 18:52:44 +03:00
|
|
|
* @param \OCA\Files_Encryption\Util $util
|
2014-11-10 14:40:24 +03:00
|
|
|
* @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) {
|
2014-11-14 19:30:38 +03:00
|
|
|
$path = self::getFileKeyPath($view, $util, $filePath);
|
|
|
|
return self::getKey($path, $view);
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* store private key from the user
|
2013-05-20 03:24:36 +04:00
|
|
|
* @param string $key
|
2013-02-05 22:43:55 +04:00
|
|
|
* @return bool
|
|
|
|
* @note Encryption of the private key must be performed by client code
|
|
|
|
* as no encryption takes place here
|
|
|
|
*/
|
2014-07-21 15:02:28 +04:00
|
|
|
public static function setPrivateKey($key, $user = '') {
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
$user = $user === '' ? \OCP\User::getUser() : $user;
|
|
|
|
$path = '/' . $user . '/files_encryption';
|
2014-07-21 15:02:28 +04:00
|
|
|
$header = Crypt::generateHeader();
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
return self::setKey($path, $user . '.privateKey', $header . $key, new \OC\Files\View());
|
2013-04-25 16:56:11 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
/**
|
|
|
|
* check if recovery key exists
|
|
|
|
*
|
|
|
|
* @param \OC\Files\View $view
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function recoveryKeyExists($view) {
|
|
|
|
|
|
|
|
$result = false;
|
|
|
|
|
|
|
|
$recoveryKeyId = Helper::getRecoveryKeyId();
|
|
|
|
if ($recoveryKeyId) {
|
2014-11-18 19:25:36 +03:00
|
|
|
$result = ($view->file_exists(self::$public_key_dir . '/' . $recoveryKeyId . ".publicKey")
|
|
|
|
&& $view->file_exists(self::$encryption_base_dir . '/' . $recoveryKeyId . ".privateKey"));
|
2014-06-23 19:13:56 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function publicShareKeyExists($view) {
|
|
|
|
$result = false;
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
$publicShareKeyId = Helper::getPublicShareKeyId();
|
|
|
|
if ($publicShareKeyId) {
|
2014-11-18 19:25:36 +03:00
|
|
|
$result = ($view->file_exists(self::$public_key_dir . '/' . $publicShareKeyId . ".publicKey")
|
|
|
|
&& $view->file_exists(self::$encryption_base_dir . '/' . $publicShareKeyId . ".privateKey"));
|
2014-11-14 19:30:38 +03:00
|
|
|
|
|
|
|
}
|
2013-04-25 16:56:11 +04:00
|
|
|
|
2013-05-09 20:24:07 +04:00
|
|
|
return $result;
|
2014-11-14 19:30:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* store public key from the user
|
|
|
|
* @param string $key
|
|
|
|
* @param string $user
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function setPublicKey($key, $user = '') {
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
$user = $user === '' ? \OCP\User::getUser() : $user;
|
|
|
|
|
2014-11-18 19:25:36 +03:00
|
|
|
return self::setKey(self::$public_key_dir, $user . '.publicKey', $key, new \OC\Files\View('/'));
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2014-07-21 15:02:28 +04:00
|
|
|
/**
|
|
|
|
* write private system key (recovery and public share key) to disk
|
|
|
|
*
|
|
|
|
* @param string $key encrypted key
|
2014-11-14 19:30:38 +03:00
|
|
|
* @param string $keyName name of the key
|
2014-07-21 15:02:28 +04:00
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public static function setPrivateSystemKey($key, $keyName) {
|
|
|
|
|
2014-11-14 19:30:38 +03:00
|
|
|
$keyName = $keyName . '.privateKey';
|
2014-07-21 15:02:28 +04:00
|
|
|
$header = Crypt::generateHeader();
|
|
|
|
|
2014-11-18 19:25:36 +03:00
|
|
|
return self::setKey(self::$encryption_base_dir, $keyName,$header . $key, new \OC\Files\View());
|
2014-07-21 15:02:28 +04:00
|
|
|
}
|
|
|
|
|
2013-02-05 22:43:55 +04:00
|
|
|
/**
|
2014-11-14 19:30:38 +03:00
|
|
|
* read private system key (recovery and public share key) from disk
|
2013-02-09 21:01:38 +04:00
|
|
|
*
|
2014-11-14 19:30:38 +03:00
|
|
|
* @param string $keyName name of the key
|
|
|
|
* @return string|boolean private system key or false
|
2013-02-05 22:43:55 +04:00
|
|
|
*/
|
2014-11-14 19:30:38 +03:00
|
|
|
public static function getPrivateSystemKey($keyName) {
|
|
|
|
$path = $keyName . '.privateKey';
|
2014-11-18 19:25:36 +03:00
|
|
|
return self::getKey($path, new \OC\Files\View(self::$encryption_base_dir));
|
2013-03-28 21:39:12 +04:00
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-03-28 21:39:12 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* store multiple share keys for a single file
|
2014-05-12 18:30:39 +04:00
|
|
|
* @param \OC\Files\View $view
|
2014-12-03 18:52:44 +03:00
|
|
|
* @param \OCA\Files_Encryption\Util $util
|
2013-11-21 03:23:38 +04:00
|
|
|
* @param string $path
|
2013-05-20 03:24:36 +04:00
|
|
|
* @param array $shareKeys
|
2013-03-28 21:39:12 +04:00
|
|
|
* @return bool
|
|
|
|
*/
|
2014-11-10 14:40:24 +03:00
|
|
|
public static function setShareKeys($view, $util, $path, array $shareKeys) {
|
2013-06-25 16:15:53 +04:00
|
|
|
|
|
|
|
// in case of system wide mount points the keys are stored directly in the data directory
|
2014-11-10 14:40:24 +03:00
|
|
|
$basePath = Keymanager::getKeyPath($view, $util, $path);
|
2013-06-25 16:15:53 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
self::keySetPreparation($view, $basePath);
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-03-28 21:39:12 +04:00
|
|
|
$result = true;
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-05-27 19:26:58 +04:00
|
|
|
foreach ($shareKeys as $userId => $shareKey) {
|
2014-11-14 19:30:38 +03:00
|
|
|
if (!self::setKey($basePath, $userId . '.shareKey', $shareKey, $view)) {
|
2013-03-28 21:39:12 +04:00
|
|
|
// If any of the keys are not set, flag false
|
|
|
|
$result = false;
|
|
|
|
}
|
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-03-28 21:39:12 +04:00
|
|
|
// Returns false if any of the keys weren't set
|
|
|
|
return $result;
|
|
|
|
}
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-03-28 21:39:12 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* retrieve shareKey for an encrypted file
|
2014-05-12 18:30:39 +04:00
|
|
|
* @param \OC\Files\View $view
|
2013-03-28 21:39:12 +04:00
|
|
|
* @param string $userId
|
2014-12-03 18:52:44 +03:00
|
|
|
* @param \OCA\Files_Encryption\Util $util
|
2013-03-28 21:39:12 +04:00
|
|
|
* @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
|
|
|
|
*/
|
2014-11-10 14:40:24 +03:00
|
|
|
public static function getShareKey($view, $userId, $util, $filePath) {
|
2014-11-14 19:30:38 +03:00
|
|
|
$path = self::getShareKeyPath($view, $util, $filePath, $userId);
|
|
|
|
return self::getKey($path, $view);
|
2013-04-22 17:29:58 +04:00
|
|
|
}
|
|
|
|
|
2013-03-28 21:39:12 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Delete a single user's shareKey for a single file
|
2014-07-04 14:06:23 +04:00
|
|
|
*
|
|
|
|
* @param \OC\Files\View $view relative to data/
|
|
|
|
* @param array $userIds list of users we want to remove
|
2014-11-10 14:40:24 +03:00
|
|
|
* @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
|
2013-03-28 21:39:12 +04:00
|
|
|
*/
|
2014-11-10 14:40:24 +03:00
|
|
|
public static function delShareKey($view, $userIds, $keysPath, $owner, $ownerPath) {
|
2013-04-25 16:56:11 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
$key = array_search($owner, $userIds, true);
|
|
|
|
if ($key !== false && $view->file_exists('/' . $owner . '/files/' . $ownerPath)) {
|
|
|
|
unset($userIds[$key]);
|
2013-06-25 18:41:51 +04:00
|
|
|
}
|
2013-03-28 21:39:12 +04:00
|
|
|
|
2014-11-10 14:40:24 +03:00
|
|
|
self::recursiveDelShareKeys($keysPath, $userIds, $view);
|
2013-05-20 03:24:36 +04:00
|
|
|
|
2013-02-09 21:01:38 +04:00
|
|
|
}
|
2013-04-19 15:17:08 +04:00
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* recursively delete share keys from given users
|
2013-04-19 15:17:08 +04:00
|
|
|
*
|
2013-05-20 03:24:36 +04:00
|
|
|
* @param string $dir directory
|
|
|
|
* @param array $userIds user ids for which the share keys should be deleted
|
2014-06-25 21:21:55 +04:00
|
|
|
* @param \OC\Files\View $view view relative to data/
|
2013-04-19 15:17:08 +04:00
|
|
|
*/
|
2014-11-10 14:40:24 +03:00
|
|
|
private static function recursiveDelShareKeys($dir, $userIds, $view) {
|
2014-06-23 19:13:56 +04:00
|
|
|
|
|
|
|
$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)) {
|
2014-11-10 14:40:24 +03:00
|
|
|
self::recursiveDelShareKeys($dir . '/' . $file, $userIds, $view);
|
2014-06-23 19:13:56 +04:00
|
|
|
} else {
|
|
|
|
foreach ($userIds as $userId) {
|
2014-11-10 14:40:24 +03:00
|
|
|
if ($userId . '.shareKey' === $file) {
|
|
|
|
\OCP\Util::writeLog('files_encryption', 'recursiveDelShareKey: delete share key: ' . $file, \OCP\Util::DEBUG);
|
2014-12-19 13:32:02 +03:00
|
|
|
self::deleteKey($view, $dir . '/' . $file);
|
2014-09-17 20:50:29 +04:00
|
|
|
}
|
2014-06-23 19:13:56 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-05-20 23:24:39 +04:00
|
|
|
}
|
2014-06-23 19:13:56 +04:00
|
|
|
closedir($dirContent);
|
2013-04-19 15:17:08 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-09 21:01:38 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Make preparations to vars and filesystem for saving a keyfile
|
2014-11-10 14:40:24 +03:00
|
|
|
*
|
|
|
|
* @param \OC\Files\View $view
|
|
|
|
* @param string $path relatvie to the views root
|
2014-02-06 19:30:58 +04:00
|
|
|
* @param string $basePath
|
2013-02-09 21:01:38 +04:00
|
|
|
*/
|
2014-11-10 14:40:24 +03:00
|
|
|
protected static function keySetPreparation($view, $path) {
|
2013-02-05 22:43:55 +04:00
|
|
|
// If the file resides within a subdirectory, create it
|
2014-11-10 14:40:24 +03:00
|
|
|
if (!$view->file_exists($path)) {
|
|
|
|
$sub_dirs = explode('/', $path);
|
2013-03-28 21:39:12 +04:00
|
|
|
$dir = '';
|
2013-05-27 19:26:58 +04:00
|
|
|
foreach ($sub_dirs as $sub_dir) {
|
2013-03-28 21:39:12 +04:00
|
|
|
$dir .= '/' . $sub_dir;
|
2013-05-27 19:26:58 +04:00
|
|
|
if (!$view->is_dir($dir)) {
|
|
|
|
$view->mkdir($dir);
|
2013-03-28 21:39:12 +04:00
|
|
|
}
|
|
|
|
}
|
2013-02-05 22:43:55 +04:00
|
|
|
}
|
2013-03-28 21:39:12 +04:00
|
|
|
}
|
2014-02-03 16:39:05 +04:00
|
|
|
|
2013-08-18 13:02:08 +04:00
|
|
|
}
|