From 5219cdf2c9b576d30c828e6375411528fcdddfd6 Mon Sep 17 00:00:00 2001 From: Evan Hahn <69474926+EvanHahn-Signal@users.noreply.github.com> Date: Wed, 5 Oct 2022 16:35:56 +0000 Subject: [PATCH] Make 1 the minimum registration ID --- ts/Crypto.ts | 28 ++++++++-------------------- ts/context/Crypto.ts | 4 ++++ ts/test-electron/Crypto_test.ts | 18 +++++++++++++++--- ts/textsecure/WebAPI.ts | 6 +++--- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/ts/Crypto.ts b/ts/Crypto.ts index 15e3d4303c7f..4971b2b87494 100644 --- a/ts/Crypto.ts +++ b/ts/Crypto.ts @@ -34,17 +34,8 @@ export type EncryptedAttachment = { digest: Uint8Array; }; -// Generate a number between zero and 16383 export function generateRegistrationId(): number { - const bytes = getRandomBytes(2); - const id = new Uint16Array( - bytes.buffer, - bytes.byteOffset, - bytes.byteLength / 2 - )[0]; - - // eslint-disable-next-line no-bitwise - return id & 0x3fff; + return randomInt(1, 16383); } export function deriveStickerPackKey(packKey: Uint8Array): Uint8Array { @@ -342,16 +333,6 @@ export function sha256(data: Uint8Array): Uint8Array { // Utility -export function getRandomValue(low: number, high: number): number { - const diff = high - low; - const bytes = getRandomBytes(1); - - // Because high and low are inclusive - const mod = diff + 1; - - return (bytes[0] % mod) + low; -} - export function getZeroes(n: number): Uint8Array { return new Uint8Array(n); } @@ -683,6 +664,13 @@ export function decrypt( return crypto.decrypt(...args); } +/** + * Generate an integer between `min` and `max`, inclusive. + */ +export function randomInt(min: number, max: number): number { + return crypto.randomInt(min, max + 1); +} + export function getRandomBytes(size: number): Uint8Array { return crypto.getRandomBytes(size); } diff --git a/ts/context/Crypto.ts b/ts/context/Crypto.ts index be1f8a80cc56..e8651db34dc4 100644 --- a/ts/context/Crypto.ts +++ b/ts/context/Crypto.ts @@ -119,6 +119,10 @@ export class Crypto { return Buffer.concat([decipher.update(input), decipher.final()]); } + public randomInt(min: number, max: number): number { + return crypto.randomInt(min, max); + } + public getRandomBytes(size: number): Uint8Array { return crypto.randomBytes(size); } diff --git a/ts/test-electron/Crypto_test.ts b/ts/test-electron/Crypto_test.ts index 88fbcf04dd7c..85f644376c74 100644 --- a/ts/test-electron/Crypto_test.ts +++ b/ts/test-electron/Crypto_test.ts @@ -25,6 +25,7 @@ import { decryptSymmetric, hmacSha256, verifyHmacSha256, + randomInt, uuidToBytes, bytesToUuid, } from '../Crypto'; @@ -164,11 +165,11 @@ describe('Crypto', () => { }); describe('generateRegistrationId', () => { - it('generates an integer between 0 and 16383 (inclusive)', () => { - let max = 0; + it('generates an integer between 1 and 16383 (inclusive)', () => { + let max = -1; for (let i = 0; i < 100; i += 1) { const id = generateRegistrationId(); - assert.isAtLeast(id, 0); + assert.isAtLeast(id, 1); assert.isAtMost(id, 16383); assert(Number.isInteger(id)); @@ -441,6 +442,17 @@ describe('Crypto', () => { }); }); + describe('randomInt', () => { + it('returns random integers in a range (inclusive)', () => { + const seen = new Set(); + for (let i = 0; i < 1_000_000 || seen.size < 3; i += 1) { + seen.add(randomInt(1, 3)); + } + + assert.deepStrictEqual(seen, new Set([1, 2, 3])); + }); + }); + describe('uuidToBytes', () => { it('converts valid UUIDs to Uint8Arrays', () => { const expectedResult = new Uint8Array([ diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index 3b930428e775..109da0b61c7b 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -35,7 +35,7 @@ import type { UUID, UUIDStringType } from '../types/UUID'; import { UUIDKind } from '../types/UUID'; import type { DirectoryConfigType } from '../types/RendererConfig'; import * as Bytes from '../Bytes'; -import { getRandomValue } from '../Crypto'; +import { randomInt } from '../Crypto'; import * as linkPreviewFetch from '../linkPreviews/linkPreviewFetch'; import { isBadgeImageFileUrlValid } from '../badges/isBadgeImageFileUrlValid'; @@ -2431,11 +2431,11 @@ export function initialize({ } function getHeaderPadding() { - const max = getRandomValue(1, 64); + const max = randomInt(1, 64); let characters = ''; for (let i = 0; i < max; i += 1) { - characters += String.fromCharCode(getRandomValue(65, 122)); + characters += String.fromCharCode(randomInt(65, 122)); } return characters;