Browse Source

Fixed periodical 'Connecting...' problem.

Also fixed safari arraybufferview warning
Closes #1551
Closes #1538
master
Igor Zhukov 7 years ago
parent
commit
237b3990b0
  1. 244
      app/js/lib/mtproto.js
  2. 35
      app/js/lib/polyfill.js
  3. 10308
      app/vendor/jquery/jquery.js
  4. 2
      app/webogram.appcache

244
app/js/lib/mtproto.js

@ -60,21 +60,83 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -60,21 +60,83 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
/**
* Server public key, obtained from here: https://core.telegram.org/api/obtaining_api_id
*
*
* -----BEGIN RSA PUBLIC KEY-----
* MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6
* lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS
* an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw
* Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+
* 8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n
* Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
* -----END RSA PUBLIC KEY-----
*
* -----BEGIN PUBLIC KEY-----
* MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAruw2yP/BCcsJliRoW5eB
* VBVle9dtjJw+OYED160Wybum9SXtBBLXriwt4rROd9csv0t0OHCaTmRqBcQ0J8fx
* hN6/cpR1GWgOZRUAiQxoMnlt0R93LCX/j1dnVa/gVbCjdSxpbrfY2g2L4frzjJvd
* l84Kd9ORYjDEAyFnEA7dD556OptgLQQ2e2iVNq8NZLYTzLp5YpOdO1doK+ttrltg
* gTCy5SrKeLoCPPbOgGsdxJxyz5KKcZnSLj16yE5HvJQn0CNpRdENvRUXe6tBP78O
* 39oJ8BTHp9oIjd6XWXAsp2CvK45Ol8wFXGF710w9lwCGNbmNxNYhtIkdqfsEcwR5
* JwIDAQAB
* -----END PUBLIC KEY-----
*
* -----BEGIN PUBLIC KEY-----
* MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvfLHfYH2r9R70w8prHbl
* Wt/nDkh+XkgpflqQVcnAfSuTtO05lNPspQmL8Y2XjVT4t8cT6xAkdgfmmvnvRPOO
* KPi0OfJXoRVylFzAQG/j83u5K3kRLbae7fLccVhKZhY46lvsueI1hQdLgNV9n1cQ
* 3TDS2pQOCtovG4eDl9wacrXOJTG2990VjgnIKNA0UMoP+KF03qzryqIt3oTvZq03
* DyWdGK+AZjgBLaDKSnC6qD2cFY81UryRWOab8zKkWAnhw2kFpcqhI0jdV5QaSCEx
* vnsjVaX0Y1N0870931/5Jb9ICe4nweZ9kSDF/gip3kWLG0o8XQpChDfyvsqB9OLV
* /wIDAQAB
* -----END PUBLIC KEY-----
*
* -----BEGIN PUBLIC KEY-----
* MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/ditzm+mPND6xkhzwFI
* z6J/968CtkcSE/7Z2qAJiXbmZ3UDJPGrzqTDHkO30R8VeRM/Kz2f4nR05GIFiITl
* 4bEjvpy7xqRDspJcCFIOcyXm8abVDhF+th6knSU0yLtNKuQVP6voMrnt9MV1X92L
* GZQLgdHZbPQz0Z5qIpaKhdyA8DEvWWvSUwwc+yi1/gGaybwlzZwqXYoPOhwMebzK
* Uk0xW14htcJrRrq+PXXQbRzTMynseCoPIoke0dtCodbA3qQxQovE16q9zz4Otv2k
* 4j63cz53J+mhkVWAeWxVGI0lltJmWtEYK6er8VqqWot3nqmWMXogrgRLggv/Nbbo
* oQIDAQAB
* -----END PUBLIC KEY-----
*
* -----BEGIN PUBLIC KEY-----
* MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmpxVY7ld/8DAjz6F6q0
* 5shjg8/4p6047bn6/m8yPy1RBsvIyvuDuGnP/RzPEhzXQ9UJ5Ynmh2XJZgHoE9xb
* nfxL5BXHplJhMtADXKM9bWB11PU1Eioc3+AXBB8QiNFBn2XI5UkO5hPhbb9mJpjA
* 9Uhw8EdfqJP8QetVsI/xrCEbwEXe0xvifRLJbY08/Gp66KpQvy7g8w7VB8wlgePe
* xW3pT13Ap6vuC+mQuJPyiHvSxjEKHgqePji9NP3tJUFQjcECqcm0yV7/2d0t/pbC
* m+ZH1sadZspQCEPPrtbkQBlvHb4OLiIWPGHKSMeRFvp3IWcmdJqXahxLCUS1Eh6M
* AQIDAQAB
* -----END PUBLIC KEY-----
*
* -----BEGIN RSA PUBLIC KEY-----
* MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6
* lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS
* an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw
* Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+
* 8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n
* Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
* -----END RSA PUBLIC KEY-----
* Bytes can be got via
* $ openssl rsa -pubin -in key.pub -text -noout
*/
var publisKeysHex = [{
modulus: 'c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d866b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde74a5bfc920f6abf59ba5c75506373e7130f9042da922179251f',
exponent: '010001'
}]
var publisKeysHex = [
{
modulus: 'c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d866b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde74a5bfc920f6abf59ba5c75506373e7130f9042da922179251f',
exponent: '010001'
},
{
modulus: 'aeec36c8ffc109cb099624685b97815415657bd76d8c9c3e398103d7ad16c9bba6f525ed0412d7ae2c2de2b44e77d72cbf4b7438709a4e646a05c43427c7f184debf72947519680e651500890c6832796dd11f772c25ff8f576755afe055b0a3752c696eb7d8da0d8be1faf38c9bdd97ce0a77d3916230c4032167100edd0f9e7a3a9b602d04367b689536af0d64b613ccba7962939d3b57682beb6dae5b608130b2e52aca78ba023cf6ce806b1dc49c72cf928a7199d22e3d7ac84e47bc9427d0236945d10dbd15177bab413fbf0edfda09f014c7a7da088dde9759702ca760af2b8e4e97cc055c617bd74c3d97008635b98dc4d621b4891da9fb0473047927',
exponent: '010001'
},
{
modulus: 'bdf2c77d81f6afd47bd30f29ac76e55adfe70e487e5e48297e5a9055c9c07d2b93b4ed3994d3eca5098bf18d978d54f8b7c713eb10247607e69af9ef44f38e28f8b439f257a11572945cc0406fe3f37bb92b79112db69eedf2dc71584a661638ea5becb9e23585074b80d57d9f5710dd30d2da940e0ada2f1b878397dc1a72b5ce2531b6f7dd158e09c828d03450ca0ff8a174deacebcaa22dde84ef66ad370f259d18af806638012da0ca4a70baa83d9c158f3552bc9158e69bf332a45809e1c36905a5caa12348dd57941a482131be7b2355a5f4635374f3bd3ddf5ff925bf4809ee27c1e67d9120c5fe08a9de458b1b4a3c5d0a428437f2beca81f4e2d5ff',
exponent: '010001'
},
{
modulus: 'b3f762b739be98f343eb1921cf0148cfa27ff7af02b6471213fed9daa0098976e667750324f1abcea4c31e43b7d11f1579133f2b3d9fe27474e462058884e5e1b123be9cbbc6a443b2925c08520e7325e6f1a6d50e117eb61ea49d2534c8bb4d2ae4153fabe832b9edf4c5755fdd8b19940b81d1d96cf433d19e6a22968a85dc80f0312f596bd2530c1cfb28b5fe019ac9bc25cd9c2a5d8a0f3a1c0c79bcca524d315b5e21b5c26b46babe3d75d06d1cd33329ec782a0f22891ed1db42a1d6c0dea431428bc4d7aabdcf3e0eb6fda4e23eb7733e7727e9a1915580796c55188d2596d2665ad1182ba7abf15aaa5a8b779ea996317a20ae044b820bff35b6e8a1',
exponent: '010001'
},
{
modulus: 'be6a71558ee577ff03023cfa17aab4e6c86383cff8a7ad38edb9fafe6f323f2d5106cbc8cafb83b869cffd1ccf121cd743d509e589e68765c96601e813dc5b9dfc4be415c7a6526132d0035ca33d6d6075d4f535122a1cdfe017041f1088d1419f65c8e5490ee613e16dbf662698c0f54870f0475fa893fc41eb55b08ff1ac211bc045ded31be27d12c96d8d3cfc6a7ae8aa50bf2ee0f30ed507cc2581e3dec56de94f5dc0a7abee0be990b893f2887bd2c6310a1e0a9e3e38bd34fded2541508dc102a9c9b4c95effd9dd2dfe96c29be647d6c69d66ca500843cfaed6e440196f1dbe0e2e22163c61ca48c79116fa77216726749a976a1c4b0944b5121e8c01',
exponent: '010001'
}
]
var publicKeysParsed = {}
var prepared = false
@ -180,7 +242,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -180,7 +242,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
.factory('MtpAuthorizer', function (MtpDcConfigurator, MtpRsaKeysManager, MtpSecureRandom, MtpTimeManager, CryptoWorker, $http, $q, $timeout) {
var chromeMatches = navigator.userAgent.match(/Chrome\/(\d+(\.\d+)?)/)
var chromeVersion = chromeMatches && parseFloat(chromeMatches[1]) || false
var xhrSendBuffer = !('ArrayBufferView' in window) && (!chromeVersion || chromeVersion < 30)
var xhrSendBuffer = !('ArrayBufferView' in window) && (chromeVersion > 0 && chromeVersion < 30)
delete $http.defaults.headers.post['Content-Type']
delete $http.defaults.headers.common['Accept']
@ -411,7 +473,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -411,7 +473,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
function mtpVerifyDhParams(g, dhPrime, gA) {
console.log(dT(), 'Verifying DH params')
var dhPrimeHex = bytesToHex(dhPrime);
var dhPrimeHex = bytesToHex(dhPrime)
if (g != 3 ||
dhPrimeHex !== 'c71caeb9c6b1c9048e6c522f70f13f73980d40238e3e21c14934d037563d930f48198a0aa7c14058229493d22530f4dbfa336f6e0ac925139543aed44cce7c3720fd51f69458705ac68cd4fe6b6b13abdc9746512969328454f18faf8c595f642477fe96bb2a941d5bcd1d4ac8cc49880708fa9b378e3c4f3a9060bee67cf9a4a4a695811051907e162753b56b0f6b410dba74d8a84b2a14b3144e0ef1284754fd17ed950d5965b4b9dd46582db1178d169c6bc465b0d6ff9ca3928fef5b9ae4e418fc15e83ebea0f87fa9ff5eed70050ded2849f47bf959d956850ce929851f0d8115f635b105ee2e4e15d04b2454bf6f4fadf034b10403119cd8e3b92fcc5b') {
// The verified value is from https://core.telegram.org/mtproto/security_guidelines
@ -597,7 +659,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -597,7 +659,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
var akStopped = false
var chromeMatches = navigator.userAgent.match(/Chrome\/(\d+(\.\d+)?)/)
var chromeVersion = chromeMatches && parseFloat(chromeMatches[1]) || false
var xhrSendBuffer = !('ArrayBufferView' in window) && (!chromeVersion || chromeVersion < 30)
var xhrSendBuffer = !('ArrayBufferView' in window) && (chromeVersion > 0 && chromeVersion < 30)
delete $http.defaults.headers.post['Content-Type']
delete $http.defaults.headers.common['Accept']
@ -837,8 +899,8 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -837,8 +899,8 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
}).then(function () {
delete self.longPollPending
setZeroTimeout(self.checkLongPoll.bind(self))
}, function () {
console.log('Long-poll failed')
}, function (error) {
console.log('Long-poll failed', error)
})
}
@ -874,48 +936,44 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -874,48 +936,44 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
this.sheduleRequest(delay)
}
MtpNetworker.prototype.getMsgKeyIv = function (msgKey, isOut) {
MtpNetworker.prototype.getMsgKey = function (dataWithPadding, isOut) {
var authKey = this.authKeyUint8
var x = isOut ? 0 : 8
var sha1aText = new Uint8Array(48)
var sha1bText = new Uint8Array(48)
var sha1cText = new Uint8Array(48)
var sha1dText = new Uint8Array(48)
var promises = {}
sha1aText.set(msgKey, 0)
sha1aText.set(authKey.subarray(x, x + 32), 16)
promises.sha1a = CryptoWorker.sha1Hash(sha1aText)
var msgKeyLargePlain = bufferConcat(authKey.subarray(88 + x, 88 + x + 32), dataWithPadding)
return CryptoWorker.sha256Hash(msgKeyLargePlain).then(function (msgKeyLarge) {
var msgKey = new Uint8Array(msgKeyLarge).subarray(8, 24)
return msgKey
})
}
sha1bText.set(authKey.subarray(x + 32, x + 48), 0)
sha1bText.set(msgKey, 16)
sha1bText.set(authKey.subarray(x + 48, x + 64), 32)
promises.sha1b = CryptoWorker.sha1Hash(sha1bText)
MtpNetworker.prototype.getAesKeyIv = function (msgKey, isOut) {
var authKey = this.authKeyUint8
var x = isOut ? 0 : 8
var sha2aText = new Uint8Array(52)
var sha2bText = new Uint8Array(52)
var promises = {}
sha1cText.set(authKey.subarray(x + 64, x + 96), 0)
sha1cText.set(msgKey, 32)
promises.sha1c = CryptoWorker.sha1Hash(sha1cText)
sha2aText.set(msgKey, 0)
sha2aText.set(authKey.subarray(x, x + 36), 16)
promises.sha2a = CryptoWorker.sha256Hash(sha2aText)
sha1dText.set(msgKey, 0)
sha1dText.set(authKey.subarray(x + 96, x + 128), 16)
promises.sha1d = CryptoWorker.sha1Hash(sha1dText)
sha2bText.set(authKey.subarray(40 + x, 40 + x + 36), 0)
sha2bText.set(msgKey, 36)
promises.sha2b = CryptoWorker.sha256Hash(sha2bText)
return $q.all(promises).then(function (result) {
var aesKey = new Uint8Array(32)
var aesIv = new Uint8Array(32)
sha1a = new Uint8Array(result.sha1a),
sha1b = new Uint8Array(result.sha1b),
sha1c = new Uint8Array(result.sha1c),
sha1d = new Uint8Array(result.sha1d)
var sha2a = new Uint8Array(result.sha2a)
var sha2b = new Uint8Array(result.sha2b)
aesKey.set(sha1a.subarray(0, 8))
aesKey.set(sha1b.subarray(8, 20), 8)
aesKey.set(sha1c.subarray(4, 16), 20)
aesKey.set(sha2a.subarray(0, 8))
aesKey.set(sha2b.subarray(8, 24), 8)
aesKey.set(sha2a.subarray(24, 32), 24)
aesIv.set(sha1a.subarray(8, 20))
aesIv.set(sha1b.subarray(0, 8), 12)
aesIv.set(sha1c.subarray(16, 20), 20)
aesIv.set(sha1d.subarray(0, 8), 24)
aesIv.set(sha2b.subarray(0, 8))
aesIv.set(sha2a.subarray(8, 24), 8)
aesIv.set(sha2b.subarray(24, 32), 24)
return [aesKey, aesIv]
})
@ -1145,7 +1203,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1145,7 +1203,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
this.checkConnectionPeriod = Math.max(1.1, Math.sqrt(this.checkConnectionPeriod))
})
}, function (error) {
console.log('Encrypted request failed', error)
console.error('Encrypted request failed', error)
if (message.container) {
angular.forEach(message.inner, function (msgID) {
@ -1173,16 +1231,12 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1173,16 +1231,12 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
}
}
MtpNetworker.prototype.getEncryptedMessage = function (bytes) {
MtpNetworker.prototype.getEncryptedMessage = function (dataWithPadding) {
var self = this
// console.log(dT(), 'Start encrypt', bytes.byteLength)
return CryptoWorker.sha1Hash(bytes).then(function (bytesHash) {
// console.log(dT(), 'after hash')
var msgKey = new Uint8Array(bytesHash).subarray(4, 20)
return self.getMsgKeyIv(msgKey, true).then(function (keyIv) {
return self.getMsgKey(dataWithPadding, true).then(function (msgKey) {
return self.getAesKeyIv(msgKey, true).then(function (keyIv) {
// console.log(dT(), 'after msg key iv')
return CryptoWorker.aesEncrypt(bytes, keyIv[0], keyIv[1]).then(function (encryptedBytes) {
return CryptoWorker.aesEncrypt(dataWithPadding, keyIv[0], keyIv[1]).then(function (encryptedBytes) {
// console.log(dT(), 'Finish encrypt')
return {
bytes: encryptedBytes,
@ -1195,7 +1249,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1195,7 +1249,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
MtpNetworker.prototype.getDecryptedMessage = function (msgKey, encryptedData) {
// console.log(dT(), 'get decrypted start')
return this.getMsgKeyIv(msgKey, false).then(function (keyIv) {
return this.getAesKeyIv(msgKey, false).then(function (keyIv) {
// console.log(dT(), 'after msg key iv')
return CryptoWorker.aesDecrypt(encryptedData, keyIv[0], keyIv[1])
})
@ -1206,7 +1260,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1206,7 +1260,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
options = options || {}
// console.log(dT(), 'Send encrypted'/*, message*/)
// console.trace()
var data = new TLSerialization({startMaxLength: message.body.length + 64})
var data = new TLSerialization({startMaxLength: message.body.length + 2048})
data.storeIntBytes(this.serverSalt, 64, 'salt')
data.storeIntBytes(this.sessionID, 64, 'session_id')
@ -1217,7 +1271,17 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1217,7 +1271,17 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
data.storeInt(message.body.length, 'message_data_length')
data.storeRawBytes(message.body, 'message_data')
return this.getEncryptedMessage(data.getBuffer()).then(function (encryptedResult) {
var dataBuffer = data.getBuffer()
var paddingLength = (16 - (data.offset % 16)) + 16 * (1 + nextRandomInt(5))
var padding = new Array(paddingLength)
MtpSecureRandom.nextBytes(padding)
var dataWithPadding = bufferConcat(dataBuffer, padding)
// console.log(dT(), 'Adding padding', dataBuffer, padding, dataWithPadding)
// console.log(dT(), 'auth_key_id', bytesToHex(self.authKeyID))
return this.getEncryptedMessage(dataWithPadding).then(function (encryptedResult) {
// console.log(dT(), 'Got encrypted out message'/*, encryptedResult*/)
var request = new TLSerialization({startMaxLength: encryptedResult.bytes.byteLength + 256})
request.storeIntBytes(self.authKeyID, 64, 'auth_key_id')
@ -1259,7 +1323,6 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1259,7 +1323,6 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
MtpNetworker.prototype.parseResponse = function (responseBuffer) {
// console.log(dT(), 'Start parsing response')
var self = this
var deserializer = new TLDeserialization(responseBuffer)
var authKeyID = deserializer.fetchIntBytes(64, false, 'auth_key_id')
@ -1269,43 +1332,44 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1269,43 +1332,44 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
var msgKey = deserializer.fetchIntBytes(128, true, 'msg_key')
var encryptedData = deserializer.fetchRawBytes(responseBuffer.byteLength - deserializer.getOffset(), true, 'encrypted_data')
return this.getDecryptedMessage(msgKey, encryptedData).then(function (dataWithPadding) {
return self.getDecryptedMessage(msgKey, encryptedData).then(function (dataWithPadding) {
// console.log(dT(), 'after decrypt')
var deserializer = new TLDeserialization(dataWithPadding, {mtproto: true})
return self.getMsgKey(dataWithPadding, false).then(function (calcMsgKey) {
if (!bytesCmp(msgKey, calcMsgKey)) {
console.warn('[MT] msg_keys', msgKey, bytesFromArrayBuffer(calcMsgKey))
throw new Error('[MT] server msgKey mismatch')
}
// console.log(dT(), 'after msgKey check')
var salt = deserializer.fetchIntBytes(64, false, 'salt')
var sessionID = deserializer.fetchIntBytes(64, false, 'session_id')
var messageID = deserializer.fetchLong('message_id')
var deserializer = new TLDeserialization(dataWithPadding, {mtproto: true})
if (!bytesCmp(sessionID, self.sessionID) &&
(!self.prevSessionID || !bytesCmp(sessionID, self.prevSessionID))) {
console.warn('Sessions', sessionID, self.sessionID, self.prevSessionID)
throw new Error('[MT] Invalid server session_id: ' + bytesToHex(sessionID))
}
var salt = deserializer.fetchIntBytes(64, false, 'salt')
var sessionID = deserializer.fetchIntBytes(64, false, 'session_id')
var messageID = deserializer.fetchLong('message_id')
var seqNo = deserializer.fetchInt('seq_no')
if (!bytesCmp(sessionID, self.sessionID) &&
(!self.prevSessionID || !bytesCmp(sessionID, self.prevSessionID))) {
console.warn('Sessions', sessionID, self.sessionID, self.prevSessionID)
throw new Error('[MT] Invalid server session_id: ' + bytesToHex(sessionID))
}
var offset = deserializer.getOffset()
var totalLength = dataWithPadding.byteLength
var seqNo = deserializer.fetchInt('seq_no')
var messageBodyLength = deserializer.fetchInt('message_data[length]')
if ((messageBodyLength % 4) ||
messageBodyLength > totalLength - offset) {
throw new Error('[MT] Invalid body length: ' + messageBodyLength)
}
var messageBody = deserializer.fetchRawBytes(messageBodyLength, true, 'message_data')
var totalLength = dataWithPadding.byteLength
var offset = deserializer.getOffset()
var paddingLength = totalLength - offset
if (paddingLength < 0 || paddingLength > 15) {
throw new Error('[MT] Invalid padding length: ' + paddingLength)
}
var hashData = convertToUint8Array(dataWithPadding).subarray(0, offset)
var messageBodyLength = deserializer.fetchInt('message_data[length]')
var offset = deserializer.getOffset()
return CryptoWorker.sha1Hash(hashData).then(function (dataHash) {
if (!bytesCmp(msgKey, bytesFromArrayBuffer(dataHash).slice(-16))) {
console.warn(msgKey, bytesFromArrayBuffer(dataHash))
throw new Error('[MT] server msgKey mismatch')
if ((messageBodyLength % 4) ||
messageBodyLength > totalLength - offset) {
throw new Error('[MT] Invalid body length: ' + messageBodyLength)
}
var messageBody = deserializer.fetchRawBytes(messageBodyLength, true, 'message_data')
var offset = deserializer.getOffset()
var paddingLength = totalLength - offset
if (paddingLength < 12 || paddingLength > 1024) {
throw new Error('[MT] Invalid padding length: ' + paddingLength)
}
var buffer = bytesToArrayBuffer(messageBody)

35
app/js/lib/polyfill.js

@ -104,19 +104,38 @@ if (!Function.prototype.bind) { @@ -104,19 +104,38 @@ if (!Function.prototype.bind) {
/* setZeroTimeout polyfill, from http://dbaron.org/log/20100309-faster-timeouts */
(function (global) {
var timeouts = []
var messageName = 'zero-timeout-message'
var originalSetTimeout = global.setTimeout
var originalClearTimeout = global.clearTimeout
var originalMinId = originalSetTimeout(function () {}, 0)
var zeroTimeouts = []
var zeroMinId = originalMinId + 100000000
function setZeroTimeout (fn) {
timeouts.push(fn)
var timeoutId = ++zeroMinId
zeroTimeouts.push([timeoutId, fn])
global.postMessage(messageName, '*')
return timeoutId
}
function clearZeroTimeout(timeoutId) {
if (timeoutId && timeoutId >= zeroMinId) {
for (var i = 0, len = zeroTimeouts.length; i < len; i++) {
if (zeroTimeouts[i][0] == timeoutId) {
console.warn('spliced timeout', timeoutId, i)
zeroTimeouts.splice(i, 1)
break
}
}
}
}
function handleMessage (event) {
if (event.source == global && event.data == messageName) {
event.stopPropagation()
if (timeouts.length > 0) {
var fn = timeouts.shift()
if (zeroTimeouts.length > 0) {
var fn = zeroTimeouts.shift()[1]
fn()
}
}
@ -124,7 +143,6 @@ if (!Function.prototype.bind) { @@ -124,7 +143,6 @@ if (!Function.prototype.bind) {
global.addEventListener('message', handleMessage, true)
var originalSetTimeout = global.setTimeout
global.setTimeout = function (callback, delay) {
if (!delay || delay <= 5) {
return setZeroTimeout(callback)
@ -132,5 +150,12 @@ if (!Function.prototype.bind) { @@ -132,5 +150,12 @@ if (!Function.prototype.bind) {
return originalSetTimeout(callback, delay)
}
global.clearTimeout = function (timeoutId) {
if (timeoutId >= zeroMinId) {
clearZeroTimeout(timeoutId)
}
return originalClearTimeout(timeoutId)
}
global.setZeroTimeout = setZeroTimeout
})(this)

10308
app/vendor/jquery/jquery.js vendored

File diff suppressed because it is too large Load Diff

2
app/webogram.appcache

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
CACHE MANIFEST
# 66
# 67
NETWORK:
*

Loading…
Cancel
Save