Skip to content

Commit 2ff7ed2

Browse files
authored
Merge pull request #5709 from LibreSign/fix/trust-libresign-ca
fix: trust LibreSign CA
2 parents 97a8bb1 + e60b445 commit 2ff7ed2

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

lib/Handler/SignEngine/Pkcs12Handler.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Pkcs12Handler extends SignEngineHandler {
2727
protected string $certificate = '';
2828
private array $signaturesFromPoppler = [];
2929
private ?JSignPdfHandler $jSignPdfHandler = null;
30+
private string $rootCertificatePem = '';
3031

3132
public function __construct(
3233
private FolderService $folderService,
@@ -103,9 +104,27 @@ private function processSignature($resource, ?string $signature): array {
103104
$result['chain'] = $this->orderCertificates($chain);
104105
$result = $this->enrichLeafWithPopplerData($resource, $result);
105106
}
107+
$result = $this->applyLibreSignRootCAFlag($result);
106108
return $result;
107109
}
108110

111+
private function applyLibreSignRootCAFlag(array $signer): array {
112+
if (empty($signer['chain'])) {
113+
return $signer;
114+
}
115+
116+
foreach ($signer['chain'] as $key => $cert) {
117+
if ($cert['isLibreSignRootCA'] && $cert['certificate_validation']['id'] !== 1) {
118+
$signer['chain'][$key]['certificate_validation'] = [
119+
'id' => 1,
120+
'label' => $this->l10n->t('Certificate is trusted.'),
121+
];
122+
}
123+
}
124+
125+
return $signer;
126+
}
127+
109128
private function extractTimestampData(array $decoded, array $result): array {
110129
$tsa = new TSA();
111130

@@ -132,20 +151,59 @@ private function extractCertificateChain(string $signature): array {
132151
}
133152

134153
$chain = [];
154+
$isLibreSignRootCA = false;
135155
foreach ($pemCertificates as $index => $pemCertificate) {
136156
$parsed = openssl_x509_parse($pemCertificate);
137157
if ($parsed) {
138158
$parsed['signature_validation'] = [
139159
'id' => 1,
140160
'label' => $this->l10n->t('Signature is valid.'),
141161
];
162+
if (!$isLibreSignRootCA) {
163+
$isLibreSignRootCA = $this->isLibreSignRootCA($pemCertificate);
164+
}
165+
$parsed['isLibreSignRootCA'] = $isLibreSignRootCA;
142166
$chain[$index] = $parsed;
143167
}
144168
}
169+
if ($isLibreSignRootCA) {
170+
foreach ($chain as $index => $cert) {
171+
$cert['isLibreSignRootCA'] = true;
172+
}
173+
}
145174

146175
return $chain;
147176
}
148177

178+
private function isLibreSignRootCA(string $certificate): bool {
179+
$rootCertificatePem = $this->getRootCertificatePem();
180+
if (empty($rootCertificatePem)) {
181+
return false;
182+
}
183+
$rootFingerprint = openssl_x509_fingerprint($rootCertificatePem, 'sha256');
184+
$fingerprint = openssl_x509_fingerprint($certificate, 'sha256');
185+
return $rootFingerprint === $fingerprint;
186+
}
187+
188+
private function getRootCertificatePem(): string {
189+
if (!empty($this->rootCertificatePem)) {
190+
return $this->rootCertificatePem;
191+
}
192+
$configPath = $this->appConfig->getValueString(Application::APP_ID, 'config_path');
193+
if (empty($configPath)
194+
|| !is_dir($configPath)
195+
|| !is_readable($configPath . DIRECTORY_SEPARATOR . 'ca.pem')
196+
) {
197+
return '';
198+
}
199+
$rootCertificatePem = file_get_contents($configPath . DIRECTORY_SEPARATOR . 'ca.pem');
200+
if ($rootCertificatePem === false) {
201+
return '';
202+
}
203+
$this->rootCertificatePem = $rootCertificatePem;
204+
return $this->rootCertificatePem;
205+
}
206+
149207
private function enrichLeafWithPopplerData($resource, array $result): array {
150208
if (empty($result['chain'])) {
151209
return $result;

0 commit comments

Comments
 (0)