use OCA\Encryption\HookManager;
use OCA\Encryption\Hooks\UserHooks;
use OCA\Encryption\KeyManager;
-use OCA\Encryption\Migrator;
use OCA\Encryption\Recovery;
use OCA\Encryption\Users\Setup;
use OCA\Encryption\Util;
public function registerEncryptionModule() {
$container = $this->getContainer();
$container->registerService('EncryptionModule', function (IAppContainer $c) {
- return new \OCA\Encryption\Crypto\Encryption($c->query('Crypt'));
+ return new \OCA\Encryption\Crypto\Encryption($c->query('Crypt'), $c->query('KeyManager'));
});
$module = $container->query('EncryptionModule');
$this->encryptionManager->registerEncryptionModule($module);
function (IAppContainer $c) {
$server = $c->getServer();
- $moduleId = $c->query('EncryptionModule')->getId();
- return new KeyManager($server->getEncryptionKeyStorage($moduleId),
+ return new KeyManager($server->getEncryptionKeyStorage(\OCA\Encryption\Crypto\Encryption::ID),
$c->query('Crypt'),
$server->getConfig(),
$server->getUserSession(),
function (IAppContainer $c) {
$server = $c->getServer();
- $moduleId = $c->query('EncryptionModule')->getId();
return new Recovery(
$server->getUserSession(),
$c->query('Crypt'),
$server->getSecureRandom(),
$c->query('KeyManager'),
$server->getConfig(),
- $server->getEncryptionKeyStorage($moduleId));
+ $server->getEncryptionKeyStorage(\OCA\Encryption\Crypto\Encryption::ID));
});
$container->registerService('UserSetup',
use OCP\Encryption\IEncryptionModule;
+use OCA\Encryption\KeyManager;
class Encryption implements IEncryptionModule {
+ const ID = '42';
+
/**
* @var Crypt
*/
private $crypt;
- public function __construct(Crypt $crypt) {
+ /** @var string */
+ private $cipher;
+
+ /** @var string */
+ private $path;
+
+ /** @var string */
+ private $user;
+
+ /** @var string */
+ private $fileKey;
+
+ /** @var string */
+ private $writeCache;
+
+ /** @var KeyManager */
+ private $keymanager;
+
+ /** @var array */
+ private $accessList;
+
+ /** @var boolean */
+ private $isWriteOperation;
+
+ public function __construct(Crypt $crypt, KeyManager $keymanager) {
$this->crypt = $crypt;
+ $this->keymanager = $keymanager;
}
/**
* @return string defining the technical unique id
*/
public function getId() {
- // we need to hard code this value
- return md5($this->getDisplayName());
+ return self::ID;
}
/**
* chunks
*
* @param string $path to the file
+ * @param string $user who read/write the file
* @param array $header contains the header data read from the file
* @param array $accessList who has access to the file contains the key 'users' and 'public'
*
* written to the header, in case of a write operation
* or if no additional data is needed return a empty array
*/
- public function begin($path, $header, $accessList) {
+ public function begin($path, $user, $header, $accessList) {
+
+ if (isset($header['cipher'])) {
+ $this->cipher = $header['cipher'];
+ } else {
+ $this->cipher = $this->crypt->getCipher();
+ }
+
+ $this->path = $path;
+ $this->accessList = $accessList;
+ $this->user = $user;
+ $this->writeCache = '';
+ $this->isWriteOperation = false;
- $cipher = $header[''];
+ $this->fileKey = $this->keymanager->getFileKey($path);
+
+ return array('cipher' => $this->cipher);
}
/**
* of a write operation
*/
public function end($path) {
- // TODO: Implement end() method.
+ $result = '';
+ if ($this->isWriteOperation) {
+ if (!empty($this->writeCache)) {
+ $result = $this->crypt->symmetricEncryptFileContent($this->writeCache, $this->fileKey);
+ $this->writeCache = '';
+ }
+ $publicKeys = array();
+ foreach ($this->accessList['users'] as $user) {
+ $publicKeys[] = $this->keymanager->getPublicKey($user);
+ }
+
+ $result = $this->crypt->multiKeyEncrypt($this->fileKey, $publicKeys);
+ }
+ return $result;
}
/**
* @return mixed encrypted data
*/
public function encrypt($data) {
- // Todo: xxx Update Signature and usages
- // passphrase is file key decrypted with user private/share key
- $this->symmetricEncryptFileContent($data);
+ $this->isWriteOperation = true;
+ if (empty($this->fileKey)) {
+ $this->fileKey = $this->crypt->generateFileKey();
+ }
+
+ // If extra data is left over from the last round, make sure it
+ // is integrated into the next 6126 / 8192 block
+ if ($this->writeCache) {
+
+ // Concat writeCache to start of $data
+ $data = $this->writeCache . $data;
+
+ // Clear the write cache, ready for reuse - it has been
+ // flushed and its old contents processed
+ $this->writeCache = '';
+
+ }
+
+ $encrypted = '';
+ // While there still remains some data to be processed & written
+ while (strlen($data) > 0) {
+
+ // Remaining length for this iteration, not of the
+ // entire file (may be greater than 8192 bytes)
+ $remainingLength = strlen($data);
+
+ // If data remaining to be written is less than the
+ // size of 1 6126 byte block
+ if ($remainingLength < 6126) {
+
+ // Set writeCache to contents of $data
+ // The writeCache will be carried over to the
+ // next write round, and added to the start of
+ // $data to ensure that written blocks are
+ // always the correct length. If there is still
+ // data in writeCache after the writing round
+ // has finished, then the data will be written
+ // to disk by $this->flush().
+ $this->writeCache = $data;
+
+ // Clear $data ready for next round
+ $data = '';
+
+ } else {
+
+ // Read the chunk from the start of $data
+ $chunk = substr($data, 0, 6126);
+
+ $encrypted .= $this->crypt->symmetricEncryptFileContent($chunk, $this->fileKey);
+
+ // Remove the chunk we just processed from
+ // $data, leaving only unprocessed data in $data
+ // var, for handling on the next round
+ $data = substr($data, 6126);
+
+ }
+
+ }
+
+ return $encrypted;
}
/**
* decrypt data
*
* @param string $data you want to decrypt
- * @param string $user decrypt as user (null for public access)
* @return mixed decrypted data
*/
- public function decrypt($data, $user) {
- // Todo: xxx Update Usages?
- $this->symmetricDecryptFileContent($data, $user);
+ public function decrypt($data) {
+ $result = '';
+ if (!empty($data)) {
+ $result = $this->crypt->symmetricDecryptFileContent($data, $this->fileKey);
+ }
+ return $result;
}
/**
* @return boolean
*/
public function shouldEncrypt($path) {
- // TODO: Implement shouldEncrypt() method.
+ return true;
}
/**
* @return integer
*/
public function getUnencryptedBlockSize() {
- // TODO: Implement getUnencryptedBlockSize() method.
+ return 6126;
}
}