Merge pull request #466 from pastoso/master
Merge pull request #466 from pastoso/master

Implement new method for code request token generation

file:b/src/php/magic.dat (new)
 Binary files /dev/null and b/src/php/magic.dat differ
file:b/src/php/token.php (new)
--- /dev/null
+++ b/src/php/token.php
@@ -1,1 +1,72 @@
+<?php
+require_once 'func.php';
 
+if ( !function_exists( 'hex2bin' ) ) {
+    function hex2bin( $str ) {
+        $sbin = "";
+        $len = strlen( $str );
+        for ( $i = 0; $i < $len; $i += 2 ) {
+            $sbin .= pack( "H*", substr( $str, $i, 2 ) );
+        }
+
+        return $sbin;
+    }
+}
+
+function generateRequestToken($country, $phone) {
+	$waString = "53160F52030A44C28310C282C29AC28DC28C463A2169295741";
+	$noMediaHash = "0001A9339CEF0E7172AEC99E99F0044DCC3F90F58C45C0A85BDEAB054DA9A61B4438258D5614A9F105FA";
+	$waPrefix = "636F6D2E7768617473617070";
+	$signature = "30820332308202F0A00302010202044C2536A4300B06072A8648CE3804030500307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E301E170D3130303632353233303731365A170D3434303231353233303731365A307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E308201B83082012C06072A8648CE3804013082011F02818100FD7F53811D75122952DF4A9C2EECE4E7F611B7523CEF4400C31E3F80B6512669455D402251FB593D8D58FABFC5F5BA30F6CB9B556CD7813B801D346FF26660B76B9950A5A49F9FE8047B1022C24FBBA9D7FEB7C61BF83B57E7C6A8A6150F04FB83F6D3C51EC3023554135A169132F675F3AE2B61D72AEFF22203199DD14801C70215009760508F15230BCCB292B982A2EB840BF0581CF502818100F7E1A085D69B3DDECBBCAB5C36B857B97994AFBBFA3AEA82F9574C0B3D0782675159578EBAD4594FE67107108180B449167123E84C281613B7CF09328CC8A6E13C167A8B547C8D28E0A3AE1E2BB3A675916EA37F0BFA213562F1FB627A01243BCCA4F1BEA8519089A883DFE15AE59F06928B665E807B552564014C3BFECF492A0381850002818100D1198B4B81687BCF246D41A8A725F0A989A51BCE326E84C828E1F556648BD71DA487054D6DE70FFF4B49432B6862AA48FC2A93161B2C15A2FF5E671672DFB576E9D12AAFF7369B9A99D04FB29D2BBBB2A503EE41B1FF37887064F41FE2805609063500A8E547349282D15981CDB58A08BEDE51DD7E9867295B3DFB45FFC6B259300B06072A8648CE3804030500032F00302C021400A602A7477ACF841077237BE090DF436582CA2F0214350CE0268D07E71E55774AB4EACD4D071CD1EFAD";
+	$classesMd5 = "2f8c600d1b5d497aee2adf672abb87b7";
+	$k = "3E44F029266A51F014C91D2B3D0F21609D3036C410DDD5B5FB74829F24D721F100C714BBE45C240DFE3BC0DBFF73CA4FDE9D065CA47A38E426872111C31EF87F0D51612535D08E2BD60C815436D1278D2989D8CCE351B5235A0D";
+	$KEY = "The piano has been drinking";
+
+
+	//TODO: This phone prefix split XXX-ZZZZZ... is ok for +34 numbers, but needs to be checked
+	//      for other countries
+	$phone1 = substr($phone, 0, 3);
+	$phone2 = substr($phone, 3);
+
+	// This AES secret is not really needed right now
+	$id = hex2bin($waString) . $country . $phone2;
+	$salt = substr(hex2bin($noMediaHash),2,4);
+	$key = pbkdf2('sha1', $id, $salt, 16, 16, true);
+	$iv = substr(hex2bin($noMediaHash),6,16);
+	$data = substr(hex2bin($noMediaHash),22);
+	$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'nofb', '');
+	mcrypt_generic_init($td, $key, $iv);
+	$aes_secret = mcrypt_generic($td, $data);
+	mcrypt_module_close($td);
+
+
+	// We xor this file because I don't want to have a copyrighted png 
+	// on my repository
+	$f =  file_get_contents("magic.dat");
+	$count = 0;
+	for ($i=0; $i < strlen($f); $i++) {
+        	$f[$i] = $f[$i] ^ $KEY[$count++];
+        	if ($count == strlen($KEY) -1) {
+                	$count = 0;
+        	}
+	}
+
+	$d = hex2bin($waPrefix) . $f;
+	$key2 = pbkdf2('sha1', $d, hex2bin($k), 128, 80, true);
+
+	$data = hex2bin($signature . $classesMd5) . $phone1 . $phone2;
+
+	$opad = str_repeat(chr(0x5C), 64);
+	$ipad = str_repeat(chr(0x36), 64);
+	for ($i = 0; $i < 64; $i++) {
+		$opad[$i] = $opad[$i] ^ $key2[$i];
+		$ipad[$i] = $ipad[$i] ^ $key2[$i];
+	}
+
+	$pack = 'H'.strlen(hash("sha1", 'lalala'));
+
+	$output = hash("sha1", $opad.pack($pack, hash("sha1", $ipad.$data)));
+
+	return base64_encode(hex2bin($output));
+}
+

--- a/src/php/whatsprot.class.php
+++ b/src/php/whatsprot.class.php
@@ -2,6 +2,7 @@
 require_once 'protocol.class.php';
 require_once 'WhatsAppEvent.php';
 require_once 'func.php';
+require_once 'token.php';
 require_once 'rc4.php';
 require_once 'mediauploader.php';
 
@@ -25,9 +26,8 @@
     const WHATSAPP_SERVER = 's.whatsapp.net';               // The hostname used to login/send messages.
     const WHATSAPP_UPLOAD_HOST = 'https://mms.whatsapp.net/client/iphone/upload.php'; // The upload host.
     const WHATSAPP_DEVICE = 'Android';                      // The device name.
-    const WHATSAPP_VER = '2.10.750';                        // The WhatsApp version.
-    const WHATSAPP_TOKEN = "30820332308202f0a00302010202044c2536a4300b06072a8648ce3804030500307c310b3009060355040613025553311330110603550408130a43616c69666f726e6961311430120603550407130b53616e746120436c61726131163014060355040a130d576861747341707020496e632e31143012060355040b130b456e67696e656572696e67311430120603550403130b427269616e204163746f6e301e170d3130303632353233303731365a170d3434303231353233303731365a307c310b3009060355040613025553311330110603550408130a43616c69666f726e6961311430120603550407130b53616e746120436c61726131163014060355040a130d576861747341707020496e632e31143012060355040b130b456e67696e656572696e67311430120603550403130b427269616e204163746f6e308201b83082012c06072a8648ce3804013082011f02818100fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c70215009760508f15230bccb292b982a2eb840bf0581cf502818100f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a0381850002818100d1198b4b81687bcf246d41a8a725f0a989a51bce326e84c828e1f556648bd71da487054d6de70fff4b49432b6862aa48fc2a93161b2c15a2ff5e671672dfb576e9d12aaff7369b9a99d04fb29d2bbbb2a503ee41b1ff37887064f41fe2805609063500a8e547349282d15981cdb58a08bede51dd7e9867295b3dfb45ffc6b259300b06072a8648ce3804030500032f00302c021400a602a7477acf841077237be090df436582ca2f0214350ce0268d07e71e55774ab4eacd4d071cd1efad022e923a364bfacff3a80de3f950b1e0";//'Od52pFozHNWF9XbTN5lrqDtnsiZGL2G3l9yw1GiQ21a31a2d9dbdc9a8ce324ef2df918064fd26e30a'; // Token used in request/registration code.
-    const WHATSAPP_USER_AGENT = 'WhatsApp/2.10.750 Android/4.2.1 Device/GalaxyS3';//'WhatsApp/2.10.523 WP7/7.10.8858 Device/HTC-HTC-H0002';  // User agent used in request/registration code.
+    const WHATSAPP_VER = 'WhatsApp/2.11.23';                // The WhatsApp version.
+    const WHATSAPP_USER_AGENT = 'WhatsApp/2.11.23 Android/4.3 Device/GalaxyS3';//'WhatsApp/2.10.523 WP7/7.10.8858 Device/HTC-HTC-H0002';  // User agent used in request/registration code.
 
     /**
      * Property declarations.
@@ -267,7 +267,7 @@
         }
 
         // Build the token.
-        $token = md5(static::WHATSAPP_TOKEN . $phone['phone']);
+        $token = generateRequestToken($phone['country'], $phone['phone']);
 
         // Build the url.
         $host = 'https://' . static::WHATSAPP_REQUEST_HOST;
@@ -280,7 +280,7 @@
             'method' => $method,
             'mcc' => $phone['mcc'],
             'mnc' => '001',
-            'token' => $token,
+            'token' => urlencode($token),
             'id' => $this->identity,
         );