From d8ddef45e8010a0b136aad212f521b1afd2470e7 Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Tue, 5 Oct 2021 11:40:54 +0200 Subject: [PATCH] Trust / Authorities - prevent expired certificates from being flushed to disk to avoid non valid paths being trusted. (ref https://github.com/opnsense/core/issues/5257) ca-root-nss should be valid at all times, we shouldn't (ever) try to cleanse whats being shipped as part of the system, but user input can be unsafe leading to dangerous situations. Eventually we could also consider preventing bundles being imported in the authorities section, but that wouldn't fix issues with already deployed certificates and user input can still lead to broken chains easily. --- src/etc/inc/system.inc | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 0c508bf52..4989ab778 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -825,7 +825,34 @@ function system_trust_configure($verbose = false) $ca = file_get_contents($ca_root_nss); foreach (config_read_array('ca') as $entry) { if (!empty($entry['crt'])) { - $ca .= "\n# {$entry['descr']}\n" . str_replace("\r", '', base64_decode($entry['crt'])); + // Split and cleans ca certificates, one entry could contain multiple certs if a user imported a bundle + // avoid expired ca's from being considered as valid alternatives. + $certlist = str_replace("\r", '', base64_decode($entry['crt'])); + $user_cas = [""]; + foreach (explode("\n", $certlist) as $row) { + $user_cas[count($user_cas)-1] .= $row ."\n"; + if (strpos($row, '---END') > 0) { + $user_cas[] = ""; + } + } + $ca .= "\n# {$entry['descr']}\n"; + foreach ($user_cas as $user_ca) { + if (!empty(trim($user_ca))) { + $certinfo = @openssl_x509_parse($user_ca); + if (!empty($certinfo['validTo']) && $certinfo['validTo_time_t'] < time()) { + $error_line = sprintf( + "refusing to import %s from %s (expired @ %s)", + $certinfo['name'], + $entry['descr'], + date('r', $certinfo['validFrom_time_t']) + ); + log_error($error_line); + $ca .= "#" . str_replace("\n", "", $error_line); + continue; + } + $ca .= $user_ca; + } + } } }