diff options
author | Olav Morken <olav.morken@uninett.no> | 2011-10-27 09:14:11 +0000 |
---|---|---|
committer | Olav Morken <olav.morken@uninett.no> | 2011-10-27 09:14:11 +0000 |
commit | 3760cec4ea34daca6dbe96c0bf9806b45b791a0c (patch) | |
tree | d646ba5e97e0bc7e0d8794e4c675061162423788 /lib/SAML2 | |
parent | 14ce744179cda0f299afe43c17d9c9c2df374147 (diff) | |
download | simplesamlphp-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.php | 29 |
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. */ |