/**
* Check the signature on a SAML2 message or assertion.
*
* @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
* @param SAML2_SignedElement $element Either a SAML2_Response or a SAML2_Assertion.
*/
public static function checkSign(SimpleSAML_Configuration $srcMetadata, SAML2_SignedElement $element)
{
$certificates = $element->getCertificates();
SimpleSAML_Logger::debug('Found ' . count($certificates) . ' certificates in ' . get_class($element));
/* Find the certificate that should verify signatures by this entity. */
$certArray = SimpleSAML_Utilities::loadPublicKey($srcMetadata, FALSE);
if ($certArray !== NULL) {
if (array_key_exists('PEM', $certArray)) {
$pemCert = $certArray['PEM'];
} else {
/*
* We don't have the full certificate stored. Try to find it
* in the message or the assertion instead.
*/
if (count($certificates) === 0) {
/* We need the full certificate in order to match it against the fingerprint. */
SimpleSAML_Logger::debug('No certificate in message when validating against fingerprint.');
return FALSE;
}
$certFingerprints = $certArray['certFingerprint'];
if (count($certFingerprints) === 0) {
/* For some reason, we have a certFingerprint entry without any fingerprints. */
throw new SimpleSAML_Error_Exception('certFingerprint array was empty.');
}
$pemCert = self::findCertificate($certFingerprints, $certificates);
}
} else {
/* Attempt CA validation. */
$caFile = $srcMetadata->getString('caFile', NULL);
if ($caFile === NULL) {
throw new SimpleSAML_Error_Exception('Missing certificate in metadata for ' . var_export($srcMetadata->getString('entityid'), TRUE));
}
$caFile = SimpleSAML_Utilities::resolveCert($caFile);
if (count($certificates) === 0) {
/* We need the full certificate in order to check it against the CA file. */
SimpleSAML_Logger::debug('No certificate in message when validating with CA.');
return FALSE;
}
/* We assume that it is the first certificate that was used to sign the message. */
$pemCert = "-----BEGIN CERTIFICATE-----\n" . chunk_split($certificates[0], 64) . "-----END CERTIFICATE-----\n";
SimpleSAML_Utilities::validateCA($pemCert, $caFile);
}
/* Extract the public key from the certificate for validation. */
$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
$key->loadKey($pemCert);
/*
* Make sure that we have a valid signature on either the response
* or the assertion.
*/
return $element->validate($key);
}