Skip to content

Commit

Permalink
Merge pull request #1106 from LibreSign/backport/1105/stable25
Browse files Browse the repository at this point in the history
[stable25] Make possible generate root cert with custom values
  • Loading branch information
vitormattos authored Oct 26, 2022
2 parents c1b17e1 + ddbf42e commit 608c034
Show file tree
Hide file tree
Showing 16 changed files with 371 additions and 161 deletions.
9 changes: 7 additions & 2 deletions lib/Controller/AccountController.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ public function createToSign(string $uuid, string $email, string $password, ?str
try {
$data = [
'uuid' => $uuid,
'email' => $email,
'user' => [
'email' => $email,
],
'password' => $password,
'signPassword' => $signPassword
];
Expand Down Expand Up @@ -135,7 +137,10 @@ public function signatureGenerate(
): JSONResponse {
try {
$data = [
'email' => $this->userSession->getUser()->getEMailAddress(),
'user' => [
'email' => $this->userSession->getUser()->getEMailAddress(),
'name' => $this->userSession->getUser()->getDisplayName(),
],
'signPassword' => $signPassword,
'userId' => $this->userSession->getUser()->getUID()
];
Expand Down
14 changes: 6 additions & 8 deletions lib/Controller/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,17 @@ public function __construct(
* @NoCSRFRequired
*/
public function generateCertificate(
string $commonName = null,
string $country = null,
string $organization = null,
string $organizationUnit = null,
array $rootCert,
string $cfsslUri = '',
string $configPath = ''
): DataResponse {
try {
foreach ($rootCert['names'] as $key => $name) {
$rootCert['names'][$key]['value'] = $this->trimAndThrowIfEmpty($key, $rootCert['names'][$key]['value']);
}
$this->installService->generate(
$this->trimAndThrowIfEmpty('commonName', $commonName),
$this->trimAndThrowIfEmpty('country', $country),
$this->trimAndThrowIfEmpty('organization', $organization),
$this->trimAndThrowIfEmpty('organizationUnit', $organizationUnit),
$this->trimAndThrowIfEmpty('commonName', $rootCert['commonName']),
$rootCert['names'],
trim($configPath),
trim($cfsslUri)
);
Expand Down
45 changes: 39 additions & 6 deletions lib/Handler/CfsslHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
* @method string getFriendlyName()
* @method CfsslHandler setCountry(string $country)
* @method string getCountry()
* @method CfsslHandler setState(string $state)
* @method string getState()
* @method CfsslHandler setLocality(string $locality)
* @method string getLocality()
* @method CfsslHandler setOrganization(string $organization)
* @method string getOrganization()
* @method CfsslHandler setOrganizationUnit(string $organizationUnit)
Expand All @@ -42,6 +46,8 @@ class CfsslHandler {
private $hosts = [];
private $friendlyName;
private $country;
private $state;
private $locality;
private $organization;
private $organizationUnit;
private $cfsslUri;
Expand Down Expand Up @@ -77,6 +83,38 @@ public function generateCertificate(): string {
return $certContent;
}

public function translateToLong($name): string {
switch ($name) {
case 'CN':
return 'CommonName';
case 'C':
return 'Country';
case 'ST':
return 'State';
case 'L':
return 'Locality';
case 'O':
return 'Organization';
case 'OU':
return 'OrganizationUnit';
}
return '';
}

public function getNames(): array {
$names = [
'C' => $this->getCountry(),
'ST' => $this->getState(),
'L' => $this->getLocality(),
'O' => $this->getOrganization(),
'OU' => $this->getOrganizationUnit(),
];
$names = array_filter($names, function ($v) {
return !empty($v);
});
return $names;
}

/**
* @psalm-suppress MixedReturnStatement
* @return array
Expand All @@ -93,12 +131,7 @@ private function newCert(): array {
'size' => 2048,
],
'names' => [
[
'C' => $this->getCountry(),
'O' => $this->getOrganization(),
'OU' => $this->getOrganizationUnit(),
'CN' => $this->getCommonName(),
],
$this->getNames(),
],
],
],
Expand Down
23 changes: 6 additions & 17 deletions lib/Handler/CfsslServerHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,21 @@ class CfsslServerHandler {

public function createConfigServer(
string $commonName,
string $country,
string $organization,
string $organizationUnit,
array $names,
string $key,
string $configPath
): void {
$this->putCsrServer(
$commonName,
$country,
$organization,
$organizationUnit,
$names,
$configPath
);
$this->putConfigServer($key, $configPath);
}

private function putCsrServer(
string $commonName,
string $country,
string $organization,
string $organizationUnit,
array $names,
string $configPath
): void {
$filename = $configPath . self::CSR_FILE;
Expand All @@ -40,15 +34,10 @@ private function putCsrServer(
'algo' => 'rsa',
'size' => 2048,
],
'names' => [
[
'C' => $country,
'O' => $organization,
'OU' => $organizationUnit,
'CN' => $commonName,
],
],
];
foreach ($names as $name) {
$content['names'][0][$name['id']] = $name['value'];
}

$response = file_put_contents($filename, json_encode($content));
if ($response === false) {
Expand Down
26 changes: 13 additions & 13 deletions lib/Handler/Pkcs12Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,17 +269,16 @@ private function getQrCodeBlocks(): array {
}

public function getCertificateHandler(): CfsslHandler {
if (!$this->cfsslHandler->getCommonName()) {
$this->cfsslHandler->setCommonName($this->config->getAppValue(Application::APP_ID, 'commonName'));
}
if (!$this->cfsslHandler->getCountry()) {
$this->cfsslHandler->setCountry($this->config->getAppValue(Application::APP_ID, 'country'));
}
if (!$this->cfsslHandler->getOrganization()) {
$this->cfsslHandler->setOrganization($this->config->getAppValue(Application::APP_ID, 'organization'));
$rootCert = $this->config->getAppValue(Application::APP_ID, 'rootCert');
$rootCert = json_decode($rootCert, true);
if (!empty($rootCert['names'])) {
foreach ($rootCert['names'] as $customName) {
$longCustomName = $this->cfsslHandler->translateToLong($customName['id']);
$this->cfsslHandler->{'set' . ucfirst($longCustomName)}($customName['value']);
}
}
if (!$this->cfsslHandler->getOrganizationUnit()) {
$this->cfsslHandler->setOrganizationUnit($this->config->getAppValue(Application::APP_ID, 'organizationUnit'));
if (!$this->cfsslHandler->getCommonName()) {
$this->cfsslHandler->setCommonName($rootCert['commonName']);
}
if (!$this->cfsslHandler->getCfsslUri()) {
$cfsslUri = $this->config->getAppValue(Application::APP_ID, 'cfsslUri');
Expand All @@ -303,14 +302,15 @@ public function getCertificateHandler(): CfsslHandler {
/**
* Generate certificate
*
* @param string $email Email
* @param array $user Example: ['email' => '', 'name' => '']
* @param string $signPassword Password of signature
* @param string $uid User id
* @return File
*/
public function generateCertificate(string $email, string $signPassword, string $uid, bool $isTempFile = false): File {
public function generateCertificate(array $user, string $signPassword, string $uid, bool $isTempFile = false): File {
$content = $this->getCertificateHandler()
->setHosts([$email])
->setHosts([$user['email']])
->setCommonName($user['name'])
->setFriendlyName($uid)
->setPassword($signPassword)
->generateCertificate();
Expand Down
71 changes: 71 additions & 0 deletions lib/Migration/Version7000Date20221026003343.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2022 Vitor Mattos <[email protected]>
*
* @author Vitor Mattos <[email protected]>
*
* @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 OCA\Libresign\Migration;

use Closure;
use OCA\Libresign\AppInfo\Application;
use OCP\DB\ISchemaWrapper;
use OCP\IConfig;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

class Version7000Date20221026003343 extends SimpleMigrationStep {
/** @var IConfig */
protected $config;

public function __construct(IConfig $config) {
$this->config = $config;
}

/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$rootCert = [];
if ($commonName = $this->config->getAppValue(Application::APP_ID, 'commonName')) {
$rootCert['commonName'] = $commonName;
$this->config->deleteAppValue(Application::APP_ID, 'commonName');
}
if ($country = $this->config->getAppValue(Application::APP_ID, 'country')) {
$rootCert['names']['C'] = $country;
$this->config->deleteAppValue(Application::APP_ID, 'country');
}
if ($organization = $this->config->getAppValue(Application::APP_ID, 'organization')) {
$rootCert['names']['O'] = $organization;
$this->config->deleteAppValue(Application::APP_ID, 'organization');
}
if ($organizationUnit = $this->config->getAppValue(Application::APP_ID, 'organizationUnit')) {
$rootCert['names']['OU'] = $organizationUnit;
$this->config->deleteAppValue(Application::APP_ID, 'organizationUnit');
}
if ($rootCert) {
$this->config->setAppValue(Application::APP_ID, 'rootCert', json_encode($rootCert));
}
}
}
19 changes: 13 additions & 6 deletions lib/Service/AccountService.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ public function validateCreateToSign(array $data): void {
} catch (\Throwable $th) {
throw new LibresignException($this->l10n->t('UUID not found'), 1);
}
if ($fileUser->getEmail() !== $data['email']) {
if ($fileUser->getEmail() !== $data['user']['email']) {
throw new LibresignException($this->l10n->t('This is not your file'), 1);
}
if ($this->userManager->userExists($data['email'])) {
if ($this->userManager->userExists($data['user']['email'])) {
throw new LibresignException($this->l10n->t('User already exists'), 1);
}
if (empty($data['password'])) {
Expand Down Expand Up @@ -172,10 +172,10 @@ public function getFileByUuid(string $uuid): array {
}

public function validateCertificateData(array $data): void {
if (!$data['email']) {
if (!$data['user']['email']) {
throw new LibresignException($this->l10n->t('You must have an email. You can define the email in your profile.'), 1);
}
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
if (!filter_var($data['user']['email'], FILTER_VALIDATE_EMAIL)) {
throw new LibresignException($this->l10n->t('Invalid email'), 1);
}
if (empty($data['signPassword'])) {
Expand Down Expand Up @@ -233,7 +233,7 @@ public function createToSign(string $uuid, string $uid, string $password, ?strin

$newUser = $this->userManager->createUser($uid, $password);
$newUser->setDisplayName($fileUser->getDisplayName());
$newUser->setEMailAddress($fileUser->getEmail());
$newUser->setSystemEMailAddress($fileUser->getEmail());

$fileUser->setUserId($newUser->getUID());
$this->fileUserMapper->update($fileUser);
Expand All @@ -248,7 +248,14 @@ public function createToSign(string $uuid, string $uid, string $password, ?strin
}

if ($signPassword) {
$this->pkcs12Handler->generateCertificate($uid, $signPassword, $newUser->getUID());
$this->pkcs12Handler->generateCertificate(
[
'email' => $newUser->getPrimaryEMailAddress(),
'name' => $newUser->getDisplayName()
],
$signPassword,
$newUser->getUID()
);
}
}

Expand Down
17 changes: 10 additions & 7 deletions lib/Service/AdminSignatureService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ public function __construct(

/**
* @return string[]
*
* @psalm-return array{commonName: string, country: string, organization: string, organizationUnit: string, cfsslUri: string, configPath: string}
*/
public function loadKeys(): array {
return [
'commonName' => $this->config->getAppValue(Application::APP_ID, 'commonName'),
'country' => $this->config->getAppValue(Application::APP_ID, 'country'),
'organization' => $this->config->getAppValue(Application::APP_ID, 'organization'),
'organizationUnit' => $this->config->getAppValue(Application::APP_ID, 'organizationUnit'),
$return = [
'cfsslUri' => $this->config->getAppValue(Application::APP_ID, 'cfsslUri'),
'configPath' => $this->config->getAppValue(Application::APP_ID, 'configPath'),
'rootCert' => [
'names' => [],
],
];
$rootCert = $this->config->getAppValue(Application::APP_ID, 'rootCert');
$rootCert = json_decode($rootCert, true);
if (is_array($rootCert)) {
$return['rootCert'] = array_merge($return['rootCert'], $rootCert);
}
return $return;
}
}
Loading

0 comments on commit 608c034

Please sign in to comment.