diff --git a/docs/source/simplesamlphp-sp.xml b/docs/source/simplesamlphp-sp.xml index ad536ca1e24fe93265872c50a21655c73775ef15..111abb1ac045a0820e44f9fc693ba7ddfb8d3185 100644 --- a/docs/source/simplesamlphp-sp.xml +++ b/docs/source/simplesamlphp-sp.xml @@ -436,6 +436,17 @@ Features</emphasis> document.</para> </glossdef> </glossentry> + + <glossentry> + <glossterm>certificate</glossterm> + + <glossdef> + <para>Name of certificate file in PEM format, in the + <filename>certs</filename> directory. Used for decrypting + assertions and as an alternative to certFingerprint for + validating signatures. </para> + </glossdef> + </glossentry> </glosslist> </section> diff --git a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php index 03ca344b2c38458d988aa34295df3aa72cdbe04a..d97ee857b844413aa861ac487dd2d5a5eebbe008 100644 --- a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php +++ b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php @@ -175,17 +175,26 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { $dom = $this->getDOM(); - /* Validate the signature. */ - $this->validator = new SimpleSAML_XML_Validator($dom, 'ID'); - /* Get the metadata of the issuer. */ $md = $this->metadata->getMetaData($this->issuer, 'saml20-idp-remote'); - /* Get fingerprint for the certificate of the issuer. */ - $issuerFingerprint = $md['certFingerprint']; - - /* Validate the fingerprint. */ - $this->validator->validateFingerprint($issuerFingerprint); + $publickey = FALSE; + if (isset($md['certificate'])) { + $publickey = file_get_contents($this->configuration->getPathValue('certdir') . $md['certificate']); + if (!$publickey) { + throw new Exception("Optional saml20-idp-remote metadata 'certificate' set, but no certificate found"); + } + } + /* Validate the signature. */ + $this->validator = new SimpleSAML_XML_Validator($dom, 'ID', $publickey); + + if (!$publickey) { + /* Get fingerprint for the certificate of the issuer. */ + $issuerFingerprint = $md['certFingerprint']; + + /* Validate the fingerprint. */ + $this->validator->validateFingerprint($issuerFingerprint); + } } diff --git a/lib/SimpleSAML/XML/Validator.php b/lib/SimpleSAML/XML/Validator.php index 277011b172a9b09b6a9c4b3bf11aec71c6ef6339..8551cf99f29e60168a42440a4a766a45658feee0 100644 --- a/lib/SimpleSAML/XML/Validator.php +++ b/lib/SimpleSAML/XML/Validator.php @@ -33,7 +33,7 @@ class SimpleSAML_XML_Validator { * @param $idAttribute The ID attribute which is used in node references. If this attribute is * NULL (the default), then we will use whatever is the default ID. */ - public function __construct($xmlDocument, $idAttribute = NULL) { + public function __construct($xmlDocument, $idAttribute = NULL, $publickey = FALSE) { assert('$xmlDocument instanceof DOMDocument'); $this->xmlDocument = $xmlDocument; @@ -69,10 +69,13 @@ class SimpleSAML_XML_Validator { } /* Load the key data. */ - if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) { - throw new Exception('Error finding key data for XML signature validation.'); + if ($publickey) { + $objKey->loadKey($publickey); + } else { + if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) { + throw new Exception('Error finding key data for XML signature validation.'); + } } - /* Check the signature. */ if (! $objXMLSecDSig->verify($objKey)) { throw new Exception("Unable to validate Signature");