Skip to content
Snippets Groups Projects
Commit d83f3bec authored by Olav Morken's avatar Olav Morken
Browse files

parseMetadata.php: Add support for verifying against a CA root with one or more certificates.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@687 44740490-163a-0410-bde0-09ae8108e29a
parent 8276a254
No related branches found
No related tags found
No related merge requests found
...@@ -28,6 +28,10 @@ $toStdOut = FALSE; ...@@ -28,6 +28,10 @@ $toStdOut = FALSE;
*/ */
$validateFingerprint = NULL; $validateFingerprint = NULL;
/* $CA contains a path to a PEM file with certificates which are trusted,
* or NULL if we don't want to verify certificates this way.
*/
$ca = NULL;
/* This variable contains the files we will parse. */ /* This variable contains the files we will parse. */
$files = array(); $files = array();
...@@ -74,6 +78,14 @@ foreach($argv as $a) { ...@@ -74,6 +78,14 @@ foreach($argv as $a) {
} }
$validateFingerprint = $v; $validateFingerprint = $v;
break; break;
case '--ca':
if($v === NULL || strlen($v) === 0) {
echo('The --ca option requires an parameter.' . "\n");
echo('Please run `' . $progName . ' --help` for usage information.' . "\n");
exit(1);
}
$ca = $v;
break;
case '--help': case '--help':
printHelp(); printHelp();
exit(0); exit(0);
...@@ -137,6 +149,8 @@ function printHelp() { ...@@ -137,6 +149,8 @@ function printHelp() {
echo(' Check the signature of the metadata,' . "\n"); echo(' Check the signature of the metadata,' . "\n");
echo(' and check the fingerprint of the' . "\n"); echo(' and check the fingerprint of the' . "\n");
echo(' certificate against <FINGERPRINT>.' . "\n"); echo(' certificate against <FINGERPRINT>.' . "\n");
echo(' --ca=<PEM file> Use the given PEM file as a source of' . "\n");
echo(' trusted root certificates.' . "\n");
echo(' -h, --help Print this help.' . "\n"); echo(' -h, --help Print this help.' . "\n");
echo(' -o=<DIR>, --out-dir=<DIR> Write the output to this directory. The' . "\n"); echo(' -o=<DIR>, --out-dir=<DIR> Write the output to this directory. The' . "\n");
echo(' default directory is metadata-generated/' . "\n"); echo(' default directory is metadata-generated/' . "\n");
...@@ -146,6 +160,60 @@ function printHelp() { ...@@ -146,6 +160,60 @@ function printHelp() {
} }
/**
* This function checks the given certificate against the CA root.
*
* @param $certificate The certificate which should be checked, as a string with a PEM-encoded certificate.
*/
function verifyCertificate($certificate) {
static $verifiedCertificates = array();
if(array_key_exists($certificate, $verifiedCertificates)) {
return $verifiedCertificates[$certificate];
}
$command = array(
'openssl', 'verify',
'-CAfile', $GLOBALS['ca'],
'-purpose', 'any',
);
$cmdline = '';
foreach($command as $c) {
$cmdline .= escapeshellarg($c) . ' ';
}
$cmdline .= '2>&1';
$descSpec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
);
$process = proc_open($cmdline, $descSpec, $pipes);
if(!is_resource($process)) {
echo('Failed to execute verification command: ' . $cmdline . "\n");
exit(1);
}
if(fwrite($pipes[0], $certificate) === FALSE) {
echo('Failed to write certificate for verification.' . "\n");
exit(1);
}
fclose($pipes[0]);
$out = trim(fgets($pipes[1]));
fclose($pipes[1]);
$status = proc_close($process);
if($status !== 0 || $out !== 'stdin: OK') {
$ok = FALSE;
} else {
$ok = TRUE;
}
$verifiedCertificates[$certificate] = $ok;
return $ok;
}
/** /**
* This function writes the metadata to to separate files in the output directory. * This function writes the metadata to to separate files in the output directory.
*/ */
...@@ -230,6 +298,7 @@ function processFile($filename) { ...@@ -230,6 +298,7 @@ function processFile($filename) {
$entities = SimpleSAML_Metadata_SAMLParser::parseDescriptorsFile($filename); $entities = SimpleSAML_Metadata_SAMLParser::parseDescriptorsFile($filename);
global $validateFingerprint; global $validateFingerprint;
global $ca;
foreach($entities as $entity) { foreach($entities as $entity) {
if($validateFingerprint !== NULL) { if($validateFingerprint !== NULL) {
...@@ -239,6 +308,20 @@ function processFile($filename) { ...@@ -239,6 +308,20 @@ function processFile($filename) {
} }
} }
if($ca !== NULL) {
$ok = FALSE;
foreach($entity->getX509Certificates() as $cert) {
if(verifyCertificate($cert)) {
$ok = TRUE;
break;
}
}
if(!$ok) {
echo('Skipping "' . $entity->getEntityId() . '" - could not verify certificate.' . "\n");
continue;
}
}
addMetadata($filename, $entity->getMetadata1xSP(), 'shib13-sp-remote'); addMetadata($filename, $entity->getMetadata1xSP(), 'shib13-sp-remote');
addMetadata($filename, $entity->getMetadata1xIdP(), 'shib13-idp-remote'); addMetadata($filename, $entity->getMetadata1xIdP(), 'shib13-idp-remote');
addMetadata($filename, $entity->getMetadata20SP(), 'saml20-sp-remote'); addMetadata($filename, $entity->getMetadata20SP(), 'saml20-sp-remote');
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment