diff --git a/docs/simplesamlphp-changelog.txt b/docs/simplesamlphp-changelog.txt
index ac6b2fe40b03ffac223784874d42e7a798e3cac5..12919f9fc8dcd17330b84fadaad29d59dd0713e0 100644
--- a/docs/simplesamlphp-changelog.txt
+++ b/docs/simplesamlphp-changelog.txt
@@ -15,11 +15,16 @@ Released TBD.
   * Clean up executable-permissions on files.
   * Change encryption to use the rsa-oaep-mgf1p key padding instead of PKCS 1.5.
   * Update translations.
+  * Add support for RSA-SHA256, RSA-SHA384 and RSA-SHA512 signature algorithms.
 
 ### `core`
 
   * `core:UserPass(Org)Base`: Add "remember username" option.
 
+### `papi`
+
+  * New authentication module supporting PAPI protocol.
+
 ### `radius`
 
   * New feature to configure multiple radius servers.
diff --git a/lib/SAML2/Utils.php b/lib/SAML2/Utils.php
index 00e5a33905d839dde73a8218eeb3ae94736c04df..79576a2b6b998ad756ad3e454d10303e541cf6c4 100644
--- a/lib/SAML2/Utils.php
+++ b/lib/SAML2/Utils.php
@@ -133,8 +133,18 @@ class SAML2_Utils {
 		}
 		$algo = $sigMethod->getAttribute('Algorithm');
 
-		if ($key->type === XMLSecurityKey::RSA_SHA1 && $algo === XMLSecurityKey::RSA_SHA256) {
-			$key = self::castKey($key, XMLSecurityKey::RSA_SHA256);
+		if ($key->type === XMLSecurityKey::RSA_SHA1) {
+			switch ($algo) {
+				case XMLSecurityKey::RSA_SHA256:
+					$key = self::castKey($key, XMLSecurityKey::RSA_SHA256);
+					break;
+				case XMLSecurityKey::RSA_SHA384:
+					$key = self::castKey($key, XMLSecurityKey::RSA_SHA384);
+					break;
+				case XMLSecurityKey::RSA_SHA512:
+					$key = self::castKey($key, XMLSecurityKey::RSA_SHA512);
+					break;
+			}
 		}
 
 		/* Check the signature. */
@@ -314,9 +324,23 @@ class SAML2_Utils {
 		$objXMLSecDSig = new XMLSecurityDSig();
 		$objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
 
+		switch ($key->type) {
+			case XMLSecurityKey::RSA_SHA256:
+				$type = XMLSecurityDSig::SHA256;
+				break;
+			case XMLSecurityKey::RSA_SHA384:
+				$type = XMLSecurityDSig::SHA384;
+				break;
+			case XMLSecurityKey::RSA_SHA512:
+				$type = XMLSecurityDSig::SHA512;
+				break;
+			default:
+				$type = XMLSecurityDSig::SHA1;
+		}
+
 		$objXMLSecDSig->addReferenceList(
 			array($root),
-			XMLSecurityDSig::SHA1,
+			$type,
 			array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
 			array('id_name' => 'ID', 'overwrite' => FALSE)
 			);
diff --git a/lib/xmlseclibs.php b/lib/xmlseclibs.php
index fc328d4a03987daea4ffedcd51fb84645b98284d..75de0b64f0a1eb641001f2488380f208a9146bbc 100644
--- a/lib/xmlseclibs.php
+++ b/lib/xmlseclibs.php
@@ -180,6 +180,8 @@ class XMLSecurityKey {
     const DSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1';
     const RSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
     const RSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
+    const RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384';
+    const RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512';
 
     private $cryptParams = array();
     public $type = 0;
@@ -282,6 +284,28 @@ class XMLSecurityKey {
                 }
                 throw new Exception('Certificate "type" (private/public) must be passed via parameters');
                 break;
+            case (XMLSecurityKey::RSA_SHA384):
+                $this->cryptParams['library'] = 'openssl';
+                $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384';
+                $this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
+                $this->cryptParams['digest'] = 'SHA384';
+                if (is_array($params) && ! empty($params['type'])) {
+                    if ($params['type'] == 'public' || $params['type'] == 'private') {
+                        $this->cryptParams['type'] = $params['type'];
+                        break;
+                    }
+                }
+            case (XMLSecurityKey::RSA_SHA512):
+                $this->cryptParams['library'] = 'openssl';
+                $this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512';
+                $this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
+                $this->cryptParams['digest'] = 'SHA512';
+                if (is_array($params) && ! empty($params['type'])) {
+                    if ($params['type'] == 'public' || $params['type'] == 'private') {
+                        $this->cryptParams['type'] = $params['type'];
+                        break;
+                    }
+                }
             default:
                 throw new Exception('Invalid Key Type');
                 return;
@@ -632,6 +656,7 @@ class XMLSecurityDSig {
     const XMLDSIGNS = 'http://www.w3.org/2000/09/xmldsig#';
     const SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1';
     const SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256';
+    const SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#sha384';
     const SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512';
     const RIPEMD160 = 'http://www.w3.org/2001/04/xmlenc#ripemd160';
 
@@ -799,6 +824,9 @@ class XMLSecurityDSig {
             case XMLSecurityDSig::SHA256:
                 $alg = 'sha256';
                 break;
+            case XMLSecurityDSig::SHA384:
+                $alg = 'sha384';
+                break;
             case XMLSecurityDSig::SHA512:
                 $alg = 'sha512';
                 break;
diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index 02eca94cc62ce328e0976a9ac38078b686d5155d..bbe6bea3258d57d3feccab144e73bd37b38b7805 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -21,8 +21,9 @@ class sspmod_saml_Message {
 
 		$keyArray = SimpleSAML_Utilities::loadPrivateKey($srcMetadata, TRUE);
 		$certArray = SimpleSAML_Utilities::loadPublicKey($srcMetadata, FALSE);
+		$ = $srcMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA1);
 
-		$privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
+		$privateKey = new XMLSecurityKey($algo, array('type' => 'private'));
 		if (array_key_exists('password', $keyArray)) {
 			$privateKey->passphrase = $keyArray['password'];
 		}