Revision: 2262
Author: olavmrk
Date: Wed Apr 21 05:56:26 2010
Log: SAMLParser: Reimplement on top of metadata classes.
http://code.google.com/p/simplesamlphp/source/detail?r=2262

Modified:
 /trunk/lib/SimpleSAML/Metadata/SAMLParser.php

=======================================
--- /trunk/lib/SimpleSAML/Metadata/SAMLParser.php       Wed Apr 21 05:55:56 2010
+++ /trunk/lib/SimpleSAML/Metadata/SAMLParser.php       Wed Apr 21 05:56:26 2010
@@ -30,34 +30,6 @@
                );


-       /**
-        * This is the binding used to send authentication requests in SAML 1.x.
-        */
- const SAML_1x_AUTHN_REQUEST = 'urn:mace:shibboleth:1.0:profiles:AuthnRequest';
-
-       /**
-        * This is the binding used for browser post in SAML 1.x.
-        */
- const SAML_1X_POST_BINDING = 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post';
-
-       /**
-        * This is the SAML 1.0 SOAP binding.
-        */
- const SAML_1X_SOAP_BINDING = 'urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding';
-
-
-       /**
-        * This is the binding used for HTTP-POST in SAML 2.0.
-        */
- const SAML_20_POST_BINDING = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST';
-
-
-       /**
-        * This is the binding used for HTTP-REDIRECT in SAML 2.0.
-        */
- const SAML_20_REDIRECT_BINDING = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect';
-
-
        /**
         * This is the entity id we find in the metadata.
         */
@@ -120,11 +92,11 @@


        /**
- * This is an array of SimpleSAML_XML_Validator classes. If this EntityDescriptor is signed, one of the - * validators should be able to verify the fingerprint of the certificate which was used to sign
-        * this EntityDescriptor.
+        * This is an array of elements that may be sued to validate this 
element.
+        *
+        * @var array
         */
-       private $validator = array();
+       private $validators = array();


        /**
@@ -136,81 +108,47 @@
        /**
         * This is the constructor for the SAMLParser class.
         *
- * @param $entityElement The DOMElement which represents the EntityDescriptor-element. - * @param $entitiesValidator A Validator instance for a signature element in the EntitiesDescriptor, - * or NULL if this EntityDescriptor isn't a child of an EntitiesDescriptor
-        *                            with a Signature element.
- * @param int|NULL $expireTime The unix timestamp for when this entity should expire, or NULL if unknwon. + * @param SAML2_XML_md_EntityDescriptor $entityElement The EntityDescriptor. + * @param int|NULL $maxExpireTime The unix timestamp for when this entity should expire, or NULL if unknwon. + * @param array $validators An array of parent elements that may validate this element.
         */
- private function __construct(DOMElement $entityElement, $entitiesValidator, $expireTime) { - assert('is_null($entitiesValidator) || $entitiesValidator instanceof SimpleSAML_XML_Validator');
-               assert('is_null($expireTime) || is_int($expireTime)');
+ private function __construct(SAML2_XML_md_EntityDescriptor $entityElement, $maxExpireTime, array $validators = array()) {
+               assert('is_null($maxExpireTime) || is_int($maxExpireTime)');

                $this->spDescriptors = array();
                $this->idpDescriptors = array();

-               $tmpDoc = new DOMDocument();
-               $tmpDoc->appendChild($tmpDoc->importNode($entityElement, TRUE));
-               $this->entityDescriptor = base64_encode($tmpDoc->saveXML());
-
- /* Extract the entity id from the EntityDescriptor element. This is a required
-                * attribute, so we throw an exception if it isn't found.
-                */
-               if(!$entityElement->hasAttribute('entityID')) {
- throw new Exception('EntityDescriptor missing required entityID attribute.');
-               }
-               $this->entityId = $entityElement->getAttribute('entityID');
-
-               if ($expireTime === NULL) {
- /* No expiry time defined by a parent element. Check if this element defines
-                        * one.
-                        */
-                       $expireTime = self::getExpireTime($entityElement);
-               }
-
-
- /* Check if the Signature element from the EntitiesDescriptor can be used to verify this
-                * EntityDescriptor, and add it to the list of validators if it 
is.
-                */
- if($entitiesValidator !== NULL && $entitiesValidator->isNodeValidated($entityElement)) {
-                       $this->validator[] = $entitiesValidator;
-               }
+               $e = $entityElement->toXML();
+               $e = $e->ownerDocument->saveXML($e);
+               $this->entityDescriptor = base64_encode($e);
+               $this->entityId = $entityElement->entityID;
+
+               $expireTime = self::getExpireTime($entityElement, 
$maxExpireTime);
+
+               $this->validators = $validators;
+               $this->validators[] = $entityElement;
+

                /* Process Extensions element, if it exists. */
                $ext = self::processExtensions($entityElement);
                $this->scopes = $ext['scopes'];
                $this->tags = $ext['tags'];

-               /* Look over the child nodes for any known element types. */
-               for($i = 0; $i < $entityElement->childNodes->length; $i++) {
-                       $child = $entityElement->childNodes->item($i);
-
-                       // Unless the child is a DOMElement, skip.
-                       if ( !($child instanceof DOMelement) ) continue;
-
- if(SimpleSAML_Utilities::isDOMElementOfType($child, 'Signature', '@ds') === TRUE) {
-                               $this->processSignature($child);
-                       }
-
- if(SimpleSAML_Utilities::isDOMElementOfType($child, 'SPSSODescriptor', '@md') === TRUE) {
+               /* Look over the RoleDescriptors. */
+               foreach ($entityElement->RoleDescriptor as $child) {
+
+                       if ($child instanceof SAML2_XML_md_SPSSODescriptor) {
                                $this->processSPSSODescriptor($child, 
$expireTime);
-                       }
-
- if(SimpleSAML_Utilities::isDOMElementOfType($child, 'IDPSSODescriptor', '@md') === TRUE) {
+                       } elseif ($child instanceof 
SAML2_XML_md_IDPSSODescriptor) {
                                $this->processIDPSSODescriptor($child, 
$expireTime);
-                       }
-
- if(SimpleSAML_Utilities::isDOMElementOfType($child, 'AttributeAuthorityDescriptor', '@md') === TRUE) {
+                       } elseif ($child instanceof 
SAML2_XML_md_AttributeAuthorityDescriptor) {
                                
$this->processAttributeAuthorityDescriptor($child, $expireTime);
                        }
-
- if(SimpleSAML_Utilities::isDOMElementOfType($child, 'Organization', '@md') === TRUE) {
-                               $this->processOrganization($child);
-                       }
-
                }

-
+               if ($entityElement->Organization) {
+                       
$this->processOrganization($entityElement->Organization);
+               }
        }


@@ -328,48 +266,55 @@
* This function parses a DOMElement which represents either an EntityDescriptor element or an * EntitiesDescriptor element. It will return an associative array of SAMLParser instances in both cases.
         *
- * @param $element The DOMElement which contains the EntityDescriptor element or the EntitiesDescriptor
-        *                  element.
+ * @param DOMElement|NULL $element The DOMElement which contains the EntityDescriptor element or the EntitiesDescriptor element. * @return An associative array of SAMLParser instances. The key of the array will be the entity id.
         */
-       public static function parseDescriptorsElement($element) {
+ public static function parseDescriptorsElement(DOMElement $element = NULL) {

                if($element === NULL) {
                        throw new Exception('Document was empty.');
                }

                assert('$element instanceof DOMElement');
-
-               $entitiesValidator = NULL;

if(SimpleSAML_Utilities::isDOMElementOfType($element, 'EntityDescriptor', '@md') === TRUE) {
-                       $elements = array($element);
-                       $expireTime = NULL;
+ return self::processDescriptorsElement(new SAML2_XML_md_EntityDescriptor($element)); } elseif(SimpleSAML_Utilities::isDOMElementOfType($element, 'EntitiesDescriptor', '@md') === TRUE) {
-
-                       /* Check if there is a signature element in the 
EntitiesDescriptor. */
- if(count(SimpleSAML_Utilities::getDOMChildren($element, 'Signature', '@ds'))
0) {
-                               try {
-                                       $entitiesValidator = new 
SimpleSAML_XML_Validator($element, 'ID');
-                               } catch(Exception $e) {
- SimpleSAML_Logger::warning('SAMLParser: Error creating XML Signature validator for XML document: ' .
-                                               $e->getMessage());
-                                       $entitiesValidator = NULL;
-                               }
-                       }
-
-                       $expireTime = self::getExpireTime($element);
-
- $elements = SimpleSAML_Utilities::getDOMChildren($element, 'EntityDescriptor', '@md'); + return self::processDescriptorsElement(new SAML2_XML_md_EntitiesDescriptor($element));
                } else {
throw new Exception('Unexpected root node: [' . $element->namespaceURI . ']:' .
                                $element->localName);
                }
+
+               return $ret;
+       }
+
+
+       /**
+        *
+ * @param SAML2_XML_md_EntityDescriptor|SAML2_XML_md_EntitiesDescriptor $element The element we should process. + * @param int|NULL $maxExpireTime The maximum expiration time of the entitites.
+        * @param array $validators  The parent-elements that may be signed.
+        * @return array  Array of SAMLParser instances.
+        */
+ private static function processDescriptorsElement($element, $maxExpireTime = NULL, array $validators = array()) {
+               assert('is_null($maxExpireTime) || is_int($maxExpireTime)');
+
+               if ($element instanceof SAML2_XML_md_EntityDescriptor) {
+ $ret = new SimpleSAML_Metadata_SAMLParser($element, $maxExpireTime, $validators);
+                       return array($ret->getEntityId() => $ret);
+               }
+
+               assert('$element instanceof SAML2_XML_md_EntitiesDescriptor');
+
+
+               $expTime = self::getExpireTime($element, $maxExpireTime);
+
+               $validators[] = $element;

                $ret = array();
-               foreach($elements as $e) {
- $entity = new SimpleSAML_Metadata_SAMLParser($e, $entitiesValidator, $expireTime);
-                       $ret[$entity->getEntityId()] = $entity;
+               foreach ($element->children as $child) {
+                       $ret += self::processDescriptorsElement($child, 
$expTime, $validators);
                }

                return $ret;
@@ -385,42 +330,29 @@
* If both the 'cacheDuration' and 'validUntil' attributes are present, the shorter of them
         * will be returned.
         *
- * @param DOMElement $element The element we should determine the expiry time of. + * @param mixed $element The element we should determine the expiry time of.
+        * @param int|NULL $maxExpireTime  The maximum expiration time.
* @return int The unix timestamp for when the element should expire. Will be NULL if no
         *              limit is set for the element.
         */
-       private static function getExpireTime(DOMElement $element) {
-
-               if ($element->hasAttribute('cacheDuration')) {
-                       $cacheDuration = 
$element->getAttribute('cacheDuration');
- $cacheDuration = SimpleSAML_Utilities::parseDuration($cacheDuration, time());
+       private static function getExpireTime($element, $maxExpireTime) {
+
+               if ($element->cacheDuration !== NULL) {
+ $expire = SimpleSAML_Utilities::parseDuration($element->cacheDuration, time());
+                       if ($maxExpireTime !== NULL && $maxExpireTime < 
$expire) {
+                               $expire = $maxExpireTime;
+                       }
                } else {
-                       $cacheDuration = NULL;
+                       $expire = $maxExpireTime;
                }

-               if ($element->hasAttribute('validUntil')) {
-                       $validUntil = $element->getAttribute('validUntil');
-                       $validUntil = 
SimpleSAML_Utilities::parseSAML2Time($validUntil);
-               } else {
-                       $validUntil = NULL;
-               }
-
-               if ($cacheDuration !== NULL && $validUntil !== NULL) {
-                       /* Both are given. Return the shortest. */
-
-                       if($cacheDuration < $validUntil) {
-                               return $cacheDuration;
-                       } else {
-                               return $validUntil;
-                       }
-
-               } elseif ($cacheDuration !== NULL) {
-                       return $cacheDuration;
-               } elseif ($validUntil !== NULL) {
-                       return $validUntil;
-               } else {
-                       return NULL;
-               }
+               if ($element->validUntil !== NULL) {
+                       if ($expire === NULL || $expire > $element->validUntil) 
{
+                               $expire = $element->validUntil;
+                       }
+               }
+
+               return $expire;
        }


@@ -803,23 +735,17 @@
          * - 'expire': Timestamp for when this descriptor expires.
* - 'keys': Array of associative arrays with the elements from parseKeyDescriptor.
         *
- * @param DOMElement $element The element we should extract metadata from. + * @param SAML2_XML_md_RoleDescriptor $element The element we should extract metadata from. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or
         *                              NULL if unknwon.
* @return Associative array with metadata we have extracted from this element.
         */
- private static function parseRoleDescriptorType(DOMElement $element, $expireTime) { + private static function parseRoleDescriptorType(SAML2_XML_md_RoleDescriptor $element, $expireTime) {
                assert('is_null($expireTime) || is_int($expireTime)');

                $ret = array();

-               if ($expireTime === NULL) {
- /* No expiry time defined by a parent element. Check if this element defines
-                        * one.
-                        */
-                       $expireTime = self::getExpireTime($element);
-               }
-
+               $expireTime = self::getExpireTime($element, $expireTime);

                if ($expireTime !== NULL) {
/* We have got an expire timestamp, either from this element, or one of the
@@ -828,12 +754,11 @@
                        $ret['expire'] = $expireTime;
                }

-               $ret['protocols'] = self::getSupportedProtocols($element);
+               $ret['protocols'] = $element->protocolSupportEnumeration;

                /* Process KeyDescriptor elements. */
                $ret['keys'] = array();
- $keys = SimpleSAML_Utilities::getDOMChildren($element, 'KeyDescriptor', '@md');
-               foreach($keys as $kd) {
+               foreach ($element->KeyDescriptor as $kd) {
                        $key = self::parseKeyDescriptor($kd);
                        if($key !== NULL) {
                                $ret['keys'][] = $key;
@@ -858,30 +783,25 @@
* - 'nameIDFormats': The NameIDFormats supported by this SSODescriptor. This may be an empty array. * - 'keys': Array of associative arrays with the elements from parseKeyDescriptor:
         *
-        * @param $element The element we should extract metadata from.
+ * @param SAML2_XML_md_SSODescriptorType $element The element we should extract metadata from. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or
         *                              NULL if unknwon.
* @return Associative array with metadata we have extracted from this element.
         */
-       private static function parseSSODescriptor($element, $expireTime) {
-               assert('$element instanceof DOMElement');
+ private static function parseSSODescriptor(SAML2_XML_md_SSODescriptorType $element, $expireTime) {
                assert('is_null($expireTime) || is_int($expireTime)');

                $sd = self::parseRoleDescriptorType($element, $expireTime);

                /* Find all SingleLogoutService elements. */
- $sd['SingleLogoutService'] = self::extractEndpoints($element, 'SingleLogoutService', FALSE); + $sd['SingleLogoutService'] = self::extractEndpoints($element->SingleLogoutService);

                /* Find all ArtifactResolutionService elements. */
- $sd['ArtifactResolutionService'] = self::extractEndpoints($element, 'ArtifactResolutionService', TRUE); + $sd['ArtifactResolutionService'] = self::extractEndpoints($element->ArtifactResolutionService);


                /* Process NameIDFormat elements. */
-               $sd['nameIDFormats'] = array();
- $nif = SimpleSAML_Utilities::getDOMChildren($element, 'NameIDFormat', '@md');
-               if(count($nif) > 0) {
-                       $sd['nameIDFormats'][] = 
self::parseNameIDFormat($nif[0]);
-               }
+               $sd['nameIDFormats'] = $element->NameIDFormat;

                return $sd;
        }
@@ -890,25 +810,23 @@
        /**
         * This function extracts metadata from a SPSSODescriptor element.
         *
-        * @param $element The element which should be parsed.
+ * @param SAML2_XML_md_SPSSODescriptor $element The element which should be parsed. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or
         *                              NULL if unknwon.
         */
-       private function processSPSSODescriptor($element, $expireTime) {
-               assert('$element instanceof DOMElement');
+ private function processSPSSODescriptor(SAML2_XML_md_SPSSODescriptor $element, $expireTime) {
                assert('is_null($expireTime) || is_int($expireTime)');

                $sp = self::parseSSODescriptor($element, $expireTime);

                /* Find all AssertionConsumerService elements. */
- $sp['AssertionConsumerService'] = self::extractEndpoints($element, 'AssertionConsumerService', TRUE); + $sp['AssertionConsumerService'] = self::extractEndpoints($element->AssertionConsumerService);

                /* Find all the attributes and SP name... */
-               #$sp['attributes'] = array();
- $attcs = SimpleSAML_Utilities::getDOMChildren($element, 'AttributeConsumingService', '@md');
+               $attcs = $element->AttributeConsumingService;
                if (count($attcs) > 0) {
                        self::parseAttributeConsumerService($attcs[0], $sp);
-               }
+               }

                $this->spDescriptors[] = $sp;
        }
@@ -917,20 +835,19 @@
        /**
         * This function extracts metadata from a IDPSSODescriptor element.
         *
-        * @param $element The element which should be parsed.
+ * @param SAML2_XML_md_IDPSSODescriptor $element The element which should be parsed. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or
         *                              NULL if unknwon.
         */
-       private function processIDPSSODescriptor($element, $expireTime) {
-               assert('$element instanceof DOMElement');
+ private function processIDPSSODescriptor(SAML2_XML_md_IDPSSODescriptor $element, $expireTime) {
                assert('is_null($expireTime) || is_int($expireTime)');

                $idp = self::parseSSODescriptor($element, $expireTime);

                /* Find all SingleSignOnService elements. */
- $idp['SingleSignOnService'] = self::extractEndpoints($element, 'SingleSignOnService', FALSE);
-
-               if ($element->getAttribute('WantAuthnRequestsSigned') === 
'true') {
+ $idp['SingleSignOnService'] = self::extractEndpoints($element->SingleSignOnService);
+
+               if ($element->WantAuthnRequestsSigned) {
                        $idp['WantAuthnRequestsSigned'] = TRUE;
                } else {
                        $idp['WantAuthnRequestsSigned'] = FALSE;
@@ -943,23 +860,20 @@
        /**
* This function extracts metadata from a AttributeAuthorityDescriptor element.
         *
-        * @param DOMElement $element The element which should be parsed.
+ * @param SAML2_XML_md_AttributeAuthorityDescriptor $element The element which should be parsed. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or
         *                              NULL if unknwon.
         */
- private function processAttributeAuthorityDescriptor(DOMElement $element, $expireTime) { + private function processAttributeAuthorityDescriptor(SAML2_XML_md_AttributeAuthorityDescriptor $element, $expireTime) {
                assert('is_null($expireTime) || is_int($expireTime)');

                $aad = self::parseRoleDescriptorType($element, $expireTime);
                $aad['entityid'] = $this->entityId;
                $aad['metadata-set'] = 'attributeauthority-remote';

- $aad['AttributeService'] = self::extractEndpoints($element, 'AttributeService', FALSE); - $aad['AssertionIDRequestService'] = self::extractEndpoints($element, 'AssertionIDRequestService', FALSE);
-               $aad['NameIDFormat'] = array_map(
-                       array('SimpleSAML_Utilities', 'getDOMText'),
-                       SimpleSAML_Utilities::getDOMChildren($element, 
'NameIDFormat', '@md')
-               );
+ $aad['AttributeService'] = self::extractEndpoints($element->AttributeService); + $aad['AssertionIDRequestService'] = self::extractEndpoints($element->AssertionIDRequestService);
+               $aad['NameIDFormat'] = $element->NameIDFormat;

                $this->attributeAuthorityDescriptors[] = $aad;
        }
@@ -968,41 +882,40 @@
        /**
         * Parse an Extensions element.
         *
- * @param DOMElement $element The DOMElement which contains the Extensions element. + * @param mixed $element The element which contains the Extensions element.
         */
-       private static function processExtensions(DOMElement $element) {
+       private static function processExtensions($element) {

                $ret = array(
                        'scopes' => array(),
                        'tags' => array(),
                );

- $extensions = SimpleSAML_Utilities::getDOMChildren($element, 'Extensions', '@md');
-               if (empty($extensions)) {
-                       /* No extension element. */
-                       return $ret;
-               }
-               $element = $extensions[0];
-
- /* See: https://spaces.internet2.edu/display/SHIB/ShibbolethMetadataProfile */ - foreach (SimpleSAML_Utilities::getDOMChildren($element, 'Scope', '@shibmd') as $scope) {
-                       $scope = SimpleSAML_Utilities::getDOMText($scope);
-                       if (!empty($scope)) {
-                               $ret['scopes'][] = $scope;
-                       }
-               }
-
- foreach (SimpleSAML_Utilities::getDOMChildren($element, 'Attribute', '@saml2') as $attribute) {
-                       $name = $attribute->getAttribute('Name');
-                       $values = array_map(
-                               array('SimpleSAML_Utilities', 'getDOMText'),
- SimpleSAML_Utilities::getDOMChildren($attribute, 'AttributeValue', '@saml2')
-                       );
-
-                       if ($name === 'tags') {
-                               foreach ($values as $tagname) {
-                                       if (!empty($tagname)) {
-                                               $ret['tags'][] = $tagname;
+               foreach ($element->Extensions as $e) {
+
+                       if ($e instanceof SAML2_XML_shibmd_Scope) {
+                               $ret['scopes'][] = $e->scope;
+                               continue;
+                       }
+
+                       if (!($e instanceof SAML2_XML_Chunk)) {
+                               continue;
+                       }
+
+ if ($e->localName === 'Attribute' && $e->namespaceURI === SAML2_Const::NS_SAML) {
+                               $attribute = $e->getXML();
+
+                               $name = $attribute->getAttribute('Name');
+                               $values = array_map(
+                                       array('SimpleSAML_Utilities', 
'getDOMText'),
+ SimpleSAML_Utilities::getDOMChildren($attribute, 'AttributeValue', '@saml2')
+                               );
+
+                               if ($name === 'tags') {
+                                       foreach ($values as $tagname) {
+                                               if (!empty($tagname)) {
+                                                       $ret['tags'][] = 
$tagname;
+                                               }
                                        }
                                }
                        }
@@ -1015,90 +928,33 @@
        /**
         * Parse and process a Organization element.
         *
- * @param $element The DOMElement which represents the Organization element.
+        * @param SAML2_XML_md_Organization $element  The Organization element.
         */
-       private function processOrganization($element) {
-               assert('$element instanceof DOMElement');
-
-               for($i = 0; $i < $element->childNodes->length; $i++) {
-                       $child = $element->childNodes->item($i);
-
-                       /* Skip text nodes. */
-                       if($child instanceof DOMText) {
-                               continue;
-                       }
-
-                       /* Determine the type. */
- if(SimpleSAML_Utilities::isDOMElementOfType($child, 'OrganizationName', '@md')) {
-                               $type = 'organizationName';
- } elseif(SimpleSAML_Utilities::isDOMElementOfType($child, 'OrganizationDisplayName', '@md')) {
-                               $type = 'organizationDisplayName';
- } elseif(SimpleSAML_Utilities::isDOMElementOfType($child, 'OrganizationURL', '@md')) {
-                               $type = 'organizationURL';
-                       } else {
-                               /* Skip unknown/unhandled elements. */
-                               continue;
-                       }
-
-                       /* Extract the text. */
-                       $text = SimpleSAML_Utilities::getDOMText($child);
-
-                       /* Skip nodes without text. */
-                       if(empty($text)) {
-                               continue;
-                       }
-
- /* Find the language of the text. This should be stored in the xml:lang attribute. */ - $language = $child->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang');
-                       //$language = $child->getAttributeNS('xml', 'lang');
-                       if(empty($language)) {
-                               /* No language given, assume 'en'. */
-                               $language = 'en';
-                       }
-
-                       /* Add the result to the appropriate list. */
-                       if($type === 'organizationName') {
-                               $this->organizationName[$language] = $text;
-                       } elseif($type === 'organizationDisplayName') {
-                               $this->organizationDisplayName[$language] = 
$text;
-                       } elseif($type === 'organizationURL') {
-                               $this->organizationURL[$language] = $text;
-                       }
-               }
+       private function processOrganization(SAML2_XML_md_Organization 
$element) {
+
+               $this->organizationName = $element->OrganizationName;
+               $this->organizationDisplayName = 
$element->OrganizationDisplayName;
+               $this->organizationURL = $element->OrganizationURL;
        }


        /**
         * This function parses AttributeConsumerService elements.
         */
-       private static function parseAttributeConsumerService($element, &$sp) {
-               assert('$element instanceof DOMElement');
+ private static function parseAttributeConsumerService(SAML2_XML_md_AttributeConsumingService $element, &$sp) {
                assert('is_array($sp)');
-
- $elements = SimpleSAML_Utilities::getDOMChildren($element, 'ServiceName', '@md');
-               foreach($elements AS $child) {
- $language = $child->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang');
-                       if(empty($language)) $language = 'en';
-                       $sp['name'][$language] = 
SimpleSAML_Utilities::getDOMText($child);
-               }
-
- $elements = SimpleSAML_Utilities::getDOMChildren($element, 'ServiceDescription', '@md');
-               foreach($elements AS $child) {
- $language = $child->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang');
-                       if(empty($language)) $language = 'en';
- $sp['description'][$language] = SimpleSAML_Utilities::getDOMText($child);
-               }
-
+
+               $sp['name'] = $element->ServiceName;
+               $sp['description'] = $element->ServiceDescription;

                $format = NULL;
- $elements = SimpleSAML_Utilities::getDOMChildren($element, 'RequestedAttribute', '@md');
                $sp['attributes'] = array();
-               foreach($elements AS $child) {
-                       $attrname = $child->getAttribute('Name');
+               foreach ($element->RequestedAttribute AS $child) {
+                       $attrname = $child->Name;
                        $sp['attributes'][] = $attrname;

-                       if ($child->hasAttribute('NameFormat')) {
-                               $attrformat = 
$child->getAttribute('NameFormat');
+                       if ($child->NameFormat !== NULL) {
+                               $attrformat = $child->NameFormat;
                        } else {
                                $attrformat = 
SAML2_Const::NAMEFORMAT_UNSPECIFIED;
                        }
@@ -1108,7 +964,6 @@
                        } elseif ($format !== $attrformat) {
                                $format = SAML2_Const::NAMEFORMAT_UNSPECIFIED;
                        }
-
                }

                if (empty($sp['attributes'])) {
@@ -1122,20 +977,6 @@
if ($format !== SAML2_Const::NAMEFORMAT_UNSPECIFIED && $format !== NULL) {
                        $sp['attributes.NameFormat'] = $format;
                }
-
-       }
-
-
-       /**
-        * This function parses NameIDFormat elements.
-        *
-        * @param $element The element which should be parsed.
-        * @return URN with the supported NameIDFormat.
-        */
-       private static function parseNameIDFormat($element) {
-               assert('$element instanceof DOMElement');
-
-               return SimpleSAML_Utilities::getDOMText($element);
        }


@@ -1150,47 +991,24 @@
* - 'isDefault': Whether this endpoint is the default endpoint for this type. This attribute may not exist.
         *
         * @param $element The element which should be parsed.
- * @param $isIndexed Wheter the endpoint is an indexed endpoint (and may have the index and isDefault attributes.). * @return Associative array with the data we have extracted from the element.
         */
-       private static function parseGenericEndpoint($element, $isIndexed) {
-               assert('$element instanceof DOMElement');
-               assert('is_bool($isIndexed)');
-
-               $name = $element->localName;
+ private static function parseGenericEndpoint(SAML2_XML_md_EndpointType $element) {

                $ep = array();

-               if(!$element->hasAttribute('Binding')) {
-                       throw new Exception($name . ' missing required Binding 
attribute.');
-               }
-               $ep['Binding'] = $element->getAttribute('Binding');
-
-               if(!$element->hasAttribute('Location')) {
-                       throw new Exception($name . ' missing required Location 
attribute.');
-               }
-               $ep['Location'] = $element->getAttribute('Location');
-
-               if($element->hasAttribute('ResponseLocation')) {
-                       $ep['ResponseLocation'] = 
$element->getAttribute('ResponseLocation');
-               }
-
-               if($isIndexed) {
-                       if(!$element->hasAttribute('index')) {
-                               throw new Exception($name . ' missing required 
index attribute.');
-                       }
-                       $ep['index'] = (int)$element->getAttribute('index');
-
-                       if($element->hasAttribute('isDefault')) {
-                               $t = $element->getAttribute('isDefault');
-                               if($t === 'false') {
-                                       $ep['isDefault'] = FALSE;
-                               } elseif($t === 'true') {
-                                       $ep['isDefault'] = TRUE;
-                               } else {
-                                       throw new Exception('Invalid value for 
isDefault attribute on ' .
-                                               $name . ' element: ' . $t);
-                               }
+               $ep['Binding'] = $element->Binding;
+               $ep['Location'] = $element->Location;
+
+               if ($element->ResponseLocation !== NULL) {
+                       $ep['ResponseLocation'] = $element->ResponseLocation;
+               }
+
+               if ($element instanceof SAML2_XML_md_IndexedEndpointType) {
+                       $ep['index'] = $element->index;
+
+                       if ($element->isDefault !== NULL) {
+                               $ep['isDefault'] = $element->isDefault;
                        }
                }

@@ -1201,19 +1019,14 @@
        /**
         * Extract generic endpoints.
         *
- * @param DOMElement $element The element we should extract an endpoint list from.
-        * @param string $name  The name of the elements.
-        * @param bool $isIndexed  Whether the endpoints are indexed.
+        * @param array $endpoints  The endpoints we should parse.
         * @return array  Array of parsed endpoints.
         */
- private static function extractEndpoints(DOMElement $element, $name, $isIndexed) {
-               assert('is_bool($isIndexed)');
-               assert('is_string($name)');
+       private static function extractEndpoints(array $endpoints) {

                $ret = array();
- $endpoints = SimpleSAML_Utilities::getDOMChildren($element, $name, '@md');
                foreach ($endpoints as $ep) {
-                       $ret[] = self::parseGenericEndpoint($ep, $isIndexed);
+                       $ret[] = self::parseGenericEndpoint($ep);
                }

                return $ret;
@@ -1230,52 +1043,39 @@
* - 'type: The type of the key. 'X509Certificate' is the only key type we support. * - 'X509Certificate': The contents of the first X509Certificate element (if the type is 'X509Certificate ').
         *
-        * @param $kd  The KeyDescriptor element.
+        * @param SAML2_XML_md_KeyDescriptor $kd  The KeyDescriptor element.
* @return Associative array describing the key, or NULL if this is an unsupported key.
         */
-       private static function parseKeyDescriptor($kd) {
-               assert('$kd instanceof DOMElement');
+ private static function parseKeyDescriptor(SAML2_XML_md_KeyDescriptor $kd) {

                $r = array();

-               if($kd->hasAttribute('use')) {
-                       $use = $kd->getAttribute('use');
-                       if($use === 'encryption') {
-                               $r['encryption'] = TRUE;
-                               $r['signing'] = FALSE;
-                       } elseif($use === 'signing') {
-                               $r['encryption'] = FALSE;
-                               $r['signing'] = TRUE;
-                       } else {
-                               throw new Exception('Invalid use-value for 
KeyDescriptor: ' . $use);
-                       }
+               if ($kd->use === 'encryption') {
+                       $r['encryption'] = TRUE;
+                       $r['signing'] = FALSE;
+               } elseif($kd->use === 'signing') {
+                       $r['encryption'] = FALSE;
+                       $r['signing'] = TRUE;
                } else {
                        $r['encryption'] = TRUE;
                        $r['signing'] = TRUE;
                }

-               $keyInfo = SimpleSAML_Utilities::getDOMChildren($kd, 'KeyInfo', 
'@ds');
-               if(count($keyInfo) === 0) {
- throw new Exception('Missing required KeyInfo field for KeyDescriptor.');
-               }
-               $keyInfo = $keyInfo[0];
-
- $X509Data = SimpleSAML_Utilities::getDOMChildren($keyInfo, 'X509Data', '@ds');
-               if(count($X509Data) === 0) {
-                       return NULL;
-               }
-               $X509Data = $X509Data[0];
-
- $X509Certificate = SimpleSAML_Utilities::getDOMChildren($X509Data, 'X509Certificate', '@ds');
-               if(count($X509Certificate) === 0) {
-                       return NULL;
-               }
-               $X509Certificate = $X509Certificate[0];
-
-               $r['type'] = 'X509Certificate';
- $r['X509Certificate'] = SimpleSAML_Utilities::getDOMText($X509Certificate);
-
-               return $r;
+               $keyInfo = $kd->KeyInfo;
+
+               foreach ($keyInfo->info as $i) {
+                       if ($i instanceof SAML2_XML_ds_X509Data) {
+                               foreach ($i->data as $d) {
+                                       if ($d instanceof 
SAML2_XML_ds_X509Certificate) {
+                                               $r['type'] = 'X509Certificate';
+                                               $r['X509Certificate'] = 
$d->certificate;
+                                               return $r;
+                                       }
+                               }
+                       }
+               }
+
+               return NULL;
        }


@@ -1349,68 +1149,7 @@
throw new Exception('Expected first element in the metadata document to be an EntityDescriptor element.');
                }

-               return $ed;
-       }
-
-
-       /**
- * This function extracts a list of supported protocols from a SPSSODescriptor or IDPSSODescriptor element.
-        *
-        * @param $element The SPSSODescriptor or IDPSSODescriptor element.
-        * @return Array with the supported protocols.
-        */
-       private static function getSupportedProtocols($element) {
-               assert('$element instanceof DOMElement');
-
-               /* The protocolSupportEnumeration is a required attribute. */
-               if(!$element->hasAttribute('protocolSupportEnumeration')) {
- throw new Exception($element->tagName . ' is missing the required protocolSupportEnumeration attribute.');
-               }
-
-               /* The attribute is a space seperated list of supported 
protocols. */
-               $supProt = $element->getAttribute('protocolSupportEnumeration');
-               $supProt = explode(' ', $supProt);
-
-               return $supProt;
-       }
-
-
-       /**
- * This function processes a signature element in an EntityDescriptor element.
-        *
- * It will attempt to validate the EntityDescriptor element using the signature. If the signature - * is good, it will and will store the fingerprint the certificate in the $validatedFingerprint variable.
-        *
-        * @param $element  The ds:Signature element.
-        */
-       private function processSignature($element) {
-               assert('$element instanceof DOMElement');
-
- /* We want to validate the EntityDescriptor which contains the signature. */
-               $entityDescriptor = $element->parentNode;
-               assert('$entityDescriptor instanceof DOMElement');
-
-               /*
-                * Make a copy of the entity descriptor, so that the validator 
can
-                * change the DOM tree in any way it wants.
-                */
-               $doc = new DOMDocument();
-               $entityDescriptor = $doc->importNode($entityDescriptor, TRUE);
-               $doc->appendChild($entityDescriptor);
-
-               /* Attempt to check the signature. */
-               try {
-                       $validator = new 
SimpleSAML_XML_Validator($entityDescriptor, 'ID');
-
-                       if($validator->isNodeValidated($entityDescriptor)) {
- /* The EntityDescriptor is signed. Store the validator in $this->validator, so - * that it can be used to verify the fingerprint of the certificate later.
-                                */
-                               $this->validator[] = $validator;
-                       }
-               } catch(Exception $e) {
- /* Ignore validation errors and pretend that this EntityDescriptor is unsigned. */
-               }
+               return new SAML2_XML_md_EntityDescriptor($ed);
        }


@@ -1424,13 +1163,12 @@
         */
        public function validateFingerprint($fingerprint) {

-               foreach($this->validator as $validator) {
-                       try {
-                               $validator->validateFingerprint($fingerprint);
-                               return TRUE;
-                       } catch(Exception $e) {
-                               /* Validation with this validator failed. */
- SimpleSAML_Logger::debug('Validation of fingerprint failed: ' . $e->getMessage());
+               foreach ($this->validators as $validator) {
+                       foreach ($validator->getValidatingCertificates() as 
$cert) {
+                               $fp = strtolower(sha1(base64_decode($cert)));
+                               if ($fp === $fingerprint) {
+                                       return TRUE;
+                               }
                        }
                }

@@ -1438,5 +1176,3 @@
        }

 }
-
-?>

--
You received this message because you are subscribed to the Google Groups 
"simpleSAMLphp commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/simplesamlphp-commits?hl=en.

Reply via email to