Skip to content

Commit 441ba17

Browse files
committed
Fix Xbox Auth on older versions
1 parent 07c7f17 commit 441ba17

File tree

1 file changed

+48
-14
lines changed

1 file changed

+48
-14
lines changed

src/network/mcpe/handler/LoginPacketHandler.php

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
use pocketmine\Server;
5050
use Ramsey\Uuid\Uuid;
5151
use Ramsey\Uuid\UuidInterface;
52+
use function base64_decode;
5253
use function chr;
5354
use function count;
5455
use function gettype;
@@ -84,8 +85,11 @@ private static function calculateUuidFromXuid(string $xuid) : UuidInterface{
8485
}
8586

8687
public function handleLogin(LoginPacket $packet) : bool{
87-
if($this->session->getProtocolId() >= ProtocolInfo::PROTOCOL_1_21_90){
88+
if($this->session->getProtocolId() >= ProtocolInfo::PROTOCOL_1_21_93){
8889
$authInfo = $this->parseAuthInfo($packet->authInfoJson);
90+
}elseif($this->session->getProtocolId() >= ProtocolInfo::PROTOCOL_1_21_90){
91+
$authInfo = $this->parseAuthInfo($packet->authInfoJson);
92+
$authInfo->AuthenticationType = AuthenticationType::SELF_SIGNED->value;
8993
}else{
9094
$authInfo = new AuthenticationInfo();
9195
$authInfo->AuthenticationType = AuthenticationType::SELF_SIGNED->value;
@@ -127,17 +131,44 @@ public function handleLogin(LoginPacket $packet) : bool{
127131
}catch(\JsonMapper_Exception $e){
128132
throw PacketHandlingException::wrap($e, "Error mapping self-signed certificate chain");
129133
}
130-
if(count($chain->chain) > 1 || !isset($chain->chain[0])){
131-
throw new PacketHandlingException("Expected exactly one certificate in self-signed certificate chain, got " . count($chain->chain));
132-
}
133-
134-
try{
135-
[, $claimsArray, ] = JwtUtils::parse($chain->chain[0]);
136-
}catch(JwtException $e){
137-
throw PacketHandlingException::wrap($e, "Error parsing self-signed certificate");
138-
}
139-
if(!isset($claimsArray["extraData"]) || !is_array($claimsArray["extraData"])){
140-
throw new PacketHandlingException("Expected \"extraData\" to be present in self-signed certificate");
134+
if($this->session->getProtocolId() >= ProtocolInfo::PROTOCOL_1_21_93){
135+
if(count($chain->chain) > 1 || !isset($chain->chain[0])){
136+
throw new PacketHandlingException("Expected exactly one certificate in self-signed certificate chain, got " . count($chain->chain));
137+
}
138+
139+
try{
140+
[, $claimsArray, ] = JwtUtils::parse($chain->chain[0]);
141+
}catch(JwtException $e){
142+
throw PacketHandlingException::wrap($e, "Error parsing self-signed certificate");
143+
}
144+
if(!isset($claimsArray["extraData"]) || !is_array($claimsArray["extraData"])){
145+
throw new PacketHandlingException("Expected \"extraData\" to be present in self-signed certificate");
146+
}
147+
}else{
148+
$claimsArray = null;
149+
150+
foreach($chain->chain as $jwt){
151+
try{
152+
[, $claims, ] = JwtUtils::parse($jwt);
153+
}catch(JwtException $e){
154+
throw PacketHandlingException::wrap($e, "Error parsing legacy certificate");
155+
}
156+
if(isset($claims["extraData"])){
157+
if($claimsArray !== null){
158+
throw new PacketHandlingException("Multiple certificates in self-signed certificate chain contain \"extraData\" field");
159+
}
160+
161+
if(!is_array($claims["extraData"])){
162+
throw new PacketHandlingException("'extraData' key should be an array");
163+
}
164+
165+
$claimsArray = $claims;
166+
}
167+
}
168+
169+
if($claimsArray === null){
170+
throw new PacketHandlingException("'extraData' not found in legacy chain data");
171+
}
141172
}
142173

143174
try{
@@ -151,7 +182,7 @@ public function handleLogin(LoginPacket $packet) : bool{
151182
}
152183
$legacyUuid = Uuid::fromString($claims->identity);
153184
$username = $claims->displayName;
154-
$xuid = "";
185+
$xuid = $this->session->getProtocolId() >= ProtocolInfo::PROTOCOL_1_21_93 ? "" : $claims->XUID;
155186

156187
$authRequired = $this->processLoginCommon($packet, $username, $legacyUuid, $xuid);
157188
if($authRequired === null){
@@ -334,7 +365,10 @@ function(array $issuerAndKey) use ($token, $clientData, $authRequired) : void{
334365
protected function processSelfSignedLogin(array $legacyCertificate, string $clientDataJwt, bool $authRequired) : void{
335366
$this->session->setHandler(null); //drop packets received during login verification
336367

337-
$rootAuthKeyDer = $this->session->getProtocolId() >= ProtocolInfo::PROTOCOL_1_21_90 ? null : ProcessLegacyLoginTask::LEGACY_MOJANG_ROOT_PUBLIC_KEY;
368+
$rootAuthKeyDer = $this->session->getProtocolId() >= ProtocolInfo::PROTOCOL_1_21_93 ? null : base64_decode(ProcessLegacyLoginTask::LEGACY_MOJANG_ROOT_PUBLIC_KEY, true);
369+
if($rootAuthKeyDer === false){ //should never happen unless the constant is messed up
370+
throw new \InvalidArgumentException("Failed to base64-decode hardcoded Mojang root public key");
371+
}
338372
$this->server->getAsyncPool()->submitTask(new ProcessLegacyLoginTask($legacyCertificate, $clientDataJwt, rootAuthKeyDer: $rootAuthKeyDer, authRequired: $authRequired, onCompletion: $this->authCallback));
339373
}
340374

0 commit comments

Comments
 (0)