Skip to content

Commit

Permalink
feat: Make possible customize default expirity
Browse files Browse the repository at this point in the history
Signed-off-by: Vitor Mattos <[email protected]>
  • Loading branch information
vitormattos committed Jan 1, 2025
1 parent 3746956 commit 757f885
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 17 deletions.
8 changes: 8 additions & 0 deletions lib/Handler/CertificateEngine/AEngineHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@ protected function getNames(): array {
return $names;
}

public function expirity(): int {
$expirity = $this->appConfig->getAppValueInt('expiry_in_days', 365);
if ($expirity < 0) {
return 365;
}
return $expirity;
}

public function isSetupOk(): bool {
return $this->appConfig->getAppValue('authkey') ? true : false;
}
Expand Down
9 changes: 6 additions & 3 deletions lib/Handler/CertificateEngine/CfsslHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,20 @@ class CfsslHandler extends AEngineHandler implements IEngineHandler {
protected $client;
protected $cfsslUri;
private string $binary = '';
private CfsslServerHandler $cfsslServerHandler;

public function __construct(
protected IConfig $config,
protected IAppConfig $appConfig,
private SystemConfig $systemConfig,
private CfsslServerHandler $cfsslServerHandler,
protected IAppDataFactory $appDataFactory,
protected IDateTimeFormatter $dateTimeFormatter,
protected ITempManager $tempManager,
) {
parent::__construct($config, $appConfig, $appDataFactory, $dateTimeFormatter, $tempManager);
$this->cfsslServerHandler = new CfsslServerHandler(
$this->getConfigPath(),
);
}

public function generateRootCert(
Expand All @@ -55,12 +58,11 @@ public function generateRootCert(
): string {
$key = bin2hex(random_bytes(16));

$configPath = $this->getConfigPath();
$this->cfsslServerHandler->createConfigServer(
$commonName,
$names,
$key,
$configPath
$this->expirity()
);

$this->genkey();
Expand Down Expand Up @@ -235,6 +237,7 @@ private function wakeUp(): void {
if (!$configPath) {
throw new LibresignException('CFSSL not configured.');
}
$this->cfsslServerHandler->updateExpirity($this->expirity());
$cmd = 'nohup ' . $binary . ' serve -address=127.0.0.1 ' .
'-ca-key ' . $configPath . DIRECTORY_SEPARATOR . 'ca-key.pem ' .
'-ca ' . $configPath . DIRECTORY_SEPARATOR . 'ca.pem ' .
Expand Down
2 changes: 2 additions & 0 deletions lib/Handler/CertificateEngine/IEngineHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public function isSetupOk(): bool;

public function setConfigPath(string $configPath): void;

public function expirity(): int;

public function configureCheck(): array;

public function toArray(): array;
Expand Down
2 changes: 1 addition & 1 deletion lib/Handler/CertificateEngine/OpenSslHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function generateCertificate(): string {
# certificatePolicies = <policyOID> CPS: http://url/with/policy/informations.pdf
CONFIG);
$csr = openssl_csr_new($this->getCsrNames(), $privateKey);
$x509 = openssl_csr_sign($csr, $rootCertificate, $rootPrivateKey, 365, [
$x509 = openssl_csr_sign($csr, $rootCertificate, $rootPrivateKey, $this->expirity(), [
'config' => $temporaryFile,
// This will set "basicConstraints" to CA:FALSE, the default is CA:TRUE
// The signer certificate is not a Certificate Authority
Expand Down
51 changes: 40 additions & 11 deletions lib/Handler/CfsslServerHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,32 @@
use OCA\Libresign\Exception\LibresignException;

class CfsslServerHandler {
private string $csrServerFile;
private string $configServerFile;
private string $configServerFileHash;
public function __construct(string $configPath) {
$this->csrServerFile = $configPath . DIRECTORY_SEPARATOR . 'csr_server.json';
$this->configServerFile = $configPath . DIRECTORY_SEPARATOR . 'config_server.json';
$this->configServerFileHash = $configPath . DIRECTORY_SEPARATOR . 'hashes.sha256';
}

public function createConfigServer(
string $commonName,
array $names,
string $key,
string $configPath,
int $expirity,
): void {
$this->putCsrServer(
$commonName,
$names,
$configPath
);
$this->putConfigServer($key, $configPath);
$this->saveNewConfig($key, $expirity);
}

private function putCsrServer(
string $commonName,
array $names,
string $configPath,
): void {
$filename = $configPath . DIRECTORY_SEPARATOR . 'csr_server.json';
$content = [
'CN' => $commonName,
'key' => [
Expand All @@ -41,7 +47,7 @@ private function putCsrServer(
foreach ($names as $id => $name) {
$content['names'][0][$id] = $name['value'];
}
$response = file_put_contents($filename, json_encode($content));
$response = file_put_contents($this->csrServerFile, json_encode($content));
if ($response === false) {
throw new LibresignException(
"Error while writing CSR server file.\n" .
Expand All @@ -51,14 +57,13 @@ private function putCsrServer(
}
}

private function putConfigServer(string $key, string $configPath): void {
$filename = $configPath . DIRECTORY_SEPARATOR . 'config_server.json';
$content = [
private function saveNewConfig(string $key, int $expirity): void {
$config = [
'signing' => [
'profiles' => [
'CA' => [
'auth_key' => 'key1',
'expiry' => '8760h',
'expiry' => ($expirity * 24) . 'h',
'usages' => [
'signing',
'digital signature',
Expand All @@ -77,10 +82,34 @@ private function putConfigServer(string $key, string $configPath): void {
],
],
];
$this->saveConfig($config);
}

$response = file_put_contents($filename, json_encode($content));
private function saveConfig(array $config): void {
$jsonConfig = json_encode($config);
$response = file_put_contents($this->configServerFile, $jsonConfig);
if ($response === false) {
throw new LibresignException('Error while writing config server file!', 500);
}
$hash = hash('sha256', $jsonConfig) . ' config_server.json';
file_put_contents($this->configServerFileHash, $hash);
}

public function updateExpirity(int $expirity): void {
if (file_exists($this->configServerFileHash)) {
$hashes = file_get_contents($this->configServerFileHash);
preg_match('/(?<hash>\w*) +config_server.json/', $hashes, $matches);
$savedHash = $matches['hash'];
} else {
$savedHash = '';
}
$jsonConfig = file_get_contents($this->configServerFile);
$currentHash = hash('sha256', $jsonConfig);
if ($currentHash === $savedHash) {
return;
}
$config = json_decode($jsonConfig, true);
$config['signing']['profiles']['CA']['expiry'] = ($expirity * 24) . 'h';
$this->saveConfig($config);
}
}
30 changes: 28 additions & 2 deletions src/views/Settings/ExpirationRules.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@update:checked="saveMaximumValidity">
{{ t('libresign', 'Maximum validity') }}
</NcCheckboxRadioSwitch>
<fieldset v-show="enableMaximumValidity" id="settings-sharing-remote-api-expiration" class="sharing__sub-section">
<fieldset v-show="enableMaximumValidity" id="settings-maximum_validity" class="sharing__sub-section">
{{ t('libresign', 'Maximum validity in seconds of a request to sign.') }}
<NcTextField v-model="maximumValidity"
type="number"
Expand All @@ -26,7 +26,7 @@
@update:checked="saveRenewalInterval">
{{ t('libresign', 'Renewal interval') }}
</NcCheckboxRadioSwitch>
<fieldset v-show="enableRenewalInterval" id="settings-sharing-remote-api-expiration" class="sharing__sub-section">
<fieldset v-show="enableRenewalInterval" id="settings-renewal-interval" class="sharing__sub-section">
{{ t('libresign', 'Renewal interval in seconds of a subscription request. When accessing the link, you will be asked to renew the link.') }}
<NcTextField v-model="renewalInterval"
type="number"
Expand All @@ -35,6 +35,15 @@
:placeholder="t('libresign', 'Renewal interval')"
@update:value="saveRenewalInterval" />
</fieldset>
<fieldset id="settings-certificate-validity" class="sharing__sub-section">
{{ t('libresign', 'The length of time for which the generated certificate will be valid, in days.') }}
<NcTextField v-model="expiryInDays"
type="number"
class="sharing__input"
:label="t('libresign', 'Expiration in days')"
:placeholder="t('libresign', 'Expiration in days')"
@update:value="saveExpiryInDays" />
</fieldset>
</NcSettingsSection>
</template>
<script>
Expand All @@ -61,6 +70,7 @@ export default {
maximumValidity: '0',
enableRenewalInterval: false,
renewalInterval: '0',
expiryInDays: 0,
url: null,
}
},
Expand All @@ -71,6 +81,7 @@ export default {
async getData() {
this.getMaximumValidity()
this.getRenewalInterval()
this.getExpiryInDays()
},
async getMaximumValidity() {
const response = await axios.get(
Expand Down Expand Up @@ -98,6 +109,21 @@ export default {
}
OCP.AppConfig.setValue('libresign', 'renewal_interval', Number(this.renewalInterval))
},
async getExpiryInDays() {
const response = await axios.get(
generateOcsUrl('/apps/provisioning_api/api/v1/config/apps/libresign/expiry_in_days'),
)
this.expiryInDays = Number(response.data.ocs.data.data).toString()
if (this.expiryInDays === 0) {
this.expiryInDays = 365
}
},
async saveExpiryInDays() {
if (!this.expiryInDays) {
this.expiryInDays = 365
}
OCP.AppConfig.setValue('libresign', 'expiry_in_days', Number(this.expiryInDays))
},
},
}
</script>
Expand Down

0 comments on commit 757f885

Please sign in to comment.