From ecbd07203286b878b720129632b9e745d64fd7e0 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Thu, 2 Aug 2012 06:21:11 +0000
Subject: [PATCH] SAML2_Utils: Fix for attack against PKCS#1 v1.5 described in
 a new paper.

See: http://www.nds.rub.de/research/publications/breaking-xml-encryption-pkcs15/

This fix avoids the problems described in that paper by taking two
measures:
- Require that decrypted contents is at least 4 bytes, since that is the
  shortest length of an XML element.
- Generate a (invalid) symmetric key that is deterministic for a given
  encrypted key and private key.

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

diff --git a/lib/SAML2/Utils.php b/lib/SAML2/Utils.php
index 99f899bfa..1eccf7596 100644
--- a/lib/SAML2/Utils.php
+++ b/lib/SAML2/Utils.php
@@ -398,9 +398,13 @@ class SAML2_Utils {
 				SimpleSAML_Logger::error('Failed to decrypt symmetric key: ' . $e->getMessage());
 				/* Create a replacement key, so that it looks like we fail in the same way as if the key was correctly padded. */
 
-				/* We base the symmetric key on the encrypted key, so that we always behave the same way for a given input key. */
+				/* We base the symmetric key on the encrypted key and private key, so that we always behave the
+				 * same way for a given input key.
+				 */
 				$encryptedKey = $encKey->getCipherValue();
-				$key = md5($encryptedKey, TRUE);
+				$pkey = openssl_pkey_get_details($symmetricKeyInfo->key);
+				$pkey = sha1(serialize($pkey), TRUE);
+				$key = sha1($encryptedKey . $pkey, TRUE);
 
 				/* Make sure that the key has the correct length. */
 				if (strlen($key) > $keySize) {
@@ -431,7 +435,7 @@ class SAML2_Utils {
 		 */
 		$xml = '<root xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'.$decrypted.'</root>';
 		$newDoc = new DOMDocument();
-		if (!$newDoc->loadXML($xml)) {
+		if (!@$newDoc->loadXML($xml)) {
 			throw new Exception('Failed to parse decrypted XML. Maybe the wrong sharedkey was used?');
 		}
 		$decryptedElement = $newDoc->firstChild->firstChild;
-- 
GitLab