| Conditions | 18 |
| Paths | 98 |
| Total Lines | 147 |
| Code Lines | 69 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 139 | private static function doDecryptElement( |
||
| 140 | DOMElement $encryptedData, |
||
| 141 | XMLSecurityKey $inputKey, |
||
| 142 | array &$blacklist |
||
| 143 | ): DOMElement { |
||
| 144 | $enc = new XMLSecEnc(); |
||
| 145 | |||
| 146 | $enc->setNode($encryptedData); |
||
| 147 | $enc->type = $encryptedData->getAttribute("Type"); |
||
| 148 | |||
| 149 | $symmetricKey = $enc->locateKey($encryptedData); |
||
| 150 | if (!$symmetricKey) { |
||
| 151 | throw new Exception('Could not locate key algorithm in encrypted data.'); |
||
| 152 | } |
||
| 153 | |||
| 154 | $symmetricKeyInfo = $enc->locateKeyInfo($symmetricKey); |
||
| 155 | if (!$symmetricKeyInfo) { |
||
| 156 | throw new Exception('Could not locate <dsig:KeyInfo> for the encrypted key.'); |
||
| 157 | } |
||
| 158 | |||
| 159 | $inputKeyAlgo = $inputKey->getAlgorithm(); |
||
| 160 | if ($symmetricKeyInfo->isEncrypted) { |
||
| 161 | $symKeyInfoAlgo = $symmetricKeyInfo->getAlgorithm(); |
||
| 162 | |||
| 163 | if (in_array($symKeyInfoAlgo, $blacklist, true)) { |
||
| 164 | throw new Exception('Algorithm disabled: ' . var_export($symKeyInfoAlgo, true)); |
||
| 165 | } |
||
| 166 | |||
| 167 | if ($symKeyInfoAlgo === XMLSecurityKey::RSA_OAEP_MGF1P && $inputKeyAlgo === XMLSecurityKey::RSA_1_5) { |
||
| 168 | /* |
||
| 169 | * The RSA key formats are equal, so loading an RSA_1_5 key |
||
| 170 | * into an RSA_OAEP_MGF1P key can be done without problems. |
||
| 171 | * We therefore pretend that the input key is an |
||
| 172 | * RSA_OAEP_MGF1P key. |
||
| 173 | */ |
||
| 174 | $inputKeyAlgo = XMLSecurityKey::RSA_OAEP_MGF1P; |
||
| 175 | } |
||
| 176 | |||
| 177 | /* Make sure that the input key format is the same as the one used to encrypt the key. */ |
||
| 178 | if ($inputKeyAlgo !== $symKeyInfoAlgo) { |
||
| 179 | throw new Exception( |
||
| 180 | 'Algorithm mismatch between input key and key used to encrypt ' . |
||
| 181 | ' the symmetric key for the message. Key was: ' . |
||
| 182 | var_export($inputKeyAlgo, true) . '; message was: ' . |
||
| 183 | var_export($symKeyInfoAlgo, true) |
||
| 184 | ); |
||
| 185 | } |
||
| 186 | |||
| 187 | /** @var XMLSecEnc $encKey */ |
||
| 188 | $encKey = $symmetricKeyInfo->encryptedCtx; |
||
| 189 | $symmetricKeyInfo->key = $inputKey->key; |
||
| 190 | |||
| 191 | $keySize = $symmetricKey->getSymmetricKeySize(); |
||
| 192 | if ($keySize === null) { |
||
| 193 | /* To protect against "key oracle" attacks, we need to be able to create a |
||
| 194 | * symmetric key, and for that we need to know the key size. |
||
| 195 | */ |
||
| 196 | throw new Exception( |
||
| 197 | 'Unknown key size for encryption algorithm: ' . var_export($symmetricKey->type, true) |
||
| 198 | ); |
||
| 199 | } |
||
| 200 | |||
| 201 | try { |
||
| 202 | /** |
||
| 203 | * @var string $key |
||
| 204 | * @psalm-suppress UndefinedClass |
||
| 205 | */ |
||
| 206 | $key = $encKey->decryptKey($symmetricKeyInfo); |
||
| 207 | if (strlen($key) !== $keySize) { |
||
| 208 | throw new Exception( |
||
| 209 | 'Unexpected key size (' . strval(strlen($key) * 8) . 'bits) for encryption algorithm: ' . |
||
| 210 | var_export($symmetricKey->type, true) |
||
| 211 | ); |
||
| 212 | } |
||
| 213 | } catch (Exception $e) { |
||
| 214 | /* We failed to decrypt this key. Log it, and substitute a "random" key. */ |
||
| 215 | // Utils::getContainer()->getLogger()->error('Failed to decrypt symmetric key: ' . $e->getMessage()); |
||
| 216 | /* Create a replacement key, so that it looks like we fail in the same way as if the key was correctly |
||
| 217 | * padded. */ |
||
| 218 | |||
| 219 | /* We base the symmetric key on the encrypted key and private key, so that we always behave the |
||
| 220 | * same way for a given input key. |
||
| 221 | */ |
||
| 222 | $encryptedKey = $encKey->getCipherValue(); |
||
| 223 | if ($encryptedKey === null) { |
||
| 224 | throw new Exception('No CipherValue available in the encrypted element.'); |
||
| 225 | } |
||
| 226 | |||
| 227 | /** @psalm-suppress PossiblyNullArgument */ |
||
| 228 | $pkey = openssl_pkey_get_details($symmetricKeyInfo->key); |
||
| 229 | $pkey = sha1(serialize($pkey), true); |
||
| 230 | $key = sha1($encryptedKey . $pkey, true); |
||
| 231 | |||
| 232 | /* Make sure that the key has the correct length. */ |
||
| 233 | if (strlen($key) > $keySize) { |
||
| 234 | $key = substr($key, 0, $keySize); |
||
| 235 | } elseif (strlen($key) < $keySize) { |
||
| 236 | $key = str_pad($key, $keySize); |
||
| 237 | } |
||
| 238 | } |
||
| 239 | $symmetricKey->loadkey($key); |
||
| 240 | } else { |
||
| 241 | $symKeyAlgo = $symmetricKey->getAlgorithm(); |
||
| 242 | /* Make sure that the input key has the correct format. */ |
||
| 243 | if ($inputKeyAlgo !== $symKeyAlgo) { |
||
| 244 | throw new Exception( |
||
| 245 | 'Algorithm mismatch between input key and key in message. ' . |
||
| 246 | 'Key was: ' . var_export($inputKeyAlgo, true) . '; message was: ' . |
||
| 247 | var_export($symKeyAlgo, true) |
||
| 248 | ); |
||
| 249 | } |
||
| 250 | $symmetricKey = $inputKey; |
||
| 251 | } |
||
| 252 | |||
| 253 | $algorithm = $symmetricKey->getAlgorithm(); |
||
| 254 | if (in_array($algorithm, $blacklist, true)) { |
||
| 255 | throw new Exception('Algorithm disabled: ' . var_export($algorithm, true)); |
||
| 256 | } |
||
| 257 | |||
| 258 | /** |
||
| 259 | * @var string $decrypted |
||
| 260 | * @psalm-suppress UndefinedClass |
||
| 261 | */ |
||
| 262 | $decrypted = $enc->decryptNode($symmetricKey, false); |
||
| 263 | |||
| 264 | /* |
||
| 265 | * This is a workaround for the case where only a subset of the XML |
||
| 266 | * tree was serialized for encryption. In that case, we may miss the |
||
| 267 | * namespaces needed to parse the XML. |
||
| 268 | */ |
||
| 269 | $xml = '<root xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ' . |
||
| 270 | 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . |
||
| 271 | $decrypted . '</root>'; |
||
| 272 | |||
| 273 | try { |
||
| 274 | $newDoc = DOMDocumentFactory::fromString($xml); |
||
| 275 | } catch (RuntimeException $e) { |
||
| 276 | throw new Exception('Failed to parse decrypted XML. Maybe the wrong sharedkey was used?', 0, $e); |
||
| 277 | } |
||
| 278 | |||
| 279 | /** @psalm-suppress PossiblyNullPropertyFetch */ |
||
| 280 | $decryptedElement = $newDoc->firstChild->firstChild; |
||
| 281 | if (!($decryptedElement instanceof DOMElement)) { |
||
| 282 | throw new Exception('Missing decrypted element or it was not actually a DOMElement.'); |
||
| 283 | } |
||
| 284 | |||
| 285 | return $decryptedElement; |
||
| 286 | } |
||
| 315 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths