summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
authorMatt Smith <mgsmith@netgate.com>2015-10-16 08:30:32 -0500
committerMatt Smith <mgsmith@netgate.com>2015-10-16 08:32:53 -0500
commitc345288bf1ca821919c2af3b4381602f197cb4fa (patch)
treedf07e8ef96100cc120a7a44346c603fc20631c39 /etc
parent6d134679cf199a7e8f7e16b021de0b5255e83d32 (diff)
downloadpfsense-c345288bf1ca821919c2af3b4381602f197cb4fa.zip
pfsense-c345288bf1ca821919c2af3b4381602f197cb4fa.tar.gz
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.
Diffstat (limited to 'etc')
-rw-r--r--etc/inc/vpn.inc68
1 files changed, 46 insertions, 22 deletions
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;
}
}
OpenPOWER on IntegriCloud