primo commit

This commit is contained in:
2024-12-17 17:34:10 +01:00
commit e650f8df99
16435 changed files with 2451012 additions and 0 deletions

View File

@ -0,0 +1,120 @@
<?php
declare(strict_types=1);
namespace Jose\Component\KeyManagement\KeyConverter;
use InvalidArgumentException;
use Jose\Component\Core\Util\Base64UrlSafe;
use SpomkyLabs\Pki\CryptoEncoding\PEM;
use SpomkyLabs\Pki\CryptoTypes\Asymmetric\EC\ECPrivateKey;
use SpomkyLabs\Pki\CryptoTypes\Asymmetric\EC\ECPublicKey;
use Throwable;
use function array_key_exists;
use function is_string;
/**
* @internal
*/
final class ECKey
{
private array $values = [];
private function __construct(array $data)
{
$this->loadJWK($data);
}
public static function createFromPEM(string $pem): self
{
$data = self::loadPEM($pem);
return new self($data);
}
public static function toPublic(self $private): self
{
$data = $private->toArray();
if (array_key_exists('d', $data)) {
unset($data['d']);
}
return new self($data);
}
/**
* @return array
*/
public function toArray()
{
return $this->values;
}
private static function loadPEM(string $data): array
{
$pem = PEM::fromString($data);
try {
$key = ECPrivateKey::fromPEM($pem);
return [
'kty' => 'EC',
'crv' => self::getCurve($key->namedCurve()),
'd' => Base64UrlSafe::encodeUnpadded($key->privateKeyOctets()),
'x' => Base64UrlSafe::encodeUnpadded($key->publicKey()->curvePointOctets()[0]),
'y' => Base64UrlSafe::encodeUnpadded($key->publicKey()->curvePointOctets()[1]),
];
} catch (Throwable) {
}
try {
$key = ECPublicKey::fromPEM($pem);
return [
'kty' => 'EC',
'crv' => self::getCurve($key->namedCurve()),
'x' => Base64UrlSafe::encodeUnpadded($key->curvePointOctets()[0]),
'y' => Base64UrlSafe::encodeUnpadded($key->curvePointOctets()[1]),
];
} catch (Throwable) {
}
throw new InvalidArgumentException('Unable to load the key.');
}
private static function getCurve(string $oid): string
{
$curves = self::getSupportedCurves();
$curve = array_search($oid, $curves, true);
if (! is_string($curve)) {
throw new InvalidArgumentException('Unsupported OID.');
}
return $curve;
}
private static function getSupportedCurves(): array
{
return [
'P-256' => '1.2.840.10045.3.1.7',
'P-384' => '1.3.132.0.34',
'P-521' => '1.3.132.0.35',
];
}
private function loadJWK(array $jwk): void
{
$keys = [
'kty' => 'The key parameter "kty" is missing.',
'crv' => 'Curve parameter is missing',
'x' => 'Point parameters are missing.',
'y' => 'Point parameters are missing.',
];
foreach ($keys as $k => $v) {
if (! array_key_exists($k, $jwk)) {
throw new InvalidArgumentException($v);
}
}
if ($jwk['kty'] !== 'EC') {
throw new InvalidArgumentException('JWK is not an Elliptic Curve key.');
}
$this->values = $jwk;
}
}