Skip to content

Commit

Permalink
Add info.xml
Browse files Browse the repository at this point in the history
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
  • Loading branch information
rullzer authored and nickvergessen committed Jan 8, 2021
1 parent a074c3c commit e0802d8
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 23 deletions.
44 changes: 21 additions & 23 deletions lib/private/IntegrityCheck/Checker.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@

namespace OC\IntegrityCheck;

use OC\App\InfoParser;
use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder;
use OC\IntegrityCheck\Exceptions\InvalidSignatureException;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OC\IntegrityCheck\Helpers\InfoParser;
use OC\IntegrityCheck\Iterator\ExcludeFileByNameFilterIterator;
use OC\IntegrityCheck\Iterator\ExcludeFoldersByPathFilterIterator;
use OCP\App\IAppManager;
Expand Down Expand Up @@ -77,6 +77,8 @@ class Checker {
private $tempManager;
/** @var IMimeTypeDetector */
private $mimeTypeDetector;
/** @var InfoParser */
private $infoParser;

/**
* @param EnvironmentHelper $environmentHelper
Expand All @@ -90,6 +92,7 @@ class Checker {
*/
public function __construct(EnvironmentHelper $environmentHelper,
FileAccessHelper $fileAccessHelper,
InfoParser $infoParser,
AppLocator $appLocator,
IConfig $config = null,
ICacheFactory $cacheFactory,
Expand All @@ -104,6 +107,7 @@ public function __construct(EnvironmentHelper $environmentHelper,
$this->appManager = $appManager;
$this->tempManager = $tempManager;
$this->mimeTypeDetector = $mimeTypeDetector;
$this->infoParser = $infoParser;
}

/**
Expand Down Expand Up @@ -239,17 +243,17 @@ private function createSignatureData(array $hashes,
$privateKey->setHash('sha1');
// See https://tools.ietf.org/html/rfc3447#page-38
$privateKey->setSaltLength(0);
$signature = $privateKey->sign(json_encode($hashes));
$sha1signature = $privateKey->sign(json_encode($hashes));

$privateKey->setHash('sha512');
$newSignature = $privateKey->sign(json_encode($hashes));
$sha512signature = $privateKey->sign(json_encode($hashes));

return [
'hashes' => $hashes,
'signature' => base64_encode($signature),
'signature' => base64_encode($sha1signature),
'signatures' => [
'sha1' => base64_encode($signature),
'sha512' => base64_encode($newSignature),
'sha1' => base64_encode($sha1signature),
'sha512' => base64_encode($sha512signature),
],
'certificate' => $certificate->saveX509($certificate->currentCert),
];
Expand Down Expand Up @@ -320,11 +324,12 @@ public function writeCoreSignature(X509 $certificate,
* @param string $signaturePath
* @param string $basePath
* @param string $certificateCN
* @param string|null $forceHash
* @return array
* @throws InvalidSignatureException
* @throws \Exception
*/
private function verify(string $signaturePath, string $basePath, string $certificateCN, bool $forceNewHash = false): array {
private function verify(string $signaturePath, string $basePath, string $certificateCN, ?string $forceHash = null): array {
if (!$this->isCodeCheckEnforced()) {
return [];
}
Expand Down Expand Up @@ -366,10 +371,10 @@ private function verify(string $signaturePath, string $basePath, string $certifi
// See https://tools.ietf.org/html/rfc3447#page-38
$rsa->setSaltLength(0);

if ($forceNewHash || isset($signatureData['signatures'])) {
if ($forceHash && isset($signatureData['signatures'][$forceHash])) {
// Check the sha512 hash
$rsa->setHash('sha512');
if (!$rsa->verify(json_encode($expectedHashes), base64_decode($signatureData['signatures']['sha512']))) {
$rsa->setHash($forceHash);
if (!$rsa->verify(json_encode($expectedHashes), base64_decode($signatureData['signatures'][$forceHash]))) {
throw new InvalidSignatureException('Signature could not get verified.');
}
} else {
Expand Down Expand Up @@ -522,24 +527,17 @@ public function verifyAppSignature(string $appId, string $path = ''): array {
$path = $this->appLocator->getAppPath($appId);
}

$parser = new InfoParser();
$result = $parser->parse($path . '/appinfo/info.xml');

if (!isset($result['dependencies']['nextcloud']['@attributes']['min-version'])) {
throw new \Exception('Could not parse nextcloud dependency');
}

$forceNewHashed = false;
$minVersion = (int)$result['dependencies']['nextcloud']['@attributes']['min-version'];
if ($minVersion >= 21) {
$forceNewHashed = true;
$minVersion = $this->infoParser->getMinVersion($path . '/appinfo/info.xml');
$forceHash = null;
if ($minVersion >= 22) {
$forceHash = 'sha512';
}

$result = $this->verify(
$path . '/appinfo/signature.json',
$path,
$appId,
$forceNewHashed
$forceHash
);
} catch (\Exception $e) {
$result = [
Expand Down Expand Up @@ -590,7 +588,7 @@ public function verifyCoreSignature(): array {
$this->environmentHelper->getServerRoot() . '/core/signature.json',
$this->environmentHelper->getServerRoot(),
'core',
true
'sha512'
);
} catch (\Exception $e) {
$result = [
Expand Down
42 changes: 42 additions & 0 deletions lib/private/IntegrityCheck/Helpers/InfoParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2021, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* 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 <http://www.gnu.org/licenses/>.
*
*/

namespace OC\IntegrityCheck\Helpers;

use OC\App\InfoParser as RealParser;

class InfoParser {
public function getMinVersion(string $infoPath): int {
$parser = new RealParser();
$result = $parser->parse($infoPath);

if (!isset($result['dependencies']['nextcloud']['@attributes']['min-version'])) {
throw new \Exception('Could not parse nextcloud dependency');
}

return (int)$result['dependencies']['nextcloud']['@attributes']['min-version'];
}
}
2 changes: 2 additions & 0 deletions lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OC\IntegrityCheck\Helpers\InfoParser;
use OC\Lock\DBLockingProvider;
use OC\Lock\MemcacheLockingProvider;
use OC\Lock\NoopLockingProvider;
Expand Down Expand Up @@ -938,6 +939,7 @@ public function __construct($webRoot, \OC\Config $config) {
return new Checker(
new EnvironmentHelper(),
new FileAccessHelper(),
new InfoParser(),
new AppLocator(),
$config,
$c->get(ICacheFactory::class),
Expand Down
Loading

0 comments on commit e0802d8

Please sign in to comment.