You are here

public static function Utilities::validateElement in SAML SP 2.0 Single Sign On (SSO) - SAML Service Provider 7

2 calls to Utilities::validateElement()
SAML2_Assertion::parseSignature in includes/Assertion.php
Parse signature on assertion.
SAML2_Response::__construct in includes/Response.php
Constructor for SAML 2 response messages.

File

includes/Utilities.php, line 772

Class

Utilities
This file is part of miniOrange SAML plugin.

Code

public static function validateElement(DOMElement $root) {

  //$data = $root->ownerDocument->saveXML($root);

  /* Create an XML security object. */
  $objXMLSecDSig = new XMLSecurityDSig();

  /* Both SAML messages and SAML assertions use the 'ID' attribute. */
  $objXMLSecDSig->idKeys[] = 'ID';

  /* Locate the XMLDSig Signature element to be used. */
  $signatureElement = self::xpQuery($root, './ds:Signature');
  if (count($signatureElement) === 0) {

    /* We don't have a signature element to validate. */
    return FALSE;
  }
  elseif (count($signatureElement) > 1) {
    echo sprintf("XMLSec: more than one signature element in root.");
    exit;
  }

  /*  elseif ((in_array('Response', $signatureElement) && $ocurrence['Response'] > 1) ||
          (in_array('Assertion', $signatureElement) && $ocurrence['Assertion'] > 1) ||
          !in_array('Response', $signatureElement) && !in_array('Assertion', $signatureElement)
      ) {
          return false;
      } */
  $signatureElement = $signatureElement[0];
  $objXMLSecDSig->sigNode = $signatureElement;

  /* Canonicalize the XMLDSig SignedInfo element in the message. */
  $objXMLSecDSig
    ->canonicalizeSignedInfo();

  /* Validate referenced xml nodes. */
  if (!$objXMLSecDSig
    ->validateReference()) {
    echo sprintf("XMLsec: digest validation failed");
    exit;
  }

  /* Check that $root is one of the signed nodes. */
  $rootSigned = FALSE;

  /** @var DOMNode $signedNode */
  foreach ($objXMLSecDSig
    ->getValidatedNodes() as $signedNode) {
    if ($signedNode
      ->isSameNode($root)) {
      $rootSigned = TRUE;
      break;
    }
    elseif ($root->parentNode instanceof DOMDocument && $signedNode
      ->isSameNode($root->ownerDocument)) {

      /* $root is the root element of a signed document. */
      $rootSigned = TRUE;
      break;
    }
  }
  if (!$rootSigned) {
    echo sprintf("XMLSec: The root element is not signed.");
    exit;
  }

  /* Now we extract all available X509 certificates in the signature element. */
  $certificates = array();
  foreach (self::xpQuery($signatureElement, './ds:KeyInfo/ds:X509Data/ds:X509Certificate') as $certNode) {
    $certData = trim($certNode->textContent);
    $certData = str_replace(array(
      "\r",
      "\n",
      "\t",
      ' ',
    ), '', $certData);
    $certificates[] = $certData;
  }
  $ret = array(
    'Signature' => $objXMLSecDSig,
    'Certificates' => $certificates,
  );
  return $ret;
}