diff --git a/lib/SAML2/HTTPRedirect.php b/lib/SAML2/HTTPRedirect.php index 6b001de18455c56caafb54e2d67141a73d46094a..6033389a070c29071a7fa690dead967af3fc78af 100644 --- a/lib/SAML2/HTTPRedirect.php +++ b/lib/SAML2/HTTPRedirect.php @@ -51,7 +51,7 @@ class SAML2_HTTPRedirect extends SAML2_Binding { if ($key !== NULL) { /* Add the signature. */ - $msg .= '&SigAlg=' . urlencode(XMLSecurityKey::RSA_SHA1); + $msg .= '&SigAlg=' . urlencode($key->type); $signature = $key->signData($msg); $msg .= '&Signature=' . urlencode(base64_encode($signature)); @@ -216,17 +216,15 @@ class SAML2_HTTPRedirect extends SAML2_Binding { $signature = base64_decode($signature); - switch ($sigAlg) { - case XMLSecurityKey::RSA_SHA1: - if ($key->type !== XMLSecurityKey::RSA_SHA1) { - throw new Exception('Invalid key type for validating signature on query string.'); - } - if (!$key->verifySignature($query,$signature)) { - throw new Exception('Unable to validate signature on query string.'); - } - break; - default: - throw new Exception('Unknown signature algorithm: ' . var_export($sigAlg, TRUE)); + if ($key->type !== XMLSecurityKey::RSA_SHA1) { + throw new Exception('Invalid key type for validating signature on query string.'); + } + if ($key->type !== $sigAlg) { + $key = SAML2_Utils::castKey($key, $sigAlg); + } + + if (!$key->verifySignature($query,$signature)) { + throw new Exception('Unable to validate signature on query string.'); } } diff --git a/lib/SAML2/Utils.php b/lib/SAML2/Utils.php index 79576a2b6b998ad756ad3e454d10303e541cf6c4..5120639cc9a57159ef1de7d65daa5af823691b12 100644 --- a/lib/SAML2/Utils.php +++ b/lib/SAML2/Utils.php @@ -91,10 +91,17 @@ class SAML2_Utils { * * @param XMLSecurityKey $key The key. * @param string $algorithm The desired algorithm. + * @param string $types Public or private key, defaults to public. * @return XMLSecurityKey The new key. */ - private static function castKey(XMLSecurityKey $key, $algorithm) { + public static function castKey(XMLSecurityKey $key, $algorithm, $type = 'public') { assert('is_string($algorithm)'); + assert('$type === "public" || $type === "private"'); + + // do nothing if algorithm is already the type of the key + if ($key->type === $algorithm) { + return $key; + } $keyInfo = openssl_pkey_get_details($key->key); if ($keyInfo === FALSE) { @@ -104,7 +111,7 @@ class SAML2_Utils { throw new Exception('Missing key in public key details.'); } - $newKey = new XMLSecurityKey($algorithm, array('type'=>'public')); + $newKey = new XMLSecurityKey($algorithm, array('type'=>$type)); $newKey->loadKey($keyInfo['key']); return $newKey; } @@ -133,18 +140,8 @@ class SAML2_Utils { } $algo = $sigMethod->getAttribute('Algorithm'); - if ($key->type === XMLSecurityKey::RSA_SHA1) { - switch ($algo) { - case XMLSecurityKey::RSA_SHA256: - $key = self::castKey($key, XMLSecurityKey::RSA_SHA256); - break; - case XMLSecurityKey::RSA_SHA384: - $key = self::castKey($key, XMLSecurityKey::RSA_SHA384); - break; - case XMLSecurityKey::RSA_SHA512: - $key = self::castKey($key, XMLSecurityKey::RSA_SHA512); - break; - } + if ($key->type === XMLSecurityKey::RSA_SHA1 && $algo !== $key->type) { + $key = self::castKey($key, $algo); } /* Check the signature. */ diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php index 6e90d65ce5ccf11761b3e37aee72869c1f39cb20..64c06da132b4848b3a3e29b4db2d0cae673ebeef 100644 --- a/modules/saml/lib/Message.php +++ b/modules/saml/lib/Message.php @@ -21,7 +21,11 @@ class sspmod_saml_Message { $keyArray = SimpleSAML_Utilities::loadPrivateKey($srcMetadata, TRUE); $certArray = SimpleSAML_Utilities::loadPublicKey($srcMetadata, FALSE); - $algo = $srcMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA1); + + $algo = $dstMetadata->getString('signature.algorithm', NULL); + if ($algo === NULL) { + $algo = $srcMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA1); + } $privateKey = new XMLSecurityKey($algo, array('type' => 'private')); if (array_key_exists('password', $keyArray)) {