/** * Retrieve and parse the metadata. * * @return SAML2_XML_md_EntitiesDescriptor|SAML2_XML_md_EntityDescriptor|NULL * The downloaded metadata or NULL if we were unable to download or parse it. */ private function downloadMetadata() { SimpleSAML\Logger::debug($this->logLoc . 'Downloading metadata from ' . var_export($this->url, TRUE)); $context = array('ssl' => array()); if ($this->sslCAFile !== NULL) { $context['ssl']['cafile'] = SimpleSAML_Utilities::resolveCert($this->sslCAFile); SimpleSAML\Logger::debug($this->logLoc . 'Validating https connection against CA certificate(s) found in ' . var_export($context['ssl']['cafile'], TRUE)); $context['ssl']['verify_peer'] = TRUE; $context['ssl']['CN_match'] = parse_url($this->url, PHP_URL_HOST); } $data = SimpleSAML_Utilities::fetch($this->url, $context); if ($data === FALSE || $data === NULL) { SimpleSAML\Logger::error($this->logLoc . 'Unable to load metadata from ' . var_export($this->url, TRUE)); return NULL; } $doc = new DOMDocument(); $res = $doc->loadXML($data); if (!$res) { SimpleSAML\Logger::error($this->logLoc . 'Error parsing XML from ' . var_export($this->url, TRUE)); return NULL; } $root = SAML2_Utils::xpQuery($doc->firstChild, '/saml_metadata:EntityDescriptor|/saml_metadata:EntitiesDescriptor'); if (count($root) === 0) { SimpleSAML\Logger::error($this->logLoc . 'No <EntityDescriptor> or <EntitiesDescriptor> in metadata from ' . var_export($this->url, TRUE)); return NULL; } if (count($root) > 1) { SimpleSAML\Logger::error($this->logLoc . 'More than one <EntityDescriptor> or <EntitiesDescriptor> in metadata from ' . var_export($this->url, TRUE)); return NULL; } $root = $root[0]; try { if ($root->localName === 'EntityDescriptor') { $md = new SAML2_XML_md_EntityDescriptor($root); } else { $md = new SAML2_XML_md_EntitiesDescriptor($root); } } catch (Exception $e) { SimpleSAML\Logger::error($this->logLoc . 'Unable to parse metadata from ' . var_export($this->url, TRUE) . ': ' . $e->getMessage()); return NULL; } if ($this->certificate !== NULL) { $file = SimpleSAML_Utilities::resolveCert($this->certificate); $certData = file_get_contents($file); if ($certData === FALSE) { throw new SimpleSAML_Error_Exception('Error loading certificate from ' . var_export($file, TRUE)); } // Extract the public key from the certificate for validation $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public')); $key->loadKey($file, TRUE); if (!$md->validate($key)) { SimpleSAML\Logger::error($this->logLoc . 'Error validating signature on metadata.'); return NULL; } SimpleSAML\Logger::debug($this->logLoc . 'Validated signature on metadata from ' . var_export($this->url, TRUE)); } return $md; }
public function getMetadataDocument() { // Get metadata entries $entities = $this->getSources(); $maxDuration = $this->getMaxDuration(); $reconstruct = $this->getReconstruct(); $entitiesDescriptor = new SAML2_XML_md_EntitiesDescriptor(); $entitiesDescriptor->Name = $this->id; $entitiesDescriptor->validUntil = time() + $maxDuration; // add RegistrationInfo extension if enabled if ($this->gConfig->hasValue('RegistrationInfo')) { $ri = new SAML2_XML_mdrpi_RegistrationInfo(); foreach ($this->gConfig->getArray('RegistrationInfo') as $riName => $riValues) { switch ($riName) { case 'authority': $ri->registrationAuthority = $riValues; break; case 'instant': $ri->registrationInstant = SAML2_Utils::xsDateTimeToTimestamp($riValues); break; case 'policies': $ri->RegistrationPolicy = $riValues; break; } } $entitiesDescriptor->Extensions[] = $ri; } /* Build EntityDescriptor elements for them. */ foreach ($entities as $entity => $sets) { $entityDescriptor = NULL; foreach ($sets as $set => $metadata) { if (!array_key_exists('entityDescriptor', $metadata)) { /* One of the sets doesn't contain an EntityDescriptor element. */ $entityDescriptor = FALSE; break; } if ($entityDescriptor == NULL) { /* First EntityDescriptor elements. */ $entityDescriptor = $metadata['entityDescriptor']; continue; } assert('is_string($entityDescriptor)'); if ($entityDescriptor !== $metadata['entityDescriptor']) { /* Entity contains multiple different EntityDescriptor elements. */ $entityDescriptor = FALSE; break; } } if (is_string($entityDescriptor) && !$reconstruct) { /* All metadata sets for the entity contain the same entity descriptor. Use that one. */ $tmp = new DOMDocument(); $tmp->loadXML(base64_decode($entityDescriptor)); $entitiesDescriptor->children[] = new SAML2_XML_md_EntityDescriptor($tmp->documentElement); } else { $tmp = new SimpleSAML_Metadata_SAMLBuilder($entity, $maxDuration, $maxDuration); $orgmeta = NULL; foreach ($sets as $set => $metadata) { $tmp->addMetadata($set, $metadata); $orgmeta = $metadata; } $tmp->addOrganizationInfo($orgmeta); $entitiesDescriptor->children[] = $tmp->getEntityDescriptor(); } } $document = $entitiesDescriptor->toXML(); // sign the metadata if enabled if ($this->shouldSign()) { $signer = new SimpleSAML_XML_Signer($this->getSigningInfo()); $signer->sign($document, $document, $document->firstChild); } return $document; }