72 lines
2.3 KiB
PHP
72 lines
2.3 KiB
PHP
|
<?php
|
||
|
namespace Misuzu\OpenID;
|
||
|
|
||
|
use RuntimeException;
|
||
|
use Index\UriBase64;
|
||
|
use phpseclib3\Crypt\PublicKeyLoader;
|
||
|
use phpseclib3\Crypt\Common\{AsymmetricKey,PrivateKey,PublicKey};
|
||
|
use phpseclib3\Math\BigInteger;
|
||
|
|
||
|
class ArrayJWTKeySet implements JWTKeySet {
|
||
|
/** @param array<string, JWTKey> $keys */
|
||
|
public function __construct(public private(set) array $keys) {}
|
||
|
|
||
|
public function getKey(?string $keyId = null, ?string $alg = null): JWTKey {
|
||
|
if($keyId === null) {
|
||
|
if($alg === null)
|
||
|
return $this->keys[array_key_first($this->keys)];
|
||
|
|
||
|
foreach($this->keys as $key)
|
||
|
if(hash_equals($key->algo, $alg))
|
||
|
return $key;
|
||
|
|
||
|
throw new RuntimeException('could not find a key that matched the requested algorithm');
|
||
|
}
|
||
|
|
||
|
if(!array_key_exists($keyId, $this->keys))
|
||
|
throw new RuntimeException('could not find a key with that id');
|
||
|
|
||
|
$key = $this->keys[$keyId];
|
||
|
if($alg !== null && !hash_equals($key->algo, $alg))
|
||
|
throw new RuntimeException('requested algorithm does not match');
|
||
|
|
||
|
return $key;
|
||
|
}
|
||
|
|
||
|
public function count(): int {
|
||
|
return count($this->keys);
|
||
|
}
|
||
|
|
||
|
public static function decodeJson(string|array|object $json): ArrayJWTKeySet {
|
||
|
if(is_object($json))
|
||
|
$json = (array)$json;
|
||
|
elseif(is_string($json))
|
||
|
$json = json_decode($json);
|
||
|
|
||
|
if(is_array($json))
|
||
|
$json = (object)$json;
|
||
|
|
||
|
if(!property_exists($json, 'keys') || !is_array($json->keys) || !array_is_list($json->keys))
|
||
|
return new ArrayJWTKeySet([]);
|
||
|
|
||
|
$keys = [];
|
||
|
|
||
|
foreach($json->keys as $keyInfo) {
|
||
|
$key = PublicKeyLoader::load(json_encode($keyInfo));
|
||
|
|
||
|
if($key instanceof AsymmetricKey && ($key instanceof PrivateKey || $key instanceof PublicKey))
|
||
|
$key = new SecLibJWTKey(
|
||
|
property_exists($keyInfo, 'alg') && is_string($keyInfo->alg) ? $keyInfo->alg : SetLibJWTKey::inferAlgorithm($key),
|
||
|
$key
|
||
|
);
|
||
|
|
||
|
if(property_exists($keyInfo, 'kid') && is_string($keyInfo->kid))
|
||
|
$keys[$keyInfo->kid] = $key;
|
||
|
else
|
||
|
$keys[] = $key;
|
||
|
}
|
||
|
|
||
|
return new ArrayJWTKeySet($keys);
|
||
|
}
|
||
|
}
|