DecryptAll.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Björn Schießle <bjoern@schiessle.org>
  6. *
  7. * @license AGPL-3.0
  8. *
  9. * This code is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License, version 3,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License, version 3,
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>
  20. *
  21. */
  22. namespace OCA\Encryption\Crypto;
  23. use OCA\Encryption\KeyManager;
  24. use OCA\Encryption\Session;
  25. use OCA\Encryption\Util;
  26. use Symfony\Component\Console\Helper\QuestionHelper;
  27. use Symfony\Component\Console\Input\InputInterface;
  28. use Symfony\Component\Console\Output\OutputInterface;
  29. use Symfony\Component\Console\Question\ConfirmationQuestion;
  30. use Symfony\Component\Console\Question\Question;
  31. class DecryptAll {
  32. /** @var Util */
  33. protected $util;
  34. /** @var QuestionHelper */
  35. protected $questionHelper;
  36. /** @var Crypt */
  37. protected $crypt;
  38. /** @var KeyManager */
  39. protected $keyManager;
  40. /** @var Session */
  41. protected $session;
  42. /**
  43. * @param Util $util
  44. * @param KeyManager $keyManager
  45. * @param Crypt $crypt
  46. * @param Session $session
  47. * @param QuestionHelper $questionHelper
  48. */
  49. public function __construct(
  50. Util $util,
  51. KeyManager $keyManager,
  52. Crypt $crypt,
  53. Session $session,
  54. QuestionHelper $questionHelper
  55. ) {
  56. $this->util = $util;
  57. $this->keyManager = $keyManager;
  58. $this->crypt = $crypt;
  59. $this->session = $session;
  60. $this->questionHelper = $questionHelper;
  61. }
  62. /**
  63. * prepare encryption module to decrypt all files
  64. *
  65. * @param InputInterface $input
  66. * @param OutputInterface $output
  67. * @param $user
  68. * @return bool
  69. */
  70. public function prepare(InputInterface $input, OutputInterface $output, $user) {
  71. $question = new Question('Please enter the recovery key password: ');
  72. if($this->util->isMasterKeyEnabled()) {
  73. $output->writeln('Use master key to decrypt all files');
  74. $user = $this->keyManager->getMasterKeyId();
  75. $password =$this->keyManager->getMasterKeyPassword();
  76. } else {
  77. $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
  78. if (!empty($user)) {
  79. $output->writeln('You can only decrypt the users files if you know');
  80. $output->writeln('the users password or if he activated the recovery key.');
  81. $output->writeln('');
  82. $questionUseLoginPassword = new ConfirmationQuestion(
  83. 'Do you want to use the users login password to decrypt all files? (y/n) ',
  84. false
  85. );
  86. $useLoginPassword = $this->questionHelper->ask($input, $output, $questionUseLoginPassword);
  87. if ($useLoginPassword) {
  88. $question = new Question('Please enter the user\'s login password: ');
  89. } else if ($this->util->isRecoveryEnabledForUser($user) === false) {
  90. $output->writeln('No recovery key available for user ' . $user);
  91. return false;
  92. } else {
  93. $user = $recoveryKeyId;
  94. }
  95. } else {
  96. $output->writeln('You can only decrypt the files of all users if the');
  97. $output->writeln('recovery key is enabled by the admin and activated by the users.');
  98. $output->writeln('');
  99. $user = $recoveryKeyId;
  100. }
  101. $question->setHidden(true);
  102. $question->setHiddenFallback(false);
  103. $password = $this->questionHelper->ask($input, $output, $question);
  104. }
  105. $privateKey = $this->getPrivateKey($user, $password);
  106. if ($privateKey !== false) {
  107. $this->updateSession($user, $privateKey);
  108. return true;
  109. } else {
  110. $output->writeln('Could not decrypt private key, maybe you entered the wrong password?');
  111. }
  112. return false;
  113. }
  114. /**
  115. * get the private key which will be used to decrypt all files
  116. *
  117. * @param string $user
  118. * @param string $password
  119. * @return bool|string
  120. * @throws \OCA\Encryption\Exceptions\PrivateKeyMissingException
  121. */
  122. protected function getPrivateKey($user, $password) {
  123. $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
  124. $masterKeyId = $this->keyManager->getMasterKeyId();
  125. if ($user === $recoveryKeyId) {
  126. $recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId);
  127. $privateKey = $this->crypt->decryptPrivateKey($recoveryKey, $password);
  128. } elseif ($user === $masterKeyId) {
  129. $masterKey = $this->keyManager->getSystemPrivateKey($masterKeyId);
  130. $privateKey = $this->crypt->decryptPrivateKey($masterKey, $password, $masterKeyId);
  131. } else {
  132. $userKey = $this->keyManager->getPrivateKey($user);
  133. $privateKey = $this->crypt->decryptPrivateKey($userKey, $password, $user);
  134. }
  135. return $privateKey;
  136. }
  137. protected function updateSession($user, $privateKey) {
  138. $this->session->prepareDecryptAll($user, $privateKey);
  139. }
  140. }