1616use Psr \Log \LoggerInterface ;
1717
1818/**
19- * Manage trusted certificates for users
19+ * Manage trusted certificates and the effective CA bundle used by Nextcloud.
20+ *
21+ * Uploaded PEM certificates are merged with the shipped default CA bundle to
22+ * produce the effective bundle consumed by HTTP clients and external storage
23+ * integrations.
24+ *
25+ * The uploaded certificates and generated bundle are stored under the
26+ * files_external path for historical reasons, maintaining compatibility
27+ * with pre-existing deployments.
2028 */
2129class CertificateManager implements ICertificateManager {
2230 private ?string $ bundlePath = null ;
@@ -30,7 +38,7 @@ public function __construct(
3038 }
3139
3240 /**
33- * Returns all certificates trusted by the user
41+ * Return the certificates stored in the internal upload area.
3442 *
3543 * @return ICertificate[]
3644 */
@@ -67,6 +75,9 @@ public function listCertificates(): array {
6775 return $ result ;
6876 }
6977
78+ /**
79+ * Check whether any uploaded certificates are present.
80+ */
7081 private function hasCertificates (): bool {
7182 if (!$ this ->config ->getSystemValueBool ('installed ' , false )) {
7283 return false ;
@@ -91,9 +102,14 @@ private function hasCertificates(): bool {
91102 }
92103
93104 /**
94- * create the certificate bundle of all trusted certificated
105+ * Rebuild the generated effected certificate bundle from:
106+ * - uploaded certificates
107+ * - the shipped default CA bundle
108+ * - the current system CA bundle, if present and different from the target
109+ *
110+ * The bundle is written atomically to /files_external/rootcerts.crt.
95111 */
96- public function createCertificateBundle (): void {
112+ private function createCertificateBundle (): void {
97113 $ path = $ this ->getPathToCertificates ();
98114 $ certs = $ this ->listCertificates ();
99115
@@ -143,11 +159,12 @@ public function createCertificateBundle(): void {
143159 }
144160
145161 /**
146- * Save the certificate and re-generate the certificate bundle
162+ * Store a certificate and regenerate the effective bundle.
147163 *
148- * @param string $certificate the certificate data
149- * @param string $name the filename for the certificate
150- * @throws \Exception If the certificate could not get added
164+ * @param string $certificate Certificate data in PEM format
165+ * @param string $name File name to store the certificate under
166+ * @return ICertificate
167+ * @throws \Exception If the certificate cannot be stored or the bundle cannot be rebuilt
151168 */
152169 #[\Override]
153170 public function addCertificate (string $ certificate , string $ name ): ICertificate {
@@ -172,7 +189,10 @@ public function addCertificate(string $certificate, string $name): ICertificate
172189 }
173190
174191 /**
175- * Remove the certificate and re-generate the certificate bundle
192+ * Remove a stored certificate and regenerate the effective bundle.
193+ *
194+ * @param string $name File name of the certificate to remove
195+ * @return bool False if the path is invalid, true otherwise
176196 */
177197 #[\Override]
178198 public function removeCertificate (string $ name ): bool {
@@ -193,16 +213,23 @@ public function removeCertificate(string $name): bool {
193213 }
194214
195215 /**
196- * Get the path to the certificate bundle
216+ * Get the relative path to the generated certificate bundle.
197217 */
198218 #[\Override]
199219 public function getCertificateBundle (): string {
200220 return $ this ->getPathToCertificates () . 'rootcerts.crt ' ;
201221 }
202222
203223 /**
204- * Get the full local path to the certificate bundle
205- * @throws \Exception when getting bundle path fails
224+ * Get the local filesystem path to the effective certificate bundle.
225+ *
226+ * Returns the generated bundle when uploaded certificates exist, otherwise
227+ * falls back to the shipped default CA bundle.
228+ *
229+ * If resolving the generated bundle fails, the default bundle is returned as
230+ * a safe fallback.
231+ *
232+ * @throws \Exception If unable to retrieve/confirm the bundle path for any reason.
206233 */
207234 #[\Override]
208235 public function getAbsoluteBundlePath (): string {
@@ -230,12 +257,19 @@ public function getAbsoluteBundlePath(): string {
230257 }
231258 }
232259
260+ /**
261+ * Get the base path used to store uploaded certificates and the generated bundle.
262+ *
263+ * Kept under the files_external namespace for compatibility with existing
264+ * deployments.
265+ */
233266 private function getPathToCertificates (): string {
234267 return '/files_external/ ' ;
235268 }
236269
237270 /**
238- * Check if we need to re-bundle the certificates because one of the sources has updated
271+ * Determine whether the generated bundle must be rebuilt because the source
272+ * CA bundle has changed or the target bundle is missing.
239273 */
240274 private function needsRebundling (): bool {
241275 $ targetBundle = $ this ->getCertificateBundle ();
@@ -248,12 +282,15 @@ private function needsRebundling(): bool {
248282 }
249283
250284 /**
251- * get mtime of ca-bundle shipped by Nextcloud
285+ * Return the modification time of the shipped default CA bundle.
252286 */
253287 protected function getFilemtimeOfCaBundle (): int {
254288 return filemtime ($ this ->getDefaultCertificatesBundlePath ());
255289 }
256290
291+ /**
292+ * Return the configured path to the shipped default CA bundle.
293+ */
257294 #[\Override]
258295 public function getDefaultCertificatesBundlePath (): string {
259296 return $ this ->config ->getSystemValueString ('default_certificates_bundle_path ' , \OC ::$ SERVERROOT . '/resources/config/ca-bundle.crt ' );
0 commit comments