diff --git a/config-templates/config.php b/config-templates/config.php index 8546299ec051b0013020fa5fc6b627c62ecf58a9..cd7276d184fb4ed39ea31e4f122e7f39d99507f3 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -212,6 +212,8 @@ $config = array ( * same name to the metadata of the SP. */ 'saml20.signresponse' => FALSE, + 'shib13.signresponse' => TRUE, + /* * Configuration of Consent storage used for attribute consent. diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php index 2026e658b8cfa2ad602b74fc2d1f0cb446b7d51b..e6073b6b66b88d8236d1196223a2555c4ac5ea4e 100644 --- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php +++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php @@ -112,13 +112,47 @@ class SimpleSAML_Bindings_Shib13_HTTPPost { $responsedom->loadXML(str_replace ("\r", "", $response)); $responseroot = $responsedom->getElementsByTagName('Response')->item(0); + + $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); + + + + /* Determine what we should sign - either the Response element or the Assertion. The default + * is to sign the Assertion, but that can be overridden by the 'signresponse' option in the + * SP metadata or 'saml20.signresponse' in the global configuration. + */ + $signResponse = FALSE; + if(array_key_exists('signresponse', $spmd) && $spmd['signresponse'] !== NULL) { + $signResponse = $spmd['signresponse']; + if(!is_bool($signResponse)) { + throw new Exception('Expected the \'signresponse\' option in the metadata of the' . + ' SP \'' . $spmd['entityid'] . '\' to be a boolean value.'); + } + } else { + $signResponse = $this->configuration->getBoolean('shib13.signresponse', TRUE); + } + + /* Check if we have an assertion to sign. Force to sign the response if not. */ + if($firstassertionroot === NULL) { + $signResponse = TRUE; + } + + + + if(!$signResponse) { + $signer->sign($firstassertionroot, $firstassertionroot); + } + + if($signResponse) { + /* Sign the response - this must be done after encrypting the assertion. */ - /* We insert the signature before the saml1p:Status element. */ - $statusElements = SimpleSAML_Utilities::getDOMChildren($responseroot, 'Status', '@saml1p'); - assert('count($statusElements) === 1'); - - $signer->sign($responseroot, $responseroot, $statusElements[0]); + /* We insert the signature before the saml2p:Status element. */ + $statusElements = SimpleSAML_Utilities::getDOMChildren($responseroot, 'Status', '@saml1p'); + assert('count($statusElements) === 1'); + $signer->sign($responseroot, $responseroot, $statusElements[0]); + } + $response = $responsedom->saveXML();