public function processSignedElements()
{
$signedElements = array();
$verifiedSeis = array();
$verifiedIds = array();
if ($this->encrypted) {
$signNodes = $this->decryptedDocument->getElementsByTagName('Signature');
} else {
$signNodes = $this->document->getElementsByTagName('Signature');
}
foreach ($signNodes as $signNode) {
$responseTag = '{' . OneLogin_Saml2_Constants::NS_SAMLP . '}Response';
$assertionTag = '{' . OneLogin_Saml2_Constants::NS_SAML . '}Assertion';
$signedElement = '{' . $signNode->parentNode->namespaceURI . '}' . $signNode->parentNode->localName;
if ($signedElement != $responseTag && $signedElement != $assertionTag) {
throw new Exception('Invalid Signature Element ' . $signedElement . ' SAML Response rejected');
}
# Check that reference URI matches the parent ID and no duplicate References or IDs
$idValue = $signNode->parentNode->getAttribute('ID');
if (empty($idValue)) {
throw new Exception('Signed Element must contain an ID. SAML Response rejected');
}
if (in_array($idValue, $verifiedIds)) {
throw new Exception('Duplicated ID. SAML Response rejected');
}
$verifiedIds[] = $idValue;
$ref = $signNode->getElementsByTagName('Reference');
if ($ref->length == 1) {
$ref = $ref->item(0);
$sei = $ref->getAttribute('URI');
if (!empty($sei)) {
$sei = substr($sei, 1);
if ($sei != $idValue) {
throw new Exception('Found an invalid Signed Element. SAML Response rejected');
}
if (in_array($sei, $verifiedSeis)) {
throw new Exception('Duplicated Reference URI. SAML Response rejected');
}
$verifiedSeis[] = $sei;
}
} else {
throw new Exception('Unexpected number of Reference nodes found for signature. SAML Response rejected.');
}
$signedElements[] = $signedElement;
}
if (!empty($signedElements)) {
// Check SignedElements
if (!$this->validateSignedElements($signedElements)) {
throw new Exception('Found an unexpected Signature Element. SAML Response rejected');
}
}
return $signedElements;
}