Esempio n. 1
0
 /**
  * @param string $uid user id
  * @param string $password user password
  * @return bool
  */
 public function setupUser($uid, $password)
 {
     if (!$this->keyManager->userHasKeys($uid)) {
         return $this->keyManager->storeKeyPair($uid, $password, $this->crypt->createKeyPair());
     }
     return true;
 }
 /**
  * @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);
     }
 }
Esempio n. 3
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;
 }
Esempio n. 4
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'));
 }
Esempio n. 5
0
 /**
  * update encrypted file, e.g. give additional users access to the file
  *
  * @param string $path path to the file which should be updated
  * @param string $uid of the user who performs the operation
  * @param array $accessList who has access to the file contains the key 'users' and 'public'
  * @return boolean
  */
 public function update($path, $uid, array $accessList)
 {
     if (empty($accessList)) {
         if (isset(self::$rememberVersion[$path])) {
             $this->keyManager->setVersion($path, self::$rememberVersion[$path], new View());
             unset(self::$rememberVersion[$path]);
         }
         return;
     }
     $fileKey = $this->keyManager->getFileKey($path, $uid);
     if (!empty($fileKey)) {
         $publicKeys = array();
         if ($this->useMasterPassword === true) {
             $publicKeys[$this->keyManager->getMasterKeyId()] = $this->keyManager->getPublicMasterKey();
         } else {
             foreach ($accessList['users'] as $user) {
                 try {
                     $publicKeys[$user] = $this->keyManager->getPublicKey($user);
                 } catch (PublicKeyMissingException $e) {
                     $this->logger->warning('Could not encrypt file for ' . $user . ': ' . $e->getMessage());
                 }
             }
         }
         $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $uid);
         $encryptedFileKey = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
         $this->keyManager->deleteAllFileKeys($path);
         $this->keyManager->setAllFileKeys($path, $encryptedFileKey);
     } else {
         $this->logger->debug('no file key found, we assume that the file "{file}" is not encrypted', array('file' => $path, 'app' => 'encryption'));
         return false;
     }
     return true;
 }
Esempio n. 6
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;
 }
Esempio n. 7
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']));
 }
Esempio n. 8
0
 /**
  * update encrypted file, e.g. give additional users access to the file
  *
  * @param string $path path to the file which should be updated
  * @param string $uid of the user who performs the operation
  * @param array $accessList who has access to the file contains the key 'users' and 'public'
  * @return boolean
  */
 public function update($path, $uid, array $accessList)
 {
     $fileKey = $this->keyManager->getFileKey($path, $uid);
     $publicKeys = array();
     foreach ($accessList['users'] as $user) {
         $publicKeys[$user] = $this->keyManager->getPublicKey($user);
     }
     $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys);
     $encryptedFileKey = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
     $this->keyManager->deleteAllFileKeys($path);
     $this->keyManager->setAllFileKeys($path, $encryptedFileKey);
     return true;
 }
Esempio n. 9
0
 /**
  * Change a user's encryption passphrase
  *
  * @param array $params keys: uid, password
  * @return boolean|null
  */
 public function setPassphrase($params)
 {
     // Get existing decrypted private key
     $privateKey = $this->session->getPrivateKey();
     $user = $this->user->getUser();
     // current logged in user changes his own password
     if ($user && $params['uid'] === $user->getUID() && $privateKey) {
         // Encrypt private key with new user pwd as passphrase
         $encryptedPrivateKey = $this->crypt->encryptPrivateKey($privateKey, $params['password'], $params['uid']);
         // Save private key
         if ($encryptedPrivateKey) {
             $this->keyManager->setPrivateKey($this->user->getUser()->getUID(), $this->crypt->generateHeader() . $encryptedPrivateKey);
         } else {
             $this->logger->error('Encryption could not update users encryption password');
         }
         // NOTE: Session does not need to be updated as the
         // private key has not changed, only the passphrase
         // used to decrypt it has changed
     } else {
         // admin changed the password for a different user, create new keys and re-encrypt file keys
         $user = $params['uid'];
         $this->initMountPoints($user);
         $recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null;
         // we generate new keys if...
         // ...we have a recovery password and the user enabled the recovery key
         // ...encryption was activated for the first time (no keys exists)
         // ...the user doesn't have any files
         if ($this->recovery->isRecoveryEnabledForUser($user) && $recoveryPassword || !$this->keyManager->userHasKeys($user) || !$this->util->userHasFiles($user)) {
             // backup old keys
             //$this->backupAllKeys('recovery');
             $newUserPassword = $params['password'];
             $keyPair = $this->crypt->createKeyPair();
             // Save public key
             $this->keyManager->setPublicKey($user, $keyPair['publicKey']);
             // Encrypt private key with new password
             $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $newUserPassword, $user);
             if ($encryptedKey) {
                 $this->keyManager->setPrivateKey($user, $this->crypt->generateHeader() . $encryptedKey);
                 if ($recoveryPassword) {
                     // if recovery key is set we can re-encrypt the key files
                     $this->recovery->recoverUsersFiles($recoveryPassword, $user);
                 }
             } else {
                 $this->logger->error('Encryption Could not update users encryption password');
             }
         }
     }
 }
Esempio n. 10
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']]));
 }
Esempio n. 11
0
 /**
  * @param $path
  * @param $uid
  * @return string
  */
 public function getFileKey($path, $uid)
 {
     $encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId, Encryption::ID);
     if (is_null($uid)) {
         $uid = $this->getPublicShareKeyId();
         $shareKey = $this->getShareKey($path, $uid);
         $privateKey = $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.privateKey', Encryption::ID);
         $privateKey = $this->crypt->decryptPrivateKey($privateKey);
     } else {
         $shareKey = $this->getShareKey($path, $uid);
         $privateKey = $this->session->getPrivateKey();
     }
     if ($encryptedFileKey && $shareKey && $privateKey) {
         return $this->crypt->multiKeyDecrypt($encryptedFileKey, $shareKey, $privateKey);
     }
     return '';
 }
Esempio n. 12
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);
     }
 }
Esempio n. 13
0
 /**
  * update encrypted file, e.g. give additional users access to the file
  *
  * @param string $path path to the file which should be updated
  * @param string $uid of the user who performs the operation
  * @param array $accessList who has access to the file contains the key 'users' and 'public'
  * @return boolean
  */
 public function update($path, $uid, array $accessList)
 {
     $fileKey = $this->keyManager->getFileKey($path, $uid);
     if (!empty($fileKey)) {
         $publicKeys = array();
         foreach ($accessList['users'] as $user) {
             $publicKeys[$user] = $this->keyManager->getPublicKey($user);
         }
         $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $uid);
         $encryptedFileKey = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
         $this->keyManager->deleteAllFileKeys($path);
         $this->keyManager->setAllFileKeys($path, $encryptedFileKey);
     } else {
         $this->logger->debug('no file key found, we assume that the file "{file}" is not encrypted', array('file' => $path, 'app' => 'encryption'));
         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']);
 }
Esempio n. 15
0
 /**
  * @dataProvider dataTestValidateMasterKey
  *
  * @param $masterKey
  */
 public function testValidateMasterKey($masterKey)
 {
     /** @var \OCA\Encryption\KeyManager | \PHPUnit_Framework_MockObject_MockObject $instance */
     $instance = $this->getMockBuilder('OCA\\Encryption\\KeyManager')->setConstructorArgs([$this->keyStorageMock, $this->cryptMock, $this->configMock, $this->userMock, $this->sessionMock, $this->logMock, $this->utilMock])->setMethods(['getPublicMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword'])->getMock();
     $instance->expects($this->once())->method('getPublicMasterKey')->willReturn($masterKey);
     $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword');
     $this->cryptMock->expects($this->any())->method('generateHeader')->willReturn('header');
     if (empty($masterKey)) {
         $this->cryptMock->expects($this->once())->method('createKeyPair')->willReturn(['publicKey' => 'public', 'privateKey' => 'private']);
         $this->keyStorageMock->expects($this->once())->method('setSystemUserKey')->with('systemKeyId.publicKey', 'public', \OCA\Encryption\Crypto\Encryption::ID);
         $this->cryptMock->expects($this->once())->method('encryptPrivateKey')->with('private', 'masterKeyPassword', 'systemKeyId')->willReturn('EncryptedKey');
         $instance->expects($this->once())->method('setSystemPrivateKey')->with('systemKeyId', 'headerEncryptedKey');
     } else {
         $this->cryptMock->expects($this->never())->method('createKeyPair');
         $this->keyStorageMock->expects($this->never())->method('setSystemUserKey');
         $this->cryptMock->expects($this->never())->method('encryptPrivateKey');
         $instance->expects($this->never())->method('setSystemPrivateKey');
     }
     $instance->validateMasterKey();
 }
Esempio n. 16
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) {
         // 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);
     }
 }
Esempio n. 17
0
 /**
  * @dataProvider dataProviderGetCipher
  * @param string $configValue
  * @param string $expected
  */
 public function testGetCipher($configValue, $expected)
 {
     $this->config->expects($this->once())->method('getSystemValue')->with($this->equalTo('cipher'), $this->equalTo('AES-256-CTR'))->willReturn($configValue);
     $this->assertSame($expected, $this->crypt->getCipher());
 }