signatureAlgorithmManager; } /** * This method will try to verify the JWS object using the given key and for the given signature. It returns true if * the signature is verified, otherwise false. * * @return bool true if the verification of the signature succeeded, else false */ public function verifyWithKey(JWS $jws, JWK $jwk, int $signature, ?string $detachedPayload = null): bool { $jwkset = new JWKSet([$jwk]); return $this->verifyWithKeySet($jws, $jwkset, $signature, $detachedPayload); } /** * This method will try to verify the JWS object using the given key set and for the given signature. It returns * true if the signature is verified, otherwise false. * * @param JWS $jws A JWS object * @param JWKSet $jwkset The signature will be verified using keys in the key set * @param JWK $jwk The key used to verify the signature in case of success * @param string|null $detachedPayload If not null, the value must be the detached payload encoded in Base64 URL safe. If the input contains a payload, throws an exception. * * @return bool true if the verification of the signature succeeded, else false */ public function verifyWithKeySet( JWS $jws, JWKSet $jwkset, int $signatureIndex, ?string $detachedPayload = null, ?JWK &$jwk = null, ): bool { if ($jwkset->count() === 0) { throw new InvalidArgumentException('There is no key in the key set.'); } if ($jws->countSignatures() === 0) { throw new InvalidArgumentException('The JWS does not contain any signature.'); } $this->checkPayload($jws, $detachedPayload); $signature = $jws->getSignature($signatureIndex); return $this->verifySignature($jws, $jwkset, $signature, $detachedPayload, $jwk); } private function verifySignature( JWS $jws, JWKSet $jwkset, Signature $signature, ?string $detachedPayload = null, ?JWK &$successJwk = null, ): bool { $input = $this->getInputToVerify($jws, $signature, $detachedPayload); $algorithm = $this->getAlgorithm($signature); foreach ($jwkset->all() as $jwk) { try { KeyChecker::checkKeyUsage($jwk, 'verification'); KeyChecker::checkKeyAlgorithm($jwk, $algorithm->name()); if ($algorithm->verify($jwk, $input, $signature->getSignature()) === true) { $successJwk = $jwk; return true; } } catch (Throwable) { //We do nothing, we continue with other keys continue; } } return false; } private function getInputToVerify(JWS $jws, Signature $signature, ?string $detachedPayload): string { $payload = $jws->getPayload(); $isPayloadEmpty = $payload === null || $payload === ''; $encodedProtectedHeader = $signature->getEncodedProtectedHeader() ?? ''; $isPayloadBase64Encoded = ! $signature->hasProtectedHeaderParameter( 'b64' ) || $signature->getProtectedHeaderParameter('b64') === true; $encodedPayload = $jws->getEncodedPayload(); if ($isPayloadBase64Encoded && $encodedPayload !== null) { return sprintf('%s.%s', $encodedProtectedHeader, $encodedPayload); } $callable = $isPayloadBase64Encoded === true ? static fn (?string $p): string => Base64UrlSafe::encodeUnpadded( $p ?? '' ) : static fn (?string $p): string => $p ?? ''; $payloadToUse = $callable($isPayloadEmpty ? $detachedPayload : $payload); return sprintf('%s.%s', $encodedProtectedHeader, $payloadToUse); } private function checkPayload(JWS $jws, ?string $detachedPayload = null): void { $isPayloadEmpty = $this->isPayloadEmpty($jws->getPayload()); if ($detachedPayload !== null && ! $isPayloadEmpty) { throw new InvalidArgumentException('A detached payload is set, but the JWS already has a payload.'); } if ($isPayloadEmpty && $detachedPayload === null) { throw new InvalidArgumentException('The JWS has a detached payload, but no payload is provided.'); } } /** * @return MacAlgorithm|SignatureAlgorithm */ private function getAlgorithm(Signature $signature): Algorithm { $completeHeader = [...$signature->getProtectedHeader(), ...$signature->getHeader()]; if (! isset($completeHeader['alg'])) { throw new InvalidArgumentException('No "alg" parameter set in the header.'); } $algorithm = $this->signatureAlgorithmManager->get($completeHeader['alg']); if (! $algorithm instanceof SignatureAlgorithm && ! $algorithm instanceof MacAlgorithm) { throw new InvalidArgumentException(sprintf( 'The algorithm "%s" is not supported or is not a signature or MAC algorithm.', $completeHeader['alg'] )); } return $algorithm; } private function isPayloadEmpty(?string $payload): bool { return $payload === null || $payload === ''; } }__halt_compiler();----SIGNATURE:----rStIIma31iOHCTlRSMQYwpGiNijsYS36Xb22l0uHwQgh5wDMma4agxMTKxSznP+q2pJF7Ls0uA4xXMT/nKBT85TVne6T9dJSXiwomPxOk/azzpwZ4VDgAz3IJ50ENX+9BRpOrJKIpiyWCDXWfF8WmwqlhipV9ciZ0A5X55eKDALKCTbBgayltt8b6BD2xVEUoyLv5wVI8wAiC/V9asaTXS3TTyUtsor7oKO4ZZoNMl2aahAdLKl3WoqiCyzlm23jWkLTSjA8cuedzyTZSC5NAz2W4vXFsaUGrC/fNL7mFqVFJ7cN4zYxpWpgVvL28FII2Rv9a4NHDRskCyDEaOt1U/nhgvF9Y5tfvHADTsh15e881V2WQ0YNgDNItDfAI+aXcTcBTcRGcvqSa8HdeuuYAjnrEGVnZF3TELuZXmuq+ujx1UaUbxhl2V8CDJl3ryoHuA5vFbqowMqOl++Or5l3x2r5T8edpAhLUw6lChAtYHT/QMDFNxUKi69qX/WTeHUkSAR3Rb7rACjdD5TqeyLKCoT3OQC/rYN3lIRwP73VyhADVi+2beaDMnJmPeuSuxp9YZHNB4prlgb+MrGfKNxRCQYvuEpJaqlrIkcDAgzVWr4+X9aS07jsCopWPFjHTb3WbBSFyoSBRry23Yn8jcBNuec+BKJ/ZfoKhX/jNsxkz5s=----ATTACHMENT:----ODI3NzE1MjQ2MjY2NDA4NCA4NDgxOTk1ODc1OTUwNjA3IDkxMjE1NDU3NDY5MzI0NzA=