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.
This commit is contained in:
Matt Smith 2015-10-16 08:30:32 -05:00
parent 6d134679cf
commit c345288bf1

View File

@ -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;
}
}