-
-
Notifications
You must be signed in to change notification settings - Fork 111
Expand file tree
/
Copy pathCrlDistributionPointsExtractor.php
More file actions
90 lines (75 loc) · 2.15 KB
/
CrlDistributionPointsExtractor.php
File metadata and controls
90 lines (75 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Libresign\Service\Crl;
final class CrlDistributionPointsExtractor {
/** @var array<string, true> */
private const ACCEPTED_EXTENSION_NAMES = [
'crldistributionpoints' => true,
'x509v3 crl distribution points' => true,
'2.5.29.31' => true,
];
private const URI_PATTERN = '/URI\s*:\s*([^\s\n]+)/i';
/**
* @param array<array-key, mixed> $extensions
* @return array{hasExtension: bool, urls: list<string>}
*/
public function extractFromExtensions(array $extensions): array {
$hasCrlExtension = false;
$orderedUrls = [];
$seenUrls = [];
foreach ($extensions as $extensionName => $extensionValue) {
if (!is_string($extensionName)) {
continue;
}
$normalizedName = strtolower(trim($extensionName));
if (!isset(self::ACCEPTED_EXTENSION_NAMES[$normalizedName])) {
continue;
}
$hasCrlExtension = true;
if (is_string($extensionValue)) {
$this->appendUrlsFromText($extensionValue, $orderedUrls, $seenUrls);
} elseif (is_array($extensionValue)) {
foreach ($extensionValue as $extensionPart) {
if (is_string($extensionPart)) {
$this->appendUrlsFromText($extensionPart, $orderedUrls, $seenUrls);
}
}
}
}
if (!$hasCrlExtension) {
return ['hasExtension' => false, 'urls' => []];
}
return [
'hasExtension' => true,
'urls' => $orderedUrls,
];
}
/**
* @param list<string> $orderedUrls
* @param array<string, true> $seenUrls
*/
private function appendUrlsFromText(string $value, array &$orderedUrls, array &$seenUrls): void {
if (stripos($value, 'URI') === false) {
return;
}
preg_match_all(self::URI_PATTERN, $value, $matches);
if (empty($matches[1])) {
return;
}
foreach ($matches[1] as $url) {
$normalizedUrl = $this->normalizeUrlToken($url);
if ($normalizedUrl === '' || isset($seenUrls[$normalizedUrl])) {
continue;
}
$seenUrls[$normalizedUrl] = true;
$orderedUrls[] = $normalizedUrl;
}
}
private function normalizeUrlToken(string $url): string {
return rtrim($url, ')]');
}
}