mirror of
https://github.com/LibreSign/libresign.git
synced 2025-12-17 21:12:16 +01:00
160 lines
4.8 KiB
PHP
160 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
/**
|
|
* SPDX-FileCopyrightText: 2020-2024 LibreCode coop and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\Libresign\Handler;
|
|
|
|
use OC\SystemConfig;
|
|
use OCA\Libresign\Exception\LibresignException;
|
|
use OCA\Libresign\Handler\CertificateEngine\Handler as CertificateEngineHandler;
|
|
use OCA\Libresign\Service\FolderService;
|
|
use OCP\AppFramework\Services\IAppConfig;
|
|
use OCP\Files\File;
|
|
use OCP\IL10N;
|
|
use TypeError;
|
|
|
|
class Pkcs12Handler extends SignEngineHandler {
|
|
private string $pfxFilename = 'signature.pfx';
|
|
private string $pfxContent = '';
|
|
|
|
public function __construct(
|
|
private FolderService $folderService,
|
|
private IAppConfig $appConfig,
|
|
private SystemConfig $systemConfig,
|
|
private CertificateEngineHandler $certificateEngineHandler,
|
|
private IL10N $l10n,
|
|
private JSignPdfHandler $jSignPdfHandler,
|
|
private FooterHandler $footerHandler,
|
|
) {
|
|
}
|
|
|
|
public function savePfx(string $uid, string $content): string {
|
|
$this->folderService->setUserId($uid);
|
|
$folder = $this->folderService->getFolder();
|
|
if ($folder->nodeExists($this->pfxFilename)) {
|
|
$file = $folder->get($this->pfxFilename);
|
|
if (!$file instanceof File) {
|
|
throw new LibresignException("path {$this->pfxFilename} already exists and is not a file!", 400);
|
|
}
|
|
$file->putContent($content);
|
|
return $content;
|
|
}
|
|
|
|
$file = $folder->newFile($this->pfxFilename);
|
|
$file->putContent($content);
|
|
return $content;
|
|
}
|
|
|
|
public function deletePfx(string $uid): void {
|
|
$this->folderService->setUserId($uid);
|
|
$folder = $this->folderService->getFolder();
|
|
try {
|
|
$file = $folder->get($this->pfxFilename);
|
|
$file->delete();
|
|
} catch (\Throwable $th) {
|
|
}
|
|
}
|
|
|
|
public function updatePassword(string $uid, string $currentPrivateKey, string $newPrivateKey): string {
|
|
$pfx = $this->getPfx($uid);
|
|
$content = $this->certificateEngineHandler->getEngine()->updatePassword(
|
|
$pfx,
|
|
$currentPrivateKey,
|
|
$newPrivateKey
|
|
);
|
|
return $this->savePfx($uid, $content);
|
|
}
|
|
|
|
public function readCertificate(string $uid, string $privateKey): array {
|
|
$this->setPassword($privateKey);
|
|
$pfx = $this->getPfx($uid);
|
|
return $this->certificateEngineHandler->getEngine()->readCertificate(
|
|
$pfx,
|
|
$privateKey
|
|
);
|
|
}
|
|
|
|
public function setPfxContent(string $content): void {
|
|
$this->pfxContent = $content;
|
|
}
|
|
|
|
/**
|
|
* Get content of pfx file
|
|
*/
|
|
public function getPfx(?string $uid = null): string {
|
|
if (!empty($this->pfxContent) || empty($uid)) {
|
|
return $this->pfxContent;
|
|
}
|
|
$this->folderService->setUserId($uid);
|
|
$folder = $this->folderService->getFolder();
|
|
if (!$folder->nodeExists($this->pfxFilename)) {
|
|
throw new LibresignException($this->l10n->t('Password to sign not defined. Create a password to sign.'), 400);
|
|
}
|
|
/** @var \OCP\Files\File */
|
|
$node = $folder->get($this->pfxFilename);
|
|
$this->pfxContent = $node->getContent();
|
|
if (empty($this->pfxContent)) {
|
|
throw new LibresignException($this->l10n->t('Password to sign not defined. Create a password to sign.'), 400);
|
|
}
|
|
if ($this->getPassword()) {
|
|
$this->certificateEngineHandler->getEngine()->opensslPkcs12Read($this->pfxContent, $this->getPassword());
|
|
}
|
|
return $this->pfxContent;
|
|
}
|
|
|
|
private function getHandler(): SignEngineHandler {
|
|
$sign_engine = $this->appConfig->getAppValue('sign_engine', 'JSignPdf');
|
|
$property = lcfirst($sign_engine) . 'Handler';
|
|
if (!property_exists($this, $property)) {
|
|
throw new LibresignException($this->l10n->t('Invalid Sign engine.'), 400);
|
|
}
|
|
$classHandler = 'OCA\\Libresign\\Handler\\' . $property;
|
|
if (!$this->$property instanceof $classHandler) {
|
|
$this->$property = \OCP\Server::get($classHandler);
|
|
}
|
|
return $this->$property;
|
|
}
|
|
|
|
public function sign(): File {
|
|
$signedContent = $this->getHandler()
|
|
->setCertificate($this->getCertificate())
|
|
->setInputFile($this->getInputFile())
|
|
->setPassword($this->getPassword())
|
|
->setVisibleElements($this->getvisibleElements())
|
|
->sign();
|
|
$this->getInputFile()->putContent($signedContent);
|
|
return $this->getInputFile();
|
|
}
|
|
|
|
public function isHandlerOk(): bool {
|
|
return $this->certificateEngineHandler->getEngine()->isSetupOk();
|
|
}
|
|
|
|
/**
|
|
* Generate certificate
|
|
*
|
|
* @param array $user Example: ['host' => '', 'name' => '']
|
|
* @param string $signPassword Password of signature
|
|
* @param string $friendlyName Friendly name
|
|
* @param bool $isTempFile
|
|
*/
|
|
public function generateCertificate(array $user, string $signPassword, string $friendlyName, bool $isTempFile = false): string {
|
|
$content = $this->certificateEngineHandler->getEngine()
|
|
->setHosts([$user['host']])
|
|
->setCommonName($user['name'])
|
|
->setFriendlyName($friendlyName)
|
|
->setPassword($signPassword)
|
|
->generateCertificate();
|
|
if (!$content) {
|
|
throw new TypeError();
|
|
}
|
|
if ($isTempFile) {
|
|
return $content;
|
|
}
|
|
return $content;
|
|
}
|
|
}
|