* Can be created either from a JWK parameter array or local file path to load a certificate from.
* Examples:
* 'file:///var/www/cert.pem'
- * ['kty' => 'RSA', 'alg' => 'RS256', 'n' => 'abc123...']
+ * ['kty' => 'RSA', 'alg' => 'RS256', 'n' => 'abc123...'].
+ *
* @param array|string $jwkOrKeyPath
+ *
* @throws OidcInvalidKeyException
*/
public function __construct($jwkOrKeyPath)
{
if (is_array($jwkOrKeyPath)) {
$this->loadFromJwkArray($jwkOrKeyPath);
- } else if (is_string($jwkOrKeyPath) && strpos($jwkOrKeyPath, 'file://') === 0) {
+ } elseif (is_string($jwkOrKeyPath) && strpos($jwkOrKeyPath, 'file://') === 0) {
$this->loadFromPath($jwkOrKeyPath);
} else {
throw new OidcInvalidKeyException('Unexpected type of key value provided');
protected function loadFromPath(string $path)
{
try {
- $this->key = PublicKeyLoader::load(
+ $key = PublicKeyLoader::load(
file_get_contents($path)
- )->withPadding(RSA::SIGNATURE_PKCS1);
+ );
} catch (\Exception $exception) {
throw new OidcInvalidKeyException("Failed to load key from file path with error: {$exception->getMessage()}");
}
- if (!($this->key instanceof RSA)) {
- throw new OidcInvalidKeyException("Key loaded from file path is not an RSA key as expected");
+ if (!$key instanceof RSA) {
+ throw new OidcInvalidKeyException('Key loaded from file path is not an RSA key as expected');
}
+
+ $this->key = $key->withPadding(RSA::SIGNATURE_PKCS1);
}
/**
*/
protected function loadFromJwkArray(array $jwk)
{
- if ($jwk['alg'] !== 'RS256') {
- throw new OidcInvalidKeyException("Only RS256 keys are currently supported. Found key using {$jwk['alg']}");
- }
-
- if (empty($jwk['use'])) {
- throw new OidcInvalidKeyException('A "use" parameter on the provided key is expected');
+ // 'alg' is optional for a JWK, but we will still attempt to validate if
+ // it exists otherwise presume it will be compatible.
+ $alg = $jwk['alg'] ?? null;
+ if ($jwk['kty'] !== 'RSA' || !(is_null($alg) || $alg === 'RS256')) {
+ throw new OidcInvalidKeyException("Only RS256 keys are currently supported. Found key using {$alg}");
}
- if ($jwk['use'] !== 'sig') {
+ // 'use' is optional for a JWK but we assume 'sig' where no value exists since that's what
+ // the OIDC discovery spec infers since 'sig' MUST be set if encryption keys come into play.
+ $use = $jwk['use'] ?? 'sig';
+ if ($use !== 'sig') {
throw new OidcInvalidKeyException("Only signature keys are currently supported. Found key for use {$jwk['use']}");
}
$n = strtr($jwk['n'] ?? '', '-_', '+/');
try {
- /** @var RSA $key */
- $this->key = PublicKeyLoader::load([
+ $key = PublicKeyLoader::load([
'e' => new BigInteger(base64_decode($jwk['e']), 256),
'n' => new BigInteger(base64_decode($n), 256),
- ])->withPadding(RSA::SIGNATURE_PKCS1);
+ ]);
} catch (\Exception $exception) {
throw new OidcInvalidKeyException("Failed to load key from JWK parameters with error: {$exception->getMessage()}");
}
+
+ if (!$key instanceof RSA) {
+ throw new OidcInvalidKeyException('Key loaded from file path is not an RSA key as expected');
+ }
+
+ $this->key = $key->withPadding(RSA::SIGNATURE_PKCS1);
}
/**
{
return $this->key->toString('PKCS8');
}
-
-}
\ No newline at end of file
+}