From be0f2f94c4bd24a2c69a6af9e5949848c29a0921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Cobucci?= Date: Tue, 29 Sep 2020 09:36:00 +0200 Subject: [PATCH] Fix compatibility with PHP 8.0 As of PHP 8.0, OpenSSL keys are ojects (OpenSSLAsymmetricKey) instead of resources. --- infection.json.dist | 4 ++-- phpstan.neon.dist | 3 +++ src/Signer/OpenSSL.php | 27 ++++++++++++++++++--------- test/unit/Signer/EcdsaTest.php | 8 +++++--- test/unit/Signer/RsaTest.php | 8 ++++++-- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/infection.json.dist b/infection.json.dist index 0e92b50e..d31f3ffd 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -10,7 +10,7 @@ "@default": true, "@function_signature": true }, - "minMsi": 94.22, - "minCoveredMsi": 94.22, + "minMsi": 92.54, + "minCoveredMsi": 92.54, "testFrameworkOptions": "--testsuite=unit" } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 5678657c..0cd9727b 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,3 +3,6 @@ parameters: paths: - src - test + + ignoreErrors: + - '#.*OpenSSLAsymmetricKey.*#' diff --git a/src/Signer/OpenSSL.php b/src/Signer/OpenSSL.php index 9689025e..72f188df 100644 --- a/src/Signer/OpenSSL.php +++ b/src/Signer/OpenSSL.php @@ -5,10 +5,11 @@ use InvalidArgumentException; use Lcobucci\JWT\Signer; +use OpenSSLAsymmetricKey; use function assert; use function is_array; -use function is_resource; +use function is_bool; use function openssl_error_string; use function openssl_free_key; use function openssl_pkey_get_details; @@ -37,16 +38,15 @@ final protected function createSignature( return $signature; } finally { - openssl_free_key($key); + $this->freeKey($key); } } - /** @return resource */ + /** @return resource|OpenSSLAsymmetricKey */ private function getPrivateKey(string $pem, string $passphrase) { $privateKey = openssl_pkey_get_private($pem, $passphrase); $this->validateKey($privateKey); - assert(is_resource($privateKey)); return $privateKey; } @@ -58,17 +58,16 @@ final protected function verifySignature( ): bool { $key = $this->getPublicKey($pem); $result = openssl_verify($payload, $expected, $key, $this->getAlgorithm()); - openssl_free_key($key); + $this->freeKey($key); return $result === 1; } - /** @return resource */ + /** @return resource|OpenSSLAsymmetricKey */ private function getPublicKey(string $pem) { $publicKey = openssl_pkey_get_public($pem); $this->validateKey($publicKey); - assert(is_resource($publicKey)); return $publicKey; } @@ -76,13 +75,13 @@ private function getPublicKey(string $pem) /** * Raises an exception when the key type is not the expected type * - * @param resource|bool $key + * @param resource|OpenSSLAsymmetricKey|bool $key * * @throws InvalidArgumentException */ private function validateKey($key): void { - if (! is_resource($key)) { + if (is_bool($key)) { throw new InvalidArgumentException( 'It was not possible to parse your key, reason: ' . openssl_error_string() ); @@ -96,6 +95,16 @@ private function validateKey($key): void } } + /** @param resource|OpenSSLAsymmetricKey $key */ + private function freeKey($key): void + { + if ($key instanceof OpenSSLAsymmetricKey) { + return; + } + + openssl_free_key($key); // Deprecated and no longer necessary as of PHP >= 8.0 + } + /** * Returns the type of key to be used to create/verify the signature (using OpenSSL constants) * diff --git a/test/unit/Signer/EcdsaTest.php b/test/unit/Signer/EcdsaTest.php index d52e4eda..89f9d751 100644 --- a/test/unit/Signer/EcdsaTest.php +++ b/test/unit/Signer/EcdsaTest.php @@ -5,8 +5,11 @@ use Lcobucci\JWT\Keys; use Lcobucci\JWT\Signer\Ecdsa\MultibyteStringConverter; +use OpenSSLAsymmetricKey; use PHPUnit\Framework\TestCase; +use function assert; +use function is_resource; use function openssl_pkey_get_private; use function openssl_pkey_get_public; use function openssl_sign; @@ -62,8 +65,8 @@ public function signShouldReturnTheAHashBasedOnTheOpenSslSignature(): void $signature = $signer->sign($payload, self::$ecdsaKeys['private']); $publicKey = openssl_pkey_get_public(self::$ecdsaKeys['public1']->getContent()); + assert(is_resource($publicKey) || $publicKey instanceof OpenSSLAsymmetricKey); - self::assertIsResource($publicKey); self::assertSame( 1, openssl_verify( @@ -90,8 +93,7 @@ public function verifyShouldDelegateToEcdsaSignerUsingPublicKey(): void { $payload = 'testing'; $privateKey = openssl_pkey_get_private(self::$ecdsaKeys['private']->getContent()); - - self::assertIsResource($privateKey); + assert(is_resource($privateKey) || $privateKey instanceof OpenSSLAsymmetricKey); $signature = ''; openssl_sign($payload, $signature, $privateKey, OPENSSL_ALGO_SHA256); diff --git a/test/unit/Signer/RsaTest.php b/test/unit/Signer/RsaTest.php index a72943fb..82f840b2 100644 --- a/test/unit/Signer/RsaTest.php +++ b/test/unit/Signer/RsaTest.php @@ -5,8 +5,11 @@ use InvalidArgumentException; use Lcobucci\JWT\Keys; +use OpenSSLAsymmetricKey; use PHPUnit\Framework\TestCase; +use function assert; +use function is_resource; use function openssl_pkey_get_private; use function openssl_pkey_get_public; use function openssl_sign; @@ -36,7 +39,8 @@ public function signShouldReturnAValidOpensslSignature(): void $signature = $signer->sign($payload, self::$rsaKeys['private']); $publicKey = openssl_pkey_get_public(self::$rsaKeys['public']->getContent()); - self::assertIsResource($publicKey); + assert(is_resource($publicKey) || $publicKey instanceof OpenSSLAsymmetricKey); + self::assertSame(1, openssl_verify($payload, $signature, $publicKey, OPENSSL_ALGO_SHA256)); } @@ -117,7 +121,7 @@ public function verifyShouldReturnTrueWhenSignatureIsValid(): void { $payload = 'testing'; $privateKey = openssl_pkey_get_private(self::$rsaKeys['private']->getContent()); - self::assertIsResource($privateKey); + assert(is_resource($privateKey) || $privateKey instanceof OpenSSLAsymmetricKey); $signature = ''; openssl_sign($payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);