mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-03 00:29:54 +00:00
Throw a more specific exception for JWT handling errors
This commit is contained in:
parent
486e0e710b
commit
84291e7980
28
src/network/mcpe/JwtException.php
Normal file
28
src/network/mcpe/JwtException.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
final class JwtException extends \RuntimeException{
|
||||
|
||||
}
|
@ -64,38 +64,38 @@ final class JwtUtils{
|
||||
* @return mixed[]
|
||||
* @phpstan-return array{mixed[], mixed[], string}
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
* @throws JwtException
|
||||
*/
|
||||
public static function parse(string $token) : array{
|
||||
$v = explode(".", $token);
|
||||
if(count($v) !== 3){
|
||||
throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($v));
|
||||
throw new JwtException("Expected exactly 3 JWT parts, got " . count($v));
|
||||
}
|
||||
$header = json_decode(self::b64UrlDecode($v[0]), true);
|
||||
if(!is_array($header)){
|
||||
throw new \UnexpectedValueException("Failed to decode JWT header JSON: " . json_last_error_msg());
|
||||
throw new JwtException("Failed to decode JWT header JSON: " . json_last_error_msg());
|
||||
}
|
||||
$body = json_decode(self::b64UrlDecode($v[1]), true);
|
||||
if(!is_array($body)){
|
||||
throw new \UnexpectedValueException("Failed to decode JWT payload JSON: " . json_last_error_msg());
|
||||
throw new JwtException("Failed to decode JWT payload JSON: " . json_last_error_msg());
|
||||
}
|
||||
$signature = self::b64UrlDecode($v[2]);
|
||||
return [$header, $body, $signature];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \UnexpectedValueException
|
||||
* @throws JwtException
|
||||
*/
|
||||
public static function verify(string $jwt, PublicKeyInterface $signingKey) : bool{
|
||||
$parts = explode('.', $jwt);
|
||||
if(count($parts) !== 3){
|
||||
throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($parts));
|
||||
throw new JwtException("Expected exactly 3 JWT parts, got " . count($parts));
|
||||
}
|
||||
[$header, $body, $signature] = $parts;
|
||||
|
||||
$plainSignature = self::b64UrlDecode($signature);
|
||||
if(strlen($plainSignature) !== 96){
|
||||
throw new \UnexpectedValueException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature));
|
||||
throw new JwtException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature));
|
||||
}
|
||||
|
||||
[$rString, $sString] = str_split($plainSignature, 48);
|
||||
@ -110,7 +110,7 @@ final class JwtUtils{
|
||||
switch($v){
|
||||
case 0: return false;
|
||||
case 1: return true;
|
||||
case -1: throw new \UnexpectedValueException("Error verifying JWT signature: " . openssl_error_string());
|
||||
case -1: throw new JwtException("Error verifying JWT signature: " . openssl_error_string());
|
||||
default: throw new AssumptionFailedError("openssl_verify() should only return -1, 0 or 1");
|
||||
}
|
||||
}
|
||||
@ -144,7 +144,7 @@ final class JwtUtils{
|
||||
}
|
||||
$decoded = base64_decode(strtr($str, '-_', '+/'), true);
|
||||
if($decoded === false){
|
||||
throw new \UnexpectedValueException("Malformed base64url encoded payload could not be decoded");
|
||||
throw new JwtException("Malformed base64url encoded payload could not be decoded");
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\auth;
|
||||
use FG\ASN1\Exception\ParserException;
|
||||
use Mdanter\Ecc\Crypto\Key\PublicKeyInterface;
|
||||
use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
|
||||
use pocketmine\network\mcpe\JwtException;
|
||||
use pocketmine\network\mcpe\JwtUtils;
|
||||
use pocketmine\network\mcpe\protocol\LoginPacket;
|
||||
use pocketmine\scheduler\AsyncTask;
|
||||
@ -106,7 +107,7 @@ class ProcessLoginTask extends AsyncTask{
|
||||
private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{
|
||||
try{
|
||||
[$headers, $claims, ] = JwtUtils::parse($jwt);
|
||||
}catch(\UnexpectedValueException $e){
|
||||
}catch(JwtException $e){
|
||||
throw new VerifyLoginException("Failed to parse JWT: " . $e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
@ -134,7 +135,7 @@ class ProcessLoginTask extends AsyncTask{
|
||||
if(!JwtUtils::verify($jwt, $signingKey)){
|
||||
throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature");
|
||||
}
|
||||
}catch(\UnexpectedValueException $e){
|
||||
}catch(JwtException $e){
|
||||
throw new VerifyLoginException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\network\mcpe\JwtException;
|
||||
use pocketmine\network\mcpe\JwtUtils;
|
||||
use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream;
|
||||
use pocketmine\network\mcpe\protocol\types\login\AuthenticationData;
|
||||
@ -89,7 +90,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{
|
||||
//validate every chain element
|
||||
try{
|
||||
[, $claims, ] = JwtUtils::parse($chain);
|
||||
}catch(\UnexpectedValueException $e){
|
||||
}catch(JwtException $e){
|
||||
throw new PacketDecodeException($e->getMessage(), 0, $e);
|
||||
}
|
||||
if(isset($claims["extraData"])){
|
||||
@ -118,7 +119,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{
|
||||
$this->clientDataJwt = $buffer->get($buffer->getLInt());
|
||||
try{
|
||||
[, $clientData, ] = JwtUtils::parse($this->clientDataJwt);
|
||||
}catch(\UnexpectedValueException $e){
|
||||
}catch(JwtException $e){
|
||||
throw new PacketDecodeException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user