DecryptAll.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\Encryption\Crypto;
  8. use OCA\Encryption\Exceptions\PrivateKeyMissingException;
  9. use OCA\Encryption\KeyManager;
  10. use OCA\Encryption\Session;
  11. use OCA\Encryption\Util;
  12. use Symfony\Component\Console\Helper\QuestionHelper;
  13. use Symfony\Component\Console\Input\InputInterface;
  14. use Symfony\Component\Console\Output\OutputInterface;
  15. use Symfony\Component\Console\Question\ConfirmationQuestion;
  16. use Symfony\Component\Console\Question\Question;
  17. class DecryptAll {
  18. /**
  19. * @param Util $util
  20. * @param KeyManager $keyManager
  21. * @param Crypt $crypt
  22. * @param Session $session
  23. * @param QuestionHelper $questionHelper
  24. */
  25. public function __construct(
  26. protected Util $util,
  27. protected KeyManager $keyManager,
  28. protected Crypt $crypt,
  29. protected Session $session,
  30. protected QuestionHelper $questionHelper,
  31. ) {
  32. }
  33. /**
  34. * prepare encryption module to decrypt all files
  35. *
  36. * @param InputInterface $input
  37. * @param OutputInterface $output
  38. * @param $user
  39. * @return bool
  40. */
  41. public function prepare(InputInterface $input, OutputInterface $output, $user) {
  42. $question = new Question('Please enter the recovery key password: ');
  43. if ($this->util->isMasterKeyEnabled()) {
  44. $output->writeln('Use master key to decrypt all files');
  45. $user = $this->keyManager->getMasterKeyId();
  46. $password = $this->keyManager->getMasterKeyPassword();
  47. } else {
  48. $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
  49. if (!empty($user)) {
  50. $output->writeln('You can only decrypt the users files if you know');
  51. $output->writeln('the users password or if they activated the recovery key.');
  52. $output->writeln('');
  53. $questionUseLoginPassword = new ConfirmationQuestion(
  54. 'Do you want to use the users login password to decrypt all files? (y/n) ',
  55. false
  56. );
  57. $useLoginPassword = $this->questionHelper->ask($input, $output, $questionUseLoginPassword);
  58. if ($useLoginPassword) {
  59. $question = new Question('Please enter the user\'s login password: ');
  60. } elseif ($this->util->isRecoveryEnabledForUser($user) === false) {
  61. $output->writeln('No recovery key available for user ' . $user);
  62. return false;
  63. } else {
  64. $user = $recoveryKeyId;
  65. }
  66. } else {
  67. $output->writeln('You can only decrypt the files of all users if the');
  68. $output->writeln('recovery key is enabled by the admin and activated by the users.');
  69. $output->writeln('');
  70. $user = $recoveryKeyId;
  71. }
  72. $question->setHidden(true);
  73. $question->setHiddenFallback(false);
  74. $password = $this->questionHelper->ask($input, $output, $question);
  75. }
  76. $privateKey = $this->getPrivateKey($user, $password);
  77. if ($privateKey !== false) {
  78. $this->updateSession($user, $privateKey);
  79. return true;
  80. } else {
  81. $output->writeln('Could not decrypt private key, maybe you entered the wrong password?');
  82. }
  83. return false;
  84. }
  85. /**
  86. * get the private key which will be used to decrypt all files
  87. *
  88. * @param string $user
  89. * @param string $password
  90. * @return bool|string
  91. * @throws PrivateKeyMissingException
  92. */
  93. protected function getPrivateKey($user, $password) {
  94. $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
  95. $masterKeyId = $this->keyManager->getMasterKeyId();
  96. if ($user === $recoveryKeyId) {
  97. $recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId);
  98. $privateKey = $this->crypt->decryptPrivateKey($recoveryKey, $password);
  99. } elseif ($user === $masterKeyId) {
  100. $masterKey = $this->keyManager->getSystemPrivateKey($masterKeyId);
  101. $privateKey = $this->crypt->decryptPrivateKey($masterKey, $password, $masterKeyId);
  102. } else {
  103. $userKey = $this->keyManager->getPrivateKey($user);
  104. $privateKey = $this->crypt->decryptPrivateKey($userKey, $password, $user);
  105. }
  106. return $privateKey;
  107. }
  108. protected function updateSession($user, $privateKey) {
  109. $this->session->prepareDecryptAll($user, $privateKey);
  110. }
  111. }