/** * @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); } }
/** * change recovery key id * * @param string $newPassword * @param string $oldPassword * @return bool */ public function changeRecoveryKeyPassword($newPassword, $oldPassword) { $recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId()); $decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword); $encryptedRecoveryKey = $this->crypt->symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword); if ($encryptedRecoveryKey) { $this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $encryptedRecoveryKey); return true; } return false; }
/** * @param string $password * @param array $keyPair * @return bool */ public function setRecoveryKey($password, $keyPair) { // Save Public Key $this->keyStorage->setSystemUserKey($this->getRecoveryKeyId() . '.publicKey', $keyPair['publicKey']); $encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'], $password); $header = $this->crypt->generateHeader(); if ($encryptedKey) { $this->setSystemPrivateKey($this->getRecoveryKeyId(), $header . $encryptedKey); return true; } return false; }
/** * encrypt data * * @param string $data you want to encrypt * @return mixed encrypted data */ public function encrypt($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; }
/** * Change a user's encryption passphrase * * @param array $params keys: uid, password * @return bool */ 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->symmetricEncryptFileContent($privateKey, $params['password']); // 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']; $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->symmetricEncryptFileContent($keyPair['privateKey'], $newUserPassword); 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'); } } } }