/** * Fetch the plain encryption key for the file and set it as plainKey property * @internal param bool $generate if true, a new key will be generated if none can be found * @return bool true on key found and set, false on key not found and new key generated and set */ public function getKey() { // Check if key is already set if (isset($this->plainKey) && isset($this->encKeyfile)) { return true; } $util = new Util($this->rootView, $this->userId); // Fetch and decrypt keyfile // Fetch existing keyfile $this->encKeyfile = Keymanager::getFileKey($this->rootView, $util, $this->relPath); // If a keyfile already exists if ($this->encKeyfile) { $shareKey = Keymanager::getShareKey($this->rootView, $this->keyId, $util, $this->relPath); // if there is no valid private key return false if ($this->privateKey === false) { // if private key is not valid redirect user to a error page Helper::redirectToErrorPage($this->session); return false; } if ($shareKey === false) { // if no share key is available redirect user to a error page Helper::redirectToErrorPage($this->session, Crypt::ENCRYPTION_NO_SHARE_KEY_FOUND); return false; } $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $this->privateKey); return true; } else { $this->newFile = true; return false; } }
/** * decrypt given file with recovery key and encrypt it again to the owner and his new key * @param string $file * @param string $privateKey recovery key to decrypt the file */ private function recoverFile($file, $privateKey) { $sharingEnabled = \OCP\Share::isEnabled(); // Find out who, if anyone, is sharing the file if ($sharingEnabled) { $result = \OCP\Share::getUsersSharingFile($file, $this->userId, true); $userIds = $result['users']; $userIds[] = $this->recoveryKeyId; if ($result['public']) { $userIds[] = $this->publicShareKeyId; } } else { $userIds = array($this->userId, $this->recoveryKeyId); } $filteredUids = $this->filterShareReadyUsers($userIds); //decrypt file key $encKeyfile = Keymanager::getFileKey($this->view, $this, $file); $shareKey = Keymanager::getShareKey($this->view, $this->recoveryKeyId, $this, $file); $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); // encrypt file key again to all users, this time with the new public key for the recovered use $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']); $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys); Keymanager::setFileKey($this->view, $this, $file, $multiEncKey['data']); Keymanager::setShareKeys($this->view, $this, $file, $multiEncKey['keys']); }
/** * @large */ public function testMultiKeyEncrypt() { # TODO: search in keyfile for actual content as IV will ensure this test always passes $pair1 = \OCA\Files_Encryption\Crypt::createKeypair(); $this->assertEquals(2, count($pair1)); $this->assertTrue(strlen($pair1['publicKey']) > 1); $this->assertTrue(strlen($pair1['privateKey']) > 1); $crypted = \OCA\Files_Encryption\Crypt::multiKeyEncrypt($this->dataShort, array($pair1['publicKey'])); $this->assertNotEquals($this->dataShort, $crypted['data']); $decrypt = \OCA\Files_Encryption\Crypt::multiKeyDecrypt($crypted['data'], $crypted['keys'][0], $pair1['privateKey']); $this->assertEquals($this->dataShort, $decrypt); }