summaryrefslogtreecommitdiffstats
path: root/lib/SAML2
diff options
context:
space:
mode:
authorOlav Morken <olav.morken@uninett.no>2011-10-27 09:14:11 +0000
committerOlav Morken <olav.morken@uninett.no>2011-10-27 09:14:11 +0000
commit3760cec4ea34daca6dbe96c0bf9806b45b791a0c (patch)
treed646ba5e97e0bc7e0d8794e4c675061162423788 /lib/SAML2
parent14ce744179cda0f299afe43c17d9c9c2df374147 (diff)
downloadsimplesamlphp-3760cec4ea34daca6dbe96c0bf9806b45b791a0c.zip
simplesamlphp-3760cec4ea34daca6dbe96c0bf9806b45b791a0c.tar.gz
simplesamlphp-3760cec4ea34daca6dbe96c0bf9806b45b791a0c.tar.bz2
SAML2_Utils: Add protection against key oracle attacks when decrypting data.
git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2953 44740490-163a-0410-bde0-09ae8108e29a
Diffstat (limited to 'lib/SAML2')
-rw-r--r--lib/SAML2/Utils.php29
1 files changed, 28 insertions, 1 deletions
diff --git a/lib/SAML2/Utils.php b/lib/SAML2/Utils.php
index 8884114..d952434 100644
--- a/lib/SAML2/Utils.php
+++ b/lib/SAML2/Utils.php
@@ -344,8 +344,35 @@ class SAML2_Utils {
$encKey = $symmetricKeyInfo->encryptedCtx;
$symmetricKeyInfo->key = $inputKey->key;
- $key = $encKey->decryptKey($symmetricKeyInfo);
+
+ $keySize = $symmetricKey->getSymmetricKeySize();
+ if ($keySize === NULL) {
+ /* To protect against "key oracle" attacks, we need to be able to create a
+ * symmetric key, and for that we need to know the key size.
+ */
+ throw new Exception('Unknown key size for encryption algorithm: ' . var_export($symmetricKey->type, TRUE));
+ }
+
+ try {
+ $key = $encKey->decryptKey($symmetricKeyInfo);
+ } catch (Exception $e) {
+ /* We failed to decrypt this key. Log it, and substitute a "random" key. */
+ 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. */
+ $encryptedKey = $encKey->getCipherValue();
+ $key = md5($encryptedKey, TRUE);
+
+ /* Make sure that the key has the correct length. */
+ if (strlen($key) > $keySize) {
+ $key = substr($key, 0, $keySize);
+ } elseif (strlen($key) < $keySize) {
+ $key = str_pad($key, $keySize);
+ }
+ }
$symmetricKey->loadkey($key);
+
} else {
$symKeyAlgo = $symmetricKey->getAlgorith();
/* Make sure that the input key has the correct format. */