Example #1
0
 /**
  * @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);
     }
 }
Example #2
0
 /**
  * @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;
 }
Example #3
0
 /**
  * @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);
 }
Example #5
0
 /**
  * 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();
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 /**
  * 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;
 }
Example #8
0
 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']));
 }
Example #9
0
 /**
  * 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']]));
 }
Example #10
0
 /**
  * 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);
     }
 }
Example #11
0
 /**
  * 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']);
 }
Example #13
0
 /**
  * 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);
     }
 }
Example #15
0
 /**
  * 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);
 }
Example #16
0
 /**
  * make sure that all system keys exists
  */
 public function setupSystem()
 {
     $this->keyManager->validateShareKey();
     $this->keyManager->validateMasterKey();
 }
Example #17
0
 /**
  * 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);
 }
Example #18
0
 public function testDeleteAllFileKeys()
 {
     $this->keyStorageMock->expects($this->once())->method('deleteAllFileKeys')->willReturn(true);
     $this->assertTrue($this->instance->deleteAllFileKeys('/'));
 }
Example #19
0
 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());
 }
Example #20
0
 /**
  * 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);
 }