From 85e9ee57dfefcd5b726369aadfe2c5d675955e53 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Fri, 30 Mar 2012 11:12:48 +0000
Subject: [PATCH] Add support for validating signatures with the rsa-sha256
 algorithm.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@3064 44740490-163a-0410-bde0-09ae8108e29a
---
 lib/SAML2/Utils.php | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/lib/SAML2/Utils.php b/lib/SAML2/Utils.php
index ea5dd2cc8..99f899bfa 100644
--- a/lib/SAML2/Utils.php
+++ b/lib/SAML2/Utils.php
@@ -86,6 +86,30 @@ class SAML2_Utils {
 	}
 
 
+	/**
+	 * Helper function to convert a XMLSecurityKey to the correct algorithm.
+	 *
+	 * @param XMLSecurityKey $key  The key.
+	 * @param string $algorithm  The desired algorithm.
+	 * @return XMLSecurityKey  The new key.
+	 */
+	private static function castKey(XMLSecurityKey $key, $algorithm) {
+		assert('is_string($algorithm)');
+
+		$keyInfo = openssl_pkey_get_details($key->key);
+		if ($keyInfo === FALSE) {
+			throw new Exception('Unable to get key details from XMLSecurityKey.');
+		}
+		if (!isset($keyInfo['key'])) {
+			throw new Exception('Missing key in public key details.');
+		}
+
+		$newKey = new XMLSecurityKey($algorithm, array('type'=>'public'));
+		$newKey->loadKey($keyInfo['key']);
+		return $newKey;
+	}
+
+
 	/**
 	 * Check a signature against a key.
 	 *
@@ -99,6 +123,20 @@ class SAML2_Utils {
 
 		$objXMLSecDSig = $info['Signature'];
 
+		$sigMethod = self::xpQuery($objXMLSecDSig->sigNode, './ds:SignedInfo/ds:SignatureMethod');
+		if (empty($sigMethod)) {
+			throw new Exception('Missing SignatureMethod element.');
+		}
+		$sigMethod = $sigMethod[0];
+		if (!$sigMethod->hasAttribute('Algorithm')) {
+			throw new Exception('Missing Algorithm-attribute on SignatureMethod element.');
+		}
+		$algo = $sigMethod->getAttribute('Algorithm');
+
+		if ($key->type === XMLSecurityKey::RSA_SHA1 && $algo === XMLSecurityKey::RSA_SHA256) {
+			$key = self::castKey($key, XMLSecurityKey::RSA_SHA256);
+		}
+
 		/* Check the signature. */
 		if (! $objXMLSecDSig->verify($key)) {
 			throw new Exception("Unable to validate Signature");
-- 
GitLab