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