misuzu/src/OpenID/ArrayJWTKeySet.php

72 lines
2.3 KiB
PHP
Raw Normal View History

2025-02-25 02:29:51 +00:00
<?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);
}
}