KeyManager.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Bjoern Schiessle <bjoern@schiessle.org>
  7. * @author Björn Schießle <bjoern@schiessle.org>
  8. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  9. * @author Clark Tomlinson <fallen013@gmail.com>
  10. * @author Julius Härtl <jus@bitgrid.net>
  11. * @author Lukas Reschke <lukas@statuscode.ch>
  12. * @author Morris Jobke <hey@morrisjobke.de>
  13. * @author Roeland Jago Douma <roeland@famdouma.nl>
  14. * @author Thomas Müller <thomas.mueller@tmit.eu>
  15. * @author Vincent Petry <vincent@nextcloud.com>
  16. *
  17. * @license AGPL-3.0
  18. *
  19. * This code is free software: you can redistribute it and/or modify
  20. * it under the terms of the GNU Affero General Public License, version 3,
  21. * as published by the Free Software Foundation.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU Affero General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU Affero General Public License, version 3,
  29. * along with this program. If not, see <http://www.gnu.org/licenses/>
  30. *
  31. */
  32. namespace OCA\Encryption;
  33. use OC\Encryption\Exceptions\DecryptionFailedException;
  34. use OC\Files\View;
  35. use OCA\Encryption\Crypto\Crypt;
  36. use OCA\Encryption\Crypto\Encryption;
  37. use OCA\Encryption\Exceptions\PrivateKeyMissingException;
  38. use OCA\Encryption\Exceptions\PublicKeyMissingException;
  39. use OCP\Encryption\Keys\IStorage;
  40. use OCP\IConfig;
  41. use OCP\IUserSession;
  42. use OCP\Lock\ILockingProvider;
  43. use Psr\Log\LoggerInterface;
  44. class KeyManager {
  45. private string $recoveryKeyId;
  46. private string $publicShareKeyId;
  47. private string $masterKeyId;
  48. private string $keyId;
  49. private string $publicKeyId = 'publicKey';
  50. private string $privateKeyId = 'privateKey';
  51. private string $shareKeyId = 'shareKey';
  52. private string $fileKeyId = 'fileKey';
  53. public function __construct(
  54. private IStorage $keyStorage,
  55. private Crypt $crypt,
  56. private IConfig $config,
  57. IUserSession $userSession,
  58. private Session $session,
  59. private LoggerInterface $logger,
  60. private Util $util,
  61. private ILockingProvider $lockingProvider,
  62. ) {
  63. $this->recoveryKeyId = $this->config->getAppValue('encryption',
  64. 'recoveryKeyId');
  65. if (empty($this->recoveryKeyId)) {
  66. $this->recoveryKeyId = 'recoveryKey_' . substr(md5((string)time()), 0, 8);
  67. $this->config->setAppValue('encryption',
  68. 'recoveryKeyId',
  69. $this->recoveryKeyId);
  70. }
  71. $this->publicShareKeyId = $this->config->getAppValue('encryption',
  72. 'publicShareKeyId');
  73. if (empty($this->publicShareKeyId)) {
  74. $this->publicShareKeyId = 'pubShare_' . substr(md5((string)time()), 0, 8);
  75. $this->config->setAppValue('encryption', 'publicShareKeyId', $this->publicShareKeyId);
  76. }
  77. $this->masterKeyId = $this->config->getAppValue('encryption',
  78. 'masterKeyId');
  79. if (empty($this->masterKeyId)) {
  80. $this->masterKeyId = 'master_' . substr(md5((string)time()), 0, 8);
  81. $this->config->setAppValue('encryption', 'masterKeyId', $this->masterKeyId);
  82. }
  83. $this->keyId = $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false;
  84. }
  85. /**
  86. * check if key pair for public link shares exists, if not we create one
  87. */
  88. public function validateShareKey() {
  89. $shareKey = $this->getPublicShareKey();
  90. if (empty($shareKey)) {
  91. $this->lockingProvider->acquireLock('encryption-generateSharedKey', ILockingProvider::LOCK_EXCLUSIVE, 'Encryption: shared key generation');
  92. try {
  93. $keyPair = $this->crypt->createKeyPair();
  94. // Save public key
  95. $this->keyStorage->setSystemUserKey(
  96. $this->publicShareKeyId . '.' . $this->publicKeyId, $keyPair['publicKey'],
  97. Encryption::ID);
  98. // Encrypt private key empty passphrase
  99. $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], '');
  100. $header = $this->crypt->generateHeader();
  101. $this->setSystemPrivateKey($this->publicShareKeyId, $header . $encryptedKey);
  102. } catch (\Throwable $e) {
  103. $this->lockingProvider->releaseLock('encryption-generateSharedKey', ILockingProvider::LOCK_EXCLUSIVE);
  104. throw $e;
  105. }
  106. $this->lockingProvider->releaseLock('encryption-generateSharedKey', ILockingProvider::LOCK_EXCLUSIVE);
  107. }
  108. }
  109. /**
  110. * check if a key pair for the master key exists, if not we create one
  111. */
  112. public function validateMasterKey() {
  113. if ($this->util->isMasterKeyEnabled() === false) {
  114. return;
  115. }
  116. $publicMasterKey = $this->getPublicMasterKey();
  117. $privateMasterKey = $this->getPrivateMasterKey();
  118. if (empty($publicMasterKey) && empty($privateMasterKey)) {
  119. // There could be a race condition here if two requests would trigger
  120. // the generation the second one would enter the key generation as long
  121. // as the first one didn't write the key to the keystorage yet
  122. $this->lockingProvider->acquireLock('encryption-generateMasterKey', ILockingProvider::LOCK_EXCLUSIVE, 'Encryption: master key generation');
  123. try {
  124. $keyPair = $this->crypt->createKeyPair();
  125. // Save public key
  126. $this->keyStorage->setSystemUserKey(
  127. $this->masterKeyId . '.' . $this->publicKeyId, $keyPair['publicKey'],
  128. Encryption::ID);
  129. // Encrypt private key with system password
  130. $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $this->getMasterKeyPassword(), $this->masterKeyId);
  131. $header = $this->crypt->generateHeader();
  132. $this->setSystemPrivateKey($this->masterKeyId, $header . $encryptedKey);
  133. } catch (\Throwable $e) {
  134. $this->lockingProvider->releaseLock('encryption-generateMasterKey', ILockingProvider::LOCK_EXCLUSIVE);
  135. throw $e;
  136. }
  137. $this->lockingProvider->releaseLock('encryption-generateMasterKey', ILockingProvider::LOCK_EXCLUSIVE);
  138. } elseif (empty($publicMasterKey)) {
  139. $this->logger->error('A private master key is available but the public key could not be found. This should never happen.');
  140. return;
  141. } elseif (empty($privateMasterKey)) {
  142. $this->logger->error('A public master key is available but the private key could not be found. This should never happen.');
  143. return;
  144. }
  145. if (!$this->session->isPrivateKeySet()) {
  146. $masterKey = $this->getSystemPrivateKey($this->masterKeyId);
  147. $decryptedMasterKey = $this->crypt->decryptPrivateKey($masterKey, $this->getMasterKeyPassword(), $this->masterKeyId);
  148. $this->session->setPrivateKey($decryptedMasterKey);
  149. }
  150. // after the encryption key is available we are ready to go
  151. $this->session->setStatus(Session::INIT_SUCCESSFUL);
  152. }
  153. /**
  154. * @return bool
  155. */
  156. public function recoveryKeyExists() {
  157. $key = $this->getRecoveryKey();
  158. return !empty($key);
  159. }
  160. /**
  161. * get recovery key
  162. *
  163. * @return string
  164. */
  165. public function getRecoveryKey() {
  166. return $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.' . $this->publicKeyId, Encryption::ID);
  167. }
  168. /**
  169. * get recovery key ID
  170. *
  171. * @return string
  172. */
  173. public function getRecoveryKeyId() {
  174. return $this->recoveryKeyId;
  175. }
  176. /**
  177. * @param string $password
  178. * @return bool
  179. */
  180. public function checkRecoveryPassword($password) {
  181. $recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.' . $this->privateKeyId, Encryption::ID);
  182. $decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $password);
  183. if ($decryptedRecoveryKey) {
  184. return true;
  185. }
  186. return false;
  187. }
  188. /**
  189. * @param string $uid
  190. * @param string $password
  191. * @param array $keyPair
  192. * @return bool
  193. */
  194. public function storeKeyPair($uid, $password, $keyPair) {
  195. // Save Public Key
  196. $this->setPublicKey($uid, $keyPair['publicKey']);
  197. $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password, $uid);
  198. $header = $this->crypt->generateHeader();
  199. if ($encryptedKey) {
  200. $this->setPrivateKey($uid, $header . $encryptedKey);
  201. return true;
  202. }
  203. return false;
  204. }
  205. /**
  206. * @param string $password
  207. * @param array $keyPair
  208. * @return bool
  209. */
  210. public function setRecoveryKey($password, $keyPair) {
  211. // Save Public Key
  212. $this->keyStorage->setSystemUserKey($this->getRecoveryKeyId().
  213. '.' . $this->publicKeyId,
  214. $keyPair['publicKey'],
  215. Encryption::ID);
  216. $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password);
  217. $header = $this->crypt->generateHeader();
  218. if ($encryptedKey) {
  219. $this->setSystemPrivateKey($this->getRecoveryKeyId(), $header . $encryptedKey);
  220. return true;
  221. }
  222. return false;
  223. }
  224. /**
  225. * @param $userId
  226. * @param $key
  227. * @return bool
  228. */
  229. public function setPublicKey($userId, $key) {
  230. return $this->keyStorage->setUserKey($userId, $this->publicKeyId, $key, Encryption::ID);
  231. }
  232. /**
  233. * @param $userId
  234. * @param string $key
  235. * @return bool
  236. */
  237. public function setPrivateKey($userId, $key) {
  238. return $this->keyStorage->setUserKey($userId,
  239. $this->privateKeyId,
  240. $key,
  241. Encryption::ID);
  242. }
  243. /**
  244. * write file key to key storage
  245. *
  246. * @param string $path
  247. * @param string $key
  248. * @return boolean
  249. */
  250. public function setFileKey($path, $key) {
  251. return $this->keyStorage->setFileKey($path, $this->fileKeyId, $key, Encryption::ID);
  252. }
  253. /**
  254. * set all file keys (the file key and the corresponding share keys)
  255. *
  256. * @param string $path
  257. * @param array $keys
  258. */
  259. public function setAllFileKeys($path, $keys) {
  260. $this->setFileKey($path, $keys['data']);
  261. foreach ($keys['keys'] as $uid => $keyFile) {
  262. $this->setShareKey($path, $uid, $keyFile);
  263. }
  264. }
  265. /**
  266. * write share key to the key storage
  267. *
  268. * @param string $path
  269. * @param string $uid
  270. * @param string $key
  271. * @return boolean
  272. */
  273. public function setShareKey($path, $uid, $key) {
  274. $keyId = $uid . '.' . $this->shareKeyId;
  275. return $this->keyStorage->setFileKey($path, $keyId, $key, Encryption::ID);
  276. }
  277. /**
  278. * Decrypt private key and store it
  279. *
  280. * @param string $uid user id
  281. * @param string $passPhrase users password
  282. * @return boolean
  283. */
  284. public function init($uid, $passPhrase) {
  285. $this->session->setStatus(Session::INIT_EXECUTED);
  286. try {
  287. if ($this->util->isMasterKeyEnabled()) {
  288. $uid = $this->getMasterKeyId();
  289. $passPhrase = $this->getMasterKeyPassword();
  290. $privateKey = $this->getSystemPrivateKey($uid);
  291. } else {
  292. $privateKey = $this->getPrivateKey($uid);
  293. }
  294. $privateKey = $this->crypt->decryptPrivateKey($privateKey, $passPhrase, $uid);
  295. } catch (PrivateKeyMissingException $e) {
  296. return false;
  297. } catch (DecryptionFailedException $e) {
  298. return false;
  299. } catch (\Exception $e) {
  300. $this->logger->warning(
  301. 'Could not decrypt the private key from user "' . $uid . '"" during login. Assume password change on the user back-end.',
  302. [
  303. 'app' => 'encryption',
  304. 'exception' => $e,
  305. ]
  306. );
  307. return false;
  308. }
  309. if ($privateKey) {
  310. $this->session->setPrivateKey($privateKey);
  311. $this->session->setStatus(Session::INIT_SUCCESSFUL);
  312. return true;
  313. }
  314. return false;
  315. }
  316. /**
  317. * @param $userId
  318. * @return string
  319. * @throws PrivateKeyMissingException
  320. */
  321. public function getPrivateKey($userId) {
  322. $privateKey = $this->keyStorage->getUserKey($userId,
  323. $this->privateKeyId, Encryption::ID);
  324. if (strlen($privateKey) !== 0) {
  325. return $privateKey;
  326. }
  327. throw new PrivateKeyMissingException($userId);
  328. }
  329. /**
  330. * @param string $path
  331. * @param $uid
  332. * @param ?bool $useLegacyFileKey null means try both
  333. * @return string
  334. */
  335. public function getFileKey(string $path, ?string $uid, ?bool $useLegacyFileKey): string {
  336. if ($uid === '') {
  337. $uid = null;
  338. }
  339. $publicAccess = is_null($uid);
  340. $encryptedFileKey = '';
  341. if ($useLegacyFileKey ?? true) {
  342. $encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId, Encryption::ID);
  343. if (empty($encryptedFileKey) && $useLegacyFileKey) {
  344. return '';
  345. }
  346. }
  347. if ($this->util->isMasterKeyEnabled()) {
  348. $uid = $this->getMasterKeyId();
  349. $shareKey = $this->getShareKey($path, $uid);
  350. if ($publicAccess) {
  351. $privateKey = $this->getSystemPrivateKey($uid);
  352. $privateKey = $this->crypt->decryptPrivateKey($privateKey, $this->getMasterKeyPassword(), $uid);
  353. } else {
  354. // when logged in, the master key is already decrypted in the session
  355. $privateKey = $this->session->getPrivateKey();
  356. }
  357. } elseif ($publicAccess) {
  358. // use public share key for public links
  359. $uid = $this->getPublicShareKeyId();
  360. $shareKey = $this->getShareKey($path, $uid);
  361. $privateKey = $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.' . $this->privateKeyId, Encryption::ID);
  362. $privateKey = $this->crypt->decryptPrivateKey($privateKey);
  363. } else {
  364. $shareKey = $this->getShareKey($path, $uid);
  365. $privateKey = $this->session->getPrivateKey();
  366. }
  367. if ($useLegacyFileKey ?? true) {
  368. if ($encryptedFileKey && $shareKey && $privateKey) {
  369. return $this->crypt->multiKeyDecryptLegacy($encryptedFileKey,
  370. $shareKey,
  371. $privateKey);
  372. }
  373. }
  374. if (!($useLegacyFileKey ?? false)) {
  375. if ($shareKey && $privateKey) {
  376. return $this->crypt->multiKeyDecrypt($shareKey, $privateKey);
  377. }
  378. }
  379. return '';
  380. }
  381. /**
  382. * Get the current version of a file
  383. *
  384. * @param string $path
  385. * @param View $view
  386. * @return int
  387. */
  388. public function getVersion($path, View $view) {
  389. $fileInfo = $view->getFileInfo($path);
  390. if ($fileInfo === false) {
  391. return 0;
  392. }
  393. return $fileInfo->getEncryptedVersion();
  394. }
  395. /**
  396. * Set the current version of a file
  397. *
  398. * @param string $path
  399. * @param int $version
  400. * @param View $view
  401. */
  402. public function setVersion($path, $version, View $view) {
  403. $fileInfo = $view->getFileInfo($path);
  404. if ($fileInfo !== false) {
  405. $cache = $fileInfo->getStorage()->getCache();
  406. $cache->update($fileInfo->getId(), ['encrypted' => $version, 'encryptedVersion' => $version]);
  407. }
  408. }
  409. /**
  410. * get the encrypted file key
  411. *
  412. * @param string $path
  413. * @return string
  414. */
  415. public function getEncryptedFileKey($path) {
  416. $encryptedFileKey = $this->keyStorage->getFileKey($path,
  417. $this->fileKeyId, Encryption::ID);
  418. return $encryptedFileKey;
  419. }
  420. /**
  421. * delete share key
  422. *
  423. * @param string $path
  424. * @param string $keyId
  425. * @return boolean
  426. */
  427. public function deleteShareKey($path, $keyId) {
  428. return $this->keyStorage->deleteFileKey(
  429. $path,
  430. $keyId . '.' . $this->shareKeyId,
  431. Encryption::ID);
  432. }
  433. /**
  434. * @param $path
  435. * @param $uid
  436. * @return mixed
  437. */
  438. public function getShareKey($path, $uid) {
  439. $keyId = $uid . '.' . $this->shareKeyId;
  440. return $this->keyStorage->getFileKey($path, $keyId, Encryption::ID);
  441. }
  442. /**
  443. * check if user has a private and a public key
  444. *
  445. * @param string $userId
  446. * @return bool
  447. * @throws PrivateKeyMissingException
  448. * @throws PublicKeyMissingException
  449. */
  450. public function userHasKeys($userId) {
  451. $privateKey = $publicKey = true;
  452. $exception = null;
  453. try {
  454. $this->getPrivateKey($userId);
  455. } catch (PrivateKeyMissingException $e) {
  456. $privateKey = false;
  457. $exception = $e;
  458. }
  459. try {
  460. $this->getPublicKey($userId);
  461. } catch (PublicKeyMissingException $e) {
  462. $publicKey = false;
  463. $exception = $e;
  464. }
  465. if ($privateKey && $publicKey) {
  466. return true;
  467. } elseif (!$privateKey && !$publicKey) {
  468. return false;
  469. } else {
  470. throw $exception;
  471. }
  472. }
  473. /**
  474. * @param $userId
  475. * @return mixed
  476. * @throws PublicKeyMissingException
  477. */
  478. public function getPublicKey($userId) {
  479. $publicKey = $this->keyStorage->getUserKey($userId, $this->publicKeyId, Encryption::ID);
  480. if (strlen($publicKey) !== 0) {
  481. return $publicKey;
  482. }
  483. throw new PublicKeyMissingException($userId);
  484. }
  485. public function getPublicShareKeyId() {
  486. return $this->publicShareKeyId;
  487. }
  488. /**
  489. * get public key for public link shares
  490. *
  491. * @return string
  492. */
  493. public function getPublicShareKey() {
  494. return $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.' . $this->publicKeyId, Encryption::ID);
  495. }
  496. /**
  497. * @param string $purpose
  498. * @param string $uid
  499. */
  500. public function backupUserKeys($purpose, $uid) {
  501. $this->keyStorage->backupUserKeys(Encryption::ID, $purpose, $uid);
  502. }
  503. /**
  504. * create a backup of the users private and public key and then delete it
  505. *
  506. * @param string $uid
  507. */
  508. public function deleteUserKeys($uid) {
  509. $this->deletePublicKey($uid);
  510. $this->deletePrivateKey($uid);
  511. }
  512. /**
  513. * @param $uid
  514. * @return bool
  515. */
  516. public function deletePublicKey($uid) {
  517. return $this->keyStorage->deleteUserKey($uid, $this->publicKeyId, Encryption::ID);
  518. }
  519. /**
  520. * @param string $uid
  521. * @return bool
  522. */
  523. private function deletePrivateKey($uid) {
  524. return $this->keyStorage->deleteUserKey($uid, $this->privateKeyId, Encryption::ID);
  525. }
  526. /**
  527. * @param string $path
  528. * @return bool
  529. */
  530. public function deleteAllFileKeys($path) {
  531. return $this->keyStorage->deleteAllFileKeys($path);
  532. }
  533. public function deleteLegacyFileKey(string $path): bool {
  534. return $this->keyStorage->deleteFileKey($path, $this->fileKeyId, Encryption::ID);
  535. }
  536. /**
  537. * @param array $userIds
  538. * @return array
  539. * @throws PublicKeyMissingException
  540. */
  541. public function getPublicKeys(array $userIds) {
  542. $keys = [];
  543. foreach ($userIds as $userId) {
  544. try {
  545. $keys[$userId] = $this->getPublicKey($userId);
  546. } catch (PublicKeyMissingException $e) {
  547. continue;
  548. }
  549. }
  550. return $keys;
  551. }
  552. /**
  553. * @param string $keyId
  554. * @return string returns openssl key
  555. */
  556. public function getSystemPrivateKey($keyId) {
  557. return $this->keyStorage->getSystemUserKey($keyId . '.' . $this->privateKeyId, Encryption::ID);
  558. }
  559. /**
  560. * @param string $keyId
  561. * @param string $key
  562. * @return string returns openssl key
  563. */
  564. public function setSystemPrivateKey($keyId, $key) {
  565. return $this->keyStorage->setSystemUserKey(
  566. $keyId . '.' . $this->privateKeyId,
  567. $key,
  568. Encryption::ID);
  569. }
  570. /**
  571. * add system keys such as the public share key and the recovery key
  572. *
  573. * @param array $accessList
  574. * @param array $publicKeys
  575. * @param string $uid
  576. * @return array
  577. * @throws PublicKeyMissingException
  578. */
  579. public function addSystemKeys(array $accessList, array $publicKeys, $uid) {
  580. if (!empty($accessList['public'])) {
  581. $publicShareKey = $this->getPublicShareKey();
  582. if (empty($publicShareKey)) {
  583. throw new PublicKeyMissingException($this->getPublicShareKeyId());
  584. }
  585. $publicKeys[$this->getPublicShareKeyId()] = $publicShareKey;
  586. }
  587. if ($this->recoveryKeyExists() &&
  588. $this->util->isRecoveryEnabledForUser($uid)) {
  589. $publicKeys[$this->getRecoveryKeyId()] = $this->getRecoveryKey();
  590. }
  591. return $publicKeys;
  592. }
  593. /**
  594. * get master key password
  595. *
  596. * @return string
  597. * @throws \Exception
  598. */
  599. public function getMasterKeyPassword() {
  600. $password = $this->config->getSystemValue('secret');
  601. if (empty($password)) {
  602. throw new \Exception('Can not get secret from Nextcloud instance');
  603. }
  604. return $password;
  605. }
  606. /**
  607. * return master key id
  608. *
  609. * @return string
  610. */
  611. public function getMasterKeyId() {
  612. return $this->masterKeyId;
  613. }
  614. /**
  615. * get public master key
  616. *
  617. * @return string
  618. */
  619. public function getPublicMasterKey() {
  620. return $this->keyStorage->getSystemUserKey($this->masterKeyId . '.' . $this->publicKeyId, Encryption::ID);
  621. }
  622. /**
  623. * get public master key
  624. *
  625. * @return string
  626. */
  627. public function getPrivateMasterKey() {
  628. return $this->keyStorage->getSystemUserKey($this->masterKeyId . '.' . $this->privateKeyId, Encryption::ID);
  629. }
  630. }