callOnPublicKey( function ($publicKey) use ($data, $signature, $algorithm): bool { $verify = $this->openSslVerify($data, $signature, $publicKey, $algorithm); if (-1 === $verify) { /** @codeCoverageIgnore Don't know how make openssl_verify returns -1 */ throw new RuntimeException('Verify error: ' . openssl_error_string()); } return (1 === $verify); } ); } /** * This method id created to wrap and mock openssl_verify * * @param string $data * @param string $signature * @param OpenSSLAsymmetricKey $publicKey * @param int $algorithm * @return int */ protected function openSslVerify(string $data, string $signature, $publicKey, int $algorithm): int { $verify = openssl_verify($data, $signature, $publicKey, $algorithm); if (false === $verify) { return -1; // @codeCoverageIgnore } return $verify; } /** * Run a closure with this public key opened * * @template T * @param Closure(OpenSSLAsymmetricKey): T $function * @return T */ public function callOnPublicKey(Closure $function) { return $this->callOnPublicKeyWithContents($function, $this->publicKeyContents()); } /** * @template T * @param Closure(OpenSSLAsymmetricKey): T $function * @param string $publicKeyContents * @return T * @throws RuntimeException when Cannot open public key */ private static function callOnPublicKeyWithContents(Closure $function, string $publicKeyContents) { /** @var false|OpenSSLAsymmetricKey $pubKey */ $pubKey = openssl_get_publickey($publicKeyContents); if (false === $pubKey) { throw new RuntimeException('Cannot open public key: ' . openssl_error_string()); } try { return $function($pubKey); } finally { if (PHP_VERSION_ID < 80000) { // phpcs:disable Generic.PHP.DeprecatedFunctions.Deprecated openssl_free_key($pubKey); // phpcs:enable } } } }