From eaad9462bb2730cd9d6522287ef833c2fb60aba8 Mon Sep 17 00:00:00 2001 From: Alka Date: Fri, 22 Dec 2023 12:29:38 +0530 Subject: [PATCH] [INJI-612]: Add telemetry events for HMac corruption Signed-off-by: Alka --- .talismanrc | 9 +-- shared/fileStorage.ts | 10 ++++ shared/storage.ts | 127 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 124 insertions(+), 22 deletions(-) diff --git a/.talismanrc b/.talismanrc index 63025b2e27..9ea68dcb3f 100644 --- a/.talismanrc +++ b/.talismanrc @@ -38,9 +38,9 @@ fileignoreconfig: - filename: shared/telemetry/TelemetryUtils.js checksum: ffe9aac2dcc590b98b0d588885c088eff189504ade653a77f74b67312bfd27ad - filename: shared/fileStorage.ts - checksum: 07cb337dc1d5b0f0eef56270ac4f4f589260ee5e490183c024cf98a2aeafb139 + checksum: f86dc7aa4a69e7109310e7ab5529a8599f38f15eb79f3f4da545aceaaf90d731 - filename: shared/storage.ts - checksum: c8d874aa373bdf526bf59192139822f56915e702ef673bac4e0d7549b0fea3d0 + checksum: c31270346f2ef717a31168a93d0311ce6f925434eb613ec7cf86553222630cdb - filename: screens/Issuers/IssuersScreen.tsx checksum: 9c53e3770dbefe26e0de67ee4b7d5cc9c52d9823cbb136a1a5104dcb0a101071 - filename: ios/Podfile.lock @@ -79,18 +79,13 @@ fileignoreconfig: checksum: feea5a7f044ef6961d53e7d1e1ffb92a3e0f72761496424f6e64288e3718d605 - filename: machines/bleShare/scan/scanMachine.ts checksum: a514c958ca3da3c5b22a1a95ad680af8f05fb22638fab79b3842aa8fcc1b4a17 - version: '' - filename: locales/spa.json checksum: eac9685c6b205ece5759e414669d27ad7ce383453d7b5e7d9f5ce75d290cc860 - version: '' - filename: screens/PasscodeScreen.tsx checksum: 5d3003027b245234f8c00bfc98836f1fb90a5d9525ffacf61c53f3d50954aa6a - version: '' - filename: screens/PasscodeScreen.tsx checksum: 3330b9db9cfce407782e82b4fe3c0b60a9ecb0f9327af2b69971e254f9e52921 - version: '' - filename: screens/Home/MyVcs/OtpVerificationModal.tsx checksum: a99fe136d9d1348c541d413324d266e179ecad6a1fe6b6bd1e0b2856a5a6d6b5 - filename: screens/QrLogin/QrConsent.tsx checksum: 8563a194a4d38814eff670f0652d1a7af77134cafb350462174b4f147dbd890d - version: '' diff --git a/shared/fileStorage.ts b/shared/fileStorage.ts index 426f121977..e2835e80b2 100644 --- a/shared/fileStorage.ts +++ b/shared/fileStorage.ts @@ -56,4 +56,14 @@ export const getFilePath = (key: string) => { return `${vcDirectoryPath}/${key}.txt`; }; +//TODO: added temporarily for INJI-612 +export const getFilePathOfHmac = (key: string) => { + return `${vcDirectoryPath}/${key}.hmac`; +}; + +//TODO: added temporarily for INJI-612 +export const getFilePathOfEncryptedHmac = (key: string) => { + return `${vcDirectoryPath}/${key}.hmace`; +}; + export const vcDirectoryPath = `${DocumentDirectoryPath}/inji/VC`; diff --git a/shared/storage.ts b/shared/storage.ts index 363c5db150..01897ba3f9 100644 --- a/shared/storage.ts +++ b/shared/storage.ts @@ -21,9 +21,19 @@ import { RECEIVED_VCS_STORE_KEY, SETTINGS_STORE_KEY, } from './constants'; -import FileStorage, {getFilePath, vcDirectoryPath} from './fileStorage'; +import FileStorage, { + getFilePath, + getFilePathOfEncryptedHmac, + getFilePathOfHmac, + vcDirectoryPath, +} from './fileStorage'; import {__AppId} from './GlobalVariables'; -import {getErrorEventData, sendErrorEvent} from './telemetry/TelemetryUtils'; +import { + getErrorEventData, + getImpressionEventData, + sendErrorEvent, + sendImpressionEvent, +} from './telemetry/TelemetryUtils'; import {TelemetryConstants} from './telemetry/TelemetryConstants'; export const MMKV = new MMKVLoader().initialize(); @@ -94,15 +104,6 @@ class Storage { ); console.debug('[Inji-406]: VC key: ', key); console.debug('[Inji-406]: is Data null', data === null); - getItem(MY_VCS_STORE_KEY, [], encryptionKey).then(res => { - console.debug('[Inji-406]: vcKeys are ', JSON.stringify(res)); - }); - getItem(RECEIVED_VCS_STORE_KEY, null, encryptionKey).then(res => { - console.debug( - '[Inji-406]: received vcKeys is ', - JSON.stringify(res), - ); - }); } return isCorrupted ? null : data; @@ -155,12 +156,40 @@ class Storage { encryptionKey: string, data: string, ) { - const storedHMACofCurrentVC = await this.readHmacForVC(key, encryptionKey); + // TODO: INJI-612 refactor + const storedHMACofCurrentVC = await this.readHmacForDataCorruptionCheck( + key, + encryptionKey, + ); const HMACofVC = await generateHmac(encryptionKey, data); + const hmacStoredinFile = await this.readHmacForVCFromFile(key); if (HMACofVC !== storedHMACofCurrentVC) { - console.debug( - `[Inji-406]: storedHmacOfCurrentVC: ${storedHMACofCurrentVC}, HMACofVC: ${HMACofVC}`, + if (__DEV__) { + sendImpressionEvent( + getImpressionEventData('VC Corruption Event', 'VC Download', { + key: key, + 'HMAC stored in MMKV': this.hexEncode(storedHMACofCurrentVC!), + 'Length HMAC stored in MMKV': storedHMACofCurrentVC?.length, + 'HMAC of VC': this.hexEncode(HMACofVC), + 'Length of HMAC of VC': HMACofVC.length, + 'HMAC stored in file': this.hexEncode(hmacStoredinFile), + 'File vs mmkv data': + hmacStoredinFile === this.hexEncode(storedHMACofCurrentVC!), + }), + ); + } + console.log( + `VC corruption Details: ${JSON.stringify({ + key: key, + 'HMAC stored in MMKV': this.hexEncode(storedHMACofCurrentVC!), + 'Length HMAC stored in MMKV': storedHMACofCurrentVC?.length, + 'HMAC of VC': this.hexEncode(HMACofVC), + 'Length of HMAC of VC': HMACofVC.length, + 'HMAC stored in file': this.hexEncode(hmacStoredinFile), + 'File vs mmkv data': + hmacStoredinFile === this.hexEncode(storedHMACofCurrentVC!), + })}`, ); } @@ -175,6 +204,57 @@ class Storage { return null; } + //TODO: added temporarily for INJI-612 + private static async readHmacForVCFromFile(key: string) { + const HMACofCurrentVC = await FileStorage.readFile(getFilePathOfHmac(key)); + return HMACofCurrentVC; + } + + private static async readHmacForDataCorruptionCheck( + key: string, + encryptionKey: string, + ) { + const encryptedHMACofCurrentVC = await MMKV.getItem(key); + const encryptedHMACofCurrentVCFromMMKVFile = await FileStorage.readFile( + getFilePathOfEncryptedHmac(key), + ); + + if (encryptedHMACofCurrentVC !== encryptedHMACofCurrentVCFromMMKVFile) { + if (__DEV__) { + sendImpressionEvent( + getImpressionEventData('Encrypted HMac Corruption', 'VC Download', { + key: key, + 'Encrypted HMAC of Current VC from MMKV store': + encryptedHMACofCurrentVC, + 'Encrypted HMAC of Current VC from file': + encryptedHMACofCurrentVCFromMMKVFile, + 'encryptedHMACofCurrentVC vs encryptedHMACofCurrentVCFromMMKVFile': `${ + encryptedHMACofCurrentVCFromMMKVFile === encryptedHMACofCurrentVC + }`, + }), + ); + } + + console.log( + `VC corruption Details: ${{ + key: key, + 'Encrypted HMAC of Current VC from MMKV store': + encryptedHMACofCurrentVC, + 'Encrypted HMAC of Current VC from file': + encryptedHMACofCurrentVCFromMMKVFile, + 'encryptedHMACofCurrentVC vs encryptedHMACofCurrentVCFromMMKVFile': `${ + encryptedHMACofCurrentVCFromMMKVFile === encryptedHMACofCurrentVC + }`, + }}`, + ); + } + + if (encryptedHMACofCurrentVC) { + return decryptJson(encryptionKey, encryptedHMACofCurrentVC); + } + return null; + } + private static async readVCFromFile(key: string) { return await FileStorage.readFile(getFilePath(key)); } @@ -185,14 +265,31 @@ class Storage { return await FileStorage.writeFile(path, data); } + // TODO: INJI-612 refactor + private static hexEncode(inp: string) { + var hex, i; + var result = ''; + for (i = 0; i < inp.length; i++) { + hex = inp.charCodeAt(i).toString(16); + result += ('000' + hex).slice(-4); + } + return result; + } + + // TODO: INJI-612 refactor private static async storeVcHmac( encryptionKey: string, data: string, key: string, ) { const HMACofVC = await generateHmac(encryptionKey, data); - console.log('[Inji-406]: Updating hmac of the vc: ', HMACofVC); const encryptedHMACofVC = await encryptJson(encryptionKey, HMACofVC); + const keyOfEncodedHmacStorage = getFilePathOfHmac(key); + const keyOfEncryptedHmacStorage = getFilePathOfEncryptedHmac(key); + + const encodedHMACofVC = this.hexEncode(HMACofVC); + await FileStorage.writeFile(keyOfEncodedHmacStorage, encodedHMACofVC); + await FileStorage.writeFile(keyOfEncryptedHmacStorage, encryptedHMACofVC); await MMKV.setItem(key, encryptedHMACofVC); }