From c4eae6ad858fd4fe7842d4f2a7335c4184812822 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaime=20Pe=CC=81rez=20Crespo?= <jaime.perez@uninett.no>
Date: Mon, 28 May 2018 09:48:55 +0200
Subject: [PATCH] bugfix: Encrypted attributes should also be automatically
 decrypted.

---
 modules/saml/lib/Message.php | 46 ++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index b80391fbc..c8fed116d 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -407,6 +407,51 @@ class sspmod_saml_Message
     }
 
 
+    /**
+     * Decrypt any encrypted attributes in an assertion.
+     *
+     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP).
+     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP).
+     * @param \SAML2\Assertion|\SAML2\Assertion $assertion The assertion containing any possibly encrypted attributes.
+     *
+     * @return void
+     *
+     * @throws \SimpleSAML_Error_Exception if we cannot get the decryption keys or decryption fails.
+     */
+    private static function decryptAttributes(
+        SimpleSAML_Configuration $srcMetadata,
+        SimpleSAML_Configuration $dstMetadata,
+        \SAML2\Assertion &$assertion
+    ) {
+        if (!$assertion->hasEncryptedAttributes()) {
+            return;
+        }
+
+        try {
+            $keys = self::getDecryptionKeys($srcMetadata, $dstMetadata);
+        } catch (Exception $e) {
+            throw new SimpleSAML_Error_Exception('Error decrypting attributes: '.$e->getMessage());
+        }
+
+        $blacklist = self::getBlacklistedAlgorithms($srcMetadata, $dstMetadata);
+
+        $error = true;
+        foreach ($keys as $i => $key) {
+            try {
+                $assertion->decryptAttributes($key, $blacklist);
+                SimpleSAML\Logger::debug('Attribute decryption with key #'.$i.' succeeded.');
+                $error = false;
+                break;
+            } catch (Exception $e) {
+                SimpleSAML\Logger::debug('Attribute decryption failed with exception: '.$e->getMessage());
+            }
+        }
+        if ($error) {
+            throw new SimpleSAML_Error_Exception('Could not decrypt the attributes');
+        }
+    }
+
+
     /**
      * Retrieve the status code of a response as a sspmod_saml_Error.
      *
@@ -609,6 +654,7 @@ class sspmod_saml_Message
         assert(is_bool($responseSigned));
 
         $assertion = self::decryptAssertion($idpMetadata, $spMetadata, $assertion);
+        self::decryptAttributes($idpMetadata, $spMetadata, $assertion);
 
         if (!self::checkSign($idpMetadata, $assertion)) {
             if (!$responseSigned) {
-- 
GitLab