From c345288bf1ca821919c2af3b4381602f197cb4fa Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Fri, 16 Oct 2015 08:30:32 -0500 Subject: Limit strongswan trusted CA certificates to those required for authentication of the configured IPsec SA's instead of trusting all known CA's. Fixes #5243. --- etc/inc/vpn.inc | 68 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 22 deletions(-) (limited to 'etc') diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc index 7647251..f1a376d 100644 --- a/etc/inc/vpn.inc +++ b/etc/inc/vpn.inc @@ -578,28 +578,6 @@ EOD; @file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan); unset($strongswan); - /* generate CA certificates files */ - if (is_array($config['ca']) && count($config['ca'])) { - foreach ($config['ca'] as $ca) { - if (!isset($ca['crt'])) { - log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr'])); - continue; - } - $cert = base64_decode($ca['crt']); - $x509cert = openssl_x509_parse(openssl_x509_read($cert)); - if (!is_array($x509cert) || !isset($x509cert['hash'])) { - log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr'])); - continue; - } - $fname = "{$capath}/{$x509cert['hash']}.0.crt"; - if (!@file_put_contents($fname, $cert)) { - log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr'])); - continue; - } - unset($cert); - } - } - /* write out CRL files */ if (is_array($config['crl']) && count($config['crl'])) { foreach ($config['crl'] as $crl) { @@ -617,6 +595,7 @@ EOD; $pskconf = ""; + $vpncas = array(); if (is_array($a_phase1) && count($a_phase1)) { foreach ($a_phase1 as $ph1ent) { @@ -636,6 +615,16 @@ EOD; continue; } + /* add signing CA cert chain of server cert + * to the list of CAs to write + */ + $cachain = ca_chain_array($cert); + if ($cachain && is_array($cachain)) { + foreach ($cachain as $cacrt) { + $vpncas[$cacrt['refid']] = $cacrt; + } + } + @chmod($certpath, 0600); $ph1keyfile = "{$keypath}/cert-{$ikeid}.key"; @@ -684,6 +673,41 @@ EOD; } } } + + /* if the client authenticates with a cert add the + * client cert CA chain to the list of CAs to write + */ + if (in_array($ph1ent['authentication_method'], + array('rsasig', 'eap-tls', 'xauth_rsa_server'))) { + + if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) { + $thisca = lookup_ca($ph1ent['caref']); + $vpncas[$ph1ent['caref']] = $thisca; + + /* follow chain up to root */ + $cachain = ca_chain_array($thisca); + if ($cachain and is_array($cachain)) { + foreach ($cachain as $cacrt) { + $vpncas[$cacrt['refid']] = $cacrt; + } + } + } + } + } + } + + /* write the required CAs */ + foreach ($vpncas as $carefid => $cadata) { + $cacrt = base64_decode($cadata['crt']); + $cacrtattrs = openssl_x509_parse($cacrt); + if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) { + log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr'])); + continue; + } + $cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt"; + if (!@file_put_contents($cafilename, $cacrt)) { + log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr'])); + continue; } } -- cgit v1.1