Project

General

Profile

« Previous | Next » 

Revision 9d8f66b9

Added by Matthew Smith over 9 years ago

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.

View differences:

src/etc/inc/vpn.inc
574 574
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
575 575
	unset($strongswan);
576 576

  
577
	/* generate CA certificates files */
578
	if (is_array($config['ca']) && count($config['ca'])) {
579
		foreach ($config['ca'] as $ca) {
580
			if (!isset($ca['crt'])) {
581
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
582
				continue;
583
			}
584
			$cert = base64_decode($ca['crt']);
585
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
586
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
587
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
588
				continue;
589
			}
590
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
591
			if (!@file_put_contents($fname, $cert)) {
592
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
593
				continue;
594
			}
595
			unset($cert);
596
		}
597
	}
598

  
599 577
	/* write out CRL files */
600 578
	if (is_array($config['crl']) && count($config['crl'])) {
601 579
		foreach ($config['crl'] as $crl) {
......
613 591

  
614 592
	$pskconf = "";
615 593

  
594
	$vpncas = array();
616 595
	if (is_array($a_phase1) && count($a_phase1)) {
617 596
		foreach ($a_phase1 as $ph1ent) {
618 597

  
......
632 611
					continue;
633 612
				}
634 613

  
614
				/* add signing CA cert chain of server cert
615
				 * to the list of CAs to write
616
				 */
617
				$cachain = ca_chain_array($cert);
618
				if ($cachain && is_array($cachain)) {
619
					foreach ($cachain as $cacrt) {
620
						$vpncas[$cacrt['refid']] = $cacrt;
621
					}
622
				}
623

  
635 624
				@chmod($certpath, 0600);
636 625

  
637 626
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
......
680 669
					}
681 670
				}
682 671
			}
672

  
673
			/* if the client authenticates with a cert add the
674
			 * client cert CA chain to the list of CAs to write
675
			 */
676
			if (in_array($ph1ent['authentication_method'],
677
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
678

  
679
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
680
					$thisca = lookup_ca($ph1ent['caref']);
681
					$vpncas[$ph1ent['caref']] = $thisca;
682

  
683
					/* follow chain up to root */
684
					$cachain = ca_chain_array($thisca);
685
					if ($cachain and is_array($cachain)) {
686
						foreach ($cachain as $cacrt) {
687
							$vpncas[$cacrt['refid']] = $cacrt;
688
						}
689
					}
690
				}
691
			}
692
		}
693
	}
694

  
695
	/* write the required CAs */
696
	foreach ($vpncas as $carefid => $cadata) {
697
		$cacrt = base64_decode($cadata['crt']);
698
		$cacrtattrs = openssl_x509_parse($cacrt);
699
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
700
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
701
			continue;
702
		}
703
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
704
		if (!@file_put_contents($cafilename, $cacrt)) {
705
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
706
				continue;
683 707
		}
684 708
	}
685 709

  

Also available in: Unified diff