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;
*/
$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. */
$files = array();
......@@ -74,6 +78,14 @@ foreach($argv as $a) {
}
$validateFingerprint = $v;
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':
printHelp();
exit(0);
......@@ -137,6 +149,8 @@ function printHelp() {
echo(' Check the signature of the metadata,' . "\n");
echo(' and check the fingerprint of the' . "\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(' -o=<DIR>, --out-dir=<DIR> Write the output to this directory. The' . "\n");
echo(' default directory is metadata-generated/' . "\n");
......@@ -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.
*/
......@@ -230,6 +298,7 @@ function processFile($filename) {
$entities = SimpleSAML_Metadata_SAMLParser::parseDescriptorsFile($filename);
global $validateFingerprint;
global $ca;
foreach($entities as $entity) {
if($validateFingerprint !== NULL) {
......@@ -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->getMetadata1xIdP(), 'shib13-idp-remote');
addMetadata($filename, $entity->getMetadata20SP(), 'saml20-sp-remote');
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment