mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 18:48:51 +02:00
N°8834 - Add compatibility with PHP 8.4 (#819)
* N°8834 - Add compatibility with PHP 8.4 * Rollback of scssphp/scssphp version upgrade due to compilation error
This commit is contained in:
@@ -1,5 +1,64 @@
|
||||
# Changelog
|
||||
|
||||
## [7.0.2](https://github.com/firebase/php-jwt/compare/v7.0.1...v7.0.2) (2025-12-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add key length validation for ec keys ([#615](https://github.com/firebase/php-jwt/issues/615)) ([7044f9a](https://github.com/firebase/php-jwt/commit/7044f9ae7e7d175d28cca71714feb236f1c0e252))
|
||||
|
||||
## [7.0.0](https://github.com/firebase/php-jwt/compare/v6.11.1...v7.0.0) (2025-12-15)
|
||||
|
||||
|
||||
### ⚠️ ⚠️ ⚠️ Security Fixes ⚠️ ⚠️ ⚠️
|
||||
* add key size validation ([#613](https://github.com/firebase/php-jwt/issues/613)) ([6b80341](https://github.com/firebase/php-jwt/commit/6b80341bf57838ea2d011487917337901cd71576))
|
||||
**NOTE**: This fix will cause keys with a size below the minimally allowed size to break.
|
||||
|
||||
### Features
|
||||
|
||||
* add SensitiveParameter attribute to security-critical parameters ([#603](https://github.com/firebase/php-jwt/issues/603)) ([4dbfac0](https://github.com/firebase/php-jwt/commit/4dbfac0260eeb0e9e643063c99998e3219cc539b))
|
||||
* store timestamp in `ExpiredException` ([#604](https://github.com/firebase/php-jwt/issues/604)) ([f174826](https://github.com/firebase/php-jwt/commit/f1748260d218a856b6a0c23715ac7fae1d7ca95b))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* validate iat and nbf on payload ([#568](https://github.com/firebase/php-jwt/issues/568)) ([953b2c8](https://github.com/firebase/php-jwt/commit/953b2c88bb445b7e3bb82a5141928f13d7343afd))
|
||||
|
||||
## [6.11.1](https://github.com/firebase/php-jwt/compare/v6.11.0...v6.11.1) (2025-04-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update error text for consistency ([#528](https://github.com/firebase/php-jwt/issues/528)) ([c11113a](https://github.com/firebase/php-jwt/commit/c11113afa13265e016a669e75494b9203b8a7775))
|
||||
|
||||
## [6.11.0](https://github.com/firebase/php-jwt/compare/v6.10.2...v6.11.0) (2025-01-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support octet typed JWK ([#587](https://github.com/firebase/php-jwt/issues/587)) ([7cb8a26](https://github.com/firebase/php-jwt/commit/7cb8a265fa81edf2fa6ef8098f5bc5ae573c33ad))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* refactor constructor Key to use PHP 8.0 syntax ([#577](https://github.com/firebase/php-jwt/issues/577)) ([29fa2ce](https://github.com/firebase/php-jwt/commit/29fa2ce9e0582cd397711eec1e80c05ce20fabca))
|
||||
|
||||
## [6.10.2](https://github.com/firebase/php-jwt/compare/v6.10.1...v6.10.2) (2024-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Mitigate PHP8.4 deprecation warnings ([#570](https://github.com/firebase/php-jwt/issues/570)) ([76808fa](https://github.com/firebase/php-jwt/commit/76808fa227f3811aa5cdb3bf81233714b799a5b5))
|
||||
* support php 8.4 ([#583](https://github.com/firebase/php-jwt/issues/583)) ([e3d68b0](https://github.com/firebase/php-jwt/commit/e3d68b044421339443c74199edd020e03fb1887e))
|
||||
|
||||
## [6.10.1](https://github.com/firebase/php-jwt/compare/v6.10.0...v6.10.1) (2024-05-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ensure ratelimit expiry is set every time ([#556](https://github.com/firebase/php-jwt/issues/556)) ([09cb208](https://github.com/firebase/php-jwt/commit/09cb2081c2c3bc0f61e2f2a5fbea5741f7498648))
|
||||
* ratelimit cache expiration ([#550](https://github.com/firebase/php-jwt/issues/550)) ([dda7250](https://github.com/firebase/php-jwt/commit/dda725033585ece30ff8cae8937320d7e9f18bae))
|
||||
|
||||
## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28)
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ composer require firebase/php-jwt
|
||||
```
|
||||
|
||||
Optionally, install the `paragonie/sodium_compat` package from composer if your
|
||||
php is < 7.2 or does not have libsodium installed:
|
||||
php env does not have libsodium installed:
|
||||
|
||||
```bash
|
||||
composer require paragonie/sodium_compat
|
||||
@@ -48,7 +48,8 @@ $decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||
print_r($decoded);
|
||||
|
||||
// Pass a stdClass in as the third parameter to get the decoded header values
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass());
|
||||
$headers = new stdClass();
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers);
|
||||
print_r($headers);
|
||||
|
||||
/*
|
||||
@@ -185,7 +186,7 @@ $passphrase = '[YOUR_PASSPHRASE]';
|
||||
// Can be generated with "ssh-keygen -t rsa -m pem"
|
||||
$privateKeyFile = '/path/to/key-with-passphrase.pem';
|
||||
|
||||
// Create a private key of type "resource"
|
||||
/** @var OpenSSLAsymmetricKey $privateKey */
|
||||
$privateKey = openssl_pkey_get_private(
|
||||
file_get_contents($privateKeyFile),
|
||||
$passphrase
|
||||
@@ -290,7 +291,7 @@ $jwks = ['keys' => []];
|
||||
|
||||
// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
|
||||
// objects. Pass this as the second parameter to JWT::decode.
|
||||
JWT::decode($payload, JWK::parseKeySet($jwks));
|
||||
JWT::decode($jwt, JWK::parseKeySet($jwks));
|
||||
```
|
||||
|
||||
Using Cached Key Sets
|
||||
@@ -349,7 +350,7 @@ use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
$decoded = JWT::decode($jwt, $keys);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
// provided key/key-array is empty or malformed.
|
||||
} catch (DomainException $e) {
|
||||
@@ -379,7 +380,7 @@ like this:
|
||||
use Firebase\JWT\JWT;
|
||||
use UnexpectedValueException;
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
$decoded = JWT::decode($jwt, $keys);
|
||||
} catch (LogicException $e) {
|
||||
// errors having to do with environmental setup or malformed JWT Keys
|
||||
} catch (UnexpectedValueException $e) {
|
||||
@@ -394,7 +395,7 @@ instead, you can do the following:
|
||||
|
||||
```php
|
||||
// return type is stdClass
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
$decoded = JWT::decode($jwt, $keys);
|
||||
|
||||
// cast to array
|
||||
$decoded = json_decode(json_encode($decoded), true);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"require": {
|
||||
"php": "^7.4||^8.0"
|
||||
"php": "^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
|
||||
@@ -32,10 +32,10 @@
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/cache": "^2.0||^3.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
}
|
||||
|
||||
@@ -80,9 +80,9 @@ class CachedKeySet implements ArrayAccess
|
||||
ClientInterface $httpClient,
|
||||
RequestFactoryInterface $httpFactory,
|
||||
CacheItemPoolInterface $cache,
|
||||
int $expiresAfter = null,
|
||||
?int $expiresAfter = null,
|
||||
bool $rateLimit = false,
|
||||
string $defaultAlg = null
|
||||
?string $defaultAlg = null
|
||||
) {
|
||||
$this->jwksUri = $jwksUri;
|
||||
$this->httpClient = $httpClient;
|
||||
@@ -180,7 +180,7 @@ class CachedKeySet implements ArrayAccess
|
||||
$jwksResponse = $this->httpClient->sendRequest($request);
|
||||
if ($jwksResponse->getStatusCode() !== 200) {
|
||||
throw new UnexpectedValueException(
|
||||
sprintf('HTTP Error: %d %s for URI "%s"',
|
||||
\sprintf('HTTP Error: %d %s for URI "%s"',
|
||||
$jwksResponse->getStatusCode(),
|
||||
$jwksResponse->getReasonPhrase(),
|
||||
$this->jwksUri,
|
||||
@@ -212,15 +212,21 @@ class CachedKeySet implements ArrayAccess
|
||||
}
|
||||
|
||||
$cacheItem = $this->cache->getItem($this->rateLimitCacheKey);
|
||||
if (!$cacheItem->isHit()) {
|
||||
$cacheItem->expiresAfter(1); // # of calls are cached each minute
|
||||
|
||||
$cacheItemData = [];
|
||||
if ($cacheItem->isHit() && \is_array($data = $cacheItem->get())) {
|
||||
$cacheItemData = $data;
|
||||
}
|
||||
|
||||
$callsPerMinute = (int) $cacheItem->get();
|
||||
$callsPerMinute = $cacheItemData['callsPerMinute'] ?? 0;
|
||||
$expiry = $cacheItemData['expiry'] ?? new \DateTime('+60 seconds', new \DateTimeZone('UTC'));
|
||||
|
||||
if (++$callsPerMinute > $this->maxCallsPerMinute) {
|
||||
return true;
|
||||
}
|
||||
$cacheItem->set($callsPerMinute);
|
||||
|
||||
$cacheItem->set(['expiry' => $expiry, 'callsPerMinute' => $callsPerMinute]);
|
||||
$cacheItem->expiresAt($expiry);
|
||||
$this->cache->save($cacheItem);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ class ExpiredException extends \UnexpectedValueException implements JWTException
|
||||
{
|
||||
private object $payload;
|
||||
|
||||
private ?int $timestamp = null;
|
||||
|
||||
public function setPayload(object $payload): void
|
||||
{
|
||||
$this->payload = $payload;
|
||||
@@ -15,4 +17,14 @@ class ExpiredException extends \UnexpectedValueException implements JWTException
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
|
||||
public function setTimestamp(int $timestamp): void
|
||||
{
|
||||
$this->timestamp = $timestamp;
|
||||
}
|
||||
|
||||
public function getTimestamp(): ?int
|
||||
{
|
||||
return $this->timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class JWK
|
||||
*
|
||||
* @uses parseKey
|
||||
*/
|
||||
public static function parseKeySet(array $jwks, string $defaultAlg = null): array
|
||||
public static function parseKeySet(#[\SensitiveParameter] array $jwks, ?string $defaultAlg = null): array
|
||||
{
|
||||
$keys = [];
|
||||
|
||||
@@ -93,7 +93,7 @@ class JWK
|
||||
*
|
||||
* @uses createPemFromModulusAndExponent
|
||||
*/
|
||||
public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
|
||||
public static function parseKey(#[\SensitiveParameter] array $jwk, ?string $defaultAlg = null): ?Key
|
||||
{
|
||||
if (empty($jwk)) {
|
||||
throw new InvalidArgumentException('JWK must not be empty');
|
||||
@@ -172,6 +172,12 @@ class JWK
|
||||
// This library works internally with EdDSA keys (Ed25519) encoded in standard base64.
|
||||
$publicKey = JWT::convertBase64urlToBase64($jwk['x']);
|
||||
return new Key($publicKey, $jwk['alg']);
|
||||
case 'oct':
|
||||
if (!isset($jwk['k'])) {
|
||||
throw new UnexpectedValueException('k not set');
|
||||
}
|
||||
|
||||
return new Key(JWT::urlsafeB64Decode($jwk['k']), $jwk['alg']);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -212,7 +218,7 @@ class JWK
|
||||
)
|
||||
);
|
||||
|
||||
return sprintf(
|
||||
return \sprintf(
|
||||
"-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n",
|
||||
wordwrap(base64_encode($pem), 64, "\n", true)
|
||||
);
|
||||
|
||||
@@ -31,6 +31,8 @@ class JWT
|
||||
private const ASN1_SEQUENCE = 0x10;
|
||||
private const ASN1_BIT_STRING = 0x03;
|
||||
|
||||
private const RSA_KEY_MIN_LENGTH=2048;
|
||||
|
||||
/**
|
||||
* When checking nbf, iat or expiration times,
|
||||
* we want to provide some extra leeway time to
|
||||
@@ -95,8 +97,8 @@ class JWT
|
||||
*/
|
||||
public static function decode(
|
||||
string $jwt,
|
||||
$keyOrKeyArray,
|
||||
stdClass &$headers = null
|
||||
#[\SensitiveParameter] $keyOrKeyArray,
|
||||
?stdClass &$headers = null
|
||||
): stdClass {
|
||||
// Validate JWT
|
||||
$timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
|
||||
@@ -127,6 +129,16 @@ class JWT
|
||||
if (!$payload instanceof stdClass) {
|
||||
throw new UnexpectedValueException('Payload must be a JSON object');
|
||||
}
|
||||
if (isset($payload->iat) && !\is_numeric($payload->iat)) {
|
||||
throw new UnexpectedValueException('Payload iat must be a number');
|
||||
}
|
||||
if (isset($payload->nbf) && !\is_numeric($payload->nbf)) {
|
||||
throw new UnexpectedValueException('Payload nbf must be a number');
|
||||
}
|
||||
if (isset($payload->exp) && !\is_numeric($payload->exp)) {
|
||||
throw new UnexpectedValueException('Payload exp must be a number');
|
||||
}
|
||||
|
||||
$sig = static::urlsafeB64Decode($cryptob64);
|
||||
if (empty($header->alg)) {
|
||||
throw new UnexpectedValueException('Empty algorithm');
|
||||
@@ -154,7 +166,7 @@ class JWT
|
||||
// token can actually be used. If it's not yet that time, abort.
|
||||
if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) {
|
||||
$ex = new BeforeValidException(
|
||||
'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf)
|
||||
'Cannot handle token with nbf prior to ' . \date(DateTime::ATOM, (int) floor($payload->nbf))
|
||||
);
|
||||
$ex->setPayload($payload);
|
||||
throw $ex;
|
||||
@@ -165,7 +177,7 @@ class JWT
|
||||
// correctly used the nbf claim).
|
||||
if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) {
|
||||
$ex = new BeforeValidException(
|
||||
'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat)
|
||||
'Cannot handle token with iat prior to ' . \date(DateTime::ATOM, (int) floor($payload->iat))
|
||||
);
|
||||
$ex->setPayload($payload);
|
||||
throw $ex;
|
||||
@@ -175,6 +187,7 @@ class JWT
|
||||
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
|
||||
$ex = new ExpiredException('Expired token');
|
||||
$ex->setPayload($payload);
|
||||
$ex->setTimestamp($timestamp);
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
@@ -185,7 +198,7 @@ class JWT
|
||||
* Converts and signs a PHP array into a JWT string.
|
||||
*
|
||||
* @param array<mixed> $payload PHP array
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
||||
* @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
||||
* @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
|
||||
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
|
||||
* @param string $keyId
|
||||
@@ -198,13 +211,13 @@ class JWT
|
||||
*/
|
||||
public static function encode(
|
||||
array $payload,
|
||||
$key,
|
||||
#[\SensitiveParameter] $key,
|
||||
string $alg,
|
||||
string $keyId = null,
|
||||
array $head = null
|
||||
?string $keyId = null,
|
||||
?array $head = null
|
||||
): string {
|
||||
$header = ['typ' => 'JWT'];
|
||||
if (isset($head) && \is_array($head)) {
|
||||
if (isset($head)) {
|
||||
$header = \array_merge($header, $head);
|
||||
}
|
||||
$header['alg'] = $alg;
|
||||
@@ -226,7 +239,7 @@ class JWT
|
||||
* Sign a string with a given key and algorithm.
|
||||
*
|
||||
* @param string $msg The message to sign
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
||||
* @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
||||
* @param string $alg Supported algorithms are 'EdDSA', 'ES384', 'ES256', 'ES256K', 'HS256',
|
||||
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
|
||||
*
|
||||
@@ -236,7 +249,7 @@ class JWT
|
||||
*/
|
||||
public static function sign(
|
||||
string $msg,
|
||||
$key,
|
||||
#[\SensitiveParameter] $key,
|
||||
string $alg
|
||||
): string {
|
||||
if (empty(static::$supported_algs[$alg])) {
|
||||
@@ -248,10 +261,19 @@ class JWT
|
||||
if (!\is_string($key)) {
|
||||
throw new InvalidArgumentException('key must be a string when using hmac');
|
||||
}
|
||||
self::validateHmacKeyLength($key, $algorithm);
|
||||
return \hash_hmac($algorithm, $msg, $key, true);
|
||||
case 'openssl':
|
||||
$signature = '';
|
||||
$success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line
|
||||
if (!$key = openssl_pkey_get_private($key)) {
|
||||
throw new DomainException('OpenSSL unable to validate key');
|
||||
}
|
||||
if (str_starts_with($alg, 'RS')) {
|
||||
self::validateRsaKeyLength($key);
|
||||
} elseif (str_starts_with($alg, 'ES')) {
|
||||
self::validateEcKeyLength($key, $alg);
|
||||
}
|
||||
$success = \openssl_sign($msg, $signature, $key, $algorithm);
|
||||
if (!$success) {
|
||||
throw new DomainException('OpenSSL unable to sign data');
|
||||
}
|
||||
@@ -290,7 +312,7 @@ class JWT
|
||||
*
|
||||
* @param string $msg The original message (header and body)
|
||||
* @param string $signature The original signature
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey
|
||||
* @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey
|
||||
* @param string $alg The algorithm
|
||||
*
|
||||
* @return bool
|
||||
@@ -300,7 +322,7 @@ class JWT
|
||||
private static function verify(
|
||||
string $msg,
|
||||
string $signature,
|
||||
$keyMaterial,
|
||||
#[\SensitiveParameter] $keyMaterial,
|
||||
string $alg
|
||||
): bool {
|
||||
if (empty(static::$supported_algs[$alg])) {
|
||||
@@ -310,7 +332,15 @@ class JWT
|
||||
list($function, $algorithm) = static::$supported_algs[$alg];
|
||||
switch ($function) {
|
||||
case 'openssl':
|
||||
$success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line
|
||||
if (!$key = openssl_pkey_get_public($keyMaterial)) {
|
||||
throw new DomainException('OpenSSL unable to validate key');
|
||||
}
|
||||
if (str_starts_with($alg, 'RS')) {
|
||||
self::validateRsaKeyLength($key);
|
||||
} elseif (str_starts_with($alg, 'ES')) {
|
||||
self::validateEcKeyLength($key, $alg);
|
||||
}
|
||||
$success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm);
|
||||
if ($success === 1) {
|
||||
return true;
|
||||
}
|
||||
@@ -347,6 +377,7 @@ class JWT
|
||||
if (!\is_string($keyMaterial)) {
|
||||
throw new InvalidArgumentException('key must be a string when using hmac');
|
||||
}
|
||||
self::validateHmacKeyLength($keyMaterial, $algorithm);
|
||||
$hash = \hash_hmac($algorithm, $msg, $keyMaterial, true);
|
||||
return self::constantTimeEquals($hash, $signature);
|
||||
}
|
||||
@@ -384,12 +415,7 @@ class JWT
|
||||
*/
|
||||
public static function jsonEncode(array $input): string
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50400) {
|
||||
$json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
|
||||
} else {
|
||||
// PHP 5.3 only
|
||||
$json = \json_encode($input);
|
||||
}
|
||||
$json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
|
||||
if ($errno = \json_last_error()) {
|
||||
self::handleJsonError($errno);
|
||||
} elseif ($json === 'null') {
|
||||
@@ -459,7 +485,7 @@ class JWT
|
||||
* @return Key
|
||||
*/
|
||||
private static function getKey(
|
||||
$keyOrKeyArray,
|
||||
#[\SensitiveParameter] $keyOrKeyArray,
|
||||
?string $kid
|
||||
): Key {
|
||||
if ($keyOrKeyArray instanceof Key) {
|
||||
@@ -666,4 +692,57 @@ class JWT
|
||||
|
||||
return [$pos, $data];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate HMAC key length
|
||||
*
|
||||
* @param string $key HMAC key material
|
||||
* @param string $algorithm The algorithm
|
||||
*
|
||||
* @throws DomainException Provided key is too short
|
||||
*/
|
||||
private static function validateHmacKeyLength(string $key, string $algorithm): void
|
||||
{
|
||||
$keyLength = \strlen($key) * 8;
|
||||
$minKeyLength = (int) \str_replace('SHA', '', $algorithm);
|
||||
if ($keyLength < $minKeyLength) {
|
||||
throw new DomainException('Provided key is too short');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate RSA key length
|
||||
*
|
||||
* @param OpenSSLAsymmetricKey $key RSA key material
|
||||
* @throws DomainException Provided key is too short
|
||||
*/
|
||||
private static function validateRsaKeyLength(#[\SensitiveParameter] OpenSSLAsymmetricKey $key): void
|
||||
{
|
||||
if (!$keyDetails = openssl_pkey_get_details($key)) {
|
||||
throw new DomainException('Unable to validate key');
|
||||
}
|
||||
if ($keyDetails['bits'] < self::RSA_KEY_MIN_LENGTH) {
|
||||
throw new DomainException('Provided key is too short');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate RSA key length
|
||||
*
|
||||
* @param OpenSSLAsymmetricKey $key RSA key material
|
||||
* @param string $algorithm The algorithm
|
||||
* @throws DomainException Provided key is too short
|
||||
*/
|
||||
private static function validateEcKeyLength(
|
||||
#[\SensitiveParameter] OpenSSLAsymmetricKey $key,
|
||||
string $algorithm
|
||||
): void {
|
||||
if (!$keyDetails = openssl_pkey_get_details($key)) {
|
||||
throw new DomainException('Unable to validate key');
|
||||
}
|
||||
$minKeyLength = (int) \str_replace('ES', '', $algorithm);
|
||||
if ($keyDetails['bits'] < $minKeyLength) {
|
||||
throw new DomainException('Provided key is too short');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,26 +9,20 @@ use TypeError;
|
||||
|
||||
class Key
|
||||
{
|
||||
/** @var string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */
|
||||
private $keyMaterial;
|
||||
/** @var string */
|
||||
private $algorithm;
|
||||
|
||||
/**
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial
|
||||
* @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial
|
||||
* @param string $algorithm
|
||||
*/
|
||||
public function __construct(
|
||||
$keyMaterial,
|
||||
string $algorithm
|
||||
#[\SensitiveParameter] private $keyMaterial,
|
||||
private string $algorithm
|
||||
) {
|
||||
if (
|
||||
!\is_string($keyMaterial)
|
||||
&& !$keyMaterial instanceof OpenSSLAsymmetricKey
|
||||
&& !$keyMaterial instanceof OpenSSLCertificate
|
||||
&& !\is_resource($keyMaterial)
|
||||
) {
|
||||
throw new TypeError('Key material must be a string, resource, or OpenSSLAsymmetricKey');
|
||||
throw new TypeError('Key material must be a string, OpenSSLCertificate, or OpenSSLAsymmetricKey');
|
||||
}
|
||||
|
||||
if (empty($keyMaterial)) {
|
||||
@@ -38,10 +32,6 @@ class Key
|
||||
if (empty($algorithm)) {
|
||||
throw new InvalidArgumentException('Algorithm must not be empty');
|
||||
}
|
||||
|
||||
// TODO: Remove in PHP 8.0 in favor of class constructor property promotion
|
||||
$this->keyMaterial = $keyMaterial;
|
||||
$this->algorithm = $algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +45,7 @@ class Key
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate
|
||||
* @return string|OpenSSLAsymmetricKey|OpenSSLCertificate
|
||||
*/
|
||||
public function getKeyMaterial()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user