Skip to content

Commit

Permalink
Merge pull request #3127 from LibreSign/backport/2594/stable28
Browse files Browse the repository at this point in the history
[stable28] Sign setup
  • Loading branch information
vitormattos authored Jun 5, 2024
2 parents ac958ca + c90ee5c commit 412f890
Show file tree
Hide file tree
Showing 16 changed files with 980 additions and 227 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ node_modules/
.phpunit.result.cache
*.phar
/src/__test__/coverage
/appinfo/install-*.json
71 changes: 20 additions & 51 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ appstore_sign_dir=$(appstore_build_directory)/sign
cert_dir=$(build_tools_directory)/certificates
npm=$(shell which npm 2> /dev/null)
composer=$(shell which composer 2> /dev/null)
ifeq (,$(shell type occ))
occ="php ../../occ"
else
occ="occ"
endif

all: dev-setup build-js-production
serve: dev-setup watch-js
Expand Down Expand Up @@ -82,49 +87,7 @@ updateocp:

# Builds the source package for the app store, ignores php and js tests
.PHONY: appstore
appstore:
rm -rf $(appstore_build_directory)
mkdir -p $(appstore_sign_dir)/$(app_name)
cp -r \
appinfo \
composer \
img \
js \
l10n \
lib \
templates \
vendor \
CHANGELOG.md \
LICENSE \
$(appstore_sign_dir)/$(app_name)

rm $(appstore_sign_dir)/$(app_name)/vendor/endroid/qr-code/assets/*
mkdir -p $(appstore_sign_dir)/$(app_name)/tests/fixtures
cp tests/fixtures/small_valid.pdf $(appstore_sign_dir)/$(app_name)/tests/fixtures

# Remove stray .htaccess files since they are filtered by Nextcloud
find $(appstore_sign_dir) -name .htaccess -exec rm {} \;

@if [ -f $(cert_dir)/$(app_name).key ]; then \
echo "Signing app files…"; \
php ../../occ integrity:sign-app \
--privateKey=$(cert_dir)/$(app_name).key\
--certificate=$(cert_dir)/$(app_name).crt\
--path=$(appstore_sign_dir)/$(app_name); \
fi
tar -czf $(appstore_package_name).tar.gz \
-C $(appstore_sign_dir) $(app_name)

@if [ -f $(cert_dir)/$(app_name).key ]; then \
echo "Signing package…"; \
openssl dgst -sha512 -sign $(cert_dir)/$(app_name).key $(build_dir)/$(app_name).tar.gz | openssl base64; \
fi

# Earlier version of appstore command that builds the app and has some custom
# support for local signing. Left here in case it's needed by some developer
# used to it.
.PHONY: appstore-local
appstore-local: clean
appstore: clean
mkdir -p $(appstore_sign_dir)/$(app_name)
composer install --no-dev
npm ci
Expand All @@ -141,12 +104,19 @@ appstore-local: clean
CHANGELOG.md \
LICENSE \
$(appstore_sign_dir)/$(app_name)

rm $(appstore_sign_dir)/$(app_name)/vendor/endroid/qr-code/assets/*
find $(appstore_sign_dir)/$(app_name)/vendor/mpdf/mpdf/ttfonts -type f -not -name 'DejaVuSerifCondensed.ttf' -delete
find $(appstore_sign_dir)/$(app_name)/vendor/mpdf/mpdf/data/ -type f -delete
rm -rf $(appstore_sign_dir)/$(app_name)/img/screenshot/
mkdir -p $(appstore_sign_dir)/$(app_name)/tests/fixtures
cp tests/fixtures/small_valid.pdf $(appstore_sign_dir)/$(app_name)/tests/fixtures \
cp tests/fixtures/small_valid.pdf $(appstore_sign_dir)/$(app_name)/tests/fixtures

$(occ) config:app:set libresign certificate_engine --value cfssl
$(occ) libresign:install --all
$(occ) libresign:install --all --architecture aarch64
$(occ) libresign:developer:sign-setup --privateKey=$(cert_dir)/$(app_name).key \
--certificate=$(cert_dir)/$(app_name).crt

@if [ -z "$$GITHUB_ACTION" ]; then \
chown -R www-data:www-data $(appstore_sign_dir)/$(app_name) ; \
Expand All @@ -157,18 +127,17 @@ appstore-local: clean
curl -o $(cert_dir)/$(app_name).crt \
"https://github.com/nextcloud/app-certificate-requests/raw/master/$(app_name)/$(app_name).crt"; \
fi
@if [ -n "$$APP_PRIVATE_KEY" ]; then \
echo "$$APP_PRIVATE_KEY" > $(cert_dir)/$(app_name).key; \
@if [ -f $(cert_dir)/$(app_name).key ]; then \
echo "Signing app files…"; \
runuser -u www-data -- \
php ../../occ integrity:sign-app \
$(occ) integrity:sign-app \
--privateKey=$(cert_dir)/$(app_name).key\
--certificate=$(cert_dir)/$(app_name).crt\
--path=$(appstore_sign_dir)/$(app_name); \
echo "Signing app files ... done"; \
fi
tar -czf $(appstore_package_name).tar.gz -C $(appstore_sign_dir) $(app_name)
@if [ -n "$$APP_PRIVATE_KEY" ]; then \
tar -czf $(appstore_package_name).tar.gz \
-C $(appstore_sign_dir) $(app_name)

@if [ -f $(cert_dir)/$(app_name).key ]; then \
echo "Signing package…"; \
openssl dgst -sha512 -sign $(cert_dir)/$(app_name).key $(appstore_package_name).tar.gz | openssl base64; \
fi
6 changes: 6 additions & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,17 @@ Developed with ❤️ by [LibreCode](https://librecode.coop). Help us transform
<architecture>x86_64</architecture>
<architecture>aarch64</architecture>
</dependencies>
<repair-steps>
<post-migration>
<step>OCA\Libresign\Migration\DeleteOldBinaries</step>
</post-migration>
</repair-steps>
<commands>
<command>OCA\Libresign\Command\Configure\Check</command>
<command>OCA\Libresign\Command\Configure\Cfssl</command>
<command>OCA\Libresign\Command\Configure\OpenSsl</command>
<command>OCA\Libresign\Command\Developer\Reset</command>
<command>OCA\Libresign\Command\Developer\SignSetup</command>
<command>OCA\Libresign\Command\Install</command>
<command>OCA\Libresign\Command\Uninstall</command>
</commands>
Expand Down
80 changes: 80 additions & 0 deletions lib/Command/Developer/SignSetup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020-2024 LibreCode coop and contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Libresign\Command\Developer;

use OC\Core\Command\Base;
use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OCA\Libresign\Service\Install\SignSetupService;
use OCP\IConfig;
use phpseclib\Crypt\RSA;
use phpseclib\File\X509;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class SignSetup extends Base {
public function __construct(
private IConfig $config,
private FileAccessHelper $fileAccessHelper,
private SignSetupService $signSetupService,
) {
parent::__construct();
}

public function isEnabled(): bool {
return $this->config->getSystemValue('debug', false) === true;
}

protected function configure(): void {
$this
->setName('libresign:developer:sign-setup')
->setDescription('Clean all LibreSign data')
->addOption('privateKey', null, InputOption::VALUE_REQUIRED, 'Path to private key to use for signing')
->addOption('certificate', null, InputOption::VALUE_REQUIRED, 'Path to certificate to use for signing')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$privateKeyPath = $input->getOption('privateKey');
$keyBundlePath = $input->getOption('certificate');
if (is_null($privateKeyPath) || is_null($keyBundlePath)) {
$output->writeln('This command requires the --path, --privateKey and --certificate.');
$output->writeln('Example: ./occ libresign:developer:sign-setup --privateKey="/libresign/private/myapp.key" --certificate="/libresign/public/mycert.crt"');
return 1;
}

$privateKey = $this->fileAccessHelper->file_get_contents((string) $privateKeyPath);
$keyBundle = $this->fileAccessHelper->file_get_contents((string) $keyBundlePath);
if ($privateKey === false) {
$output->writeln(sprintf('Private key "%s" does not exists.', $privateKeyPath));
return 1;
}

if ($keyBundle === false) {
$output->writeln(sprintf('Certificate "%s" does not exists.', $keyBundlePath));
return 1;
}

$rsa = new RSA();
$rsa->loadKey($privateKey);
$x509 = new X509();
$x509->loadX509($keyBundle);
$x509->setPrivateKey($rsa);
try {
foreach ($this->signSetupService->getArchitectures() as $architecture) {
$this->signSetupService->writeAppSignature($x509, $rsa, $architecture);
}
$output->writeln('Successfully signed');
} catch (\Exception $e) {
$output->writeln('Error: ' . $e->getMessage());
return 1;
}
return 0;
}
}
10 changes: 10 additions & 0 deletions lib/Command/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ protected function configure(): void {
shortcut: null,
mode: InputOption::VALUE_NONE,
description: 'Java'
)
->addOption(
name: 'architecture',
shortcut: null,
mode: InputOption::VALUE_REQUIRED,
description: 'x86_64 or aarch64'
);
}

Expand All @@ -70,6 +76,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->installService->setOutput($output);

try {
$architecture = (string) $input->getOption('architecture');
if (in_array($architecture, ['x86_64', 'aarch64'])) {
$this->installService->setArchitecture($architecture);
}
$all = $input->getOption('all');
if ($input->getOption('java') || $all) {
$this->installService->installJava();
Expand Down
10 changes: 10 additions & 0 deletions lib/Command/Uninstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,23 @@ protected function configure(): void {
shortcut: null,
mode: InputOption::VALUE_NONE,
description: 'Java'
)
->addOption(
name: 'architecture',
shortcut: null,
mode: InputOption::VALUE_REQUIRED,
description: 'x86_64 or aarch64'
);
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$ok = false;

try {
$architecture = (string) $input->getOption('architecture');
if (in_array($architecture, ['x86_64', 'aarch64'])) {
$this->installService->setArchitecture($architecture);
}
$all = $input->getOption('all');
if ($input->getOption('java') || $all) {
$this->installService->uninstallJava();
Expand Down
12 changes: 12 additions & 0 deletions lib/Exception/InvalidSignatureException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 LibreCode coop and contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Libresign\Exception;

class InvalidSignatureException extends \Exception {
}
10 changes: 2 additions & 8 deletions lib/Handler/CertificateEngine/CfsslHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use OC\SystemConfig;
use OCA\Libresign\AppInfo\Application;
use OCA\Libresign\Exception\LibresignException;
use OCA\Libresign\Handler\CfsslServerHandler;
use OCA\Libresign\Helper\ConfigureCheckHelper;
Expand Down Expand Up @@ -374,8 +373,8 @@ private function checkBinaries(): array {
->setResource('cfssl'),
];
}
$cfsslInstalled = $this->appConfig->getAppValue('cfssl_bin');
if (!$cfsslInstalled) {
$binary = $this->appConfig->getAppValue('cfssl_bin');
if (!$binary) {
return [
(new ConfigureCheckHelper())
->setErrorMessage('CFSSL not installed.')
Expand All @@ -384,11 +383,6 @@ private function checkBinaries(): array {
];
}

$instanceId = $this->systemConfig->getValue('instanceid', null);
$binary = $this->systemConfig->getValue('datadirectory', \OC::$SERVERROOT . '/data/') . DIRECTORY_SEPARATOR .
'appdata_' . $instanceId . DIRECTORY_SEPARATOR .
Application::APP_ID . DIRECTORY_SEPARATOR .
'cfssl';
if (!file_exists($binary)) {
return [
(new ConfigureCheckHelper())
Expand Down
58 changes: 58 additions & 0 deletions lib/Migration/DeleteOldBinaries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 LibreCode coop and contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Libresign\Migration;

use OCP\Files\AppData\IAppDataFactory;
use OCP\Files\IAppData;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;

class DeleteOldBinaries implements IRepairStep {
protected IAppData $appData;
protected IOutput $output;
protected array $allowedFiles = [
'x86_64',
'aarch64',
'openssl_config',
'cfssl_config',
'unauthenticated',
];
public function __construct(
protected IAppDataFactory $appDataFactory,
) {
$this->appData = $appDataFactory->get('libresign');
}

public function getName(): string {
return 'Delete old binaries.';
}

public function run(IOutput $output): void {
$output->warning('Run the follow command first: files:scan-app-data libresign');
$this->output = $output;
$folder = $this->appData->getFolder('/');

$list = $this->getDirectoryListing($folder);
foreach ($list as $file) {
if (!in_array($file->getName(), $this->allowedFiles)) {
$file->delete();
}
}
}

private function getDirectoryListing(ISimpleFolder $node): array {
$reflection = new \ReflectionClass($node);
$reflectionProperty = $reflection->getProperty('folder');
$reflectionProperty->setAccessible(true);
$folder = $reflectionProperty->getValue($node);
$list = $folder->getDirectoryListing();
return $list;
}
}
Loading

0 comments on commit 412f890

Please sign in to comment.