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

◆ decodeToken()

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

◆ encode()

encode ( )
131  {
132 
133  }

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 = Info::LOGIN_PACKET

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