Skip to content
Snippets Groups Projects
Commit 25a5916b authored by Jaime Perez Crespo's avatar Jaime Perez Crespo
Browse files

Move validateCA(), validateCABuiltIn() and validateCAExec() from...

Move validateCA(), validateCABuiltIn() and validateCAExec() from SimpleSAML_Utilities to SimpleSAML_XML_Validator, where they are used. Remove validateCABuiltIn() and validateCAExec() from SimpleSAML_Utilities as they are no longer used. Eventually, all of this should disappear.
parent 42af2eb5
No related branches found
No related tags found
No related merge requests found
......@@ -524,130 +524,10 @@ class SimpleSAML_Utilities {
/**
* Validate a certificate against a CA file, by using the builtin
* openssl_x509_checkpurpose function
*
* @param string $certificate The certificate, in PEM format.
* @param string $caFile File with trusted certificates, in PEM-format.
* @return boolean|string TRUE on success, or a string with error messages if it failed.
* @deprecated This method will be removed in SSP 2.0.
*/
private static function validateCABuiltIn($certificate, $caFile) {
assert('is_string($certificate)');
assert('is_string($caFile)');
/* Clear openssl errors. */
while(openssl_error_string() !== FALSE);
$res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, array($caFile));
$errors = '';
/* Log errors. */
while( ($error = openssl_error_string()) !== FALSE) {
$errors .= ' [' . $error . ']';
}
if($res !== TRUE) {
return $errors;
}
return TRUE;
}
/**
* Validate the certificate used to sign the XML against a CA file, by using the "openssl verify" command.
*
* This function uses the openssl verify command to verify a certificate, to work around limitations
* on the openssl_x509_checkpurpose function. That function will not work on certificates without a purpose
* set.
*
* @param string $certificate The certificate, in PEM format.
* @param string $caFile File with trusted certificates, in PEM-format.
* @return boolean|string TRUE on success, a string with error messages on failure.
* @deprecated This method will be removed in SSP 2.0.
*/
private static function validateCAExec($certificate, $caFile) {
assert('is_string($certificate)');
assert('is_string($caFile)');
$command = array(
'openssl', 'verify',
'-CAfile', $caFile,
'-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)) {
throw new Exception('Failed to execute verification command: ' . $cmdline);
}
if (fwrite($pipes[0], $certificate) === FALSE) {
throw new Exception('Failed to write certificate for verification.');
}
fclose($pipes[0]);
$out = '';
while (!feof($pipes[1])) {
$line = trim(fgets($pipes[1]));
if(strlen($line) > 0) {
$out .= ' [' . $line . ']';
}
}
fclose($pipes[1]);
$status = proc_close($process);
if ($status !== 0 || $out !== ' [stdin: OK]') {
return $out;
}
return TRUE;
}
/**
* Validate the certificate used to sign the XML against a CA file.
*
* This function throws an exception if unable to validate against the given CA file.
*
* @param string $certificate The certificate, in PEM format.
* @param string $caFile File with trusted certificates, in PEM-format.
* @deprecated This method will be removed in SSP 2.0.
*/
public static function validateCA($certificate, $caFile) {
assert('is_string($certificate)');
assert('is_string($caFile)');
if (!file_exists($caFile)) {
throw new Exception('Could not load CA file: ' . $caFile);
}
SimpleSAML_Logger::debug('Validating certificate against CA file: ' . var_export($caFile, TRUE));
$resBuiltin = self::validateCABuiltIn($certificate, $caFile);
if ($resBuiltin !== TRUE) {
SimpleSAML_Logger::debug('Failed to validate with internal function: ' . var_export($resBuiltin, TRUE));
$resExternal = self::validateCAExec($certificate, $caFile);
if ($resExternal !== TRUE) {
SimpleSAML_Logger::debug('Failed to validate with external function: ' . var_export($resExternal, TRUE));
throw new Exception('Could not verify certificate against CA file "'
. $caFile . '". Internal result:' . $resBuiltin .
' External result:' . $resExternal);
}
}
SimpleSAML_Logger::debug('Successfully validated certificate.');
SimpleSAML_XML_Validator::validateCertificate($certificate, $caFile);
}
......
......@@ -289,7 +289,134 @@ class SimpleSAML_XML_Validator {
throw new Exception('Key used to sign the message was not an X509 certificate.');
}
SimpleSAML_Utilities::validateCA($this->x509Certificate, $caFile);
self::validateCertificate($this->x509Certificate, $caFile);
}
/**
* Validate a certificate against a CA file, by using the builtin
* openssl_x509_checkpurpose function
*
* @param string $certificate The certificate, in PEM format.
* @param string $caFile File with trusted certificates, in PEM-format.
* @return boolean|string TRUE on success, or a string with error messages if it failed.
* @deprecated
*/
private static function validateCABuiltIn($certificate, $caFile) {
assert('is_string($certificate)');
assert('is_string($caFile)');
/* Clear openssl errors. */
while(openssl_error_string() !== FALSE);
$res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, array($caFile));
$errors = '';
/* Log errors. */
while( ($error = openssl_error_string()) !== FALSE) {
$errors .= ' [' . $error . ']';
}
if($res !== TRUE) {
return $errors;
}
return TRUE;
}
/**
* Validate the certificate used to sign the XML against a CA file, by using the "openssl verify" command.
*
* This function uses the openssl verify command to verify a certificate, to work around limitations
* on the openssl_x509_checkpurpose function. That function will not work on certificates without a purpose
* set.
*
* @param string $certificate The certificate, in PEM format.
* @param string $caFile File with trusted certificates, in PEM-format.
* @return boolean|string TRUE on success, a string with error messages on failure.
* @deprecated
*/
private static function validateCAExec($certificate, $caFile) {
assert('is_string($certificate)');
assert('is_string($caFile)');
$command = array(
'openssl', 'verify',
'-CAfile', $caFile,
'-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)) {
throw new Exception('Failed to execute verification command: ' . $cmdline);
}
if (fwrite($pipes[0], $certificate) === FALSE) {
throw new Exception('Failed to write certificate for verification.');
}
fclose($pipes[0]);
$out = '';
while (!feof($pipes[1])) {
$line = trim(fgets($pipes[1]));
if(strlen($line) > 0) {
$out .= ' [' . $line . ']';
}
}
fclose($pipes[1]);
$status = proc_close($process);
if ($status !== 0 || $out !== ' [stdin: OK]') {
return $out;
}
return TRUE;
}
/**
* Validate the certificate used to sign the XML against a CA file.
*
* This function throws an exception if unable to validate against the given CA file.
*
* @param string $certificate The certificate, in PEM format.
* @param string $caFile File with trusted certificates, in PEM-format.
* @deprecated
*/
public static function validateCertificate($certificate, $caFile) {
assert('is_string($certificate)');
assert('is_string($caFile)');
if (!file_exists($caFile)) {
throw new Exception('Could not load CA file: ' . $caFile);
}
SimpleSAML_Logger::debug('Validating certificate against CA file: ' . var_export($caFile, TRUE));
$resBuiltin = self::validateCABuiltIn($certificate, $caFile);
if ($resBuiltin !== TRUE) {
SimpleSAML_Logger::debug('Failed to validate with internal function: ' . var_export($resBuiltin, TRUE));
$resExternal = self::validateCAExec($certificate, $caFile);
if ($resExternal !== TRUE) {
SimpleSAML_Logger::debug('Failed to validate with external function: ' . var_export($resExternal, TRUE));
throw new Exception('Could not verify certificate against CA file "'
. $caFile . '". Internal result:' . $resBuiltin .
' External result:' . $resExternal);
}
}
SimpleSAML_Logger::debug('Successfully validated certificate.');
}
}
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