/** * BC compatible version of the signature check * * @param \SAML2\SignedElement $element * @param \SAML2\Certificate\X509[] $pemCandidates * * @throws \Exception * * @return bool */ protected function validateElementWithKeys(SignedElement $element, $pemCandidates) { $lastException = null; foreach ($pemCandidates as $index => $candidateKey) { $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public')); $key->loadKey($candidateKey->getCertificate()); try { /* * Make sure that we have a valid signature on either the response or the assertion. */ $result = $element->validate($key); if ($result) { $this->logger->debug(sprintf('Validation with key "#%d" succeeded', $index)); return true; } $this->logger->debug(sprintf('Validation with key "#%d" failed without exception.', $index)); } catch (\Exception $e) { $this->logger->debug(sprintf('Validation with key "#%d" failed with exception: %s', $index, $e->getMessage())); $lastException = $e; } } if ($lastException !== null) { throw $lastException; } else { return false; } }
public function canValidate(SignedElement $signedElement, CertificateProvider $configuration) { if ($configuration->getCertificateFingerprints() === null) { $this->logger->debug('Configuration does not have "certFingerprint" value, cannot validate signature with fingerprint'); return false; } // use internal cache to prevent doing certificate extraction twice. $this->certificates = $signedElement->getCertificates(); if (empty($this->certificates)) { $this->logger->debug('Signed element does not have certificates, cannot validate signature with fingerprint'); return false; } return true; }
/** * Check the signature on a SAML2 message or assertion. * * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender. * @param \SAML2\SignedElement $element Either a \SAML2\Response or a \SAML2\Assertion. */ public static function checkSign(SimpleSAML_Configuration $srcMetadata, \SAML2\SignedElement $element) { /* Find the public key that should verify signatures by this entity. */ $keys = $srcMetadata->getPublicKeys('signing'); if ($keys !== NULL) { $pemKeys = array(); foreach ($keys as $key) { switch ($key['type']) { case 'X509Certificate': $pemKeys[] = "-----BEGIN CERTIFICATE-----\n" . chunk_split($key['X509Certificate'], 64) . "-----END CERTIFICATE-----\n"; break; default: SimpleSAML\Logger::debug('Skipping unknown key type: ' . $key['type']); } } } elseif ($srcMetadata->hasValue('certFingerprint')) { SimpleSAML\Logger::notice("Validating certificates by fingerprint is deprecated. Please use " . "certData or certificate options in your remote metadata configuration."); $certFingerprint = $srcMetadata->getArrayizeString('certFingerprint'); foreach ($certFingerprint as &$fp) { $fp = strtolower(str_replace(':', '', $fp)); } $certificates = $element->getCertificates(); /* * We don't have the full certificate stored. Try to find it * in the message or the assertion instead. */ if (count($certificates) === 0) { /* We need the full certificate in order to match it against the fingerprint. */ SimpleSAML\Logger::debug('No certificate in message when validating against fingerprint.'); return FALSE; } else { SimpleSAML\Logger::debug('Found ' . count($certificates) . ' certificates in ' . get_class($element)); } $pemCert = self::findCertificate($certFingerprint, $certificates); $pemKeys = array($pemCert); } else { throw new SimpleSAML_Error_Exception('Missing certificate in metadata for ' . var_export($srcMetadata->getString('entityid'), TRUE)); } SimpleSAML\Logger::debug('Has ' . count($pemKeys) . ' candidate keys for validation.'); $lastException = NULL; foreach ($pemKeys as $i => $pem) { $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public')); $key->loadKey($pem); try { /* * Make sure that we have a valid signature on either the response * or the assertion. */ $res = $element->validate($key); if ($res) { SimpleSAML\Logger::debug('Validation with key #' . $i . ' succeeded.'); return TRUE; } SimpleSAML\Logger::debug('Validation with key #' . $i . ' failed without exception.'); } catch (Exception $e) { SimpleSAML\Logger::debug('Validation with key #' . $i . ' failed with exception: ' . $e->getMessage()); $lastException = $e; } } /* We were unable to validate the signature with any of our keys. */ if ($lastException !== NULL) { throw $lastException; } else { return FALSE; } }