DecryptAll.php 4.3 KB

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