diff --git a/config/config-template.php b/config/config-template.php
index dfb80660c36b609587a9ec0336b4daa2f595d9a3..ebdd972583a68ee982d12a78b217e30bfe83b03d 100644
--- a/config/config-template.php
+++ b/config/config-template.php
@@ -283,6 +283,15 @@ $config = array (
 	 */
 	'auth.auto.delay_login' => 0,
 
+
+	/*
+	 * This option enables signing of all messages sent with the
+	 * HTTP-Redirect binding. The default value is false. To enable, set
+	 * this option to true, and add a 'privatekey' element to the entity
+	 * (IdP or SP) which is sending the message.
+	 */
+	'binding.httpredirect.sign' => true,
+
 );
 
 
diff --git a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
index 6d777b639150eba3cb45a7b46dc760a916f78f48..d50144c4fa4c6bab7f4564f5b14fdb859883b15f 100644
--- a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
+++ b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
@@ -29,8 +29,76 @@ class SimpleSAML_Bindings_SAML20_HTTPRedirect {
 		$this->configuration = $configuration;
 		$this->metadata = $metadatastore;
 	}
-	
-	public function getRedirectURL($request, $remoteentityid, $relayState = null, $endpoint = 'SingleSignOnService', $direction = 'SAMLRequest', $mode = 'SP') {
+
+
+	public function signQuery($query, $md) {
+
+		/* Check if signing of HTTP-Redirect messages is enabled. */
+		if($this->configuration->getValue('binding.httpredirect.sign', false) !== true) {
+			return $query;
+		}
+
+		/* Don't attempt to sign the query if no private key is set in the metadata.  */
+		if(!array_key_exists('privatekey', $md) || $md['privatekey'] === NULL) {
+			return $query;
+		}
+
+
+		/* Load the private key. */
+
+		$privatekey = $this->configuration->getBaseDir() . 'cert/' . $md['privatekey'];
+		if (!file_exists($privatekey)) {
+			throw new Exception('Could not find private key file [' . $privatekey . '] which is needed to sign the request.');
+		}
+
+		$keydata = file_get_contents($privatekey);
+		if($keydata === FALSE) {
+			throw new Exception('Unable to load private key file: ' . $privatekey);
+		}
+
+		$keyid = openssl_pkey_get_private($keydata);
+		if($keyid === FALSE) {
+			throw new Exception('OpenSSL was unable to parse the private key from the following file: ' . $privatekey);
+		}
+
+		/* Make sure that the loaded key is a RSA key. */
+		$keydetails = openssl_pkey_get_details($keyid);
+		if($keydetails === FALSE) {
+			throw new Exception('Unable to get key details of already loaded key.');
+		}
+		if($keydetails['type'] !== OPENSSL_KEYTYPE_RSA) {
+			throw new Exception('Private key used to sign the query string isn\'t a RSA key. Key was loaded from the following file: ' . $privatekey);
+		}
+
+
+		/* Sign the query string. According to the specification, the string which should be
+		 * signed is the concatenation of the following query parameters (in order):
+		 * - SAMLRequest/SAMLResponse
+		 * - RelayState (if present)
+		 * - SigAlg
+		 *
+		 * We assume that the query string now contains only the two first parameters.
+		 */
+
+		/* Append the signature algorithm. We always use RSA-SHA1. */
+		$algURI = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
+		$query = $query . "&" . "SigAlg=" . urlencode($algURI);
+
+		/* Sign the query string. The default hash algorithm of openssl_sign is (fortunately) SHA1. */
+		if(!openssl_sign($query, $signature, $keyid)) {
+			throw new Exception('OpenSSL was unable to sign the query string.');
+		}
+
+		/* Free the key we used. */
+		openssl_pkey_free($keyid);
+
+		/* Return the signed query string. */
+		$query = $query . "&" . "Signature=" . urlencode(base64_encode($signature));
+		return $query;
+	}
+
+
+	public function getRedirectURL($request, $localentityid, $remoteentityid, $relayState = null, $endpoint = 'SingleSignOnService', $direction = 'SAMLRequest', $mode = 'SP') {
 	
 		if (!in_array($mode, array('SP', 'IdP'))) {
 			throw new Exception('mode parameter of sendMessage() must be either SP or IdP');
@@ -51,21 +119,28 @@ class SimpleSAML_Bindings_SAML20_HTTPRedirect {
 		if (!isset($idpTargetUrl) or $idpTargetUrl == '') {
 			throw new Exception('Could not find endpoint [' .$endpoint  . '] in metadata for [' . $remoteentityid . '] (looking in ' . $metadataset . ')');
 		}
-	
-		$encodedRequest = urlencode( base64_encode( gzdeflate( $request ) ));
-		
-		$redirectURL = $idpTargetUrl . "?" . $direction . "=" . $encodedRequest;
+
+		$request = urlencode( base64_encode( gzdeflate( $request ) ));
+		$request = $direction . "=" . $request;
 		if (isset($relayState)) {
-			$redirectURL .= "&RelayState=" . urlencode($relayState);
+			$request .= "&RelayState=" . urlencode($relayState);
 		}
+
+		$metadataset = 'saml20-sp-hosted';
+		if ($mode == 'IdP') {
+			$metadataset = 'saml20-idp-hosted';
+		}
+		$localmd = $this->metadata->getMetaData($localentityid, $metadataset);
+		$request = $this->signQuery($request, $localmd);
+		$redirectURL = $idpTargetUrl . "?" . $request;
+
 		return $redirectURL;
 	
 	}
 	
-	
-	public function sendMessage($request, $remoteentityid, $relayState = null, $endpoint = 'SingleSignOnService', $direction = 'SAMLRequest', $mode = 'SP') {
+	public function sendMessage($request, $localentityid, $remoteentityid, $relayState = null, $endpoint = 'SingleSignOnService', $direction = 'SAMLRequest', $mode = 'SP') {
 		
-		$redirectURL = $this->getRedirectURL($request, $remoteentityid, $relayState, $endpoint, $direction, $mode);
+		$redirectURL = $this->getRedirectURL($request, $localentityid, $remoteentityid, $relayState, $endpoint, $direction, $mode);
 		
 		if ($this->configuration->getValue('debug')) {
 	
diff --git a/lib/SimpleSAML/XML/SAML20/AuthnRequest.php b/lib/SimpleSAML/XML/SAML20/AuthnRequest.php
index b804e00713fa8aaa80f6e030ab26fc19e6763e7f..cba1a2e20a05ffe67b232a8e6ef0c57355f601b9 100644
--- a/lib/SimpleSAML/XML/SAML20/AuthnRequest.php
+++ b/lib/SimpleSAML/XML/SAML20/AuthnRequest.php
@@ -132,7 +132,7 @@ class SimpleSAML_XML_SAML20_AuthnRequest {
 	}
 	
 
-	public function generate($spentityid) {
+	public function generate($spentityid, $destination) {
 		$md = $this->metadata->getMetaData($spentityid);
 		
 		$id = self::generateID();
@@ -154,6 +154,7 @@ class SimpleSAML_XML_SAML20_AuthnRequest {
 		  "IssueInstant=\"" . $issueInstant . "\" " .
 		  "ForceAuthn=\"false\" " .
 		  "IsPassive=\"false\" " .
+		  "Destination=\"" . $destination . "\" " .
 		  "ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" " .
 		  "AssertionConsumerServiceURL=\"" . $assertionConsumerServiceURL . "\">\n" .
 			"<saml:Issuer " .
diff --git a/lib/SimpleSAML/XML/SAML20/LogoutRequest.php b/lib/SimpleSAML/XML/SAML20/LogoutRequest.php
index a4bbd294a872ca14b4b4e8ac6cc041f2c178f9e9..137ff0c985be3e527b7d2b6aa9576be5d7d00043 100644
--- a/lib/SimpleSAML/XML/SAML20/LogoutRequest.php
+++ b/lib/SimpleSAML/XML/SAML20/LogoutRequest.php
@@ -141,6 +141,7 @@ class SimpleSAML_XML_SAML20_LogoutRequest {
       "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" " . 
       "ID=\"" . $id . "\" " .
       "Version=\"2.0\" " .
+      "Destination=\"" . $destination . "\" " .
       "IssueInstant=\"" . $issueInstant . "\"> " .
         "<saml:Issuer " . 
         "xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">" .
diff --git a/metadata-templates/saml20-sp-hosted.php b/metadata-templates/saml20-sp-hosted.php
index 01517f0794103d1cfec8eea1268a5e44e5261826..cf429df10fda445d2874902ddaa7fab331f0b149 100644
--- a/metadata-templates/saml20-sp-hosted.php
+++ b/metadata-templates/saml20-sp-hosted.php
@@ -15,7 +15,22 @@ $metadata = array(
 		'host'							=>	'sp.example.org',
 		'spNameQualifier' 				=>	'sp.example.org',
 		'NameIDFormat'					=>	'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
-		'ForceAuthn'					=>	'false'
+		'ForceAuthn'					=>	'false',
+
+		/*
+		 * This option configures the name of a file which contains a
+		 * RSA key for this service provider. The file must be located
+		 * in the cert-directory of the SimpleSAMLPHP installation.
+		 *
+		 * This key will be used to sign all outgoing authentication-
+		 * requests, logoutrequests and logoutresponses (everything
+		 * that uses the HTTP-Redirect binding).
+		 *
+		 * To enable signing, set this option to a private key file
+		 * and enable the 'binding.httpredirect.sign' global option.
+		 */
+		'privatekey' => 'server.pem',
+
 	)
 
 );
diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php
index 3b12d99637d8bd82f73c88572e8413be9afaee1b..2fa3b21c03e9db84f9757d7107b4c0f946a90382 100644
--- a/www/saml2/idp/SingleLogoutService.php
+++ b/www/saml2/idp/SingleLogoutService.php
@@ -52,7 +52,7 @@ if (isset($_GET['SAMLRequest'])) {
 		/* Send the response using the HTTP-Redirect binding. */
 		$binding = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config,
 			$metadata);
-		$binding->sendMessage($responseText, $spentityid, $relayState,
+		$binding->sendMessage($responseText, $idpentityid, $spentityid, $relayState,
 			'SingleLogoutService', 'SAMLResponse', 'IdP');
 		exit;
 	}
@@ -114,7 +114,7 @@ if ($spentityid) {
 		}
 		
 		//$request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
-		$httpredirect->sendMessage($req, $spentityid, $relayState, 'SingleLogoutService', 'SAMLRequest', 'IdP');
+		$httpredirect->sendMessage($req, $idpentityid, $spentityid, $relayState, 'SingleLogoutService', 'SAMLRequest', 'IdP');
 		
 		exit();
 
@@ -165,7 +165,7 @@ try {
 	}
 	
 	//$request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
-	$httpredirect->sendMessage($logoutResponseXML, $logoutrequest->getIssuer(), $relayState, 'SingleLogoutService', 'SAMLResponse', 'IdP');
+	$httpredirect->sendMessage($logoutResponseXML, $idpentityid, $logoutrequest->getIssuer(), $relayState, 'SingleLogoutService', 'SAMLResponse', 'IdP');
 
 } catch(Exception $exception) {
 	
diff --git a/www/saml2/sp/SingleLogoutService.php b/www/saml2/sp/SingleLogoutService.php
index 671733d422f1339c87060d56c5942bdad7c55753..53cf3c1f1a44314174dd756c4db2a91978ebc8b6 100644
--- a/www/saml2/sp/SingleLogoutService.php
+++ b/www/saml2/sp/SingleLogoutService.php
@@ -77,7 +77,7 @@ if (isset($_GET['SAMLRequest'])) {
 		'SP me (' . $responder . ') is sending logout response to IdP (' . $requester . ')');
 	
 	// Send the Logout response using HTTP POST binding.
-	$httpredirect->sendMessage($logoutResponseXML, $requester, $logoutrequest->getRelayState(), 'SingleLogoutServiceResponse', 'SAMLResponse');
+	$httpredirect->sendMessage($logoutResponseXML, $responser, $requester, $logoutrequest->getRelayState(), 'SingleLogoutServiceResponse', 'SAMLResponse');
 
 } elseif(isset($_GET['SAMLResponse'])) {
 	
diff --git a/www/saml2/sp/initSLO.php b/www/saml2/sp/initSLO.php
index 193f352551fe2bddf4df36c3645f874be6d679d5..7ded295484608de03857248f0343547547c99be5 100644
--- a/www/saml2/sp/initSLO.php
+++ b/www/saml2/sp/initSLO.php
@@ -46,7 +46,7 @@ if (isset($session) ) {
 			'SP (' . $spentityid . ') is sending logout request to IdP (' . $idpentityid . ')');
 		
 		//$request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
-		$httpredirect->sendMessage($req, $idpentityid, $relayState, 'SingleLogoutService', 'SAMLRequest', 'SP');
+		$httpredirect->sendMessage($req, $spentityid, $idpentityid, $relayState, 'SingleLogoutService', 'SAMLRequest', 'SP');
 		
 
 	} catch(Exception $exception) {
diff --git a/www/saml2/sp/initSSO.php b/www/saml2/sp/initSSO.php
index c78a49b87838ecac11a62c212f703959939744fa..5a8ff34b4d12e16223439259973f96942a6be092 100644
--- a/www/saml2/sp/initSSO.php
+++ b/www/saml2/sp/initSSO.php
@@ -64,7 +64,9 @@ if (!isset($session) || !$session->isValid() ) {
 	try {
 		$sr = new SimpleSAML_XML_SAML20_AuthnRequest($config, $metadata);
 	
-		$req = $sr->generate($spentityid);
+		$md = $metadata->getMetaData($idpentityid, 'saml20-idp-remote');
+		$req = $sr->generate($spentityid, $md['SingleSignOnService']);
+
 		
 		$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
 		
@@ -76,7 +78,7 @@ if (!isset($session) || !$session->isValid() ) {
 		$logger->log(LOG_NOTICE, $session->getTrackID(), 'SAML2.0', 'SP.initSSO', 'AuthnRequest', $idpentityid, 
 			'SP (' . $spentityid . ') is sending authenticatino request to IdP (' . $idpentityid . ')');
 		
-		$httpredirect->sendMessage($req, $idpentityid, $relayState);
+		$httpredirect->sendMessage($req, $spentityid, $idpentityid, $relayState);
 
 	
 	} catch(Exception $exception) {