GenisysPro  for Minecraft PE/Windows 10 v1.1.x
Feature-rich server software for Minecraft PE and Windows 10 Edition
LoginPacket Class Reference

Public Member Functions

 decode ()
 
 encode ()
 
 decodeToken ($token, $key)
 
- Public Member Functions inherited from DataPacket
 pid ()
 
 encode ()
 
 decode ()
 
 reset ()
 
 clean ()
 
 __debugInfo ()
 
 getEntityMetadata (bool $types=true)
 
 putEntityMetadata (array $metadata)
 
 getName ()
 
- Public Member Functions inherited from BinaryStream
 __construct ($buffer="", $offset=0)
 
 reset ()
 
 setBuffer ($buffer=null, $offset=0)
 
 getOffset ()
 
 getBuffer ()
 
 get ($len)
 
 put ($str)
 
 getBool ()
 
 putBool ($v)
 
 getLong ()
 
 putLong ($v)
 
 getInt ()
 
 putInt ($v)
 
 getLLong ()
 
 putLLong ($v)
 
 getLInt ()
 
 putLInt ($v)
 
 getSignedShort ()
 
 putShort ($v)
 
 getShort ()
 
 putSignedShort ($v)
 
 getFloat (int $accuracy=-1)
 
 putFloat ($v)
 
 getLShort ($signed=true)
 
 putLShort ($v)
 
 getLFloat (int $accuracy=-1)
 
 putLFloat ($v)
 
 getTriad ()
 
 putTriad ($v)
 
 getLTriad ()
 
 putLTriad ($v)
 
 getByte ()
 
 putByte ($v)
 
 getUUID ()
 
 putUUID (UUID $uuid)
 
 getSlot ()
 
 putSlot (Item $item)
 
 getString ()
 
 putString ($v)
 
 getUnsignedVarInt ()
 
 putUnsignedVarInt ($v)
 
 getVarInt ()
 
 putVarInt ($v)
 
 getEntityId ()
 
 putEntityId ($v)
 
 getBlockCoords (&$x, &$y, &$z)
 
 putBlockCoords ($x, $y, $z)
 
 getVector3f (&$x, &$y, &$z)
 
 putVector3f ($x, $y, $z)
 
 feof ()
 

Data Fields

const NETWORK_ID = ProtocolInfo::LOGIN_PACKET
 
const MOJANG_PUBKEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V"
 
const EDITION_POCKET = 0
 
 $username
 
 $protocol
 
 $gameEdition
 
 $clientUUID
 
 $clientId
 
 $identityPublicKey
 
 $serverAddress
 
 $skinId = null
 
 $skin = null
 
 $clientData = []
 
 $deviceModel
 
 $deviceOS
 
- Data Fields inherited from DataPacket
const NETWORK_ID = 0
 
 $isEncoded = false
 
- Data Fields inherited from BinaryStream
 $offset
 
 $buffer
 

Member Function Documentation

◆ decode()

decode ( )
57  {
58  $this->protocol = $this->getInt();
59  if(!in_array($this->protocol, ProtocolInfo::ACCEPTED_PROTOCOLS)){
60  $this->buffer = null;
61  return;
62  }
63 
64  $this->gameEdition = $this->getByte();
65 
66  $this->setBuffer($this->getString(), 0);
67 
68  $time = time();
69 
70  $chainData = json_decode($this->get($this->getLInt()))->{"chain"};
71  // Start with the trusted one
72  $chainKey = self::MOJANG_PUBKEY;
73  while(!empty($chainData)){
74  foreach($chainData as $index => $chain){
75  list($verified, $webtoken) = $this->decodeToken($chain, $chainKey);
76  if(isset($webtoken["extraData"])){
77  if(isset($webtoken["extraData"]["displayName"])){
78  $this->username = $webtoken["extraData"]["displayName"];
79  }
80  if(isset($webtoken["extraData"]["identity"])){
81  $this->clientUUID = $webtoken["extraData"]["identity"];
82  }
83  }
84  if($verified){
85  $verified = isset($webtoken["nbf"]) && $webtoken["nbf"] <= $time && isset($webtoken["exp"]) && $webtoken["exp"] > $time;
86  }
87  if($verified and isset($webtoken["identityPublicKey"])){
88  // Looped key chain. #blamemojang
89  if($webtoken["identityPublicKey"] != self::MOJANG_PUBKEY) $chainKey = $webtoken["identityPublicKey"];
90  break;
91  }elseif($chainKey === null){
92  // We have already gave up
93  break;
94  }
95  }
96  if(!$verified && $chainKey !== null){
97  $chainKey = null;
98  }else{
99  unset($chainData[$index]);
100  }
101  }
102 
103  list($verified, $this->clientData) = $this->decodeToken($this->get($this->getLInt()), $chainKey);
104 
105  $this->clientId = $this->clientData["ClientRandomId"] ?? null;
106  $this->serverAddress = $this->clientData["ServerAddress"] ?? null;
107  $this->skinId = $this->clientData["SkinId"] ?? null;
108 
109  if(isset($this->clientData["SkinData"])){
110  $this->skin = base64_decode($this->clientData["SkinData"]);
111  }
112 
113  if(isset($this->clientData["DeviceModel"])){
114  $this->deviceModel = $this->clientData["DeviceModel"];
115  }
116 
117  if(isset($this->clientData["DeviceOS"])){
118  $this->deviceOS = $this->clientData["DeviceOS"];
119  }
120 
121  if($verified){
122  $this->identityPublicKey = $chainKey;
123  }
124  }

◆ decodeToken()

decodeToken (   $token,
  $key 
)
Parameters
$token
$key
Returns
array
139  {
140  $tokens = explode(".", $token);
141  list($headB64, $payloadB64, $sigB64) = $tokens;
142 
143  if($key !== null and extension_loaded("openssl")){
144  $sig = base64_decode(strtr($sigB64, '-_', '+/'), true);
145  $rawLen = 48; // ES384
146  for($i = $rawLen; $i > 0 and $sig[$rawLen - $i] == chr(0); $i--){
147  }
148  $j = $i + (ord($sig[$rawLen - $i]) >= 128 ? 1 : 0);
149  for($k = $rawLen; $k > 0 and $sig[2 * $rawLen - $k] == chr(0); $k--){
150  }
151  $l = $k + (ord($sig[2 * $rawLen - $k]) >= 128 ? 1 : 0);
152  $len = 2 + $j + 2 + $l;
153  $derSig = chr(48);
154  if($len > 255){
155  throw new \RuntimeException("Invalid signature format");
156  }elseif($len >= 128){
157  $derSig .= chr(81);
158  }
159  $derSig .= chr($len) . chr(2) . chr($j);
160  $derSig .= str_repeat(chr(0), $j - $i) . substr($sig, $rawLen - $i, $i);
161  $derSig .= chr(2) . chr($l);
162  $derSig .= str_repeat(chr(0), $l - $k) . substr($sig, 2 * $rawLen - $k, $k);
163 
164  $verified = openssl_verify($headB64 . "." . $payloadB64, $derSig, "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----\n", OPENSSL_ALGO_SHA384) === 1;
165  }else{
166  $verified = false;
167  }
168 
169  return [$verified, json_decode(base64_decode($payloadB64), true)];
170  }

◆ encode()

encode ( )
129  {
130 
131  }

Field Documentation

◆ $clientData

$clientData = []

◆ $clientId

$clientId

◆ $clientUUID

$clientUUID

◆ $deviceModel

$deviceModel

◆ $deviceOS

$deviceOS

◆ $gameEdition

$gameEdition

◆ $identityPublicKey

$identityPublicKey

◆ $protocol

$protocol

◆ $serverAddress

$serverAddress

◆ $skin

$skin = null

◆ $skinId

$skinId = null

◆ $username

$username

◆ EDITION_POCKET

const EDITION_POCKET = 0

◆ MOJANG_PUBKEY

const MOJANG_PUBKEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V"

◆ NETWORK_ID

const NETWORK_ID = ProtocolInfo::LOGIN_PACKET

The documentation for this class was generated from the following file: