From e23e89f3849d21199990566476420f4a670138c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Sun, 18 Feb 2024 23:10:25 +0100 Subject: [PATCH] feat(occ): Add user:keys:test command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- core/Command/User/Keys/Verify.php | 100 ++++++++++++++++++++ core/register_command.php | 1 + lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + 4 files changed, 103 insertions(+) create mode 100644 core/Command/User/Keys/Verify.php diff --git a/core/Command/User/Keys/Verify.php b/core/Command/User/Keys/Verify.php new file mode 100644 index 00000000000..c4264457572 --- /dev/null +++ b/core/Command/User/Keys/Verify.php @@ -0,0 +1,100 @@ + + * + * @author Marcel Müller + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OC\Core\Command\User\Keys; + +use OC\Security\IdentityProof\Manager; +use OCP\IUser; +use OCP\IUserManager; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class Verify extends Command { + public function __construct( + protected IUserManager $userManager, + protected Manager $keyManager, + ) { + parent::__construct(); + } + + protected function configure(): void { + $this + ->setName('user:keys:verify') + ->setDescription('Verify if the stored public key matches the stored private key') + ->addArgument( + 'user-id', + InputArgument::REQUIRED, + 'User ID of the user to verify' + ) + ; + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output): int { + $userId = $input->getArgument('user-id'); + + $user = $this->userManager->get($userId); + if (!$user instanceof IUser) { + $output->writeln('Unknown user'); + return static::FAILURE; + } + + $key = $this->keyManager->getKey($user); + $publicKey = $key->getPublic(); + $privateKey = $key->getPrivate(); + + $output->writeln('User public key size: ' . strlen($publicKey)); + $output->writeln('User private key size: ' . strlen($privateKey)); + + // Derive the public key from the private key again to validate the stored public key + $opensslPrivateKey = openssl_pkey_get_private($privateKey); + $publicKeyDerived = openssl_pkey_get_details($opensslPrivateKey); + $publicKeyDerived = $publicKeyDerived['key']; + $output->writeln('User derived public key size: ' . strlen($publicKeyDerived)); + + $output->writeln(''); + + $output->writeln('Stored public key:'); + $output->writeln($publicKey); + $output->writeln('Derived public key:'); + $output->writeln($publicKeyDerived); + + if ($publicKey != $publicKeyDerived) { + $output->writeln('Stored public key does not match stored private key'); + return static::FAILURE; + } + + $output->writeln('Stored public key matches stored private key'); + + return static::SUCCESS; + } +} diff --git a/core/register_command.php b/core/register_command.php index ac585214906..4a84e551ce0 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -161,6 +161,7 @@ if ($config->getSystemValueBool('installed', false)) { $application->add(Server::get(Command\User\AuthTokens\Add::class)); $application->add(Server::get(Command\User\AuthTokens\ListCommand::class)); $application->add(Server::get(Command\User\AuthTokens\Delete::class)); + $application->add(Server::get(Command\User\Keys\Verify::class)); $application->add(Server::get(Command\Group\Add::class)); $application->add(Server::get(Command\Group\Delete::class)); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index e041c3c4d21..d5c89d0237f 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -1124,6 +1124,7 @@ return array( 'OC\\Core\\Command\\User\\Disable' => $baseDir . '/core/Command/User/Disable.php', 'OC\\Core\\Command\\User\\Enable' => $baseDir . '/core/Command/User/Enable.php', 'OC\\Core\\Command\\User\\Info' => $baseDir . '/core/Command/User/Info.php', + 'OC\\Core\\Command\\User\\Keys\\Verify' => $baseDir . '/core/Command/User/Keys/Verify.php', 'OC\\Core\\Command\\User\\LastSeen' => $baseDir . '/core/Command/User/LastSeen.php', 'OC\\Core\\Command\\User\\ListCommand' => $baseDir . '/core/Command/User/ListCommand.php', 'OC\\Core\\Command\\User\\Report' => $baseDir . '/core/Command/User/Report.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index e75a1d0ec63..906a5ac1996 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -1157,6 +1157,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Core\\Command\\User\\Disable' => __DIR__ . '/../../..' . '/core/Command/User/Disable.php', 'OC\\Core\\Command\\User\\Enable' => __DIR__ . '/../../..' . '/core/Command/User/Enable.php', 'OC\\Core\\Command\\User\\Info' => __DIR__ . '/../../..' . '/core/Command/User/Info.php', + 'OC\\Core\\Command\\User\\Keys\\Verify' => __DIR__ . '/../../..' . '/core/Command/User/Keys/Verify.php', 'OC\\Core\\Command\\User\\LastSeen' => __DIR__ . '/../../..' . '/core/Command/User/LastSeen.php', 'OC\\Core\\Command\\User\\ListCommand' => __DIR__ . '/../../..' . '/core/Command/User/ListCommand.php', 'OC\\Core\\Command\\User\\Report' => __DIR__ . '/../../..' . '/core/Command/User/Report.php',