diff --git a/src/Encryption.php b/src/Encryption.php index b1e0ed7..3903045 100644 --- a/src/Encryption.php +++ b/src/Encryption.php @@ -36,11 +36,12 @@ public static function padPayload(string $payload, int $maxLengthToPad, string $ if ($contentEncoding === "aesgcm") { return pack('n*', $padLen).str_pad($payload, $padLen + $payloadLen, chr(0), STR_PAD_LEFT); - } elseif ($contentEncoding === "aes128gcm") { + } + if ($contentEncoding === "aes128gcm") { return str_pad($payload.chr(2), $padLen + $payloadLen, chr(0), STR_PAD_RIGHT); - } else { - throw new \ErrorException("This content encoding is not supported"); } + + throw new \ErrorException("This content encoding is not supported"); } /** @@ -63,7 +64,7 @@ public static function encrypt(string $payload, string $userPublicKey, string $u } /** - * @throws \ErrorException + * @throws \RuntimeException */ public static function deterministicEncrypt(string $payload, string $userPublicKey, string $userAuthToken, string $contentEncoding, array $localKeyObject, string $salt): array { @@ -88,7 +89,7 @@ public static function deterministicEncrypt(string $payload, string $userPublicK ]); } if (!$localPublicKey) { - throw new \ErrorException('Failed to convert local public key from hexadecimal to binary'); + throw new \RuntimeException('Failed to convert local public key from hexadecimal to binary.'); } // get user public key object @@ -225,7 +226,9 @@ private static function createInfo(string $type, ?string $context, string $conte } return 'Content-Encoding: '.$type.chr(0).'P-256'.$context; - } elseif ($contentEncoding === "aes128gcm") { + } + + if ($contentEncoding === "aes128gcm") { return 'Content-Encoding: '.$type.chr(0); } @@ -299,23 +302,22 @@ private static function createLocalKeyObjectUsingOpenSSL(): array } /** - * @throws \ErrorException + * @throws \ValueError */ private static function getIKM(string $userAuthToken, string $userPublicKey, string $localPublicKey, string $sharedSecret, string $contentEncoding): string { - if (!empty($userAuthToken)) { - if ($contentEncoding === "aesgcm") { - $info = 'Content-Encoding: auth'.chr(0); - } elseif ($contentEncoding === "aes128gcm") { - $info = "WebPush: info".chr(0).$userPublicKey.$localPublicKey; - } else { - throw new \ErrorException("This content encoding is not supported"); - } - - return self::hkdf($userAuthToken, $sharedSecret, $info, 32); + if (empty($userAuthToken)) { + return $sharedSecret; + } + if($contentEncoding === "aesgcm") { + $info = 'Content-Encoding: auth'.chr(0); + } elseif($contentEncoding === "aes128gcm") { + $info = "WebPush: info".chr(0).$userPublicKey.$localPublicKey; + } else { + throw new \ValueError("This content encoding is not supported."); } - return $sharedSecret; + return self::hkdf($userAuthToken, $sharedSecret, $info, 32); } private static function calculateAgreementKey(JWK $private_key, JWK $public_key): string @@ -325,7 +327,7 @@ private static function calculateAgreementKey(JWK $private_key, JWK $public_key) $result = openssl_pkey_derive($publicPem, $privatePem, 256); if ($result === false) { - throw new \Exception('Unable to compute the agreement key'); + throw new \RuntimeException('Unable to compute the agreement key.'); } return $result; } diff --git a/src/Subscription.php b/src/Subscription.php index b211ddf..bad3061 100644 --- a/src/Subscription.php +++ b/src/Subscription.php @@ -27,7 +27,7 @@ public function __construct( ) { if($publicKey || $authToken || $contentEncoding) { $supportedContentEncodings = ['aesgcm', 'aes128gcm']; - if ($contentEncoding && !in_array($contentEncoding, $supportedContentEncodings)) { + if ($contentEncoding && !in_array($contentEncoding, $supportedContentEncodings, true)) { throw new \ErrorException('This content encoding ('.$contentEncoding.') is not supported.'); } $this->contentEncoding = $contentEncoding ?: "aesgcm"; diff --git a/src/WebPush.php b/src/WebPush.php index 3a94db4..ce363a9 100644 --- a/src/WebPush.php +++ b/src/WebPush.php @@ -133,7 +133,7 @@ public function sendOneNotification(SubscriptionInterface $subscription, ?string * * @param null|int $batchSize Defaults the value defined in defaultOptions during instantiation (which defaults to 1000). * - * @return \Generator|MessageSentReport[] + * @return \Generator * @throws \ErrorException */ public function flush(?int $batchSize = null): \Generator @@ -186,7 +186,7 @@ public function flush(?int $batchSize = null): \Generator } /** - * @throws \ErrorException + * @throws \ErrorException|\Random\RandomException */ protected function prepare(array $notifications): array { @@ -282,21 +282,24 @@ public function getAutomaticPadding(): int /** * @param bool|int $automaticPadding Max padding length * - * @throws \Exception + * @throws \ValueError */ public function setAutomaticPadding(bool|int $automaticPadding): WebPush { - if ($automaticPadding > Encryption::MAX_PAYLOAD_LENGTH) { - throw new \Exception('Automatic padding is too large. Max is '.Encryption::MAX_PAYLOAD_LENGTH.'. Recommended max is '.Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH.' for compatibility reasons (see README).'); - } elseif ($automaticPadding < 0) { - throw new \Exception('Padding length should be positive or zero.'); - } elseif ($automaticPadding === true) { - $this->automaticPadding = Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH; + if ($automaticPadding === true) { + $automaticPadding = Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH; } elseif ($automaticPadding === false) { - $this->automaticPadding = 0; - } else { - $this->automaticPadding = $automaticPadding; + $automaticPadding = 0; + } + + if($automaticPadding > Encryption::MAX_PAYLOAD_LENGTH) { + throw new \ValueError('Automatic padding is too large. Max is '.Encryption::MAX_PAYLOAD_LENGTH.'. Recommended max is '.Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH.' for compatibility reasons (see README).'); } + if($automaticPadding < 0) { + throw new \ValueError('Padding length should be positive or zero.'); + } + + $this->automaticPadding = $automaticPadding; return $this; } diff --git a/tests/PushServiceTest.php b/tests/PushServiceTest.php index ef878cb..f4bc95d 100644 --- a/tests/PushServiceTest.php +++ b/tests/PushServiceTest.php @@ -119,7 +119,7 @@ protected function createClosureTest($browserId, $options): callable $messageIndex = 0; foreach ($supportedContentEncodings as $contentEncoding) { - if (!in_array($contentEncoding, ['aesgcm', 'aes128gcm'])) { + if (!in_array($contentEncoding, ['aesgcm', 'aes128gcm'], true)) { $this->expectException(ErrorException::class); $this->expectExceptionMessage('This content encoding ('.$contentEncoding.') is not supported.'); $this->markTestIncomplete('Unsupported content encoding: '.$contentEncoding);