diff options
Diffstat (limited to '')
-rw-r--r-- | vendor/web-token/jwt-core/Util/BigInteger.php | 464 | ||||
-rw-r--r-- | vendor/web-token/jwt-core/Util/ECKey.php | 612 | ||||
-rw-r--r-- | vendor/web-token/jwt-core/Util/ECSignature.php | 186 | ||||
-rw-r--r-- | vendor/web-token/jwt-core/Util/Hash.php | 180 | ||||
-rw-r--r-- | vendor/web-token/jwt-core/Util/JsonConverter.php | 54 | ||||
-rw-r--r-- | vendor/web-token/jwt-core/Util/KeyChecker.php | 214 | ||||
-rw-r--r-- | vendor/web-token/jwt-core/Util/RSAKey.php | 644 |
7 files changed, 1177 insertions, 1177 deletions
diff --git a/vendor/web-token/jwt-core/Util/BigInteger.php b/vendor/web-token/jwt-core/Util/BigInteger.php index 2513670..3b719e6 100644 --- a/vendor/web-token/jwt-core/Util/BigInteger.php +++ b/vendor/web-token/jwt-core/Util/BigInteger.php @@ -1,232 +1,232 @@ -<?php - -declare(strict_types=1); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Spomky-Labs - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -namespace Jose\Component\Core\Util; - -/** - * @internal - */ -class BigInteger -{ - /** - * Holds the BigInteger's value. - * - * @var \GMP - */ - private $value; - - private function __construct(\GMP $value) - { - $this->value = $value; - } - - /** - * @return BigInteger - */ - public static function createFromGMPResource(\GMP $value): self - { - return new self($value); - } - - /** - * @return BigInteger - */ - public static function createFromBinaryString(string $value): self - { - $value = '0x'.\unpack('H*', $value)[1]; - $value = \gmp_init($value, 16); - - return new self($value); - } - - /** - * @return BigInteger - */ - public static function createFromDecimal(int $value): self - { - $value = \gmp_init($value, 10); - - return new self($value); - } - - /** - * Converts a BigInteger to a binary string. - */ - public function toBytes(): string - { - if (0 === \gmp_cmp($this->value, \gmp_init(0))) { - return ''; - } - - $temp = \gmp_strval(\gmp_abs($this->value), 16); - $temp = \mb_strlen($temp, '8bit') & 1 ? '0'.$temp : $temp; - $temp = \hex2bin($temp); - - return \ltrim($temp, \chr(0)); - } - - /** - * Adds two BigIntegers. - * - * @param BigInteger $y - * - * @return BigInteger - */ - public function add(self $y): self - { - $value = \gmp_add($this->value, $y->value); - - return self::createFromGMPResource($value); - } - - /** - * Subtracts two BigIntegers. - * - * @param BigInteger $y - * - * @return BigInteger - */ - public function subtract(self $y): self - { - $value = \gmp_sub($this->value, $y->value); - - return self::createFromGMPResource($value); - } - - /** - * Multiplies two BigIntegers. - * - * @param BigInteger $x - * - * @return BigInteger - */ - public function multiply(self $x): self - { - $value = \gmp_mul($this->value, $x->value); - - return self::createFromGMPResource($value); - } - - /** - * Divides two BigIntegers. - * - * @param BigInteger $x - * - * @return BigInteger - */ - public function divide(self $x): self - { - $value = \gmp_div($this->value, $x->value); - - return self::createFromGMPResource($value); - } - - /** - * Performs modular exponentiation. - * - * @param BigInteger $e - * @param BigInteger $n - * - * @return BigInteger - */ - public function modPow(self $e, self $n): self - { - $value = \gmp_powm($this->value, $e->value, $n->value); - - return self::createFromGMPResource($value); - } - - /** - * Performs modular exponentiation. - * - * @param BigInteger $d - * - * @return BigInteger - */ - public function mod(self $d): self - { - $value = \gmp_mod($this->value, $d->value); - - return self::createFromGMPResource($value); - } - - /** - * Calculates modular inverses. - * - * @param BigInteger $n - * - * @return BigInteger - */ - public function modInverse(self $n): self - { - $value = \gmp_invert($this->value, $n->value); - - return self::createFromGMPResource($value); - } - - /** - * Compares two numbers. - * - * @param BigInteger $y - */ - public function compare(self $y): int - { - return \gmp_cmp($this->value, $y->value); - } - - /** - * @param BigInteger $y - */ - public function equals(self $y): bool - { - return 0 === $this->compare($y); - } - - /** - * @param BigInteger $y - * - * @return BigInteger - */ - public static function random(self $y): self - { - $zero = self::createFromDecimal(0); - - return self::createFromGMPResource(\gmp_random_range($zero->value, $y->value)); - } - - /** - * @param BigInteger $y - * - * @return BigInteger - */ - public function gcd(self $y): self - { - return self::createFromGMPResource(\gmp_gcd($this->value, $y->value)); - } - - /** - * @param BigInteger $y - */ - public function lowerThan(self $y): bool - { - return 0 > $this->compare($y); - } - - public function isEven(): bool - { - $zero = self::createFromDecimal(0); - $two = self::createFromDecimal(2); - - return $this->mod($two)->equals($zero); - } -} +<?php
+
+declare(strict_types=1);
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2018 Spomky-Labs
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ */
+
+namespace Jose\Component\Core\Util;
+
+/**
+ * @internal
+ */
+class BigInteger
+{
+ /**
+ * Holds the BigInteger's value.
+ *
+ * @var \GMP
+ */
+ private $value;
+
+ private function __construct(\GMP $value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * @return BigInteger
+ */
+ public static function createFromGMPResource(\GMP $value): self
+ {
+ return new self($value);
+ }
+
+ /**
+ * @return BigInteger
+ */
+ public static function createFromBinaryString(string $value): self
+ {
+ $value = '0x'.\unpack('H*', $value)[1];
+ $value = \gmp_init($value, 16);
+
+ return new self($value);
+ }
+
+ /**
+ * @return BigInteger
+ */
+ public static function createFromDecimal(int $value): self
+ {
+ $value = \gmp_init($value, 10);
+
+ return new self($value);
+ }
+
+ /**
+ * Converts a BigInteger to a binary string.
+ */
+ public function toBytes(): string
+ {
+ if (0 === \gmp_cmp($this->value, \gmp_init(0))) {
+ return '';
+ }
+
+ $temp = \gmp_strval(\gmp_abs($this->value), 16);
+ $temp = \mb_strlen($temp, '8bit') & 1 ? '0'.$temp : $temp;
+ $temp = \hex2bin($temp);
+
+ return \ltrim($temp, \chr(0));
+ }
+
+ /**
+ * Adds two BigIntegers.
+ *
+ * @param BigInteger $y
+ *
+ * @return BigInteger
+ */
+ public function add(self $y): self
+ {
+ $value = \gmp_add($this->value, $y->value);
+
+ return self::createFromGMPResource($value);
+ }
+
+ /**
+ * Subtracts two BigIntegers.
+ *
+ * @param BigInteger $y
+ *
+ * @return BigInteger
+ */
+ public function subtract(self $y): self
+ {
+ $value = \gmp_sub($this->value, $y->value);
+
+ return self::createFromGMPResource($value);
+ }
+
+ /**
+ * Multiplies two BigIntegers.
+ *
+ * @param BigInteger $x
+ *
+ * @return BigInteger
+ */
+ public function multiply(self $x): self
+ {
+ $value = \gmp_mul($this->value, $x->value);
+
+ return self::createFromGMPResource($value);
+ }
+
+ /**
+ * Divides two BigIntegers.
+ *
+ * @param BigInteger $x
+ *
+ * @return BigInteger
+ */
+ public function divide(self $x): self
+ {
+ $value = \gmp_div($this->value, $x->value);
+
+ return self::createFromGMPResource($value);
+ }
+
+ /**
+ * Performs modular exponentiation.
+ *
+ * @param BigInteger $e
+ * @param BigInteger $n
+ *
+ * @return BigInteger
+ */
+ public function modPow(self $e, self $n): self
+ {
+ $value = \gmp_powm($this->value, $e->value, $n->value);
+
+ return self::createFromGMPResource($value);
+ }
+
+ /**
+ * Performs modular exponentiation.
+ *
+ * @param BigInteger $d
+ *
+ * @return BigInteger
+ */
+ public function mod(self $d): self
+ {
+ $value = \gmp_mod($this->value, $d->value);
+
+ return self::createFromGMPResource($value);
+ }
+
+ /**
+ * Calculates modular inverses.
+ *
+ * @param BigInteger $n
+ *
+ * @return BigInteger
+ */
+ public function modInverse(self $n): self
+ {
+ $value = \gmp_invert($this->value, $n->value);
+
+ return self::createFromGMPResource($value);
+ }
+
+ /**
+ * Compares two numbers.
+ *
+ * @param BigInteger $y
+ */
+ public function compare(self $y): int
+ {
+ return \gmp_cmp($this->value, $y->value);
+ }
+
+ /**
+ * @param BigInteger $y
+ */
+ public function equals(self $y): bool
+ {
+ return 0 === $this->compare($y);
+ }
+
+ /**
+ * @param BigInteger $y
+ *
+ * @return BigInteger
+ */
+ public static function random(self $y): self
+ {
+ $zero = self::createFromDecimal(0);
+
+ return self::createFromGMPResource(\gmp_random_range($zero->value, $y->value));
+ }
+
+ /**
+ * @param BigInteger $y
+ *
+ * @return BigInteger
+ */
+ public function gcd(self $y): self
+ {
+ return self::createFromGMPResource(\gmp_gcd($this->value, $y->value));
+ }
+
+ /**
+ * @param BigInteger $y
+ */
+ public function lowerThan(self $y): bool
+ {
+ return 0 > $this->compare($y);
+ }
+
+ public function isEven(): bool
+ {
+ $zero = self::createFromDecimal(0);
+ $two = self::createFromDecimal(2);
+
+ return $this->mod($two)->equals($zero);
+ }
+}
diff --git a/vendor/web-token/jwt-core/Util/ECKey.php b/vendor/web-token/jwt-core/Util/ECKey.php index da409ba..6460084 100644 --- a/vendor/web-token/jwt-core/Util/ECKey.php +++ b/vendor/web-token/jwt-core/Util/ECKey.php @@ -1,306 +1,306 @@ -<?php - -declare(strict_types=1); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Spomky-Labs - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -namespace Jose\Component\Core\Util; - -use Base64Url\Base64Url; -use InvalidArgumentException; -use Jose\Component\Core\JWK; -use Jose\Component\Core\Util\Ecc\Curve; -use Jose\Component\Core\Util\Ecc\NistCurve; -use RuntimeException; -use Throwable; - -/** - * @internal - */ -class ECKey -{ - public static function convertToPEM(JWK $jwk): string - { - if ($jwk->has('d')) { - return self::convertPrivateKeyToPEM($jwk); - } - - return self::convertPublicKeyToPEM($jwk); - } - - public static function convertPublicKeyToPEM(JWK $jwk): string - { - switch ($jwk->get('crv')) { - case 'P-256': - $der = self::p256PublicKey(); - - break; - case 'P-384': - $der = self::p384PublicKey(); - - break; - case 'P-521': - $der = self::p521PublicKey(); - - break; - default: - throw new InvalidArgumentException('Unsupported curve.'); - } - $der .= self::getKey($jwk); - $pem = '-----BEGIN PUBLIC KEY-----'.PHP_EOL; - $pem .= chunk_split(base64_encode($der), 64, PHP_EOL); - $pem .= '-----END PUBLIC KEY-----'.PHP_EOL; - - return $pem; - } - - public static function convertPrivateKeyToPEM(JWK $jwk): string - { - switch ($jwk->get('crv')) { - case 'P-256': - $der = self::p256PrivateKey($jwk); - - break; - case 'P-384': - $der = self::p384PrivateKey($jwk); - - break; - case 'P-521': - $der = self::p521PrivateKey($jwk); - - break; - default: - throw new InvalidArgumentException('Unsupported curve.'); - } - $der .= self::getKey($jwk); - $pem = '-----BEGIN EC PRIVATE KEY-----'.PHP_EOL; - $pem .= chunk_split(base64_encode($der), 64, PHP_EOL); - $pem .= '-----END EC PRIVATE KEY-----'.PHP_EOL; - - return $pem; - } - - /** - * Creates a EC key with the given curve and additional values. - * - * @param string $curve The curve - * @param array $values values to configure the key - */ - public static function createECKey(string $curve, array $values = []): JWK - { - try { - $jwk = self::createECKeyUsingOpenSSL($curve); - } catch (Throwable $e) { - $jwk = self::createECKeyUsingPurePhp($curve); - } - $values = array_merge($values, $jwk); - - return new JWK($values); - } - - private static function getNistCurve(string $curve): Curve - { - switch ($curve) { - case 'P-256': - return NistCurve::curve256(); - case 'P-384': - return NistCurve::curve384(); - case 'P-521': - return NistCurve::curve521(); - default: - throw new InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve)); - } - } - - private static function getNistCurveSize(string $curve): int - { - switch ($curve) { - case 'P-256': - return 256; - case 'P-384': - return 384; - case 'P-521': - return 521; - default: - throw new InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve)); - } - } - - private static function createECKeyUsingPurePhp(string $curve): array - { - $nistCurve = self::getNistCurve($curve); - $privateKey = $nistCurve->createPrivateKey(); - $publicKey = $nistCurve->createPublicKey($privateKey); - - return [ - 'kty' => 'EC', - 'crv' => $curve, - 'x' => Base64Url::encode(str_pad(gmp_export($publicKey->getPoint()->getX()), (int) ceil($nistCurve->getSize() / 8), "\0", STR_PAD_LEFT)), - 'y' => Base64Url::encode(str_pad(gmp_export($publicKey->getPoint()->getY()), (int) ceil($nistCurve->getSize() / 8), "\0", STR_PAD_LEFT)), - 'd' => Base64Url::encode(str_pad(gmp_export($privateKey->getSecret()), (int) ceil($nistCurve->getSize() / 8), "\0", STR_PAD_LEFT)), - ]; - } - - private static function createECKeyUsingOpenSSL(string $curve): array - { - $key = openssl_pkey_new([ - 'curve_name' => self::getOpensslCurveName($curve), - 'private_key_type' => OPENSSL_KEYTYPE_EC, - ]); - if (false === $key) { - throw new RuntimeException('Unable to create the key'); - } - $result = openssl_pkey_export($key, $out); - if (false === $result) { - throw new RuntimeException('Unable to create the key'); - } - $res = openssl_pkey_get_private($out); - if (false === $res) { - throw new RuntimeException('Unable to create the key'); - } - $details = openssl_pkey_get_details($res); - $nistCurveSize = self::getNistCurveSize($curve); - - return [ - 'kty' => 'EC', - 'crv' => $curve, - 'd' => Base64Url::encode(str_pad($details['ec']['d'], (int) ceil($nistCurveSize / 8), "\0", STR_PAD_LEFT)), - 'x' => Base64Url::encode(str_pad($details['ec']['x'], (int) ceil($nistCurveSize / 8), "\0", STR_PAD_LEFT)), - 'y' => Base64Url::encode(str_pad($details['ec']['y'], (int) ceil($nistCurveSize / 8), "\0", STR_PAD_LEFT)), - ]; - } - - private static function getOpensslCurveName(string $curve): string - { - switch ($curve) { - case 'P-256': - return 'prime256v1'; - case 'P-384': - return 'secp384r1'; - case 'P-521': - return 'secp521r1'; - default: - throw new InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve)); - } - } - - private static function p256PublicKey(): string - { - return pack( - 'H*', - '3059' // SEQUENCE, length 89 - .'3013' // SEQUENCE, length 19 - .'0607' // OID, length 7 - .'2a8648ce3d0201' // 1.2.840.10045.2.1 = EC Public Key - .'0608' // OID, length 8 - .'2a8648ce3d030107' // 1.2.840.10045.3.1.7 = P-256 Curve - .'0342' // BIT STRING, length 66 - .'00' // prepend with NUL - pubkey will follow - ); - } - - private static function p384PublicKey(): string - { - return pack( - 'H*', - '3076' // SEQUENCE, length 118 - .'3010' // SEQUENCE, length 16 - .'0607' // OID, length 7 - .'2a8648ce3d0201' // 1.2.840.10045.2.1 = EC Public Key - .'0605' // OID, length 5 - .'2b81040022' // 1.3.132.0.34 = P-384 Curve - .'0362' // BIT STRING, length 98 - .'00' // prepend with NUL - pubkey will follow - ); - } - - private static function p521PublicKey(): string - { - return pack( - 'H*', - '30819b' // SEQUENCE, length 154 - .'3010' // SEQUENCE, length 16 - .'0607' // OID, length 7 - .'2a8648ce3d0201' // 1.2.840.10045.2.1 = EC Public Key - .'0605' // OID, length 5 - .'2b81040023' // 1.3.132.0.35 = P-521 Curve - .'038186' // BIT STRING, length 134 - .'00' // prepend with NUL - pubkey will follow - ); - } - - private static function p256PrivateKey(JWK $jwk): string - { - $d = unpack('H*', str_pad(Base64Url::decode($jwk->get('d')), 32, "\0", STR_PAD_LEFT))[1]; - - return pack( - 'H*', - '3077' // SEQUENCE, length 87+length($d)=32 - .'020101' // INTEGER, 1 - .'0420' // OCTET STRING, length($d) = 32 - .$d - .'a00a' // TAGGED OBJECT #0, length 10 - .'0608' // OID, length 8 - .'2a8648ce3d030107' // 1.3.132.0.34 = P-384 Curve - .'a144' // TAGGED OBJECT #1, length 68 - .'0342' // BIT STRING, length 66 - .'00' // prepend with NUL - pubkey will follow - ); - } - - private static function p384PrivateKey(JWK $jwk): string - { - $d = unpack('H*', str_pad(Base64Url::decode($jwk->get('d')), 48, "\0", STR_PAD_LEFT))[1]; - - return pack( - 'H*', - '3081a4' // SEQUENCE, length 116 + length($d)=48 - .'020101' // INTEGER, 1 - .'0430' // OCTET STRING, length($d) = 30 - .$d - .'a007' // TAGGED OBJECT #0, length 7 - .'0605' // OID, length 5 - .'2b81040022' // 1.3.132.0.34 = P-384 Curve - .'a164' // TAGGED OBJECT #1, length 100 - .'0362' // BIT STRING, length 98 - .'00' // prepend with NUL - pubkey will follow - ); - } - - private static function p521PrivateKey(JWK $jwk): string - { - $d = unpack('H*', str_pad(Base64Url::decode($jwk->get('d')), 66, "\0", STR_PAD_LEFT))[1]; - - return pack( - 'H*', - '3081dc' // SEQUENCE, length 154 + length($d)=66 - .'020101' // INTEGER, 1 - .'0442' // OCTET STRING, length(d) = 66 - .$d - .'a007' // TAGGED OBJECT #0, length 7 - .'0605' // OID, length 5 - .'2b81040023' // 1.3.132.0.35 = P-521 Curve - .'a18189' // TAGGED OBJECT #1, length 137 - .'038186' // BIT STRING, length 134 - .'00' // prepend with NUL - pubkey will follow - ); - } - - private static function getKey(JWK $jwk): string - { - $nistCurveSize = self::getNistCurveSize($jwk->get('crv')); - $length = (int) ceil($nistCurveSize / 8); - - return - "\04" - .str_pad(Base64Url::decode($jwk->get('x')), $length, "\0", STR_PAD_LEFT) - .str_pad(Base64Url::decode($jwk->get('y')), $length, "\0", STR_PAD_LEFT); - } -} +<?php
+
+declare(strict_types=1);
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2018 Spomky-Labs
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ */
+
+namespace Jose\Component\Core\Util;
+
+use Base64Url\Base64Url;
+use InvalidArgumentException;
+use Jose\Component\Core\JWK;
+use Jose\Component\Core\Util\Ecc\Curve;
+use Jose\Component\Core\Util\Ecc\NistCurve;
+use RuntimeException;
+use Throwable;
+
+/**
+ * @internal
+ */
+class ECKey
+{
+ public static function convertToPEM(JWK $jwk): string
+ {
+ if ($jwk->has('d')) {
+ return self::convertPrivateKeyToPEM($jwk);
+ }
+
+ return self::convertPublicKeyToPEM($jwk);
+ }
+
+ public static function convertPublicKeyToPEM(JWK $jwk): string
+ {
+ switch ($jwk->get('crv')) {
+ case 'P-256':
+ $der = self::p256PublicKey();
+
+ break;
+ case 'P-384':
+ $der = self::p384PublicKey();
+
+ break;
+ case 'P-521':
+ $der = self::p521PublicKey();
+
+ break;
+ default:
+ throw new InvalidArgumentException('Unsupported curve.');
+ }
+ $der .= self::getKey($jwk);
+ $pem = '-----BEGIN PUBLIC KEY-----'.PHP_EOL;
+ $pem .= chunk_split(base64_encode($der), 64, PHP_EOL);
+ $pem .= '-----END PUBLIC KEY-----'.PHP_EOL;
+
+ return $pem;
+ }
+
+ public static function convertPrivateKeyToPEM(JWK $jwk): string
+ {
+ switch ($jwk->get('crv')) {
+ case 'P-256':
+ $der = self::p256PrivateKey($jwk);
+
+ break;
+ case 'P-384':
+ $der = self::p384PrivateKey($jwk);
+
+ break;
+ case 'P-521':
+ $der = self::p521PrivateKey($jwk);
+
+ break;
+ default:
+ throw new InvalidArgumentException('Unsupported curve.');
+ }
+ $der .= self::getKey($jwk);
+ $pem = '-----BEGIN EC PRIVATE KEY-----'.PHP_EOL;
+ $pem .= chunk_split(base64_encode($der), 64, PHP_EOL);
+ $pem .= '-----END EC PRIVATE KEY-----'.PHP_EOL;
+
+ return $pem;
+ }
+
+ /**
+ * Creates a EC key with the given curve and additional values.
+ *
+ * @param string $curve The curve
+ * @param array $values values to configure the key
+ */
+ public static function createECKey(string $curve, array $values = []): JWK
+ {
+ try {
+ $jwk = self::createECKeyUsingOpenSSL($curve);
+ } catch (Throwable $e) {
+ $jwk = self::createECKeyUsingPurePhp($curve);
+ }
+ $values = array_merge($values, $jwk);
+
+ return new JWK($values);
+ }
+
+ private static function getNistCurve(string $curve): Curve
+ {
+ switch ($curve) {
+ case 'P-256':
+ return NistCurve::curve256();
+ case 'P-384':
+ return NistCurve::curve384();
+ case 'P-521':
+ return NistCurve::curve521();
+ default:
+ throw new InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve));
+ }
+ }
+
+ private static function getNistCurveSize(string $curve): int
+ {
+ switch ($curve) {
+ case 'P-256':
+ return 256;
+ case 'P-384':
+ return 384;
+ case 'P-521':
+ return 521;
+ default:
+ throw new InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve));
+ }
+ }
+
+ private static function createECKeyUsingPurePhp(string $curve): array
+ {
+ $nistCurve = self::getNistCurve($curve);
+ $privateKey = $nistCurve->createPrivateKey();
+ $publicKey = $nistCurve->createPublicKey($privateKey);
+
+ return [
+ 'kty' => 'EC',
+ 'crv' => $curve,
+ 'x' => Base64Url::encode(str_pad(gmp_export($publicKey->getPoint()->getX()), (int) ceil($nistCurve->getSize() / 8), "\0", STR_PAD_LEFT)),
+ 'y' => Base64Url::encode(str_pad(gmp_export($publicKey->getPoint()->getY()), (int) ceil($nistCurve->getSize() / 8), "\0", STR_PAD_LEFT)),
+ 'd' => Base64Url::encode(str_pad(gmp_export($privateKey->getSecret()), (int) ceil($nistCurve->getSize() / 8), "\0", STR_PAD_LEFT)),
+ ];
+ }
+
+ private static function createECKeyUsingOpenSSL(string $curve): array
+ {
+ $key = openssl_pkey_new([
+ 'curve_name' => self::getOpensslCurveName($curve),
+ 'private_key_type' => OPENSSL_KEYTYPE_EC,
+ ]);
+ if (false === $key) {
+ throw new RuntimeException('Unable to create the key');
+ }
+ $result = openssl_pkey_export($key, $out);
+ if (false === $result) {
+ throw new RuntimeException('Unable to create the key');
+ }
+ $res = openssl_pkey_get_private($out);
+ if (false === $res) {
+ throw new RuntimeException('Unable to create the key');
+ }
+ $details = openssl_pkey_get_details($res);
+ $nistCurveSize = self::getNistCurveSize($curve);
+
+ return [
+ 'kty' => 'EC',
+ 'crv' => $curve,
+ 'd' => Base64Url::encode(str_pad($details['ec']['d'], (int) ceil($nistCurveSize / 8), "\0", STR_PAD_LEFT)),
+ 'x' => Base64Url::encode(str_pad($details['ec']['x'], (int) ceil($nistCurveSize / 8), "\0", STR_PAD_LEFT)),
+ 'y' => Base64Url::encode(str_pad($details['ec']['y'], (int) ceil($nistCurveSize / 8), "\0", STR_PAD_LEFT)),
+ ];
+ }
+
+ private static function getOpensslCurveName(string $curve): string
+ {
+ switch ($curve) {
+ case 'P-256':
+ return 'prime256v1';
+ case 'P-384':
+ return 'secp384r1';
+ case 'P-521':
+ return 'secp521r1';
+ default:
+ throw new InvalidArgumentException(sprintf('The curve "%s" is not supported.', $curve));
+ }
+ }
+
+ private static function p256PublicKey(): string
+ {
+ return pack(
+ 'H*',
+ '3059' // SEQUENCE, length 89
+ .'3013' // SEQUENCE, length 19
+ .'0607' // OID, length 7
+ .'2a8648ce3d0201' // 1.2.840.10045.2.1 = EC Public Key
+ .'0608' // OID, length 8
+ .'2a8648ce3d030107' // 1.2.840.10045.3.1.7 = P-256 Curve
+ .'0342' // BIT STRING, length 66
+ .'00' // prepend with NUL - pubkey will follow
+ );
+ }
+
+ private static function p384PublicKey(): string
+ {
+ return pack(
+ 'H*',
+ '3076' // SEQUENCE, length 118
+ .'3010' // SEQUENCE, length 16
+ .'0607' // OID, length 7
+ .'2a8648ce3d0201' // 1.2.840.10045.2.1 = EC Public Key
+ .'0605' // OID, length 5
+ .'2b81040022' // 1.3.132.0.34 = P-384 Curve
+ .'0362' // BIT STRING, length 98
+ .'00' // prepend with NUL - pubkey will follow
+ );
+ }
+
+ private static function p521PublicKey(): string
+ {
+ return pack(
+ 'H*',
+ '30819b' // SEQUENCE, length 154
+ .'3010' // SEQUENCE, length 16
+ .'0607' // OID, length 7
+ .'2a8648ce3d0201' // 1.2.840.10045.2.1 = EC Public Key
+ .'0605' // OID, length 5
+ .'2b81040023' // 1.3.132.0.35 = P-521 Curve
+ .'038186' // BIT STRING, length 134
+ .'00' // prepend with NUL - pubkey will follow
+ );
+ }
+
+ private static function p256PrivateKey(JWK $jwk): string
+ {
+ $d = unpack('H*', str_pad(Base64Url::decode($jwk->get('d')), 32, "\0", STR_PAD_LEFT))[1];
+
+ return pack(
+ 'H*',
+ '3077' // SEQUENCE, length 87+length($d)=32
+ .'020101' // INTEGER, 1
+ .'0420' // OCTET STRING, length($d) = 32
+ .$d
+ .'a00a' // TAGGED OBJECT #0, length 10
+ .'0608' // OID, length 8
+ .'2a8648ce3d030107' // 1.3.132.0.34 = P-384 Curve
+ .'a144' // TAGGED OBJECT #1, length 68
+ .'0342' // BIT STRING, length 66
+ .'00' // prepend with NUL - pubkey will follow
+ );
+ }
+
+ private static function p384PrivateKey(JWK $jwk): string
+ {
+ $d = unpack('H*', str_pad(Base64Url::decode($jwk->get('d')), 48, "\0", STR_PAD_LEFT))[1];
+
+ return pack(
+ 'H*',
+ '3081a4' // SEQUENCE, length 116 + length($d)=48
+ .'020101' // INTEGER, 1
+ .'0430' // OCTET STRING, length($d) = 30
+ .$d
+ .'a007' // TAGGED OBJECT #0, length 7
+ .'0605' // OID, length 5
+ .'2b81040022' // 1.3.132.0.34 = P-384 Curve
+ .'a164' // TAGGED OBJECT #1, length 100
+ .'0362' // BIT STRING, length 98
+ .'00' // prepend with NUL - pubkey will follow
+ );
+ }
+
+ private static function p521PrivateKey(JWK $jwk): string
+ {
+ $d = unpack('H*', str_pad(Base64Url::decode($jwk->get('d')), 66, "\0", STR_PAD_LEFT))[1];
+
+ return pack(
+ 'H*',
+ '3081dc' // SEQUENCE, length 154 + length($d)=66
+ .'020101' // INTEGER, 1
+ .'0442' // OCTET STRING, length(d) = 66
+ .$d
+ .'a007' // TAGGED OBJECT #0, length 7
+ .'0605' // OID, length 5
+ .'2b81040023' // 1.3.132.0.35 = P-521 Curve
+ .'a18189' // TAGGED OBJECT #1, length 137
+ .'038186' // BIT STRING, length 134
+ .'00' // prepend with NUL - pubkey will follow
+ );
+ }
+
+ private static function getKey(JWK $jwk): string
+ {
+ $nistCurveSize = self::getNistCurveSize($jwk->get('crv'));
+ $length = (int) ceil($nistCurveSize / 8);
+
+ return
+ "\04"
+ .str_pad(Base64Url::decode($jwk->get('x')), $length, "\0", STR_PAD_LEFT)
+ .str_pad(Base64Url::decode($jwk->get('y')), $length, "\0", STR_PAD_LEFT);
+ }
+}
diff --git a/vendor/web-token/jwt-core/Util/ECSignature.php b/vendor/web-token/jwt-core/Util/ECSignature.php index 5bfa5b0..14cb15d 100644 --- a/vendor/web-token/jwt-core/Util/ECSignature.php +++ b/vendor/web-token/jwt-core/Util/ECSignature.php @@ -1,93 +1,93 @@ -<?php - -declare(strict_types=1); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Spomky-Labs - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -namespace Jose\Component\Core\Util; - -/** - * @internal - */ -class ECSignature -{ - public static function toDER(string $signature, int $partLength): string - { - $signature = \unpack('H*', $signature)[1]; - if (\mb_strlen($signature, '8bit') !== 2 * $partLength) { - throw new \InvalidArgumentException('Invalid length.'); - } - $R = \mb_substr($signature, 0, $partLength, '8bit'); - $S = \mb_substr($signature, $partLength, null, '8bit'); - - $R = self::preparePositiveInteger($R); - $Rl = \mb_strlen($R, '8bit') / 2; - $S = self::preparePositiveInteger($S); - $Sl = \mb_strlen($S, '8bit') / 2; - $der = \pack('H*', - '30'.($Rl + $Sl + 4 > 128 ? '81' : '').\dechex($Rl + $Sl + 4) - .'02'.\dechex($Rl).$R - .'02'.\dechex($Sl).$S - ); - - return $der; - } - - public static function fromDER(string $der, int $partLength): string - { - $hex = \unpack('H*', $der)[1]; - if ('30' !== \mb_substr($hex, 0, 2, '8bit')) { // SEQUENCE - throw new \RuntimeException(); - } - if ('81' === \mb_substr($hex, 2, 2, '8bit')) { // LENGTH > 128 - $hex = \mb_substr($hex, 6, null, '8bit'); - } else { - $hex = \mb_substr($hex, 4, null, '8bit'); - } - if ('02' !== \mb_substr($hex, 0, 2, '8bit')) { // INTEGER - throw new \RuntimeException(); - } - - $Rl = \hexdec(\mb_substr($hex, 2, 2, '8bit')); - $R = self::retrievePositiveInteger(\mb_substr($hex, 4, $Rl * 2, '8bit')); - $R = \str_pad($R, $partLength, '0', STR_PAD_LEFT); - - $hex = \mb_substr($hex, 4 + $Rl * 2, null, '8bit'); - if ('02' !== \mb_substr($hex, 0, 2, '8bit')) { // INTEGER - throw new \RuntimeException(); - } - $Sl = \hexdec(\mb_substr($hex, 2, 2, '8bit')); - $S = self::retrievePositiveInteger(\mb_substr($hex, 4, $Sl * 2, '8bit')); - $S = \str_pad($S, $partLength, '0', STR_PAD_LEFT); - - return \pack('H*', $R.$S); - } - - private static function preparePositiveInteger(string $data): string - { - if (\mb_substr($data, 0, 2, '8bit') > '7f') { - return '00'.$data; - } - while ('00' === \mb_substr($data, 0, 2, '8bit') && \mb_substr($data, 2, 2, '8bit') <= '7f') { - $data = \mb_substr($data, 2, null, '8bit'); - } - - return $data; - } - - private static function retrievePositiveInteger(string $data): string - { - while ('00' === \mb_substr($data, 0, 2, '8bit') && \mb_substr($data, 2, 2, '8bit') > '7f') { - $data = \mb_substr($data, 2, null, '8bit'); - } - - return $data; - } -} +<?php
+
+declare(strict_types=1);
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2018 Spomky-Labs
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ */
+
+namespace Jose\Component\Core\Util;
+
+/**
+ * @internal
+ */
+class ECSignature
+{
+ public static function toDER(string $signature, int $partLength): string
+ {
+ $signature = \unpack('H*', $signature)[1];
+ if (\mb_strlen($signature, '8bit') !== 2 * $partLength) {
+ throw new \InvalidArgumentException('Invalid length.');
+ }
+ $R = \mb_substr($signature, 0, $partLength, '8bit');
+ $S = \mb_substr($signature, $partLength, null, '8bit');
+
+ $R = self::preparePositiveInteger($R);
+ $Rl = \mb_strlen($R, '8bit') / 2;
+ $S = self::preparePositiveInteger($S);
+ $Sl = \mb_strlen($S, '8bit') / 2;
+ $der = \pack('H*',
+ '30'.($Rl + $Sl + 4 > 128 ? '81' : '').\dechex($Rl + $Sl + 4)
+ .'02'.\dechex($Rl).$R
+ .'02'.\dechex($Sl).$S
+ );
+
+ return $der;
+ }
+
+ public static function fromDER(string $der, int $partLength): string
+ {
+ $hex = \unpack('H*', $der)[1];
+ if ('30' !== \mb_substr($hex, 0, 2, '8bit')) { // SEQUENCE
+ throw new \RuntimeException();
+ }
+ if ('81' === \mb_substr($hex, 2, 2, '8bit')) { // LENGTH > 128
+ $hex = \mb_substr($hex, 6, null, '8bit');
+ } else {
+ $hex = \mb_substr($hex, 4, null, '8bit');
+ }
+ if ('02' !== \mb_substr($hex, 0, 2, '8bit')) { // INTEGER
+ throw new \RuntimeException();
+ }
+
+ $Rl = \hexdec(\mb_substr($hex, 2, 2, '8bit'));
+ $R = self::retrievePositiveInteger(\mb_substr($hex, 4, $Rl * 2, '8bit'));
+ $R = \str_pad($R, $partLength, '0', STR_PAD_LEFT);
+
+ $hex = \mb_substr($hex, 4 + $Rl * 2, null, '8bit');
+ if ('02' !== \mb_substr($hex, 0, 2, '8bit')) { // INTEGER
+ throw new \RuntimeException();
+ }
+ $Sl = \hexdec(\mb_substr($hex, 2, 2, '8bit'));
+ $S = self::retrievePositiveInteger(\mb_substr($hex, 4, $Sl * 2, '8bit'));
+ $S = \str_pad($S, $partLength, '0', STR_PAD_LEFT);
+
+ return \pack('H*', $R.$S);
+ }
+
+ private static function preparePositiveInteger(string $data): string
+ {
+ if (\mb_substr($data, 0, 2, '8bit') > '7f') {
+ return '00'.$data;
+ }
+ while ('00' === \mb_substr($data, 0, 2, '8bit') && \mb_substr($data, 2, 2, '8bit') <= '7f') {
+ $data = \mb_substr($data, 2, null, '8bit');
+ }
+
+ return $data;
+ }
+
+ private static function retrievePositiveInteger(string $data): string
+ {
+ while ('00' === \mb_substr($data, 0, 2, '8bit') && \mb_substr($data, 2, 2, '8bit') > '7f') {
+ $data = \mb_substr($data, 2, null, '8bit');
+ }
+
+ return $data;
+ }
+}
diff --git a/vendor/web-token/jwt-core/Util/Hash.php b/vendor/web-token/jwt-core/Util/Hash.php index 105c865..ecf0438 100644 --- a/vendor/web-token/jwt-core/Util/Hash.php +++ b/vendor/web-token/jwt-core/Util/Hash.php @@ -1,90 +1,90 @@ -<?php - -declare(strict_types=1); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Spomky-Labs - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -namespace Jose\Component\Core\Util; - -/** - * @internal - */ -class Hash -{ - /** - * Hash Parameter. - * - * @var string - */ - private $hash; - - /** - * Hash Length. - * - * @var int - */ - private $length; - - /** - * @return Hash - */ - public static function sha1(): self - { - return new self('sha1', 20); - } - - /** - * @return Hash - */ - public static function sha256(): self - { - return new self('sha256', 32); - } - - /** - * @return Hash - */ - public static function sha384(): self - { - return new self('sha384', 48); - } - - /** - * @return Hash - */ - public static function sha512(): self - { - return new self('sha512', 64); - } - - private function __construct(string $hash, int $length) - { - $this->hash = $hash; - $this->length = $length; - } - - public function getLength(): int - { - return $this->length; - } - - /** - * Compute the HMAC. - */ - public function hash(string $text): string - { - return \hash($this->hash, $text, true); - } - - public function name(): string - { - return $this->hash; - } -} +<?php
+
+declare(strict_types=1);
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2018 Spomky-Labs
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ */
+
+namespace Jose\Component\Core\Util;
+
+/**
+ * @internal
+ */
+class Hash
+{
+ /**
+ * Hash Parameter.
+ *
+ * @var string
+ */
+ private $hash;
+
+ /**
+ * Hash Length.
+ *
+ * @var int
+ */
+ private $length;
+
+ /**
+ * @return Hash
+ */
+ public static function sha1(): self
+ {
+ return new self('sha1', 20);
+ }
+
+ /**
+ * @return Hash
+ */
+ public static function sha256(): self
+ {
+ return new self('sha256', 32);
+ }
+
+ /**
+ * @return Hash
+ */
+ public static function sha384(): self
+ {
+ return new self('sha384', 48);
+ }
+
+ /**
+ * @return Hash
+ */
+ public static function sha512(): self
+ {
+ return new self('sha512', 64);
+ }
+
+ private function __construct(string $hash, int $length)
+ {
+ $this->hash = $hash;
+ $this->length = $length;
+ }
+
+ public function getLength(): int
+ {
+ return $this->length;
+ }
+
+ /**
+ * Compute the HMAC.
+ */
+ public function hash(string $text): string
+ {
+ return \hash($this->hash, $text, true);
+ }
+
+ public function name(): string
+ {
+ return $this->hash;
+ }
+}
diff --git a/vendor/web-token/jwt-core/Util/JsonConverter.php b/vendor/web-token/jwt-core/Util/JsonConverter.php index ef95126..2d1faad 100644 --- a/vendor/web-token/jwt-core/Util/JsonConverter.php +++ b/vendor/web-token/jwt-core/Util/JsonConverter.php @@ -1,27 +1,27 @@ -<?php - -declare(strict_types=1); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Spomky-Labs - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -namespace Jose\Component\Core\Util; - -final class JsonConverter -{ - public static function encode($payload): string - { - return \json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } - - public static function decode(string $payload) - { - return \json_decode($payload, true, 512, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } -} +<?php
+
+declare(strict_types=1);
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2018 Spomky-Labs
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ */
+
+namespace Jose\Component\Core\Util;
+
+final class JsonConverter
+{
+ public static function encode($payload): string
+ {
+ return \json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+ }
+
+ public static function decode(string $payload)
+ {
+ return \json_decode($payload, true, 512, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+ }
+}
diff --git a/vendor/web-token/jwt-core/Util/KeyChecker.php b/vendor/web-token/jwt-core/Util/KeyChecker.php index 09385a4..38cf581 100644 --- a/vendor/web-token/jwt-core/Util/KeyChecker.php +++ b/vendor/web-token/jwt-core/Util/KeyChecker.php @@ -1,107 +1,107 @@ -<?php - -declare(strict_types=1); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Spomky-Labs - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -namespace Jose\Component\Core\Util; - -use Jose\Component\Core\JWK; - -/** - * @internal - */ -class KeyChecker -{ - /** - * @throws \InvalidArgumentException - */ - public static function checkKeyUsage(JWK $key, string $usage): bool - { - if ($key->has('use')) { - return self::checkUsage($key, $usage); - } - if ($key->has('key_ops')) { - return self::checkOperation($key, $usage); - } - - return true; - } - - private static function checkOperation(JWK $key, string $usage): bool - { - $ops = $key->get('key_ops'); - if (!\is_array($ops)) { - $ops = [$ops]; - } - switch ($usage) { - case 'verification': - if (!\in_array('verify', $ops, true)) { - throw new \InvalidArgumentException('Key cannot be used to verify a signature'); - } - - return true; - case 'signature': - if (!\in_array('sign', $ops, true)) { - throw new \InvalidArgumentException('Key cannot be used to sign'); - } - - return true; - case 'encryption': - if (!\in_array('encrypt', $ops, true) && !\in_array('wrapKey', $ops, true)) { - throw new \InvalidArgumentException('Key cannot be used to encrypt'); - } - - return true; - case 'decryption': - if (!\in_array('decrypt', $ops, true) && !\in_array('unwrapKey', $ops, true)) { - throw new \InvalidArgumentException('Key cannot be used to decrypt'); - } - - return true; - default: - throw new \InvalidArgumentException('Unsupported key usage.'); - } - } - - private static function checkUsage(JWK $key, string $usage): bool - { - $use = $key->get('use'); - switch ($usage) { - case 'verification': - case 'signature': - if ('sig' !== $use) { - throw new \InvalidArgumentException('Key cannot be used to sign or verify a signature.'); - } - - return true; - case 'encryption': - case 'decryption': - if ('enc' !== $use) { - throw new \InvalidArgumentException('Key cannot be used to encrypt or decrypt.'); - } - - return true; - default: - throw new \InvalidArgumentException('Unsupported key usage.'); - } - } - - public static function checkKeyAlgorithm(JWK $key, string $algorithm) - { - if (!$key->has('alg')) { - return; - } - - if ($key->get('alg') !== $algorithm) { - throw new \InvalidArgumentException(\sprintf('Key is only allowed for algorithm "%s".', $key->get('alg'))); - } - } -} +<?php
+
+declare(strict_types=1);
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2018 Spomky-Labs
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ */
+
+namespace Jose\Component\Core\Util;
+
+use Jose\Component\Core\JWK;
+
+/**
+ * @internal
+ */
+class KeyChecker
+{
+ /**
+ * @throws \InvalidArgumentException
+ */
+ public static function checkKeyUsage(JWK $key, string $usage): bool
+ {
+ if ($key->has('use')) {
+ return self::checkUsage($key, $usage);
+ }
+ if ($key->has('key_ops')) {
+ return self::checkOperation($key, $usage);
+ }
+
+ return true;
+ }
+
+ private static function checkOperation(JWK $key, string $usage): bool
+ {
+ $ops = $key->get('key_ops');
+ if (!\is_array($ops)) {
+ $ops = [$ops];
+ }
+ switch ($usage) {
+ case 'verification':
+ if (!\in_array('verify', $ops, true)) {
+ throw new \InvalidArgumentException('Key cannot be used to verify a signature');
+ }
+
+ return true;
+ case 'signature':
+ if (!\in_array('sign', $ops, true)) {
+ throw new \InvalidArgumentException('Key cannot be used to sign');
+ }
+
+ return true;
+ case 'encryption':
+ if (!\in_array('encrypt', $ops, true) && !\in_array('wrapKey', $ops, true)) {
+ throw new \InvalidArgumentException('Key cannot be used to encrypt');
+ }
+
+ return true;
+ case 'decryption':
+ if (!\in_array('decrypt', $ops, true) && !\in_array('unwrapKey', $ops, true)) {
+ throw new \InvalidArgumentException('Key cannot be used to decrypt');
+ }
+
+ return true;
+ default:
+ throw new \InvalidArgumentException('Unsupported key usage.');
+ }
+ }
+
+ private static function checkUsage(JWK $key, string $usage): bool
+ {
+ $use = $key->get('use');
+ switch ($usage) {
+ case 'verification':
+ case 'signature':
+ if ('sig' !== $use) {
+ throw new \InvalidArgumentException('Key cannot be used to sign or verify a signature.');
+ }
+
+ return true;
+ case 'encryption':
+ case 'decryption':
+ if ('enc' !== $use) {
+ throw new \InvalidArgumentException('Key cannot be used to encrypt or decrypt.');
+ }
+
+ return true;
+ default:
+ throw new \InvalidArgumentException('Unsupported key usage.');
+ }
+ }
+
+ public static function checkKeyAlgorithm(JWK $key, string $algorithm)
+ {
+ if (!$key->has('alg')) {
+ return;
+ }
+
+ if ($key->get('alg') !== $algorithm) {
+ throw new \InvalidArgumentException(\sprintf('Key is only allowed for algorithm "%s".', $key->get('alg')));
+ }
+ }
+}
diff --git a/vendor/web-token/jwt-core/Util/RSAKey.php b/vendor/web-token/jwt-core/Util/RSAKey.php index 3670034..8f6a0d6 100644 --- a/vendor/web-token/jwt-core/Util/RSAKey.php +++ b/vendor/web-token/jwt-core/Util/RSAKey.php @@ -1,322 +1,322 @@ -<?php - -declare(strict_types=1); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2018 Spomky-Labs - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -namespace Jose\Component\Core\Util; - -use Base64Url\Base64Url; -use FG\ASN1\Universal\BitString; -use FG\ASN1\Universal\Integer; -use FG\ASN1\Universal\NullObject; -use FG\ASN1\Universal\ObjectIdentifier; -use FG\ASN1\Universal\OctetString; -use FG\ASN1\Universal\Sequence; -use Jose\Component\Core\JWK; - -/** - * @internal - */ -class RSAKey -{ - /** - * @var Sequence - */ - private $sequence; - - /** - * @var bool - */ - private $private = false; - - /** - * @var array - */ - private $values = []; - - /** - * @var BigInteger - */ - private $modulus; - - /** - * @var int - */ - private $modulus_length; - - /** - * @var BigInteger - */ - private $public_exponent; - - /** - * @var BigInteger|null - */ - private $private_exponent = null; - - /** - * @var BigInteger[] - */ - private $primes = []; - - /** - * @var BigInteger[] - */ - private $exponents = []; - - /** - * @var BigInteger|null - */ - private $coefficient = null; - - private function __construct(JWK $data) - { - $this->loadJWK($data->all()); - $this->populateBigIntegers(); - $this->private = \array_key_exists('d', $this->values); - } - - /** - * @return RSAKey - */ - public static function createFromJWK(JWK $jwk): self - { - return new self($jwk); - } - - public function getModulus(): BigInteger - { - return $this->modulus; - } - - public function getModulusLength(): int - { - return $this->modulus_length; - } - - public function getExponent(): BigInteger - { - $d = $this->getPrivateExponent(); - if (null !== $d) { - return $d; - } - - return $this->getPublicExponent(); - } - - public function getPublicExponent(): BigInteger - { - return $this->public_exponent; - } - - public function getPrivateExponent(): ?BigInteger - { - return $this->private_exponent; - } - - /** - * @return BigInteger[] - */ - public function getPrimes(): array - { - return $this->primes; - } - - /** - * @return BigInteger[] - */ - public function getExponents(): array - { - return $this->exponents; - } - - public function getCoefficient(): ?BigInteger - { - return $this->coefficient; - } - - public function isPublic(): bool - { - return !\array_key_exists('d', $this->values); - } - - /** - * @param RSAKey $private - * - * @return RSAKey - */ - public static function toPublic(self $private): self - { - $data = $private->toArray(); - $keys = ['p', 'd', 'q', 'dp', 'dq', 'qi']; - foreach ($keys as $key) { - if (\array_key_exists($key, $data)) { - unset($data[$key]); - } - } - - return new self(new JWK($data)); - } - - public function toArray(): array - { - return $this->values; - } - - private function loadJWK(array $jwk) - { - if (!\array_key_exists('kty', $jwk)) { - throw new \InvalidArgumentException('The key parameter "kty" is missing.'); - } - if ('RSA' !== $jwk['kty']) { - throw new \InvalidArgumentException('The JWK is not a RSA key.'); - } - - $this->values = $jwk; - } - - private function populateBigIntegers() - { - $this->modulus = $this->convertBase64StringToBigInteger($this->values['n']); - $this->modulus_length = \mb_strlen($this->getModulus()->toBytes(), '8bit'); - $this->public_exponent = $this->convertBase64StringToBigInteger($this->values['e']); - - if (!$this->isPublic()) { - $this->private_exponent = $this->convertBase64StringToBigInteger($this->values['d']); - - if (\array_key_exists('p', $this->values) && \array_key_exists('q', $this->values)) { - $this->primes = [ - $this->convertBase64StringToBigInteger($this->values['p']), - $this->convertBase64StringToBigInteger($this->values['q']), - ]; - if (\array_key_exists('dp', $this->values) && \array_key_exists('dq', $this->values) && \array_key_exists('qi', $this->values)) { - $this->exponents = [ - $this->convertBase64StringToBigInteger($this->values['dp']), - $this->convertBase64StringToBigInteger($this->values['dq']), - ]; - $this->coefficient = $this->convertBase64StringToBigInteger($this->values['qi']); - } - } - } - } - - private function convertBase64StringToBigInteger(string $value): BigInteger - { - return BigInteger::createFromBinaryString(Base64Url::decode($value)); - } - - /** - * @throws \Exception - */ - public function toPEM(): string - { - if (null === $this->sequence) { - $this->sequence = new Sequence(); - if (\array_key_exists('d', $this->values)) { - $this->initPrivateKey(); - } else { - $this->initPublicKey(); - } - } - $result = '-----BEGIN '.($this->private ? 'RSA PRIVATE' : 'PUBLIC').' KEY-----'.PHP_EOL; - $result .= \chunk_split(\base64_encode($this->sequence->getBinary()), 64, PHP_EOL); - $result .= '-----END '.($this->private ? 'RSA PRIVATE' : 'PUBLIC').' KEY-----'.PHP_EOL; - - return $result; - } - - /** - * @throws \Exception - */ - private function initPublicKey() - { - $oid_sequence = new Sequence(); - $oid_sequence->addChild(new ObjectIdentifier('1.2.840.113549.1.1.1')); - $oid_sequence->addChild(new NullObject()); - $this->sequence->addChild($oid_sequence); - $n = new Integer($this->fromBase64ToInteger($this->values['n'])); - $e = new Integer($this->fromBase64ToInteger($this->values['e'])); - $key_sequence = new Sequence(); - $key_sequence->addChild($n); - $key_sequence->addChild($e); - $key_bit_string = new BitString(\bin2hex($key_sequence->getBinary())); - $this->sequence->addChild($key_bit_string); - } - - private function initPrivateKey() - { - $this->sequence->addChild(new Integer(0)); - $oid_sequence = new Sequence(); - $oid_sequence->addChild(new ObjectIdentifier('1.2.840.113549.1.1.1')); - $oid_sequence->addChild(new NullObject()); - $this->sequence->addChild($oid_sequence); - $v = new Integer(0); - $n = new Integer($this->fromBase64ToInteger($this->values['n'])); - $e = new Integer($this->fromBase64ToInteger($this->values['e'])); - $d = new Integer($this->fromBase64ToInteger($this->values['d'])); - $p = new Integer($this->fromBase64ToInteger($this->values['p'])); - $q = new Integer($this->fromBase64ToInteger($this->values['q'])); - $dp = \array_key_exists('dp', $this->values) ? new Integer($this->fromBase64ToInteger($this->values['dp'])) : new Integer(0); - $dq = \array_key_exists('dq', $this->values) ? new Integer($this->fromBase64ToInteger($this->values['dq'])) : new Integer(0); - $qi = \array_key_exists('qi', $this->values) ? new Integer($this->fromBase64ToInteger($this->values['qi'])) : new Integer(0); - $key_sequence = new Sequence(); - $key_sequence->addChild($v); - $key_sequence->addChild($n); - $key_sequence->addChild($e); - $key_sequence->addChild($d); - $key_sequence->addChild($p); - $key_sequence->addChild($q); - $key_sequence->addChild($dp); - $key_sequence->addChild($dq); - $key_sequence->addChild($qi); - $key_octet_string = new OctetString(\bin2hex($key_sequence->getBinary())); - $this->sequence->addChild($key_octet_string); - } - - /** - * @param string $value - * - * @return string - */ - private function fromBase64ToInteger($value) - { - return \gmp_strval(\gmp_init(\current(\unpack('H*', Base64Url::decode($value))), 16), 10); - } - - /** - * Exponentiate with or without Chinese Remainder Theorem. - * Operation with primes 'p' and 'q' is appox. 2x faster. - * - * @param RSAKey $key - */ - public static function exponentiate(self $key, BigInteger $c): BigInteger - { - if ($c->compare(BigInteger::createFromDecimal(0)) < 0 || $c->compare($key->getModulus()) > 0) { - throw new \RuntimeException(); - } - if ($key->isPublic() || empty($key->getPrimes()) || empty($key->getExponents()) || null === $key->getCoefficient()) { - return $c->modPow($key->getExponent(), $key->getModulus()); - } - - $p = $key->getPrimes()[0]; - $q = $key->getPrimes()[1]; - $dP = $key->getExponents()[0]; - $dQ = $key->getExponents()[1]; - $qInv = $key->getCoefficient(); - - $m1 = $c->modPow($dP, $p); - $m2 = $c->modPow($dQ, $q); - $h = $qInv->multiply($m1->subtract($m2)->add($p))->mod($p); - $m = $m2->add($h->multiply($q)); - - return $m; - } -} +<?php
+
+declare(strict_types=1);
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2018 Spomky-Labs
+ *
+ * This software may be modified and distributed under the terms
+ * of the MIT license. See the LICENSE file for details.
+ */
+
+namespace Jose\Component\Core\Util;
+
+use Base64Url\Base64Url;
+use FG\ASN1\Universal\BitString;
+use FG\ASN1\Universal\Integer;
+use FG\ASN1\Universal\NullObject;
+use FG\ASN1\Universal\ObjectIdentifier;
+use FG\ASN1\Universal\OctetString;
+use FG\ASN1\Universal\Sequence;
+use Jose\Component\Core\JWK;
+
+/**
+ * @internal
+ */
+class RSAKey
+{
+ /**
+ * @var Sequence
+ */
+ private $sequence;
+
+ /**
+ * @var bool
+ */
+ private $private = false;
+
+ /**
+ * @var array
+ */
+ private $values = [];
+
+ /**
+ * @var BigInteger
+ */
+ private $modulus;
+
+ /**
+ * @var int
+ */
+ private $modulus_length;
+
+ /**
+ * @var BigInteger
+ */
+ private $public_exponent;
+
+ /**
+ * @var BigInteger|null
+ */
+ private $private_exponent = null;
+
+ /**
+ * @var BigInteger[]
+ */
+ private $primes = [];
+
+ /**
+ * @var BigInteger[]
+ */
+ private $exponents = [];
+
+ /**
+ * @var BigInteger|null
+ */
+ private $coefficient = null;
+
+ private function __construct(JWK $data)
+ {
+ $this->loadJWK($data->all());
+ $this->populateBigIntegers();
+ $this->private = \array_key_exists('d', $this->values);
+ }
+
+ /**
+ * @return RSAKey
+ */
+ public static function createFromJWK(JWK $jwk): self
+ {
+ return new self($jwk);
+ }
+
+ public function getModulus(): BigInteger
+ {
+ return $this->modulus;
+ }
+
+ public function getModulusLength(): int
+ {
+ return $this->modulus_length;
+ }
+
+ public function getExponent(): BigInteger
+ {
+ $d = $this->getPrivateExponent();
+ if (null !== $d) {
+ return $d;
+ }
+
+ return $this->getPublicExponent();
+ }
+
+ public function getPublicExponent(): BigInteger
+ {
+ return $this->public_exponent;
+ }
+
+ public function getPrivateExponent(): ?BigInteger
+ {
+ return $this->private_exponent;
+ }
+
+ /**
+ * @return BigInteger[]
+ */
+ public function getPrimes(): array
+ {
+ return $this->primes;
+ }
+
+ /**
+ * @return BigInteger[]
+ */
+ public function getExponents(): array
+ {
+ return $this->exponents;
+ }
+
+ public function getCoefficient(): ?BigInteger
+ {
+ return $this->coefficient;
+ }
+
+ public function isPublic(): bool
+ {
+ return !\array_key_exists('d', $this->values);
+ }
+
+ /**
+ * @param RSAKey $private
+ *
+ * @return RSAKey
+ */
+ public static function toPublic(self $private): self
+ {
+ $data = $private->toArray();
+ $keys = ['p', 'd', 'q', 'dp', 'dq', 'qi'];
+ foreach ($keys as $key) {
+ if (\array_key_exists($key, $data)) {
+ unset($data[$key]);
+ }
+ }
+
+ return new self(new JWK($data));
+ }
+
+ public function toArray(): array
+ {
+ return $this->values;
+ }
+
+ private function loadJWK(array $jwk)
+ {
+ if (!\array_key_exists('kty', $jwk)) {
+ throw new \InvalidArgumentException('The key parameter "kty" is missing.');
+ }
+ if ('RSA' !== $jwk['kty']) {
+ throw new \InvalidArgumentException('The JWK is not a RSA key.');
+ }
+
+ $this->values = $jwk;
+ }
+
+ private function populateBigIntegers()
+ {
+ $this->modulus = $this->convertBase64StringToBigInteger($this->values['n']);
+ $this->modulus_length = \mb_strlen($this->getModulus()->toBytes(), '8bit');
+ $this->public_exponent = $this->convertBase64StringToBigInteger($this->values['e']);
+
+ if (!$this->isPublic()) {
+ $this->private_exponent = $this->convertBase64StringToBigInteger($this->values['d']);
+
+ if (\array_key_exists('p', $this->values) && \array_key_exists('q', $this->values)) {
+ $this->primes = [
+ $this->convertBase64StringToBigInteger($this->values['p']),
+ $this->convertBase64StringToBigInteger($this->values['q']),
+ ];
+ if (\array_key_exists('dp', $this->values) && \array_key_exists('dq', $this->values) && \array_key_exists('qi', $this->values)) {
+ $this->exponents = [
+ $this->convertBase64StringToBigInteger($this->values['dp']),
+ $this->convertBase64StringToBigInteger($this->values['dq']),
+ ];
+ $this->coefficient = $this->convertBase64StringToBigInteger($this->values['qi']);
+ }
+ }
+ }
+ }
+
+ private function convertBase64StringToBigInteger(string $value): BigInteger
+ {
+ return BigInteger::createFromBinaryString(Base64Url::decode($value));
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function toPEM(): string
+ {
+ if (null === $this->sequence) {
+ $this->sequence = new Sequence();
+ if (\array_key_exists('d', $this->values)) {
+ $this->initPrivateKey();
+ } else {
+ $this->initPublicKey();
+ }
+ }
+ $result = '-----BEGIN '.($this->private ? 'RSA PRIVATE' : 'PUBLIC').' KEY-----'.PHP_EOL;
+ $result .= \chunk_split(\base64_encode($this->sequence->getBinary()), 64, PHP_EOL);
+ $result .= '-----END '.($this->private ? 'RSA PRIVATE' : 'PUBLIC').' KEY-----'.PHP_EOL;
+
+ return $result;
+ }
+
+ /**
+ * @throws \Exception
+ */
+ private function initPublicKey()
+ {
+ $oid_sequence = new Sequence();
+ $oid_sequence->addChild(new ObjectIdentifier('1.2.840.113549.1.1.1'));
+ $oid_sequence->addChild(new NullObject());
+ $this->sequence->addChild($oid_sequence);
+ $n = new Integer($this->fromBase64ToInteger($this->values['n']));
+ $e = new Integer($this->fromBase64ToInteger($this->values['e']));
+ $key_sequence = new Sequence();
+ $key_sequence->addChild($n);
+ $key_sequence->addChild($e);
+ $key_bit_string = new BitString(\bin2hex($key_sequence->getBinary()));
+ $this->sequence->addChild($key_bit_string);
+ }
+
+ private function initPrivateKey()
+ {
+ $this->sequence->addChild(new Integer(0));
+ $oid_sequence = new Sequence();
+ $oid_sequence->addChild(new ObjectIdentifier('1.2.840.113549.1.1.1'));
+ $oid_sequence->addChild(new NullObject());
+ $this->sequence->addChild($oid_sequence);
+ $v = new Integer(0);
+ $n = new Integer($this->fromBase64ToInteger($this->values['n']));
+ $e = new Integer($this->fromBase64ToInteger($this->values['e']));
+ $d = new Integer($this->fromBase64ToInteger($this->values['d']));
+ $p = new Integer($this->fromBase64ToInteger($this->values['p']));
+ $q = new Integer($this->fromBase64ToInteger($this->values['q']));
+ $dp = \array_key_exists('dp', $this->values) ? new Integer($this->fromBase64ToInteger($this->values['dp'])) : new Integer(0);
+ $dq = \array_key_exists('dq', $this->values) ? new Integer($this->fromBase64ToInteger($this->values['dq'])) : new Integer(0);
+ $qi = \array_key_exists('qi', $this->values) ? new Integer($this->fromBase64ToInteger($this->values['qi'])) : new Integer(0);
+ $key_sequence = new Sequence();
+ $key_sequence->addChild($v);
+ $key_sequence->addChild($n);
+ $key_sequence->addChild($e);
+ $key_sequence->addChild($d);
+ $key_sequence->addChild($p);
+ $key_sequence->addChild($q);
+ $key_sequence->addChild($dp);
+ $key_sequence->addChild($dq);
+ $key_sequence->addChild($qi);
+ $key_octet_string = new OctetString(\bin2hex($key_sequence->getBinary()));
+ $this->sequence->addChild($key_octet_string);
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return string
+ */
+ private function fromBase64ToInteger($value)
+ {
+ return \gmp_strval(\gmp_init(\current(\unpack('H*', Base64Url::decode($value))), 16), 10);
+ }
+
+ /**
+ * Exponentiate with or without Chinese Remainder Theorem.
+ * Operation with primes 'p' and 'q' is appox. 2x faster.
+ *
+ * @param RSAKey $key
+ */
+ public static function exponentiate(self $key, BigInteger $c): BigInteger
+ {
+ if ($c->compare(BigInteger::createFromDecimal(0)) < 0 || $c->compare($key->getModulus()) > 0) {
+ throw new \RuntimeException();
+ }
+ if ($key->isPublic() || empty($key->getPrimes()) || empty($key->getExponents()) || null === $key->getCoefficient()) {
+ return $c->modPow($key->getExponent(), $key->getModulus());
+ }
+
+ $p = $key->getPrimes()[0];
+ $q = $key->getPrimes()[1];
+ $dP = $key->getExponents()[0];
+ $dQ = $key->getExponents()[1];
+ $qInv = $key->getCoefficient();
+
+ $m1 = $c->modPow($dP, $p);
+ $m2 = $c->modPow($dQ, $q);
+ $h = $qInv->multiply($m1->subtract($m2)->add($p))->mod($p);
+ $m = $m2->add($h->multiply($q));
+
+ return $m;
+ }
+}
|