From 33c68d56e7f51db60d64628736244bc9cc1ee099 Mon Sep 17 00:00:00 2001
From: Sergio Gomez <sergio@uco.es>
Date: Mon, 27 Mar 2017 20:43:06 +0200
Subject: [PATCH] SimpleSAML_XML_* classes refactorized to PSR-2

---
 lib/SimpleSAML/XML/Errors.php               | 244 +++---
 lib/SimpleSAML/XML/Parser.php               | 118 +--
 lib/SimpleSAML/XML/Shib13/AuthnRequest.php  |  78 +-
 lib/SimpleSAML/XML/Shib13/AuthnResponse.php | 798 ++++++++++----------
 lib/SimpleSAML/XML/Signer.php               | 361 ++++-----
 lib/SimpleSAML/XML/Validator.php            | 649 ++++++++--------
 6 files changed, 1143 insertions(+), 1105 deletions(-)

diff --git a/lib/SimpleSAML/XML/Errors.php b/lib/SimpleSAML/XML/Errors.php
index a6d14dd9f..48d93b73d 100644
--- a/lib/SimpleSAML/XML/Errors.php
+++ b/lib/SimpleSAML/XML/Errors.php
@@ -12,124 +12,128 @@
 
 namespace SimpleSAML\XML;
 
-class Errors {
-
-	/**
-	 * This is an stack of error logs. The topmost element is the one we are
-	 * currently working on.
-	 */
-	private static $errorStack = array();
-
-	/**
-	 * This is the xml error state we had before we began logging.
-	 */
-	private static $xmlErrorState;
-
-
-	/**
-	 * Append current XML errors to the the current stack level.
-	 */
-	private static function addErrors() {
-
-		$currentErrors = libxml_get_errors();
-		libxml_clear_errors();
-
-		$level = count(self::$errorStack) - 1;
-		self::$errorStack[$level] = array_merge(self::$errorStack[$level], $currentErrors);
-	}
-
-
-	/**
-	 * Start error logging.
-	 *
-	 * A call to this function will begin a new error logging context. Every call must have
-	 * a corresponding call to end().
-	 */
-	public static function begin() {
-
-		// Check whether the error access functions are present
-		if(!function_exists('libxml_use_internal_errors')) {
-			return;
-		}
-
-		if(count(self::$errorStack) === 0) {
-			// No error logging is currently in progress. Initialize it.
-			self::$xmlErrorState = libxml_use_internal_errors(TRUE);
-			libxml_clear_errors();
-		} else {
-			/* We have already started error logging. Append the current errors to the
-			 * list of errors in this level.
-			 */
-			self::addErrors();
-		}
-
-		// Add a new level to the error stack
-		self::$errorStack[] = array();
-	}
-
-
-	/**
-	 * End error logging.
-	 *
-	 * @return array  An array with the LibXMLErrors which has occurred since begin() was called.
-	 */
-	public static function end() {
-
-		// Check whether the error access functions are present
-		if(!function_exists('libxml_use_internal_errors')) {
-			// Pretend that no errors occurred
-			return array();
-		}
-
-		// Add any errors which may have occurred
-		self::addErrors();
-
-
-		$ret = array_pop(self::$errorStack);
-
-		if(count(self::$errorStack) === 0) {
-			// Disable our error logging and restore the previous state
-			libxml_use_internal_errors(self::$xmlErrorState);
-		}
-
-		return $ret;
-	}
-
-
-	/**
-	 * Format an error as a string.
-	 *
-	 * This function formats the given LibXMLError object as a string.
-	 *
-	 * @param $error \LibXMLError  The LibXMLError which should be formatted.
-	 * @return string  A string representing the given LibXMLError.
-	 */
-	public static function formatError($error) {
-		assert('$error instanceof LibXMLError');
-		return 'level=' . $error->level . ',code='  . $error->code . ',line=' . $error->line . ',col=' . $error->column .
-			',msg=' . trim($error->message);
-	}
-
-
-	/**
-	 * Format a list of errors as a string.
-	 *
-	 * This fucntion takes an array of LibXMLError objects and creates a string with all the errors.
-	 * Each error will be separated by a newline, and the string will end with a newline-character.
-	 *
-	 * @param $errors array  An array of errors.
-	 * @return string  A string representing the errors. An empty string will be returned if there were no
-	 *          errors in the array.
-	 */
-	public static function formatErrors($errors) {
-		assert('is_array($errors)');
-
-		$ret = '';
-		foreach($errors as $error) {
-			$ret .= self::formatError($error) . "\n";
-		}
-
-		return $ret;
-	}
-
+class Errors
+{
+
+    /**
+     * This is an stack of error logs. The topmost element is the one we are
+     * currently working on.
+     */
+    private static $errorStack = array();
+
+    /**
+     * This is the xml error state we had before we began logging.
+     */
+    private static $xmlErrorState;
+
+
+    /**
+     * Append current XML errors to the the current stack level.
+     */
+    private static function addErrors()
+    {
+        $currentErrors = libxml_get_errors();
+        libxml_clear_errors();
+
+        $level = count(self::$errorStack) - 1;
+        self::$errorStack[$level] = array_merge(self::$errorStack[$level], $currentErrors);
+    }
+
+
+    /**
+     * Start error logging.
+     *
+     * A call to this function will begin a new error logging context. Every call must have
+     * a corresponding call to end().
+     */
+    public static function begin()
+    {
+
+        // Check whether the error access functions are present
+        if (!function_exists('libxml_use_internal_errors')) {
+            return;
+        }
+
+        if (count(self::$errorStack) === 0) {
+            // No error logging is currently in progress. Initialize it.
+            self::$xmlErrorState = libxml_use_internal_errors(true);
+            libxml_clear_errors();
+        } else {
+            /* We have already started error logging. Append the current errors to the
+             * list of errors in this level.
+             */
+            self::addErrors();
+        }
+
+        // Add a new level to the error stack
+        self::$errorStack[] = array();
+    }
+
+
+    /**
+     * End error logging.
+     *
+     * @return array  An array with the LibXMLErrors which has occurred since begin() was called.
+     */
+    public static function end()
+    {
+
+        // Check whether the error access functions are present
+        if (!function_exists('libxml_use_internal_errors')) {
+            // Pretend that no errors occurred
+            return array();
+        }
+
+        // Add any errors which may have occurred
+        self::addErrors();
+
+
+        $ret = array_pop(self::$errorStack);
+
+        if (count(self::$errorStack) === 0) {
+            // Disable our error logging and restore the previous state
+            libxml_use_internal_errors(self::$xmlErrorState);
+        }
+
+        return $ret;
+    }
+
+
+    /**
+     * Format an error as a string.
+     *
+     * This function formats the given LibXMLError object as a string.
+     *
+     * @param $error \LibXMLError  The LibXMLError which should be formatted.
+     * @return string  A string representing the given LibXMLError.
+     */
+    public static function formatError($error)
+    {
+        assert('$error instanceof LibXMLError');
+        return 'level=' . $error->level . ',code='  . $error->code . ',line=' . $error->line . ',col=' . $error->column .
+            ',msg=' . trim($error->message);
+    }
+
+
+    /**
+     * Format a list of errors as a string.
+     *
+     * This fucntion takes an array of LibXMLError objects and creates a string with all the errors.
+     * Each error will be separated by a newline, and the string will end with a newline-character.
+     *
+     * @param $errors array  An array of errors.
+     * @return string  A string representing the errors. An empty string will be returned if there were no
+     *          errors in the array.
+     */
+    public static function formatErrors($errors)
+    {
+        assert('is_array($errors)');
+
+        $ret = '';
+        foreach ($errors as $error) {
+            $ret .= self::formatError($error) . "\n";
+        }
+
+        return $ret;
+    }
 }
diff --git a/lib/SimpleSAML/XML/Parser.php b/lib/SimpleSAML/XML/Parser.php
index d36beb4fd..b43fe49a7 100644
--- a/lib/SimpleSAML/XML/Parser.php
+++ b/lib/SimpleSAML/XML/Parser.php
@@ -9,59 +9,69 @@
 
 namespace SimpleSAML\XML;
 
-class Parser  {
+class Parser
+{
+    public $simplexml = null;
 
-	var $simplexml = null;
-
-	function __construct($xml) {;
-		$this->simplexml = new \SimpleXMLElement($xml);
-		$this->simplexml->registerXPathNamespace('saml2',     'urn:oasis:names:tc:SAML:2.0:assertion');
-		$this->simplexml->registerXPathNamespace('saml2meta', 'urn:oasis:names:tc:SAML:2.0:metadata');
-		$this->simplexml->registerXPathNamespace('ds',        'http://www.w3.org/2000/09/xmldsig#');
-		
-	}
-	
-	public static function fromSimpleXMLElement(\SimpleXMLElement $element) {
-		
-		// Traverse all existing namespaces in element
-		$namespaces = $element->getNamespaces();
-		foreach ($namespaces AS $prefix => $ns) {
-			$element[(($prefix === '') ? 'xmlns' : 'xmlns:' . $prefix)] = $ns;
-		}
-		
-		/* Create a new parser with the xml document where the namespace definitions
-		 * are added.
-		 */
-		$parser = new Parser($element->asXML());
-		return $parser;
-		
-	}
-	
-	public function getValueDefault($xpath, $defvalue) {
-		try {
-			return $this->getValue($xpath, true);
-		} catch (\Exception $e) {
-			return $defvalue;
-		}
-	}
-	
-	public function getValue($xpath, $required = false) {
-		
-		$result = $this->simplexml->xpath($xpath);
-		if (! $result or !is_array($result)) {
-			if ($required) throw new \Exception('Could not get value from XML document using the following XPath expression: ' . $xpath);
-				else return null;
-		}
-		return (string) $result[0];
-	}
-	
-	public function getValueAlternatives(array $xpath, $required = false) {
-		foreach ($xpath AS $x) {
-			$seek = $this->getValue($x);
-			if ($seek) return $seek;
-		}
-		if ($required) throw new \Exception('Could not get value from XML document using multiple alternative XPath expressions.');
-			else return null;
-	}
-	
+    public function __construct($xml)
+    {
+        ;
+        $this->simplexml = new \SimpleXMLElement($xml);
+        $this->simplexml->registerXPathNamespace('saml2', 'urn:oasis:names:tc:SAML:2.0:assertion');
+        $this->simplexml->registerXPathNamespace('saml2meta', 'urn:oasis:names:tc:SAML:2.0:metadata');
+        $this->simplexml->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#');
+    }
+    
+    public static function fromSimpleXMLElement(\SimpleXMLElement $element)
+    {
+        
+        // Traverse all existing namespaces in element
+        $namespaces = $element->getNamespaces();
+        foreach ($namespaces as $prefix => $ns) {
+            $element[(($prefix === '') ? 'xmlns' : 'xmlns:' . $prefix)] = $ns;
+        }
+        
+        /* Create a new parser with the xml document where the namespace definitions
+         * are added.
+         */
+        $parser = new Parser($element->asXML());
+        return $parser;
+    }
+    
+    public function getValueDefault($xpath, $defvalue)
+    {
+        try {
+            return $this->getValue($xpath, true);
+        } catch (\Exception $e) {
+            return $defvalue;
+        }
+    }
+    
+    public function getValue($xpath, $required = false)
+    {
+        $result = $this->simplexml->xpath($xpath);
+        if (! $result or !is_array($result)) {
+            if ($required) {
+                throw new \Exception('Could not get value from XML document using the following XPath expression: ' . $xpath);
+            } else {
+                return null;
+            }
+        }
+        return (string) $result[0];
+    }
+    
+    public function getValueAlternatives(array $xpath, $required = false)
+    {
+        foreach ($xpath as $x) {
+            $seek = $this->getValue($x);
+            if ($seek) {
+                return $seek;
+            }
+        }
+        if ($required) {
+            throw new \Exception('Could not get value from XML document using multiple alternative XPath expressions.');
+        } else {
+            return null;
+        }
+    }
 }
diff --git a/lib/SimpleSAML/XML/Shib13/AuthnRequest.php b/lib/SimpleSAML/XML/Shib13/AuthnRequest.php
index 47fecc60e..f52fea212 100644
--- a/lib/SimpleSAML/XML/Shib13/AuthnRequest.php
+++ b/lib/SimpleSAML/XML/Shib13/AuthnRequest.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * The Shibboleth 1.3 Authentication Request. Not part of SAML 1.1, 
+ * The Shibboleth 1.3 Authentication Request. Not part of SAML 1.1,
  * but an extension using query paramters no XML.
  *
  * @author Andreas Ã…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
@@ -10,40 +10,44 @@
 
 namespace SimpleSAML\XML\Shib13;
 
-class AuthnRequest {
-
-	private $issuer = null;
-	private $relayState = null;
-
-	public function setRelayState($relayState) {
-		$this->relayState = $relayState;
-	}
-	
-	public function getRelayState() {
-		return $this->relayState;
-	}
-	
-	public function setIssuer($issuer) {
-		$this->issuer = $issuer;
-	}
-	public function getIssuer() {
-		return $this->issuer;
-	}
-
-	public function createRedirect($destination, $shire) {
-		$metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-		$idpmetadata = $metadata->getMetaDataConfig($destination, 'shib13-idp-remote');
-
-		$desturl = $idpmetadata->getDefaultEndpoint('SingleSignOnService', array('urn:mace:shibboleth:1.0:profiles:AuthnRequest'));
-		$desturl = $desturl['Location'];
-
-		$target = $this->getRelayState();
-		
-		$url = $desturl . '?' .
-	    	'providerId=' . urlencode($this->getIssuer()) .
-		    '&shire=' . urlencode($shire) .
-		    (isset($target) ? '&target=' . urlencode($target) : '');
-		return $url;
-	}
-
+class AuthnRequest
+{
+    private $issuer = null;
+    private $relayState = null;
+
+    public function setRelayState($relayState)
+    {
+        $this->relayState = $relayState;
+    }
+    
+    public function getRelayState()
+    {
+        return $this->relayState;
+    }
+    
+    public function setIssuer($issuer)
+    {
+        $this->issuer = $issuer;
+    }
+    public function getIssuer()
+    {
+        return $this->issuer;
+    }
+
+    public function createRedirect($destination, $shire)
+    {
+        $metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $idpmetadata = $metadata->getMetaDataConfig($destination, 'shib13-idp-remote');
+
+        $desturl = $idpmetadata->getDefaultEndpoint('SingleSignOnService', array('urn:mace:shibboleth:1.0:profiles:AuthnRequest'));
+        $desturl = $desturl['Location'];
+
+        $target = $this->getRelayState();
+        
+        $url = $desturl . '?' .
+            'providerId=' . urlencode($this->getIssuer()) .
+            '&shire=' . urlencode($shire) .
+            (isset($target) ? '&target=' . urlencode($target) : '');
+        return $url;
+    }
 }
diff --git a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
index 17ae3b90b..a8f4fc32b 100644
--- a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
+++ b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
@@ -1,5 +1,5 @@
 <?php
- 
+
 /**
  * A Shibboleth 1.3 authentication response.
  *
@@ -9,7 +9,6 @@
 
 namespace SimpleSAML\XML\Shib13;
 
-
 use SAML2\DOMDocumentFactory;
 use SAML2\Utils;
 use SimpleSAML\Utils\Config;
@@ -17,140 +16,146 @@ use SimpleSAML\Utils\Random;
 use SimpleSAML\Utils\Time;
 use SimpleSAML\XML\Validator;
 
-class AuthnResponse {
+class AuthnResponse
+{
 
-	/**
-	 * @var Validator This variable contains an XML validator for this message.
-	 */
+    /**
+     * @var Validator This variable contains an XML validator for this message.
+     */
     private $validator = null;
 
 
-	/**
-	 * Whether this response was validated by some external means (e.g. SSL).
-	 *
-	 * @var bool
-	 */
-	private $messageValidated = FALSE;
-
-
-	const SHIB_PROTOCOL_NS = 'urn:oasis:names:tc:SAML:1.0:protocol';
-	const SHIB_ASSERT_NS = 'urn:oasis:names:tc:SAML:1.0:assertion';
-
-
-	/**
-	 * The DOMDocument which represents this message.
-	 *
-	 * @var \DOMDocument
-	 */
-	private $dom;
-
-	/**
-	 * The relaystate which is associated with this response.
-	 *
-	 * @var string|NULL
-	 */
-	private $relayState = null;
-
-
-	/**
-	 * Set whether this message was validated externally.
-	 *
-	 * @param bool $messageValidated  TRUE if the message is already validated, FALSE if not.
-	 */
-	public function setMessageValidated($messageValidated) {
-		assert('is_bool($messageValidated)');
-
-		$this->messageValidated = $messageValidated;
-	}
-
-
-	public function setXML($xml) {
-		assert('is_string($xml)');
+    /**
+     * Whether this response was validated by some external means (e.g. SSL).
+     *
+     * @var bool
+     */
+    private $messageValidated = false;
 
-		try {
-			$this->dom = DOMDocumentFactory::fromString(str_replace ("\r", "", $xml));
-		} catch(\Exception $e) {
-			throw new \Exception('Unable to parse AuthnResponse XML.');
-		}
-	}
 
-	public function setRelayState($relayState) {
-		$this->relayState = $relayState;
-	}
+    const SHIB_PROTOCOL_NS = 'urn:oasis:names:tc:SAML:1.0:protocol';
+    const SHIB_ASSERT_NS = 'urn:oasis:names:tc:SAML:1.0:assertion';
 
-	public function getRelayState() {
-		return $this->relayState;
-	}
 
-	public function validate() {
-		assert('$this->dom instanceof DOMDocument');
+    /**
+     * The DOMDocument which represents this message.
+     *
+     * @var \DOMDocument
+     */
+    private $dom;
 
-		if ($this->messageValidated) {
-			// This message was validated externally
-			return TRUE;
-		}
+    /**
+     * The relaystate which is associated with this response.
+     *
+     * @var string|NULL
+     */
+    private $relayState = null;
 
-		// Validate the signature
-		$this->validator = new Validator($this->dom, array('ResponseID', 'AssertionID'));
 
-		// Get the issuer of the response
-		$issuer = $this->getIssuer();
+    /**
+     * Set whether this message was validated externally.
+     *
+     * @param bool $messageValidated  TRUE if the message is already validated, FALSE if not.
+     */
+    public function setMessageValidated($messageValidated)
+    {
+        assert('is_bool($messageValidated)');
+
+        $this->messageValidated = $messageValidated;
+    }
+
+
+    public function setXML($xml)
+    {
+        assert('is_string($xml)');
+
+        try {
+            $this->dom = DOMDocumentFactory::fromString(str_replace("\r", "", $xml));
+        } catch (\Exception $e) {
+            throw new \Exception('Unable to parse AuthnResponse XML.');
+        }
+    }
+
+    public function setRelayState($relayState)
+    {
+        $this->relayState = $relayState;
+    }
+
+    public function getRelayState()
+    {
+        return $this->relayState;
+    }
+
+    public function validate()
+    {
+        assert('$this->dom instanceof DOMDocument');
+
+        if ($this->messageValidated) {
+            // This message was validated externally
+            return true;
+        }
+
+        // Validate the signature
+        $this->validator = new Validator($this->dom, array('ResponseID', 'AssertionID'));
+
+        // Get the issuer of the response
+        $issuer = $this->getIssuer();
+
+        // Get the metadata of the issuer
+        $metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $md = $metadata->getMetaDataConfig($issuer, 'shib13-idp-remote');
+
+        $publicKeys = $md->getPublicKeys('signing');
+        if ($publicKeys !== null) {
+            $certFingerprints = array();
+            foreach ($publicKeys as $key) {
+                if ($key['type'] !== 'X509Certificate') {
+                    continue;
+                }
+                $certFingerprints[] = sha1(base64_decode($key['X509Certificate']));
+            }
+            $this->validator->validateFingerprint($certFingerprints);
+        } elseif ($md->hasValue('certFingerprint')) {
+            $certFingerprints = $md->getArrayizeString('certFingerprint');
+
+            // Validate the fingerprint
+            $this->validator->validateFingerprint($certFingerprints);
+        } elseif ($md->hasValue('caFile')) {
+            // Validate against CA
+            $this->validator->validateCA(Config::getCertPath($md->getString('caFile')));
+        } else {
+            throw new \SimpleSAML_Error_Exception('Missing certificate in Shibboleth 1.3 IdP Remote metadata for identity provider [' . $issuer . '].');
+        }
+
+        return true;
+    }
+
+
+    /* Checks if the given node is validated by the signature on this response.
+     *
+     * Returns:
+     *  TRUE if the node is validated or FALSE if not.
+     */
+    private function isNodeValidated($node)
+    {
+        if ($this->messageValidated) {
+            // This message was validated externally
+            return true;
+        }
 
-		// Get the metadata of the issuer
-		$metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-		$md = $metadata->getMetaDataConfig($issuer, 'shib13-idp-remote');
+        if ($this->validator === null) {
+            return false;
+        }
 
-		$publicKeys = $md->getPublicKeys('signing');
-		if ($publicKeys !== NULL) {
-			$certFingerprints = array();
-			foreach ($publicKeys as $key) {
-				if ($key['type'] !== 'X509Certificate') {
-					continue;
-				}
-				$certFingerprints[] = sha1(base64_decode($key['X509Certificate']));
-			}
-			$this->validator->validateFingerprint($certFingerprints);
-		} elseif ($md->hasValue('certFingerprint')) {
-			$certFingerprints = $md->getArrayizeString('certFingerprint');
+        // Convert the node to a DOM node if it is an element from SimpleXML
+        if ($node instanceof \SimpleXMLElement) {
+            $node = dom_import_simplexml($node);
+        }
 
-			// Validate the fingerprint
-			$this->validator->validateFingerprint($certFingerprints);
-		} elseif ($md->hasValue('caFile')) {
-			// Validate against CA
-			$this->validator->validateCA(Config::getCertPath($md->getString('caFile')));
-		} else {
-			throw new \SimpleSAML_Error_Exception('Missing certificate in Shibboleth 1.3 IdP Remote metadata for identity provider [' . $issuer . '].');
-		}
+        assert('$node instanceof DOMNode');
 
-		return true;
-	}
-
-
-	/* Checks if the given node is validated by the signature on this response.
-	 *
-	 * Returns:
-	 *  TRUE if the node is validated or FALSE if not.
-	 */
-	private function isNodeValidated($node) {
-
-		if ($this->messageValidated) {
-			// This message was validated externally
-			return TRUE;
-		}
-
-		if($this->validator === NULL) {
-			return FALSE;
-		}
-
-		// Convert the node to a DOM node if it is an element from SimpleXML
-		if($node instanceof \SimpleXMLElement) {
-			$node = dom_import_simplexml($node);
-		}
-
-		assert('$node instanceof DOMNode');
-
-		return $this->validator->isNodeValidated($node);
-	}
+        return $this->validator->isNodeValidated($node);
+    }
 
 
     /**
@@ -161,139 +166,138 @@ class AuthnResponse {
      *                        then the query will be relative to the root of the response.
      * @return \DOMNodeList
      */
-	private function doXPathQuery($query, $node = NULL) {
-		assert('is_string($query)');
-		assert('$this->dom instanceof DOMDocument');
-
-		if($node === NULL) {
-			$node = $this->dom->documentElement;
-		}
-
-		assert('$node instanceof DOMNode');
-
-		$xPath = new \DOMXpath($this->dom);
-		$xPath->registerNamespace('shibp', self::SHIB_PROTOCOL_NS);
-		$xPath->registerNamespace('shib', self::SHIB_ASSERT_NS);
-
-		return $xPath->query($query, $node);
-	}
-
-	/**
-	 * Retrieve the session index of this response.
-	 *
-	 * @return string|NULL  The session index of this response.
-	 */
-	function getSessionIndex() {
-		assert('$this->dom instanceof DOMDocument');
-
-		$query = '/shibp:Response/shib:Assertion/shib:AuthnStatement';
-		$nodelist = $this->doXPathQuery($query);
-		if ($node = $nodelist->item(0)) {
-			return $node->getAttribute('SessionIndex');
-		}
-
-		return NULL;
-	}
-
-	
-	public function getAttributes() {
-
-		$metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-		$md = $metadata->getMetadata($this->getIssuer(), 'shib13-idp-remote');
-		$base64 = isset($md['base64attributes']) ? $md['base64attributes'] : false;
-
-		if (! ($this->dom instanceof \DOMDocument) ) {
-			return array();
-		}
-
-		$attributes = array();
-
-		$assertions = $this->doXPathQuery('/shibp:Response/shib:Assertion');
-
-		foreach ($assertions AS $assertion) {
-
-			if(!$this->isNodeValidated($assertion)) {
-				throw new \Exception('Shib13 AuthnResponse contained an unsigned assertion.');
-			}
+    private function doXPathQuery($query, $node = null)
+    {
+        assert('is_string($query)');
+        assert('$this->dom instanceof DOMDocument');
 
-			$conditions = $this->doXPathQuery('shib:Conditions', $assertion);
-			if ($conditions && $conditions->length > 0) {
-				$condition = $conditions->item(0);
+        if ($node === null) {
+            $node = $this->dom->documentElement;
+        }
 
-				$start = $condition->getAttribute('NotBefore');
-				$end = $condition->getAttribute('NotOnOrAfter');
+        assert('$node instanceof DOMNode');
 
-				if ($start && $end) {
-					if (!self::checkDateConditions($start, $end)) {
-						error_log('Date check failed ... (from ' . $start . ' to ' . $end . ')');
-						continue;
-					}
-				}
-			}
+        $xPath = new \DOMXpath($this->dom);
+        $xPath->registerNamespace('shibp', self::SHIB_PROTOCOL_NS);
+        $xPath->registerNamespace('shib', self::SHIB_ASSERT_NS);
 
-			$attribute_nodes = $this->doXPathQuery('shib:AttributeStatement/shib:Attribute/shib:AttributeValue', $assertion);
-			/** @var \DOMElement $attribute */
-			foreach($attribute_nodes as $attribute) {
+        return $xPath->query($query, $node);
+    }
 
-				$value = $attribute->textContent;
-				$name = $attribute->parentNode->getAttribute('AttributeName');
-
-				if ($attribute->hasAttribute('Scope')) {
-					$scopePart = '@' . $attribute->getAttribute('Scope');
-				} else {
-					$scopePart = '';
-				}
-
-				if(!is_string($name)) {
-					throw new \Exception('Shib13 Attribute node without an AttributeName.');
-				}
-
-				if(!array_key_exists($name, $attributes)) {
-					$attributes[$name] = array();
-				}
-
-				if ($base64) {
-					$encodedvalues = explode('_', $value);
-					foreach($encodedvalues AS $v) {
-						$attributes[$name][] = base64_decode($v) . $scopePart;
-					}
-				} else {
-					$attributes[$name][] = $value . $scopePart;
-				}
-			}
-		}
-
-		return $attributes;
-	}
-
-	
-	public function getIssuer() {
-
-		$query = '/shibp:Response/shib:Assertion/@Issuer';
-		$nodelist = $this->doXPathQuery($query);
-
-		if ($attr = $nodelist->item(0)) {
-			return $attr->nodeValue;
-		} else {
-			throw new \Exception('Could not find Issuer field in Authentication response');
-		}
-
-	}
-
-	public function getNameID() {
-
-		$nameID = array();
-
-		$query = '/shibp:Response/shib:Assertion/shib:AuthenticationStatement/shib:Subject/shib:NameIdentifier';
-		$nodelist = $this->doXPathQuery($query);
-
-		if ($node = $nodelist->item(0)) {
-			$nameID["Value"] = $node->nodeValue;
-			$nameID["Format"] = $node->getAttribute('Format');
-		}
-
-		return $nameID;
-	}
+    /**
+     * Retrieve the session index of this response.
+     *
+     * @return string|NULL  The session index of this response.
+     */
+    public function getSessionIndex()
+    {
+        assert('$this->dom instanceof DOMDocument');
+
+        $query = '/shibp:Response/shib:Assertion/shib:AuthnStatement';
+        $nodelist = $this->doXPathQuery($query);
+        if ($node = $nodelist->item(0)) {
+            return $node->getAttribute('SessionIndex');
+        }
+
+        return null;
+    }
+
+    
+    public function getAttributes()
+    {
+        $metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $md = $metadata->getMetadata($this->getIssuer(), 'shib13-idp-remote');
+        $base64 = isset($md['base64attributes']) ? $md['base64attributes'] : false;
+
+        if (! ($this->dom instanceof \DOMDocument)) {
+            return array();
+        }
+
+        $attributes = array();
+
+        $assertions = $this->doXPathQuery('/shibp:Response/shib:Assertion');
+
+        foreach ($assertions as $assertion) {
+            if (!$this->isNodeValidated($assertion)) {
+                throw new \Exception('Shib13 AuthnResponse contained an unsigned assertion.');
+            }
+
+            $conditions = $this->doXPathQuery('shib:Conditions', $assertion);
+            if ($conditions && $conditions->length > 0) {
+                $condition = $conditions->item(0);
+
+                $start = $condition->getAttribute('NotBefore');
+                $end = $condition->getAttribute('NotOnOrAfter');
+
+                if ($start && $end) {
+                    if (!self::checkDateConditions($start, $end)) {
+                        error_log('Date check failed ... (from ' . $start . ' to ' . $end . ')');
+                        continue;
+                    }
+                }
+            }
+
+            $attribute_nodes = $this->doXPathQuery('shib:AttributeStatement/shib:Attribute/shib:AttributeValue', $assertion);
+            /** @var \DOMElement $attribute */
+            foreach ($attribute_nodes as $attribute) {
+                $value = $attribute->textContent;
+                $name = $attribute->parentNode->getAttribute('AttributeName');
+
+                if ($attribute->hasAttribute('Scope')) {
+                    $scopePart = '@' . $attribute->getAttribute('Scope');
+                } else {
+                    $scopePart = '';
+                }
+
+                if (!is_string($name)) {
+                    throw new \Exception('Shib13 Attribute node without an AttributeName.');
+                }
+
+                if (!array_key_exists($name, $attributes)) {
+                    $attributes[$name] = array();
+                }
+
+                if ($base64) {
+                    $encodedvalues = explode('_', $value);
+                    foreach ($encodedvalues as $v) {
+                        $attributes[$name][] = base64_decode($v) . $scopePart;
+                    }
+                } else {
+                    $attributes[$name][] = $value . $scopePart;
+                }
+            }
+        }
+
+        return $attributes;
+    }
+
+    
+    public function getIssuer()
+    {
+        $query = '/shibp:Response/shib:Assertion/@Issuer';
+        $nodelist = $this->doXPathQuery($query);
+
+        if ($attr = $nodelist->item(0)) {
+            return $attr->nodeValue;
+        } else {
+            throw new \Exception('Could not find Issuer field in Authentication response');
+        }
+    }
+
+    public function getNameID()
+    {
+        $nameID = array();
+
+        $query = '/shibp:Response/shib:Assertion/shib:AuthenticationStatement/shib:Subject/shib:NameIdentifier';
+        $nodelist = $this->doXPathQuery($query);
+
+        if ($node = $nodelist->item(0)) {
+            $nameID["Value"] = $node->nodeValue;
+            $nameID["Format"] = $node->getAttribute('Format');
+        }
+
+        return $nameID;
+    }
 
 
     /**
@@ -305,69 +309,69 @@ class AuthnResponse {
      * @param array|NULL $attributes The attributes which should be included in the response.
      * @return string The response.
      */
-	public function generate(\SimpleSAML_Configuration $idp, \SimpleSAML_Configuration $sp, $shire, $attributes) {
-		assert('is_string($shire)');
-		assert('$attributes === NULL || is_array($attributes)');
-
-		if ($sp->hasValue('scopedattributes')) {
-			$scopedAttributes = $sp->getArray('scopedattributes');
-		} elseif ($idp->hasValue('scopedattributes')) {
-			$scopedAttributes = $idp->getArray('scopedattributes');
-		} else {
-			$scopedAttributes = array();
-		}
-
-		$id = Random::generateID();
-		
-		$issueInstant = Time::generateTimestamp();
-		
-		// 30 seconds timeskew back in time to allow differing clocks
-		$notBefore = Time::generateTimestamp(time() - 30);
-		
-		
-		$assertionExpire = Time::generateTimestamp(time() + 60 * 5);# 5 minutes
-		$assertionid = Random::generateID();
-
-		$spEntityId = $sp->getString('entityid');
-
-		$audience = $sp->getString('audience', $spEntityId);
-		$base64 = $sp->getBoolean('base64attributes', FALSE);
-
-		$namequalifier = $sp->getString('NameQualifier', $spEntityId);
-		$nameid = Random::generateID();
-		$subjectNode =
-			'<Subject>' .
-			'<NameIdentifier' .
-			' Format="urn:mace:shibboleth:1.0:nameIdentifier"' .
-			' NameQualifier="' . htmlspecialchars($namequalifier) . '"' .
-			'>' .
-			htmlspecialchars($nameid) .
-			'</NameIdentifier>' .
-			'<SubjectConfirmation>' .
-			'<ConfirmationMethod>' .
-			'urn:oasis:names:tc:SAML:1.0:cm:bearer' .
-			'</ConfirmationMethod>' .
-			'</SubjectConfirmation>' .
-			'</Subject>';
-
-		$encodedattributes = '';
-
-		if (is_array($attributes)) {
-
-			$encodedattributes .= '<AttributeStatement>';
-			$encodedattributes .= $subjectNode;
-
-			foreach ($attributes AS $name => $value) {
-				$encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes);
-			}
-
-			$encodedattributes .= '</AttributeStatement>';
-		}
-
-		/*
-		 * The SAML 1.1 response message
-		 */
-		$response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
+    public function generate(\SimpleSAML_Configuration $idp, \SimpleSAML_Configuration $sp, $shire, $attributes)
+    {
+        assert('is_string($shire)');
+        assert('$attributes === NULL || is_array($attributes)');
+
+        if ($sp->hasValue('scopedattributes')) {
+            $scopedAttributes = $sp->getArray('scopedattributes');
+        } elseif ($idp->hasValue('scopedattributes')) {
+            $scopedAttributes = $idp->getArray('scopedattributes');
+        } else {
+            $scopedAttributes = array();
+        }
+
+        $id = Random::generateID();
+        
+        $issueInstant = Time::generateTimestamp();
+        
+        // 30 seconds timeskew back in time to allow differing clocks
+        $notBefore = Time::generateTimestamp(time() - 30);
+        
+        
+        $assertionExpire = Time::generateTimestamp(time() + 60 * 5);# 5 minutes
+        $assertionid = Random::generateID();
+
+        $spEntityId = $sp->getString('entityid');
+
+        $audience = $sp->getString('audience', $spEntityId);
+        $base64 = $sp->getBoolean('base64attributes', false);
+
+        $namequalifier = $sp->getString('NameQualifier', $spEntityId);
+        $nameid = Random::generateID();
+        $subjectNode =
+            '<Subject>' .
+            '<NameIdentifier' .
+            ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' .
+            ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' .
+            '>' .
+            htmlspecialchars($nameid) .
+            '</NameIdentifier>' .
+            '<SubjectConfirmation>' .
+            '<ConfirmationMethod>' .
+            'urn:oasis:names:tc:SAML:1.0:cm:bearer' .
+            '</ConfirmationMethod>' .
+            '</SubjectConfirmation>' .
+            '</Subject>';
+
+        $encodedattributes = '';
+
+        if (is_array($attributes)) {
+            $encodedattributes .= '<AttributeStatement>';
+            $encodedattributes .= $subjectNode;
+
+            foreach ($attributes as $name => $value) {
+                $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes);
+            }
+
+            $encodedattributes .= '</AttributeStatement>';
+        }
+
+        /*
+         * The SAML 1.1 response message
+         */
+        $response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
     xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
     xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant. '"
@@ -386,96 +390,94 @@ class AuthnResponse {
         </Conditions>
         <AuthenticationStatement AuthenticationInstant="' . $issueInstant. '"
             AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' .
-			$subjectNode . '
+            $subjectNode . '
         </AuthenticationStatement>
         ' . $encodedattributes . '
     </Assertion>
 </Response>';
 
-		return $response;
-	}
-
-
-	/**
-	 * Format a shib13 attribute.
-	 *
-	 * @param string $name  Name of the attribute.
-	 * @param array $values  Values of the attribute (as an array of strings).
-	 * @param bool $base64  Whether the attriubte values should be base64-encoded.
-	 * @param array $scopedAttributes  Array of attributes names which are scoped.
-	 * @return string  The attribute encoded as an XML-string.
-	 */
-	private function enc_attribute($name, $values, $base64, $scopedAttributes) {
-		assert('is_string($name)');
-		assert('is_array($values)');
-		assert('is_bool($base64)');
-		assert('is_array($scopedAttributes)');
-
-		if (in_array($name, $scopedAttributes, TRUE)) {
-			$scoped = TRUE;
-		} else {
-			$scoped = FALSE;
-		}
-
-		$attr = '<Attribute AttributeName="' . htmlspecialchars($name) . '" AttributeNamespace="urn:mace:shibboleth:1.0:attributeNamespace:uri">';
-		foreach ($values AS $value) {
-
-			$scopePart = '';
-			if ($scoped) {
-				$tmp = explode('@', $value, 2);
-				if (count($tmp) === 2) {
-					$value = $tmp[0];
-					$scopePart = ' Scope="' . htmlspecialchars($tmp[1]) . '"';
-				}
-			}
-
-			if ($base64) {
-				$value = base64_encode($value);
-			}
-
-			$attr .= '<AttributeValue' . $scopePart . '>' . htmlspecialchars($value) . '</AttributeValue>';
-		}
-		$attr .= '</Attribute>';
-
-		return $attr;
-	}
-
-	/**
-	 * Check if we are currently between the given date & time conditions.
-	 *
-	 * Note that this function allows a 10-minute leap from the initial time as marked by $start.
-	 *
-	 * @param string|null $start A SAML2 timestamp marking the start of the period to check. Defaults to null, in which
-	 *     case there's no limitations in the past.
-	 * @param string|null $end A SAML2 timestamp marking the end of the period to check. Defaults to null, in which
-	 *     case there's no limitations in the future.
-	 *
-	 * @return bool True if the current time belongs to the period specified by $start and $end. False otherwise.
-	 *
-	 * @see \SAML2\Utils::xsDateTimeToTimestamp.
-	 *
-	 * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
-	 * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
-	 */
-	protected static function checkDateConditions($start = null, $end = null)
-	{
-		$currentTime = time();
-
-		if (!empty($start)) {
-			$startTime = Utils::xsDateTimeToTimestamp($start);
-			// allow for a 10 minute difference in time
-			if (($startTime < 0) || (($startTime - 600) > $currentTime)) {
-				return false;
-			}
-		}
-		if (!empty($end)) {
-			$endTime = Utils::xsDateTimeToTimestamp($end);
-			if (($endTime < 0) || ($endTime <= $currentTime)) {
-				return false;
-			}
-		}
-		return true;
-	}
+        return $response;
+    }
 
-}
 
+    /**
+     * Format a shib13 attribute.
+     *
+     * @param string $name  Name of the attribute.
+     * @param array $values  Values of the attribute (as an array of strings).
+     * @param bool $base64  Whether the attriubte values should be base64-encoded.
+     * @param array $scopedAttributes  Array of attributes names which are scoped.
+     * @return string  The attribute encoded as an XML-string.
+     */
+    private function enc_attribute($name, $values, $base64, $scopedAttributes)
+    {
+        assert('is_string($name)');
+        assert('is_array($values)');
+        assert('is_bool($base64)');
+        assert('is_array($scopedAttributes)');
+
+        if (in_array($name, $scopedAttributes, true)) {
+            $scoped = true;
+        } else {
+            $scoped = false;
+        }
+
+        $attr = '<Attribute AttributeName="' . htmlspecialchars($name) . '" AttributeNamespace="urn:mace:shibboleth:1.0:attributeNamespace:uri">';
+        foreach ($values as $value) {
+            $scopePart = '';
+            if ($scoped) {
+                $tmp = explode('@', $value, 2);
+                if (count($tmp) === 2) {
+                    $value = $tmp[0];
+                    $scopePart = ' Scope="' . htmlspecialchars($tmp[1]) . '"';
+                }
+            }
+
+            if ($base64) {
+                $value = base64_encode($value);
+            }
+
+            $attr .= '<AttributeValue' . $scopePart . '>' . htmlspecialchars($value) . '</AttributeValue>';
+        }
+        $attr .= '</Attribute>';
+
+        return $attr;
+    }
+
+    /**
+     * Check if we are currently between the given date & time conditions.
+     *
+     * Note that this function allows a 10-minute leap from the initial time as marked by $start.
+     *
+     * @param string|null $start A SAML2 timestamp marking the start of the period to check. Defaults to null, in which
+     *     case there's no limitations in the past.
+     * @param string|null $end A SAML2 timestamp marking the end of the period to check. Defaults to null, in which
+     *     case there's no limitations in the future.
+     *
+     * @return bool True if the current time belongs to the period specified by $start and $end. False otherwise.
+     *
+     * @see \SAML2\Utils::xsDateTimeToTimestamp.
+     *
+     * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
+     * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
+     */
+    protected static function checkDateConditions($start = null, $end = null)
+    {
+        $currentTime = time();
+
+        if (!empty($start)) {
+            $startTime = Utils::xsDateTimeToTimestamp($start);
+            // allow for a 10 minute difference in time
+            if (($startTime < 0) || (($startTime - 600) > $currentTime)) {
+                return false;
+            }
+        }
+        if (!empty($end)) {
+            $endTime = Utils::xsDateTimeToTimestamp($end);
+            if (($endTime < 0) || ($endTime <= $currentTime)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/lib/SimpleSAML/XML/Signer.php b/lib/SimpleSAML/XML/Signer.php
index 9e5622bab..b62c94a13 100644
--- a/lib/SimpleSAML/XML/Signer.php
+++ b/lib/SimpleSAML/XML/Signer.php
@@ -15,100 +15,103 @@ use RobRichards\XMLSecLibs\XMLSecurityDSig;
 use RobRichards\XMLSecLibs\XMLSecurityKey;
 use SimpleSAML\Utils\Config;
 
-class Signer {
+class Signer
+{
 
 
-	/**
-	 * @var string The name of the ID attribute.
-	 */
-	private $idAttrName;
+    /**
+     * @var string The name of the ID attribute.
+     */
+    private $idAttrName;
 
     /**
      * @var XMLSecurityKey|bool  The private key (as an XMLSecurityKey).
      */
-	private $privateKey;
-
-	/**
-	 * @var string The certificate (as text).
-	 */
-	private $certificate;
-
-
-	/**
-	 * @var string Extra certificates which should be included in the response.
-	 */
-	private $extraCertificates;
-
-
-	/**
-	 * Constructor for the metadata signer.
-	 *
-	 * You can pass an list of options as key-value pairs in the array. This allows you to initialize
-	 * a metadata signer in one call.
-	 *
-	 * The following keys are recognized:
-	 *  - privatekey       The file with the private key, relative to the cert-directory.
-	 *  - privatekey_pass  The passphrase for the private key.
-	 *  - certificate      The file with the certificate, relative to the cert-directory.
-	 *  - privatekey_array The private key, as an array returned from SimpleSAML_Utilities::loadPrivateKey.
-	 *  - publickey_array  The public key, as an array returned from SimpleSAML_Utilities::loadPublicKey.
-	 *  - id               The name of the ID attribute.
-	 *
-	 * @param $options array  Associative array with options for the constructor. Defaults to an empty array.
-	 */
-	public function __construct($options = array()) {
-		assert('is_array($options)');
-
-		$this->idAttrName = FALSE;
-		$this->privateKey = FALSE;
-		$this->certificate = FALSE;
-		$this->extraCertificates = array();
-
-		if(array_key_exists('privatekey', $options)) {
-			$pass = NULL;
-			if(array_key_exists('privatekey_pass', $options)) {
-				$pass = $options['privatekey_pass'];
-			}
-
-			$this->loadPrivateKey($options['privatekey'], $pass);
-		}
-
-		if(array_key_exists('certificate', $options)) {
-			$this->loadCertificate($options['certificate']);
-		}
-
-		if (array_key_exists('privatekey_array', $options)) {
-			$this->loadPrivateKeyArray($options['privatekey_array']);
-		}
-
-		if (array_key_exists('publickey_array', $options)) {
-			$this->loadPublicKeyArray($options['publickey_array']);
-		}
-
-		if(array_key_exists('id', $options)) {
-			$this->setIdAttribute($options['id']);
-		}
-	}
-
-
-	/**
-	 * Set the private key from an array.
-	 *
-	 * This function loads the private key from an array matching what is returned
-	 * by SimpleSAML_Utilities::loadPrivateKey(...).
-	 *
-	 * @param array $privatekey  The private key.
-	 */
-	public function loadPrivateKeyArray($privatekey) {
-		assert('is_array($privatekey)');
-		assert('array_key_exists("PEM", $privatekey)');
-
-		$this->privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
-		if (array_key_exists('password', $privatekey)) {
-			$this->privateKey->passphrase = $privatekey['password'];
-		}
-		$this->privateKey->loadKey($privatekey['PEM'], FALSE);
-	}
+    private $privateKey;
+
+    /**
+     * @var string The certificate (as text).
+     */
+    private $certificate;
+
+
+    /**
+     * @var string Extra certificates which should be included in the response.
+     */
+    private $extraCertificates;
+
+
+    /**
+     * Constructor for the metadata signer.
+     *
+     * You can pass an list of options as key-value pairs in the array. This allows you to initialize
+     * a metadata signer in one call.
+     *
+     * The following keys are recognized:
+     *  - privatekey       The file with the private key, relative to the cert-directory.
+     *  - privatekey_pass  The passphrase for the private key.
+     *  - certificate      The file with the certificate, relative to the cert-directory.
+     *  - privatekey_array The private key, as an array returned from SimpleSAML_Utilities::loadPrivateKey.
+     *  - publickey_array  The public key, as an array returned from SimpleSAML_Utilities::loadPublicKey.
+     *  - id               The name of the ID attribute.
+     *
+     * @param $options array  Associative array with options for the constructor. Defaults to an empty array.
+     */
+    public function __construct($options = array())
+    {
+        assert('is_array($options)');
+
+        $this->idAttrName = false;
+        $this->privateKey = false;
+        $this->certificate = false;
+        $this->extraCertificates = array();
+
+        if (array_key_exists('privatekey', $options)) {
+            $pass = null;
+            if (array_key_exists('privatekey_pass', $options)) {
+                $pass = $options['privatekey_pass'];
+            }
+
+            $this->loadPrivateKey($options['privatekey'], $pass);
+        }
+
+        if (array_key_exists('certificate', $options)) {
+            $this->loadCertificate($options['certificate']);
+        }
+
+        if (array_key_exists('privatekey_array', $options)) {
+            $this->loadPrivateKeyArray($options['privatekey_array']);
+        }
+
+        if (array_key_exists('publickey_array', $options)) {
+            $this->loadPublicKeyArray($options['publickey_array']);
+        }
+
+        if (array_key_exists('id', $options)) {
+            $this->setIdAttribute($options['id']);
+        }
+    }
+
+
+    /**
+     * Set the private key from an array.
+     *
+     * This function loads the private key from an array matching what is returned
+     * by SimpleSAML_Utilities::loadPrivateKey(...).
+     *
+     * @param array $privatekey  The private key.
+     */
+    public function loadPrivateKeyArray($privatekey)
+    {
+        assert('is_array($privatekey)');
+        assert('array_key_exists("PEM", $privatekey)');
+
+        $this->privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
+        if (array_key_exists('password', $privatekey)) {
+            $this->privateKey->passphrase = $privatekey['password'];
+        }
+        $this->privateKey->loadKey($privatekey['PEM'], false);
+    }
 
 
     /**
@@ -122,25 +125,26 @@ class Signer {
      *                           key is unencrypted.
      * @throws \Exception
      */
-	public function loadPrivateKey($file, $pass = NULL) {
-		assert('is_string($file)');
-		assert('is_string($pass) || is_null($pass)');
-
-		$keyFile = Config::getCertPath($file);
-		if (!file_exists($keyFile)) {
-			throw new \Exception('Could not find private key file "' . $keyFile . '".');
-		}
-		$keyData = file_get_contents($keyFile);
-		if($keyData === FALSE) {
-			throw new \Exception('Unable to read private key file "' . $keyFile . '".');
-		}
-
-		$privatekey = array('PEM' => $keyData);
-		if($pass !== NULL) {
-			$privatekey['password'] = $pass;
-		}
-		$this->loadPrivateKeyArray($privatekey);
-	}
+    public function loadPrivateKey($file, $pass = null)
+    {
+        assert('is_string($file)');
+        assert('is_string($pass) || is_null($pass)');
+
+        $keyFile = Config::getCertPath($file);
+        if (!file_exists($keyFile)) {
+            throw new \Exception('Could not find private key file "' . $keyFile . '".');
+        }
+        $keyData = file_get_contents($keyFile);
+        if ($keyData === false) {
+            throw new \Exception('Unable to read private key file "' . $keyFile . '".');
+        }
+
+        $privatekey = array('PEM' => $keyData);
+        if ($pass !== null) {
+            $privatekey['password'] = $pass;
+        }
+        $this->loadPrivateKeyArray($privatekey);
+    }
 
 
     /**
@@ -152,17 +156,18 @@ class Signer {
      * @param array $publickey The public key.
      * @throws \Exception
      */
-	public function loadPublicKeyArray($publickey) {
-		assert('is_array($publickey)');
+    public function loadPublicKeyArray($publickey)
+    {
+        assert('is_array($publickey)');
 
-		if (!array_key_exists('PEM', $publickey)) {
-			// We have a public key with only a fingerprint
-			throw new \Exception('Tried to add a certificate fingerprint in a signature.');
-		}
+        if (!array_key_exists('PEM', $publickey)) {
+            // We have a public key with only a fingerprint
+            throw new \Exception('Tried to add a certificate fingerprint in a signature.');
+        }
 
-		// For now, we only assume that the public key is an X509 certificate
-		$this->certificate = $publickey['PEM'];
-	}
+        // For now, we only assume that the public key is an X509 certificate
+        $this->certificate = $publickey['PEM'];
+    }
 
 
     /**
@@ -175,31 +180,33 @@ class Signer {
      *                      the cert-directory.
      * @throws \Exception
      */
-	public function loadCertificate($file) {
-		assert('is_string($file)');
+    public function loadCertificate($file)
+    {
+        assert('is_string($file)');
 
-		$certFile = Config::getCertPath($file);
-		if (!file_exists($certFile)) {
-			throw new \Exception('Could not find certificate file "' . $certFile . '".');
-		}
+        $certFile = Config::getCertPath($file);
+        if (!file_exists($certFile)) {
+            throw new \Exception('Could not find certificate file "' . $certFile . '".');
+        }
 
-		$this->certificate = file_get_contents($certFile);
-		if($this->certificate === FALSE) {
-			throw new \Exception('Unable to read certificate file "' . $certFile . '".');
-		}
-	}
+        $this->certificate = file_get_contents($certFile);
+        if ($this->certificate === false) {
+            throw new \Exception('Unable to read certificate file "' . $certFile . '".');
+        }
+    }
 
 
-	/**
-	 * Set the attribute name for the ID value.
-	 *
-	 * @param $idAttrName string  The name of the attribute which contains the id.
-	 */
-	public function setIDAttribute($idAttrName) {
-		assert('is_string($idAttrName)');
+    /**
+     * Set the attribute name for the ID value.
+     *
+     * @param $idAttrName string  The name of the attribute which contains the id.
+     */
+    public function setIDAttribute($idAttrName)
+    {
+        assert('is_string($idAttrName)');
 
-		$this->idAttrName = $idAttrName;
-	}
+        $this->idAttrName = $idAttrName;
+    }
 
 
     /**
@@ -211,21 +218,22 @@ class Signer {
      * @param $file string  The file which contains the certificate, relative to the cert-directory.
      * @throws \Exception
      */
-	public function addCertificate($file) {
-		assert('is_string($file)');
+    public function addCertificate($file)
+    {
+        assert('is_string($file)');
 
-		$certFile = Config::getCertPath($file);
-		if (!file_exists($certFile)) {
-			throw new \Exception('Could not find extra certificate file "' . $certFile . '".');
-		}
+        $certFile = Config::getCertPath($file);
+        if (!file_exists($certFile)) {
+            throw new \Exception('Could not find extra certificate file "' . $certFile . '".');
+        }
 
-		$certificate = file_get_contents($certFile);
-		if($certificate === FALSE) {
-			throw new \Exception('Unable to read extra certificate file "' . $certFile . '".');
-		}
+        $certificate = file_get_contents($certFile);
+        if ($certificate === false) {
+            throw new \Exception('Unable to read extra certificate file "' . $certFile . '".');
+        }
 
-		$this->extraCertificates[] = $certificate;
-	}
+        $this->extraCertificates[] = $certificate;
+    }
 
 
     /**
@@ -240,42 +248,43 @@ class Signer {
      *                                   $insertInto.
      * @throws \Exception
      */
-	public function sign($node, $insertInto, $insertBefore = NULL) {
-		assert('$node instanceof DOMElement');
-		assert('$insertInto instanceof DOMElement');
-		assert('is_null($insertBefore) || $insertBefore instanceof DOMElement ' .
-			'|| $insertBefore instanceof DOMComment || $insertBefore instanceof DOMText');
+    public function sign($node, $insertInto, $insertBefore = null)
+    {
+        assert('$node instanceof DOMElement');
+        assert('$insertInto instanceof DOMElement');
+        assert('is_null($insertBefore) || $insertBefore instanceof DOMElement ' .
+            '|| $insertBefore instanceof DOMComment || $insertBefore instanceof DOMText');
 
-		if($this->privateKey === FALSE) {
-			throw new \Exception('Private key not set.');
-		}
+        if ($this->privateKey === false) {
+            throw new \Exception('Private key not set.');
+        }
 
 
-		$objXMLSecDSig = new XMLSecurityDSig();
-		$objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
+        $objXMLSecDSig = new XMLSecurityDSig();
+        $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
 
-		$options = array();
-		if($this->idAttrName !== FALSE) {
-			$options['id_name'] = $this->idAttrName;
-		}
+        $options = array();
+        if ($this->idAttrName !== false) {
+            $options['id_name'] = $this->idAttrName;
+        }
 
-		$objXMLSecDSig->addReferenceList(array($node), XMLSecurityDSig::SHA1,
-			array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
-			$options);
+        $objXMLSecDSig->addReferenceList(array($node), XMLSecurityDSig::SHA1,
+            array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
+            $options);
 
-		$objXMLSecDSig->sign($this->privateKey);
+        $objXMLSecDSig->sign($this->privateKey);
 
 
-		if($this->certificate !== FALSE) {
-			// Add the certificate to the signature
-			$objXMLSecDSig->add509Cert($this->certificate, TRUE);
-		}
+        if ($this->certificate !== false) {
+            // Add the certificate to the signature
+            $objXMLSecDSig->add509Cert($this->certificate, true);
+        }
 
-		// Add extra certificates
-		foreach($this->extraCertificates as $certificate) {
-			$objXMLSecDSig->add509Cert($certificate, TRUE);
-		}
+        // Add extra certificates
+        foreach ($this->extraCertificates as $certificate) {
+            $objXMLSecDSig->add509Cert($certificate, true);
+        }
 
-		$objXMLSecDSig->insertSignature($insertInto, $insertBefore);
-	}
+        $objXMLSecDSig->insertSignature($insertInto, $insertBefore);
+    }
 }
diff --git a/lib/SimpleSAML/XML/Validator.php b/lib/SimpleSAML/XML/Validator.php
index c04067bbe..09c2a077e 100644
--- a/lib/SimpleSAML/XML/Validator.php
+++ b/lib/SimpleSAML/XML/Validator.php
@@ -3,7 +3,7 @@
 /**
  * This class implements helper functions for XML validation.
  *
- * @author Olav Morken, UNINETT AS. 
+ * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
 
@@ -13,18 +13,19 @@ use RobRichards\XMLSecLibs\XMLSecEnc;
 use RobRichards\XMLSecLibs\XMLSecurityDSig;
 use SimpleSAML\Logger;
 
-class Validator {
+class Validator
+{
 
-	/**
-	 * This variable contains the X509 certificate the XML document
-	 * was signed with, or NULL if it wasn't signed with an X509 certificate.
-	 */
-	private $x509Certificate;
+    /**
+     * This variable contains the X509 certificate the XML document
+     * was signed with, or NULL if it wasn't signed with an X509 certificate.
+     */
+    private $x509Certificate;
 
-	/**
-	 * This variable contains the nodes which are signed.
-	 */
-	private $validNodes = null;
+    /**
+     * This variable contains the nodes which are signed.
+     */
+    private $validNodes = null;
 
 
     /**
@@ -45,147 +46,151 @@ class Validator {
      * @param array|bool $publickey The public key / certificate which should be used to validate the XML node.
      * @throws \Exception
      */
-	public function __construct($xmlNode, $idAttribute = NULL, $publickey = FALSE) {
-		assert('$xmlNode instanceof \DOMNode');
-
-		if ($publickey === NULL) {
-			$publickey = FALSE;
-		} elseif(is_string($publickey)) {
-			$publickey = array(
-				'PEM' => $publickey,
-			);
-		} else {
-			assert('$publickey === FALSE || is_array($publickey)');
-		}
-
-		// Create an XML security object
-		$objXMLSecDSig = new XMLSecurityDSig();
-
-		// Add the id attribute if the user passed in an id attribute
-		if($idAttribute !== NULL) {
-			if (is_string($idAttribute)) {
-				$objXMLSecDSig->idKeys[] = $idAttribute;
-			} elseif (is_array($idAttribute)) {
-				foreach ($idAttribute AS $ida) 
-					$objXMLSecDSig->idKeys[] = $ida;
-			}
-		}
-
-		// Locate the XMLDSig Signature element to be used
-		$signatureElement = $objXMLSecDSig->locateSignature($xmlNode);
-		if (!$signatureElement) {
-			throw new \Exception('Could not locate XML Signature element.');
-		}
-
-		// Canonicalize the XMLDSig SignedInfo element in the message
-		$objXMLSecDSig->canonicalizeSignedInfo();
-
-		// Validate referenced xml nodes
-		if (!$objXMLSecDSig->validateReference()) {
-			throw new \Exception('XMLsec: digest validation failed');
-		}
-
-
-		// Find the key used to sign the document
-		$objKey = $objXMLSecDSig->locateKey();
-		if (empty($objKey)) {
-			throw new \Exception('Error loading key to handle XML signature');
-		}
-
-		// Load the key data
-		if ($publickey !== FALSE && array_key_exists('PEM', $publickey)) {
-			// We have PEM data for the public key / certificate
-			$objKey->loadKey($publickey['PEM']);
-		} else {
-			// No PEM data. Search for key in signature
-
-			if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) {
-				throw new \Exception('Error finding key data for XML signature validation.');
-			}
-
-			if ($publickey !== FALSE) {
-				/* $publickey is set, and should therefore contain one or more fingerprints.
-				 * Check that the response contains a certificate with a matching
-				 * fingerprint.
-				 */
-				assert('is_array($publickey["certFingerprint"])');
-
-				$certificate = $objKey->getX509Certificate();
-				if ($certificate === NULL) {
-					// Wasn't signed with an X509 certificate
-					throw new \Exception('Message wasn\'t signed with an X509 certificate,' .
-						' and no public key was provided in the metadata.');
-				}
-
-				self::validateCertificateFingerprint($certificate, $publickey['certFingerprint']);
-				// Key OK
-			}
-		}
-
-		// Check the signature
-		if ($objXMLSecDSig->verify($objKey) !== 1) {
-			throw new \Exception("Unable to validate Signature");
-		}
-
-		// Extract the certificate
-		$this->x509Certificate = $objKey->getX509Certificate();
-
-		// Find the list of validated nodes
-		$this->validNodes = $objXMLSecDSig->getValidatedNodes();
-	}
-
-
-	/**
-	 * Retrieve the X509 certificate which was used to sign the XML.
-	 *
-	 * This function will return the certificate as a PEM-encoded string. If the XML
-	 * wasn't signed by an X509 certificate, NULL will be returned.
-	 *
-	 * @return string  The certificate as a PEM-encoded string, or NULL if not signed with an X509 certificate.
-	 */
-	public function getX509Certificate() {
-		return $this->x509Certificate;
-	}
-
-
-	/**
-	 * Calculates the fingerprint of an X509 certificate.
-	 *
-	 * @param $x509cert string  The certificate as a base64-encoded string. The string may optionally
-	 *                          be framed with '-----BEGIN CERTIFICATE-----' and '-----END CERTIFICATE-----'.
-	 * @return string  The fingerprint as a 40-character lowercase hexadecimal number. NULL is returned if the
-	 *                 argument isn't an X509 certificate.
-	 */
-	private static function calculateX509Fingerprint($x509cert) {
-		assert('is_string($x509cert)');
-
-		$lines = explode("\n", $x509cert);
-
-		$data = '';
-
-		foreach($lines as $line) {
-			// Remove '\r' from end of line if present
-			$line = rtrim($line);
-			if($line === '-----BEGIN CERTIFICATE-----') {
-				// Delete junk from before the certificate
-				$data = '';
-			} elseif($line === '-----END CERTIFICATE-----') {
-				// Ignore data after the certificate
-				break;
-			} elseif($line === '-----BEGIN PUBLIC KEY-----') {
-				// This isn't an X509 certificate
-				return NULL;
-			} else {
-				// Append the current line to the certificate data
-				$data .= $line;
-			}
-		}
-
-		/* $data now contains the certificate as a base64-encoded string. The fingerprint
-		 * of the certificate is the sha1-hash of the certificate.
-		 */
-		return strtolower(sha1(base64_decode($data)));
-	}
+    public function __construct($xmlNode, $idAttribute = null, $publickey = false)
+    {
+        assert('$xmlNode instanceof \DOMNode');
+
+        if ($publickey === null) {
+            $publickey = false;
+        } elseif (is_string($publickey)) {
+            $publickey = array(
+                'PEM' => $publickey,
+            );
+        } else {
+            assert('$publickey === FALSE || is_array($publickey)');
+        }
+
+        // Create an XML security object
+        $objXMLSecDSig = new XMLSecurityDSig();
+
+        // Add the id attribute if the user passed in an id attribute
+        if ($idAttribute !== null) {
+            if (is_string($idAttribute)) {
+                $objXMLSecDSig->idKeys[] = $idAttribute;
+            } elseif (is_array($idAttribute)) {
+                foreach ($idAttribute as $ida) {
+                    $objXMLSecDSig->idKeys[] = $ida;
+                }
+            }
+        }
+
+        // Locate the XMLDSig Signature element to be used
+        $signatureElement = $objXMLSecDSig->locateSignature($xmlNode);
+        if (!$signatureElement) {
+            throw new \Exception('Could not locate XML Signature element.');
+        }
+
+        // Canonicalize the XMLDSig SignedInfo element in the message
+        $objXMLSecDSig->canonicalizeSignedInfo();
+
+        // Validate referenced xml nodes
+        if (!$objXMLSecDSig->validateReference()) {
+            throw new \Exception('XMLsec: digest validation failed');
+        }
+
+
+        // Find the key used to sign the document
+        $objKey = $objXMLSecDSig->locateKey();
+        if (empty($objKey)) {
+            throw new \Exception('Error loading key to handle XML signature');
+        }
+
+        // Load the key data
+        if ($publickey !== false && array_key_exists('PEM', $publickey)) {
+            // We have PEM data for the public key / certificate
+            $objKey->loadKey($publickey['PEM']);
+        } else {
+            // No PEM data. Search for key in signature
+
+            if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) {
+                throw new \Exception('Error finding key data for XML signature validation.');
+            }
+
+            if ($publickey !== false) {
+                /* $publickey is set, and should therefore contain one or more fingerprints.
+                 * Check that the response contains a certificate with a matching
+                 * fingerprint.
+                 */
+                assert('is_array($publickey["certFingerprint"])');
+
+                $certificate = $objKey->getX509Certificate();
+                if ($certificate === null) {
+                    // Wasn't signed with an X509 certificate
+                    throw new \Exception('Message wasn\'t signed with an X509 certificate,' .
+                        ' and no public key was provided in the metadata.');
+                }
+
+                self::validateCertificateFingerprint($certificate, $publickey['certFingerprint']);
+                // Key OK
+            }
+        }
+
+        // Check the signature
+        if ($objXMLSecDSig->verify($objKey) !== 1) {
+            throw new \Exception("Unable to validate Signature");
+        }
+
+        // Extract the certificate
+        $this->x509Certificate = $objKey->getX509Certificate();
+
+        // Find the list of validated nodes
+        $this->validNodes = $objXMLSecDSig->getValidatedNodes();
+    }
+
+
+    /**
+     * Retrieve the X509 certificate which was used to sign the XML.
+     *
+     * This function will return the certificate as a PEM-encoded string. If the XML
+     * wasn't signed by an X509 certificate, NULL will be returned.
+     *
+     * @return string  The certificate as a PEM-encoded string, or NULL if not signed with an X509 certificate.
+     */
+    public function getX509Certificate()
+    {
+        return $this->x509Certificate;
+    }
+
+
+    /**
+     * Calculates the fingerprint of an X509 certificate.
+     *
+     * @param $x509cert string  The certificate as a base64-encoded string. The string may optionally
+     *                          be framed with '-----BEGIN CERTIFICATE-----' and '-----END CERTIFICATE-----'.
+     * @return string  The fingerprint as a 40-character lowercase hexadecimal number. NULL is returned if the
+     *                 argument isn't an X509 certificate.
+     */
+    private static function calculateX509Fingerprint($x509cert)
+    {
+        assert('is_string($x509cert)');
+
+        $lines = explode("\n", $x509cert);
+
+        $data = '';
+
+        foreach ($lines as $line) {
+            // Remove '\r' from end of line if present
+            $line = rtrim($line);
+            if ($line === '-----BEGIN CERTIFICATE-----') {
+                // Delete junk from before the certificate
+                $data = '';
+            } elseif ($line === '-----END CERTIFICATE-----') {
+                // Ignore data after the certificate
+                break;
+            } elseif ($line === '-----BEGIN PUBLIC KEY-----') {
+                // This isn't an X509 certificate
+                return null;
+            } else {
+                // Append the current line to the certificate data
+                $data .= $line;
+            }
+        }
+
+        /* $data now contains the certificate as a base64-encoded string. The fingerprint
+         * of the certificate is the sha1-hash of the certificate.
+         */
+        return strtolower(sha1(base64_decode($data)));
+    }
 
 
     /**
@@ -198,31 +203,31 @@ class Validator {
      * @param array $fingerprints The valid fingerprints.
      * @throws \Exception
      */
-	private static function validateCertificateFingerprint($certificate, $fingerprints) {
-		assert('is_string($certificate)');
-		assert('is_array($fingerprints)');
-
-		$certFingerprint = self::calculateX509Fingerprint($certificate);
-		if ($certFingerprint === NULL) {
-			// Couldn't calculate fingerprint from X509 certificate. Should not happen.
-			throw new \Exception('Unable to calculate fingerprint from X509' .
-				' certificate. Maybe it isn\'t an X509 certificate?');
-		}
-
-		foreach ($fingerprints as $fp) {
-			assert('is_string($fp)');
-
-			if ($fp === $certFingerprint) {
-				// The fingerprints matched
-				return;
-			}
-
-		}
-
-		// None of the fingerprints matched. Throw an exception describing the error.
-		throw new \Exception('Invalid fingerprint of certificate. Expected one of [' .
-			implode('], [', $fingerprints) . '], but got [' . $certFingerprint . ']');
-	}
+    private static function validateCertificateFingerprint($certificate, $fingerprints)
+    {
+        assert('is_string($certificate)');
+        assert('is_array($fingerprints)');
+
+        $certFingerprint = self::calculateX509Fingerprint($certificate);
+        if ($certFingerprint === null) {
+            // Couldn't calculate fingerprint from X509 certificate. Should not happen.
+            throw new \Exception('Unable to calculate fingerprint from X509' .
+                ' certificate. Maybe it isn\'t an X509 certificate?');
+        }
+
+        foreach ($fingerprints as $fp) {
+            assert('is_string($fp)');
+
+            if ($fp === $certFingerprint) {
+                // The fingerprints matched
+                return;
+            }
+        }
+
+        // None of the fingerprints matched. Throw an exception describing the error.
+        throw new \Exception('Invalid fingerprint of certificate. Expected one of [' .
+            implode('], [', $fingerprints) . '], but got [' . $certFingerprint . ']');
+    }
 
 
     /**
@@ -236,52 +241,54 @@ class Validator {
      *                                    or an array of fingerprints.
      * @throws \Exception
      */
-	public function validateFingerprint($fingerprints) {
-		assert('is_string($fingerprints) || is_array($fingerprints)');
+    public function validateFingerprint($fingerprints)
+    {
+        assert('is_string($fingerprints) || is_array($fingerprints)');
 
-		if($this->x509Certificate === NULL) {
-			throw new \Exception('Key used to sign the message was not an X509 certificate.');
-		}
+        if ($this->x509Certificate === null) {
+            throw new \Exception('Key used to sign the message was not an X509 certificate.');
+        }
 
-		if(!is_array($fingerprints)) {
-			$fingerprints = array($fingerprints);
-		}
+        if (!is_array($fingerprints)) {
+            $fingerprints = array($fingerprints);
+        }
 
-		// Normalize the fingerprints
-		foreach($fingerprints as &$fp) {
-			assert('is_string($fp)');
+        // Normalize the fingerprints
+        foreach ($fingerprints as &$fp) {
+            assert('is_string($fp)');
 
-			// Make sure that the fingerprint is in the correct format
-			$fp = strtolower(str_replace(":", "", $fp));
-		}
+            // Make sure that the fingerprint is in the correct format
+            $fp = strtolower(str_replace(":", "", $fp));
+        }
 
-		self::validateCertificateFingerprint($this->x509Certificate, $fingerprints);
-	}
-
-
-	/**
-	 * This function checks if the given XML node was signed.
-	 *
-	 * @param $node \DOMNode  The XML node which we should verify that was signed.
-	 *
-	 * @return bool  TRUE if this node (or a parent node) was signed. FALSE if not.
-	 */
-	public function isNodeValidated($node) {
-		assert('$node instanceof \DOMNode');
-
-		while($node !== NULL) {
-			if(in_array($node, $this->validNodes)) {
-				return TRUE;
-			}
+        self::validateCertificateFingerprint($this->x509Certificate, $fingerprints);
+    }
 
-			$node = $node->parentNode;
-		}
 
-		/* Neither this node nor any of the parent nodes could be found in the list of
-		 * signed nodes.
-		 */
-		return FALSE;
-	}
+    /**
+     * This function checks if the given XML node was signed.
+     *
+     * @param $node \DOMNode  The XML node which we should verify that was signed.
+     *
+     * @return bool  TRUE if this node (or a parent node) was signed. FALSE if not.
+     */
+    public function isNodeValidated($node)
+    {
+        assert('$node instanceof \DOMNode');
+
+        while ($node !== null) {
+            if (in_array($node, $this->validNodes)) {
+                return true;
+            }
+
+            $node = $node->parentNode;
+        }
+
+        /* Neither this node nor any of the parent nodes could be found in the list of
+         * signed nodes.
+         */
+        return false;
+    }
 
 
     /**
@@ -292,47 +299,48 @@ class Validator {
      * @param $caFile string  File with trusted certificates, in PEM-format.
      * @throws \Exception
      */
-	public function validateCA($caFile) {
+    public function validateCA($caFile)
+    {
+        assert('is_string($caFile)');
 
-		assert('is_string($caFile)');
+        if ($this->x509Certificate === null) {
+            throw new \Exception('Key used to sign the message was not an X509 certificate.');
+        }
 
-		if($this->x509Certificate === NULL) {
-			throw new \Exception('Key used to sign the message was not an X509 certificate.');
-		}
-
-		self::validateCertificate($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)');
+    /**
+     * 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);
+        // Clear openssl errors
+        while (openssl_error_string() !== false);
 
-		$res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, array($caFile));
+        $res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, array($caFile));
 
-		$errors = '';
-		// Log errors
-		while( ($error = openssl_error_string()) !== FALSE) {
-			$errors .= ' [' . $error . ']';
-		}
+        $errors = '';
+        // Log errors
+        while (($error = openssl_error_string()) !== false) {
+            $errors .= ' [' . $error . ']';
+        }
 
-		if($res !== TRUE) {
-			return $errors;
-		}
+        if ($res !== true) {
+            return $errors;
+        }
 
-		return TRUE;
-	}
+        return true;
+    }
 
 
     /**
@@ -348,51 +356,52 @@ class Validator {
      * @throws \Exception
      * @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;
+    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;
     }
 
 
@@ -406,30 +415,30 @@ class Validator {
      * @throws \Exception
      * @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);
-		}
-
-		Logger::debug('Validating certificate against CA file: ' . var_export($caFile, TRUE));
-
-		$resBuiltin = self::validateCABuiltIn($certificate, $caFile);
-		if ($resBuiltin !== TRUE) {
-			Logger::debug('Failed to validate with internal function: ' . var_export($resBuiltin, TRUE));
-
-			$resExternal = self::validateCAExec($certificate, $caFile);
-			if ($resExternal !== TRUE) {
-				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);
-			}
-		}
-
-		Logger::debug('Successfully validated certificate.');
-	}
-
+    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);
+        }
+
+        Logger::debug('Validating certificate against CA file: ' . var_export($caFile, true));
+
+        $resBuiltin = self::validateCABuiltIn($certificate, $caFile);
+        if ($resBuiltin !== true) {
+            Logger::debug('Failed to validate with internal function: ' . var_export($resBuiltin, true));
+
+            $resExternal = self::validateCAExec($certificate, $caFile);
+            if ($resExternal !== true) {
+                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);
+            }
+        }
+
+        Logger::debug('Successfully validated certificate.');
+    }
 }
-- 
GitLab