/**
  * 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;
 }