mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 00:24:40 +00:00
System: Trust: Certificates - link certificates by subject on import, closes https://github.com/opnsense/core/issues/7813
It looks like we only linked certificates on CA import, move that code into the Cert model and improve it a bit, also trigger when importing a new certificate manually now. To improve the matching, we search for subjects that match best based on item length now (e.g. a dn ZH,NL should precede one with only NL)
This commit is contained in:
parent
db58e04ac3
commit
1be6303460
@ -127,15 +127,8 @@ class CaController extends ApiMutableModelControllerBase
|
||||
}
|
||||
}
|
||||
$certmdl = new Cert();
|
||||
foreach ($certmdl->cert->iterateItems() as $cert) {
|
||||
$x509_2 = openssl_x509_parse((string)$cert->crt_payload);
|
||||
if ($x509_2 !== false) {
|
||||
if ($this->compare_issuer($x509_2['issuer'], $x509['subject'])) {
|
||||
$cert->caref = (string)$node->refid;
|
||||
}
|
||||
}
|
||||
}
|
||||
$certmdl->serializeToConfig();
|
||||
$certmdl->linkCaRefs(null, $this->getModel());
|
||||
$certmdl->serializeToConfig(false, true); /* we need to force save to maintain integrity */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -110,6 +110,7 @@ class CertController extends ApiMutableModelControllerBase
|
||||
$error = gettext('Invalid private key provided');
|
||||
}
|
||||
}
|
||||
$this->getModel()->linkCaRefs($node->refid);
|
||||
break;
|
||||
case 'import_csr':
|
||||
if (CertStore::parseX509((string)$node->crt_payload) === false) {
|
||||
|
||||
@ -37,4 +37,57 @@ use OPNsense\Base\Messages\Message;
|
||||
*/
|
||||
class Cert extends BaseModel
|
||||
{
|
||||
/**
|
||||
* compare subject to issuer (subject fits within issuer DN)
|
||||
* @param array $subject to find
|
||||
* @param array $issuer to match on
|
||||
* @return bool
|
||||
*/
|
||||
private function compare_issuer(array $subject, array $issuer): bool
|
||||
{
|
||||
return empty(array_diff(
|
||||
array_map('serialize', $subject),
|
||||
array_map('serialize', $issuer)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* link certificates to ca's in our trust store (based on issuer)
|
||||
* @param string $refid optional certificate reference id to link
|
||||
* @param null|Ca $ca_mdl optional Ca model to use, comstructs one when not offered
|
||||
* @return void
|
||||
*/
|
||||
public function linkCaRefs(?string $refid=null, mixed $ca_mdl=null): void
|
||||
{
|
||||
$ca_subjects = [];
|
||||
foreach ($this->cert->iterateItems() as $cert) {
|
||||
if ($refid != null && $cert->refid != $refid) {
|
||||
continue;
|
||||
}
|
||||
$cert_x509 = openssl_x509_parse((string)$cert->crt_payload);
|
||||
if ($cert_x509 === false) {
|
||||
continue;
|
||||
}
|
||||
if (empty($ca_subjects)) {
|
||||
/* collect on first item for matching */
|
||||
$mdl = $ca_mdl == null ? new Ca() : $ca_mdl;
|
||||
foreach ($mdl->ca->iterateItems() as $ca) {
|
||||
$x509 = openssl_x509_parse((string)$ca->crt_payload);
|
||||
if ($x509 === false) {
|
||||
continue;
|
||||
}
|
||||
/* add sort key, longer paths should match earlier. e.g. NL,ZH should precede NL */
|
||||
$key = sprintf('%04d-%s', count($x509['subject']), $ca->refid);
|
||||
$ca_subjects[$key] = ['subject' => $x509['subject'], 'caref' => (string)$ca->refid];
|
||||
}
|
||||
krsort($ca_subjects);
|
||||
}
|
||||
foreach ($ca_subjects as $caref => $item) {
|
||||
if ($this->compare_issuer($item['subject'], $cert_x509['issuer'])) {
|
||||
$cert->caref = $item['caref'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user