diff --git a/ECDHES.php b/ECDHES.php index 1f6bdb8..1d942f2 100644 --- a/ECDHES.php +++ b/ECDHES.php @@ -2,15 +2,6 @@ declare(strict_types=1); -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2020 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\Encryption\Algorithm\KeyEncryption; use function array_key_exists; @@ -38,8 +29,14 @@ public function allowedKeyTypes(): array return ['EC', 'OKP']; } - public function getAgreementKey(int $encryptionKeyLength, string $algorithm, JWK $recipientKey, ?JWK $senderKey, array $complete_header = [], array &$additional_header_values = []): string - { + public function getAgreementKey( + int $encryptionKeyLength, + string $algorithm, + JWK $recipientKey, + ?JWK $senderKey, + array $complete_header = [], + array &$additional_header_values = [] + ): string { if ($recipientKey->has('d')) { [$public_key, $private_key] = $this->getKeysFromPrivateKeyAndHeader($recipientKey, $complete_header); } else { @@ -54,9 +51,6 @@ public function getAgreementKey(int $encryptionKeyLength, string $algorithm, JWK return ConcatKDF::generate($agreed_key, $algorithm, $encryptionKeyLength, $apu, $apv); } - /** - * @throws InvalidArgumentException if the curve is not supported - */ public function calculateAgreementKey(JWK $private_key, JWK $public_key): string { switch ($public_key->get('crv')) { @@ -70,12 +64,12 @@ public function calculateAgreementKey(JWK $private_key, JWK $public_key): string $privatePem = ECKey::convertPrivateKeyToPEM($private_key); $res = openssl_pkey_derive($publicPem, $privatePem, $curve->getSize()); - if (false === $res) { + if ($res === false) { throw new RuntimeException('Unable to derive the key'); } return $res; - } catch (Throwable $throwable) { + } catch (Throwable) { //Does nothing. Will fallback to the pure PHP function } } @@ -111,8 +105,6 @@ public function getKeyManagementMode(): string } /** - * @throws InvalidArgumentException if the curve is not supported - * * @return JWK[] */ private function getKeysFromPublicKey(JWK $recipient_key, array &$additional_header_values): array @@ -137,15 +129,15 @@ private function getKeysFromPublicKey(JWK $recipient_key, array &$additional_hea default: throw new InvalidArgumentException(sprintf('The curve "%s" is not supported', $public_key->get('crv'))); } - $epk = $private_key->toPublic()->all(); + $epk = $private_key->toPublic() + ->all() + ; $additional_header_values['epk'] = $epk; return [$public_key, $private_key]; } /** - * @throws InvalidArgumentException if the curves are different - * * @return JWK[] */ private function getKeysFromPrivateKeyAndHeader(JWK $recipient_key, array $complete_header): array @@ -160,15 +152,12 @@ private function getKeysFromPrivateKeyAndHeader(JWK $recipient_key, array $compl return [$public_key, $private_key]; } - /** - * @throws InvalidArgumentException if the ephemeral public key is missing or invalid - */ private function getPublicKey(array $complete_header): JWK { - if (!isset($complete_header['epk'])) { + if (! isset($complete_header['epk'])) { throw new InvalidArgumentException('The header parameter "epk" is missing.'); } - if (!is_array($complete_header['epk'])) { + if (! is_array($complete_header['epk'])) { throw new InvalidArgumentException('The header parameter "epk" is not an array of parameters'); } $public_key = new JWK($complete_header['epk']); @@ -177,16 +166,13 @@ private function getPublicKey(array $complete_header): JWK return $public_key; } - /** - * @throws InvalidArgumentException if the key is invalid - */ private function checkKey(JWK $key, bool $is_private): void { - if (!in_array($key->get('kty'), $this->allowedKeyTypes(), true)) { + if (! in_array($key->get('kty'), $this->allowedKeyTypes(), true)) { throw new InvalidArgumentException('Wrong key type.'); } foreach (['x', 'crv'] as $k) { - if (!$key->has($k)) { + if (! $key->has($k)) { throw new InvalidArgumentException(sprintf('The key parameter "%s" is missing.', $k)); } } @@ -195,7 +181,7 @@ private function checkKey(JWK $key, bool $is_private): void case 'P-256': case 'P-384': case 'P-521': - if (!$key->has('y')) { + if (! $key->has('y')) { throw new InvalidArgumentException('The key parameter "y" is missing.'); } @@ -207,44 +193,31 @@ private function checkKey(JWK $key, bool $is_private): void default: throw new InvalidArgumentException(sprintf('The curve "%s" is not supported', $key->get('crv'))); } - if (true === $is_private && !$key->has('d')) { + if ($is_private === true && ! $key->has('d')) { throw new InvalidArgumentException('The key parameter "d" is missing.'); } } - /** - * @throws InvalidArgumentException if the curve is not supported - */ private function getCurve(string $crv): Curve { - switch ($crv) { - 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', $crv)); - } + return match ($crv) { + 'P-256' => NistCurve::curve256(), + 'P-384' => NistCurve::curve384(), + 'P-521' => NistCurve::curve521(), + default => throw new InvalidArgumentException(sprintf('The curve "%s" is not supported', $crv)), + }; } private function convertBase64ToBigInteger(string $value): BigInteger { $data = unpack('H*', Base64UrlSafe::decode($value)); - if (!is_array($data) || !isset($data[1])) { + if (! is_array($data) || ! isset($data[1])) { throw new InvalidArgumentException('Unable to convert base64 to integer'); } return BigInteger::fromBase($data[1], 16); } - /** - * @throws InvalidArgumentException if the data cannot be converted - */ private function convertDecToBin(BigInteger $dec): string { if ($dec->compareTo(BigInteger::zero()) < 0) { @@ -252,12 +225,12 @@ private function convertDecToBin(BigInteger $dec): string } $hex = $dec->toBase(16); - if (0 !== mb_strlen($hex, '8bit') % 2) { - $hex = '0'.$hex; + if (mb_strlen($hex, '8bit') % 2 !== 0) { + $hex = '0' . $hex; } $bin = hex2bin($hex); - if (false === $bin) { + if ($bin === false) { throw new InvalidArgumentException('Unable to convert integer to string'); } @@ -266,8 +239,6 @@ private function convertDecToBin(BigInteger $dec): string /** * @param string $curve The curve - * - * @throws InvalidArgumentException if the curve is not supported */ private function createOKPKey(string $curve): JWK { @@ -300,12 +271,9 @@ private function createOKPKey(string $curve): JWK ]); } - /** - * @throws RuntimeException if the extension "sodium" is not available - */ private function checkSodiumExtensionIsAvailable(): void { - if (!extension_loaded('sodium')) { + if (! extension_loaded('sodium')) { throw new RuntimeException('The extension "sodium" is not available. Please install it to use this method'); } } diff --git a/ECDHESA128KW.php b/ECDHESA128KW.php index 8378b73..8fbacc1 100644 --- a/ECDHESA128KW.php +++ b/ECDHESA128KW.php @@ -2,15 +2,6 @@ declare(strict_types=1); -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2020 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\Encryption\Algorithm\KeyEncryption; use AESKW\A128KW as Wrapper; @@ -22,7 +13,7 @@ public function name(): string return 'ECDH-ES+A128KW'; } - protected function getWrapper() + protected function getWrapper(): Wrapper { return new Wrapper(); } diff --git a/ECDHESA192KW.php b/ECDHESA192KW.php index 32dde77..948c383 100644 --- a/ECDHESA192KW.php +++ b/ECDHESA192KW.php @@ -2,15 +2,6 @@ declare(strict_types=1); -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2020 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\Encryption\Algorithm\KeyEncryption; use AESKW\A192KW as Wrapper; @@ -22,7 +13,7 @@ public function name(): string return 'ECDH-ES+A192KW'; } - protected function getWrapper() + protected function getWrapper(): Wrapper { return new Wrapper(); } diff --git a/ECDHESA256KW.php b/ECDHESA256KW.php index ace3cc7..367cf44 100644 --- a/ECDHESA256KW.php +++ b/ECDHESA256KW.php @@ -2,15 +2,6 @@ declare(strict_types=1); -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2020 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\Encryption\Algorithm\KeyEncryption; use AESKW\A256KW as Wrapper; @@ -22,7 +13,7 @@ public function name(): string return 'ECDH-ES+A256KW'; } - protected function getWrapper() + protected function getWrapper(): Wrapper { return new Wrapper(); } diff --git a/ECDHESAESKW.php b/ECDHESAESKW.php index 07f92cb..7e29ced 100644 --- a/ECDHESAESKW.php +++ b/ECDHESAESKW.php @@ -2,17 +2,11 @@ declare(strict_types=1); -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2020 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\Encryption\Algorithm\KeyEncryption; +use AESKW\A128KW; +use AESKW\A192KW; +use AESKW\A256KW; use Jose\Component\Core\JWK; abstract class ECDHESAESKW implements KeyAgreementWithKeyWrapping @@ -22,19 +16,43 @@ public function allowedKeyTypes(): array return ['EC', 'OKP']; } - public function wrapAgreementKey(JWK $recipientKey, ?JWK $senderKey, string $cek, int $encryption_key_length, array $complete_header, array &$additional_header_values): string - { + public function wrapAgreementKey( + JWK $recipientKey, + ?JWK $senderKey, + string $cek, + int $encryption_key_length, + array $complete_header, + array &$additional_header_values + ): string { $ecdh_es = new ECDHES(); - $agreement_key = $ecdh_es->getAgreementKey($this->getKeyLength(), $this->name(), $recipientKey->toPublic(), $senderKey, $complete_header, $additional_header_values); + $agreement_key = $ecdh_es->getAgreementKey( + $this->getKeyLength(), + $this->name(), + $recipientKey->toPublic(), + $senderKey, + $complete_header, + $additional_header_values + ); $wrapper = $this->getWrapper(); return $wrapper::wrap($agreement_key, $cek); } - public function unwrapAgreementKey(JWK $recipientKey, ?JWK $senderKey, string $encrypted_cek, int $encryption_key_length, array $complete_header): string - { + public function unwrapAgreementKey( + JWK $recipientKey, + ?JWK $senderKey, + string $encrypted_cek, + int $encryption_key_length, + array $complete_header + ): string { $ecdh_es = new ECDHES(); - $agreement_key = $ecdh_es->getAgreementKey($this->getKeyLength(), $this->name(), $recipientKey, $senderKey, $complete_header); + $agreement_key = $ecdh_es->getAgreementKey( + $this->getKeyLength(), + $this->name(), + $recipientKey, + $senderKey, + $complete_header + ); $wrapper = $this->getWrapper(); return $wrapper::unwrap($agreement_key, $encrypted_cek); @@ -45,10 +63,7 @@ public function getKeyManagementMode(): string return self::MODE_WRAP; } - /** - * @return \AESKW\A128KW|\AESKW\A192KW|\AESKW\A256KW - */ - abstract protected function getWrapper(); + abstract protected function getWrapper(): A128KW|A192KW|A256KW; abstract protected function getKeyLength(): int; } diff --git a/Util/ConcatKDF.php b/Util/ConcatKDF.php index 871395b..e55e6aa 100644 --- a/Util/ConcatKDF.php +++ b/Util/ConcatKDF.php @@ -2,26 +2,18 @@ declare(strict_types=1); -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2020 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\Encryption\Algorithm\KeyEncryption\Util; use InvalidArgumentException; use ParagonIE\ConstantTime\Base64UrlSafe; +use const STR_PAD_LEFT; /** * @internal * * @see https://tools.ietf.org/html/rfc7518#section-4.6.2 */ -class ConcatKDF +final class ConcatKDF { /** * Key Derivation Function. @@ -32,16 +24,21 @@ class ConcatKDF * @param string $apu Agreement PartyUInfo (information about the producer) * @param string $apv Agreement PartyVInfo (information about the recipient) */ - public static function generate(string $Z, string $algorithm, int $encryption_key_size, string $apu = '', string $apv = ''): string - { - $apu = !self::isEmpty($apu) ? Base64UrlSafe::decode($apu) : ''; - $apv = !self::isEmpty($apv) ? Base64UrlSafe::decode($apv) : ''; + public static function generate( + string $Z, + string $algorithm, + int $encryption_key_size, + string $apu = '', + string $apv = '' + ): string { + $apu = ! self::isEmpty($apu) ? Base64UrlSafe::decode($apu) : ''; + $apv = ! self::isEmpty($apv) ? Base64UrlSafe::decode($apv) : ''; $encryption_segments = [ self::toInt32Bits(1), // Round number 1 $Z, // Z (shared secret) - self::toInt32Bits(mb_strlen($algorithm, '8bit')).$algorithm, // Size of algorithm's name and algorithm - self::toInt32Bits(mb_strlen($apu, '8bit')).$apu, // PartyUInfo - self::toInt32Bits(mb_strlen($apv, '8bit')).$apv, // PartyVInfo + self::toInt32Bits(mb_strlen($algorithm, '8bit')) . $algorithm, // Size of algorithm's name and algorithm + self::toInt32Bits(mb_strlen($apu, '8bit')) . $apu, // PartyUInfo + self::toInt32Bits(mb_strlen($apv, '8bit')) . $apv, // PartyVInfo self::toInt32Bits($encryption_key_size), // SuppPubInfo (the encryption key size) '', // SuppPrivInfo ]; @@ -60,7 +57,7 @@ public static function generate(string $Z, string $algorithm, int $encryption_ke private static function toInt32Bits(int $value): string { $result = hex2bin(str_pad(dechex($value), 8, '0', STR_PAD_LEFT)); - if (false === $result) { + if ($result === false) { throw new InvalidArgumentException('Invalid result'); } @@ -69,6 +66,6 @@ private static function toInt32Bits(int $value): string private static function isEmpty(?string $value): bool { - return null === $value || '' === $value; + return $value === null || $value === ''; } } diff --git a/composer.json b/composer.json index 5dbd03c..6368a59 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ }, "require": { "ext-openssl": "*", - "spomky-labs/aes-key-wrap": "^5.0|^6.0", + "spomky-labs/aes-key-wrap": "^7.0", "web-token/jwt-encryption": "^2.1", "web-token/jwt-util-ecc": "^2.1" }