From 44ba9bf8582f5c313f9590cce1d35fde026df66c Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 11 May 2021 09:54:55 +0200 Subject: Enhance identify proof storage Signed-off-by: Roeland Jago Douma --- lib/private/Security/IdentityProof/Manager.php | 64 +++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/lib/private/Security/IdentityProof/Manager.php b/lib/private/Security/IdentityProof/Manager.php index 49b9bb10c3e..6e2aa61d9ac 100644 --- a/lib/private/Security/IdentityProof/Manager.php +++ b/lib/private/Security/IdentityProof/Manager.php @@ -31,6 +31,7 @@ namespace OC\Security\IdentityProof; use OC\Files\AppData\Factory; use OCP\Files\IAppData; +use OCP\Files\SimpleFS\ISimpleFolder; use OCP\IConfig; use OCP\IUser; use OCP\Security\ICrypto; @@ -97,14 +98,39 @@ class Manager { } catch (\Exception $e) { } $folder = $this->appData->getFolder($id); - $folder->newFile('private') - ->putContent($this->crypto->encrypt($privateKey)); - $folder->newFile('public') - ->putContent($publicKey); + $folder->newFile('private_enc') + ->putContent($this->encrypt($privateKey, $id)); + $folder->newFile('public_enc') + ->putContent($this->encrypt($publicKey, $id)); return new Key($publicKey, $privateKey); } + private function encrypt(string $key, string $id): string { + $data = [ + 'key' => $key, + 'id' => $id, + 'version' => 1 + ]; + + return $this->crypto->encrypt(json_encode($data)); + } + + private function decrypt(string $cipherText, string $id): string { + $plain = $this->crypto->decrypt($cipherText); + $data = json_decode($plain, true); + + if ($data['version'] !== 1) { + throw new \RuntimeException('Invalid version'); + } + + if ($data['id'] !== $id) { + throw new \RuntimeException($data['id'] . ' does not match ' . $id); + } + + return $data['key']; + } + /** * Get key for a specific id * @@ -113,16 +139,40 @@ class Manager { protected function retrieveKey(string $id): Key { try { $folder = $this->appData->getFolder($id); - $privateKey = $this->crypto->decrypt( - $folder->getFile('private')->getContent() + + $this->migrate($folder, $id); + + $privateKey = $this->decrypt( + $folder->getFile('private_enc')->getContent(), + $id ); - $publicKey = $folder->getFile('public')->getContent(); + $publicKey = $this->decrypt( + $folder->getFile('public_enc')->getContent(), + $id + ); + return new Key($publicKey, $privateKey); } catch (\Exception $e) { return $this->generateKey($id); } } + private function migrate(ISimpleFolder $folder, string $id): void { + if (!$folder->fileExists('private') && !$folder->fileExists('public')) { + return; + } + + $private = $folder->getFile('private'); + $folder->newFile('private_enc') + ->putContent($this->encrypt($this->crypto->decrypt($private->getContent()), $id)); + $private->delete(); + + $public = $folder->getFile('public'); + $folder->newFile('public_enc') + ->putContent($this->encrypt($public->getContent(), $id)); + $public->delete(); + } + /** * Get public and private key for $user * -- cgit v1.2.3