From 0c9a3b8548c01aace2a05a8dfa6d86dc8cf681ff Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Mon, 25 Jul 2022 04:56:10 +0200 Subject: [PATCH] Fix computing call fingerprint --- src/components/call/index.ts | 3 ++- src/helpers/bigInt/bigIntConstants.ts | 5 +++++ src/helpers/bigInt/bigIntConversion.ts | 9 +++++++++ src/lib/calls/callsController.ts | 3 ++- src/lib/crypto/computeDhKey.ts | 6 +++--- src/lib/mtproto/tl_utils.ts | 16 +++++----------- src/scss/partials/popups/_call.scss | 1 + 7 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 src/helpers/bigInt/bigIntConstants.ts diff --git a/src/components/call/index.ts b/src/components/call/index.ts index 57d47804..f2e4fc0d 100644 --- a/src/components/call/index.ts +++ b/src/components/call/index.ts @@ -10,6 +10,7 @@ import { attachClickEvent } from "../../helpers/dom/clickEvent"; import ControlsHover from "../../helpers/dom/controlsHover"; import findUpClassName from "../../helpers/dom/findUpClassName"; import { addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen } from "../../helpers/dom/fullScreen"; +import replaceContent from "../../helpers/dom/replaceContent"; import MovablePanel from "../../helpers/movablePanel"; import onMediaLoad from "../../helpers/onMediaLoad"; import themeController from "../../helpers/themeController"; @@ -441,7 +442,7 @@ export default class PopupCall extends PopupElement { if(!this.emojisSubtitle.textContent && connectionState < CALL_STATE.EXCHANGING_KEYS) { Promise.resolve(instance.getEmojisFingerprint()).then((emojis) => { - this.emojisSubtitle.append(wrapEmojiText(emojis.join(''))); + replaceContent(this.emojisSubtitle, wrapEmojiText(emojis.join(''))); }); } diff --git a/src/helpers/bigInt/bigIntConstants.ts b/src/helpers/bigInt/bigIntConstants.ts new file mode 100644 index 00000000..d2ae8f26 --- /dev/null +++ b/src/helpers/bigInt/bigIntConstants.ts @@ -0,0 +1,5 @@ +import bigInt from 'big-integer'; + +export const safeBigInt = bigInt(Number.MAX_SAFE_INTEGER); +export const ulongBigInt = bigInt(bigInt[2]).pow(64); +export const longBigInt = ulongBigInt.divide(bigInt[2]); diff --git a/src/helpers/bigInt/bigIntConversion.ts b/src/helpers/bigInt/bigIntConversion.ts index 088e7359..65c9876c 100644 --- a/src/helpers/bigInt/bigIntConversion.ts +++ b/src/helpers/bigInt/bigIntConversion.ts @@ -1,4 +1,5 @@ import bigInt from 'big-integer'; +import { longBigInt, ulongBigInt } from './bigIntConstants'; export function bigIntFromBytes(bytes: Uint8Array | number[], base = 256) { return bigInt.fromArray(bytes instanceof Uint8Array ? [...bytes] : bytes, base); @@ -7,3 +8,11 @@ export function bigIntFromBytes(bytes: Uint8Array | number[], base = 256) { export function bigIntToBytes(bigInt: bigInt.BigInteger) { return new Uint8Array(bigInt.toArray(256).value); } + +export function bigIntToSigned(bigInt: bigInt.BigInteger) { + return bigInt.greater(longBigInt) ? bigInt.minus(ulongBigInt) : bigInt; +} + +export function bigIntToUnsigned(bigInt: bigInt.BigInteger) { + return bigInt.isNegative() ? ulongBigInt.add(bigInt) : bigInt; +} diff --git a/src/lib/calls/callsController.ts b/src/lib/calls/callsController.ts index 4b71b235..62948a1f 100644 --- a/src/lib/calls/callsController.ts +++ b/src/lib/calls/callsController.ts @@ -115,7 +115,8 @@ export class CallsController extends EventListenerBase<{ const {key, key_fingerprint} = await this.managers.appCallsManager.computeKey(g_a, dh.b, dh.p); if(call.key_fingerprint !== key_fingerprint) { - this.log.error('Incorrect key fingerprint', call.key_fingerprint, key_fingerprint); + this.log.error('Incorrect key fingerprint', call.key_fingerprint, key_fingerprint, g_a, dh); + instance.hangUp('phoneCallDiscardReasonDisconnect'); break; } diff --git a/src/lib/crypto/computeDhKey.ts b/src/lib/crypto/computeDhKey.ts index 7b1b9762..230d673e 100644 --- a/src/lib/crypto/computeDhKey.ts +++ b/src/lib/crypto/computeDhKey.ts @@ -4,14 +4,14 @@ * https://github.com/morethanwords/tweb/blob/master/LICENSE */ -import { bigIntFromBytes } from "../../helpers/bigInt/bigIntConversion"; +import { bigIntFromBytes, bigIntToSigned } from "../../helpers/bigInt/bigIntConversion"; import cryptoWorker from "./cryptoMessagePort"; export default async function computeDhKey(g_b: Uint8Array, a: Uint8Array, p: Uint8Array) { const key = await cryptoWorker.invokeCrypto('mod-pow', g_b, a, p); const keySha1Hashed = await cryptoWorker.invokeCrypto('sha1', key); - const key_fingerprint = keySha1Hashed.slice(-8).reverse(); // key_fingerprint: key_fingerprint as any // ! it doesn't work - const key_fingerprint_long = bigIntFromBytes(key_fingerprint).toString(10); // bigInt2str(str2bigInt(bytesToHex(key_fingerprint), 16), 10); + const key_fingerprint = keySha1Hashed.slice(-8).reverse(); + const key_fingerprint_long = bigIntToSigned(bigIntFromBytes(key_fingerprint)).toString(10); return {key, key_fingerprint: key_fingerprint_long}; } diff --git a/src/lib/mtproto/tl_utils.ts b/src/lib/mtproto/tl_utils.ts index 2c8de448..ab9955bb 100644 --- a/src/lib/mtproto/tl_utils.ts +++ b/src/lib/mtproto/tl_utils.ts @@ -17,16 +17,14 @@ import isObject from '../../helpers/object/isObject'; import gzipUncompress from '../../helpers/gzipUncompress'; import bigInt from 'big-integer'; import ulongFromInts from '../../helpers/long/ulongFromInts'; +import { safeBigInt } from '../../helpers/bigInt/bigIntConstants'; +import { bigIntToSigned, bigIntToUnsigned } from '../../helpers/bigInt/bigIntConversion'; const boolFalse = +Schema.API.constructors.find((c) => c.predicate === 'boolFalse').id; const boolTrue = +Schema.API.constructors.find((c) => c.predicate === 'boolTrue').id; const vector = +Schema.API.constructors.find((c) => c.predicate === 'vector').id; const gzipPacked = +Schema.MTProto.constructors.find((c) => c.predicate === 'gzip_packed').id; -const safeBigInt = bigInt(Number.MAX_SAFE_INTEGER); -const ulongBigInt = bigInt(bigInt[2]).pow(64); -const longBigInt = ulongBigInt.divide(bigInt[2]); - class TLSerialization { private maxLength = 2048; // 2Kb private offset = 0; // in bytes @@ -151,11 +149,7 @@ class TLSerialization { } } - let _bigInt = bigInt(sLong as string); - if(_bigInt.isNegative()) { // make it unsigned - _bigInt = ulongBigInt.add(_bigInt); - } - + const _bigInt = bigIntToUnsigned(bigInt(sLong as string)); const {quotient, remainder} = _bigInt.divmod(0x100000000); const high = quotient.toJSNumber(); const low = remainder.toJSNumber(); @@ -504,8 +498,8 @@ class TLDeserialization { const iHigh = this.readInt((field || '') + ':long[high]'); let ulong = ulongFromInts(iHigh, iLow); - if(/* !unsigned && */!this.mtproto && ulong.greater(longBigInt)) { // make it signed - ulong = ulong.minus(ulongBigInt); + if(/* !unsigned && */!this.mtproto) { // make it signed + ulong = bigIntToSigned(ulong); } if(!this.mtproto) { diff --git a/src/scss/partials/popups/_call.scss b/src/scss/partials/popups/_call.scss index ab42559b..1269e9b2 100644 --- a/src/scss/partials/popups/_call.scss +++ b/src/scss/partials/popups/_call.scss @@ -10,6 +10,7 @@ #{$parent} { &-header { width: 100%; + justify-content: space-between; } &-title {