/** * @NoAdminRequired * @UseSession * * @param string $oldPassword * @param string $newPassword * @return DataResponse */ public function updatePrivateKeyPassword($oldPassword, $newPassword) { $result = false; $uid = $this->userSession->getUser()->getUID(); $errorMessage = $this->l->t('Could not update the private key password.'); //check if password is correct $passwordCorrect = $this->userManager->checkPassword($uid, $newPassword); if ($passwordCorrect !== false) { $encryptedKey = $this->keyManager->getPrivateKey($uid); $decryptedKey = $this->crypt->decryptPrivateKey($encryptedKey, $oldPassword); if ($decryptedKey) { $encryptedKey = $this->crypt->symmetricEncryptFileContent($decryptedKey, $newPassword); $header = $this->crypt->generateHeader(); if ($encryptedKey) { $this->keyManager->setPrivateKey($uid, $header . $encryptedKey); $this->session->setPrivateKey($decryptedKey); $result = true; } } else { $errorMessage = $this->l->t('The old password was not correct, please try again.'); } } else { $errorMessage = $this->l->t('The current log-in password was not correct, please try again.'); } if ($result === true) { $this->session->setStatus(Session::INIT_SUCCESSFUL); return new DataResponse(['message' => (string) $this->l->t('Private key password successfully updated.')]); } else { return new DataResponse(['message' => (string) $errorMessage], Http::STATUS_BAD_REQUEST); } }
/** * @param string $uid userid * @param string $password user password * @return bool */ public function setupServerSide($uid, $password) { // Check if user already has keys if (!$this->keyManager->userHasKeys($uid)) { return $this->keyManager->storeKeyPair($uid, $password, $this->crypt->createKeyPair()); } return true; }
/** * @dataProvider dataTestSetupUser * * @param bool $hasKeys * @param bool $expected */ public function testSetupUser($hasKeys, $expected) { $this->keyManagerMock->expects($this->once())->method('userHasKeys')->with('uid')->willReturn($hasKeys); if ($hasKeys) { $this->keyManagerMock->expects($this->never())->method('storeKeyPair'); } else { $this->cryptMock->expects($this->once())->method('createKeyPair')->willReturn('keyPair'); $this->keyManagerMock->expects($this->once())->method('storeKeyPair')->with('uid', 'password', 'keyPair')->willReturn(true); } $this->assertSame($expected, $this->instance->setupUser('uid', 'password')); }
public function testSetVersionWithoutFileInfo() { $view = $this->getMockBuilder('\\OC\\Files\\View')->disableOriginalConstructor()->getMock(); $view->expects($this->once())->method('getFileInfo')->with('/admin/files/myfile.txt')->willReturn(false); /** @var \OC\Files\View $view */ $this->instance->setVersion('/admin/files/myfile.txt', 5, $view); }
/** * create key-pair for every user */ protected function createKeyPairs() { $this->output->writeln("\n"); $progress = new ProgressBar($this->output); $progress->setFormat(" %message% \n [%bar%]"); $progress->start(); foreach ($this->userManager->getBackends() as $backend) { $limit = 500; $offset = 0; do { $users = $backend->getUsers('', $limit, $offset); foreach ($users as $user) { if ($this->keyManager->userHasKeys($user) === false) { $progress->setMessage('Create key-pair for ' . $user); $progress->advance(); $this->setupUserFS($user); $password = $this->generateOneTimePassword($user); $this->userSetup->setupUser($user, $password); } else { // users which already have a key-pair will be stored with a // empty password and filtered out later $this->userPasswords[$user] = ''; } } $offset += $limit; } while (count($users) >= $limit); } $progress->setMessage('Key-pair created for all users'); $progress->finish(); }
/** * add system keys such as the public share key and the recovery key * * @param array $accessList * @param array $publicKeys * @return array */ public function addSystemKeys(array $accessList, array $publicKeys) { if (!empty($accessList['public'])) { $publicKeys[$this->keyManager->getPublicShareKeyId()] = $this->keyManager->getPublicShareKey(); } if ($this->keyManager->recoveryKeyExists() && $this->util->isRecoveryEnabledForUser()) { $publicKeys[$this->keyManager->getRecoveryKeyId()] = $this->keyManager->getRecoveryKey(); } return $publicKeys; }
/** * get the private key which will be used to decrypt all files * * @param string $user * @param string $password * @return bool|string * @throws \OCA\Encryption\Exceptions\PrivateKeyMissingException */ protected function getPrivateKey($user, $password) { $recoveryKeyId = $this->keyManager->getRecoveryKeyId(); if ($user === $recoveryKeyId) { $recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId); $privateKey = $this->crypt->decryptPrivateKey($recoveryKey, $password); } else { $userKey = $this->keyManager->getPrivateKey($user); $privateKey = $this->crypt->decryptPrivateKey($userKey, $password, $user); } return $privateKey; }
public function testRecoverFile() { $this->keyManagerMock->expects($this->once())->method('getEncryptedFileKey')->willReturn(true); $this->keyManagerMock->expects($this->once())->method('getShareKey')->willReturn(true); $this->cryptMock->expects($this->once())->method('multiKeyDecrypt')->willReturn(true); $this->fileMock->expects($this->once())->method('getAccessList')->willReturn(['users' => ['admin']]); $this->keyManagerMock->expects($this->once())->method('getPublicKey')->willReturn('publicKey'); $this->keyManagerMock->expects($this->once())->method('addSystemKeys')->with($this->anything(), $this->anything(), $this->equalTo('admin'))->willReturn(['admin' => 'publicKey']); $this->cryptMock->expects($this->once())->method('multiKeyEncrypt'); $this->keyManagerMock->expects($this->once())->method('setAllFileKeys'); $this->assertNull(self::invokePrivate($this->instance, 'recoverFile', ['/', 'testkey', 'admin'])); }
/** * Test case if the public key is missing. ownCloud should still encrypt * the file for the remaining users */ public function testUpdateMissingPublicKey() { $this->keyManagerMock->expects($this->once())->method('getFileKey')->willReturn('fileKey'); $this->keyManagerMock->expects($this->any())->method('getPublicKey')->willReturnCallback(function ($user) { throw new PublicKeyMissingException($user); }); $this->keyManagerMock->expects($this->any())->method('addSystemKeys')->willReturnCallback(function ($accessList, $publicKeys) { return $publicKeys; }); $this->cryptMock->expects($this->once())->method('multiKeyEncrypt')->willReturnCallback(function ($fileKey, $publicKeys) { $this->assertEmpty($publicKeys); $this->assertSame('fileKey', $fileKey); }); $this->keyManagerMock->expects($this->never())->method('getVersion'); $this->keyManagerMock->expects($this->never())->method('setVersion'); $this->assertTrue($this->instance->update('path', 'user1', ['users' => ['user1']])); }
/** * recover file * * @param string $path * @param string $privateKey * @param string $uid */ private function recoverFile($path, $privateKey, $uid) { $encryptedFileKey = $this->keyManager->getEncryptedFileKey($path); $shareKey = $this->keyManager->getShareKey($path, $this->keyManager->getRecoveryKeyId()); if ($encryptedFileKey && $shareKey && $privateKey) { $fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey, $shareKey, $privateKey); } if (!empty($fileKey)) { $accessList = $this->file->getAccessList($path); $publicKeys = array(); foreach ($accessList['users'] as $user) { $publicKeys[$user] = $this->keyManager->getPublicKey($user); } $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $uid); $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys); $this->keyManager->setAllFileKeys($path, $encryptedKeyfiles); } }
/** * check if the encryption module is able to read the file, * e.g. if all encryption keys exists * * @param string $path * @param string $uid user for whom we want to check if he can read the file * @return bool * @throws DecryptionFailedException */ public function isReadable($path, $uid) { $fileKey = $this->keyManager->getFileKey($path, $uid); if (empty($fileKey)) { $owner = $this->util->getOwner($path); if ($owner !== $uid) { // if it is a shared file we throw a exception with a useful // error message because in this case it means that the file was // shared with the user at a point where the user didn't had a // valid private/public key $msg = 'Encryption module "' . $this->getDisplayName() . '" is not able to read ' . $path; $hint = $this->l->t('Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.'); $this->logger->warning($msg); throw new DecryptionFailedException($msg, $hint); } return false; } return true; }
/** * test updatePrivateKeyPassword() with the correct old and new password */ public function testUpdatePrivateKeyPassword() { $oldPassword = '******'; $newPassword = '******'; $this->ocSessionMock->expects($this->once())->method('get')->with('loginname')->willReturn('testUser'); $this->userManagerMock->expects($this->at(0))->method('checkPassword')->with('testUserUid', 'new')->willReturn(false); $this->userManagerMock->expects($this->at(1))->method('checkPassword')->with('testUser', 'new')->willReturn(true); $this->cryptMock->expects($this->once())->method('decryptPrivateKey')->willReturn('decryptedKey'); $this->cryptMock->expects($this->once())->method('encryptPrivateKey')->willReturn('encryptedKey'); $this->cryptMock->expects($this->once())->method('generateHeader')->willReturn('header.'); // methods which must be called after successful changing the key password $this->keyManagerMock->expects($this->once())->method('setPrivateKey')->with($this->equalTo('testUserUid'), $this->equalTo('header.encryptedKey')); $this->sessionMock->expects($this->once())->method('setPrivateKey')->with($this->equalTo('decryptedKey')); $this->sessionMock->expects($this->once())->method('setStatus')->with($this->equalTo(Session::INIT_SUCCESSFUL)); $result = $this->controller->updatePrivateKeyPassword($oldPassword, $newPassword); $data = $result->getData(); $this->assertSame(Http::STATUS_OK, $result->getStatus()); $this->assertSame('Private key password successfully updated.', $data['message']); }
/** * test add public share key and or recovery key to the list of public keys * * @dataProvider dataTestAddSystemKeys * * @param array $accessList * @param array $publicKeys * @param string $uid * @param array $expectedKeys */ public function testAddSystemKeys($accessList, $publicKeys, $uid, $expectedKeys) { $publicShareKeyId = 'publicShareKey'; $recoveryKeyId = 'recoveryKey'; $this->keyStorageMock->expects($this->any())->method('getSystemUserKey')->willReturnCallback(function ($keyId, $encryptionModuleId) { return $keyId; }); $this->utilMock->expects($this->any())->method('isRecoveryEnabledForUser')->willReturnCallback(function ($uid) { if ($uid === 'user1') { return true; } return false; }); // set key IDs self::invokePrivate($this->instance, 'publicShareKeyId', [$publicShareKeyId]); self::invokePrivate($this->instance, 'recoveryKeyId', [$recoveryKeyId]); $result = $this->instance->addSystemKeys($accessList, $publicKeys, $uid); foreach ($expectedKeys as $expected) { $this->assertArrayHasKey($expected, $result); } $this->assertSameSize($expectedKeys, $result); }
/** * @NoAdminRequired * @UseSession * * @param string $oldPassword * @param string $newPassword * @return DataResponse */ public function updatePrivateKeyPassword($oldPassword, $newPassword) { $result = false; $uid = $this->userSession->getUser()->getUID(); $errorMessage = $this->l->t('Could not update the private key password.'); //check if password is correct $passwordCorrect = $this->userManager->checkPassword($uid, $newPassword); if ($passwordCorrect === false) { // if check with uid fails we need to check the password with the login name // e.g. in the ldap case. For local user we need to check the password with // the uid because in this case the login name is case insensitive $loginName = $this->ocSession->get('loginname'); $passwordCorrect = $this->userManager->checkPassword($loginName, $newPassword); } if ($passwordCorrect !== false) { $encryptedKey = $this->keyManager->getPrivateKey($uid); $decryptedKey = $this->crypt->decryptPrivateKey($encryptedKey, $oldPassword, $uid); if ($decryptedKey) { $encryptedKey = $this->crypt->encryptPrivateKey($decryptedKey, $newPassword, $uid); $header = $this->crypt->generateHeader(); if ($encryptedKey) { $this->keyManager->setPrivateKey($uid, $header . $encryptedKey); $this->session->setPrivateKey($decryptedKey); $result = true; } } else { $errorMessage = $this->l->t('The old password was not correct, please try again.'); } } else { $errorMessage = $this->l->t('The current log-in password was not correct, please try again.'); } if ($result === true) { $this->session->setStatus(Session::INIT_SUCCESSFUL); return new DataResponse(['message' => (string) $this->l->t('Private key password successfully updated.')]); } else { return new DataResponse(['message' => (string) $errorMessage], Http::STATUS_BAD_REQUEST); } }
/** * Check if the module is ready to be used by that specific user. * In case a module is not ready - because e.g. key pairs have not been generated * upon login this method can return false before any operation starts and might * cause issues during operations. * * @param string $user * @return boolean * @since 9.1.0 */ public function isReadyForUser($user) { return $this->keyManager->userHasKeys($user); }
/** * make sure that all system keys exists */ public function setupSystem() { $this->keyManager->validateShareKey(); $this->keyManager->validateMasterKey(); }
/** * after password reset we create a new key pair for the user * * @param array $params */ public function postPasswordReset($params) { $password = $params['password']; $this->keyManager->replaceUserKeys($params['uid']); $this->userSetup->setupServerSide($params['uid'], $password); }
public function testDeleteAllFileKeys() { $this->keyStorageMock->expects($this->once())->method('deleteAllFileKeys')->willReturn(true); $this->assertTrue($this->instance->deleteAllFileKeys('/')); }
public function testGetPublicMasterKey() { $this->keyStorageMock->expects($this->once())->method('getSystemUserKey')->with('systemKeyId.publicKey', \OCA\Encryption\Crypto\Encryption::ID)->willReturn(true); $this->assertTrue($this->instance->getPublicMasterKey()); }
/** * after password reset we create a new key pair for the user * * @param array $params */ public function postPasswordReset($params) { $password = $params['password']; $this->keyManager->deleteUserKeys($params['uid']); $this->userSetup->setupUser($params['uid'], $password); }