diff --git a/keyserver/src/push/encrypted-notif-utils-api.js b/keyserver/src/push/encrypted-notif-utils-api.js --- a/keyserver/src/push/encrypted-notif-utils-api.js +++ b/keyserver/src/push/encrypted-notif-utils-api.js @@ -6,6 +6,7 @@ import { blobServiceUpload } from './utils.js'; import { encryptAndUpdateOlmSession } from '../updaters/olm-session-updater.js'; +import { encrypt, generateKey, generateIV } from '../utils/aes-crypto-utils.js'; import { getOlmUtility } from '../utils/olm-utils.js'; const encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI = { @@ -54,6 +55,35 @@ Buffer.byteLength(serializedPayload), getEncryptedNotifHash: async (serializedNotification: string) => getOlmUtility().sha256(serializedNotification), + getBlobHash: async (blob: Uint8Array) => { + return getOlmUtility().sha256(new Uint8Array(blob.buffer)); + }, + generateAESKey: async () => { + const aesKeyBytes = await generateKey(); + return Buffer.from(aesKeyBytes).toString('base64'); + }, + generateAESIV: async () => { + const ivBytes = await generateIV(); + return Buffer.from(ivBytes).toString('base64'); + }, + encryptWithAESKey: async ( + encryptionKey: string, + initializationVector: string, + unencryptedData: string, + ) => { + const encryptionKeyBytes = new Uint8Array( + Buffer.from(encryptionKey, 'base64'), + ); + const initializationVectorBytes = new Uint8Array( + Buffer.from(initializationVector, 'base64'), + ); + const unencrypotedDataBytes = new TextEncoder().encode(unencryptedData); + return await encrypt( + encryptionKeyBytes, + unencrypotedDataBytes, + initializationVectorBytes, + ); + }, }; export default encryptedNotifUtilsAPI; diff --git a/lib/types/notif-types.js b/lib/types/notif-types.js --- a/lib/types/notif-types.js +++ b/lib/types/notif-types.js @@ -420,4 +420,12 @@ >, +getNotifByteSize: (serializedNotification: string) => number, +getEncryptedNotifHash: (serializedNotification: string) => Promise, + +getBlobHash: (blob: Uint8Array) => Promise, + +generateAESKey: () => Promise, + +generateAESIV: () => Promise, + +encryptWithAESKey: ( + encryptionKey: string, + initializationVector: string, + unencrypotedData: string, + ) => Promise, }; diff --git a/lib/utils/__mocks__/config.js b/lib/utils/__mocks__/config.js --- a/lib/utils/__mocks__/config.js +++ b/lib/utils/__mocks__/config.js @@ -47,9 +47,13 @@ fetchMessages: jest.fn(), }, encryptedNotifUtilsAPI: { + generateAESKey: jest.fn(), + generateAESIV: jest.fn(), + encryptWithAESKey: jest.fn(), encryptSerializedNotifPayload: jest.fn(), uploadLargeNotifPayload: jest.fn(), getEncryptedNotifHash: jest.fn(), + getBlobHash: jest.fn(), getNotifByteSize: jest.fn(), }, }); diff --git a/native/push/encrypted-notif-utils-api.js b/native/push/encrypted-notif-utils-api.js --- a/native/push/encrypted-notif-utils-api.js +++ b/native/push/encrypted-notif-utils-api.js @@ -4,6 +4,11 @@ import { getConfig } from 'lib/utils/config.js'; import { commUtilsModule } from '../native-modules.js'; +import { + encrypt, + generateKey, + generateIV, +} from '../utils/aes-crypto-module.js'; const encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI = { encryptSerializedNotifPayload: async ( @@ -37,6 +42,38 @@ ); return commUtilsModule.sha256(notifAsArrayBuffer); }, + getBlobHash: async (blob: Uint8Array) => { + return commUtilsModule.sha256(blob.buffer); + }, + generateAESKey: async () => { + const aesKeyBytes = await generateKey(); + return await commUtilsModule.base64EncodeBuffer(aesKeyBytes.buffer); + }, + generateAESIV: async () => { + const ivBytes = await generateIV(); + return commUtilsModule.base64EncodeBuffer(ivBytes.buffer); + }, + encryptWithAESKey: async ( + encryptionKey: string, + initializationVector: string, + unencrypotedData: string, + ) => { + const [ + encryptionKeyBytes, + unencrypotedDataBytes, + initializationVectorBytes, + ] = await Promise.all([ + commUtilsModule.base64DecodeBuffer(encryptionKey), + commUtilsModule.encodeStringToUTF8ArrayBuffer(unencrypotedData), + commUtilsModule.base64DecodeBuffer(initializationVector), + ]); + + return await encrypt( + new Uint8Array(encryptionKeyBytes), + new Uint8Array(unencrypotedDataBytes), + new Uint8Array(initializationVectorBytes), + ); + }, }; export default encryptedNotifUtilsAPI; diff --git a/web/push-notif/encrypted-notif-utils-api.js b/web/push-notif/encrypted-notif-utils-api.js --- a/web/push-notif/encrypted-notif-utils-api.js +++ b/web/push-notif/encrypted-notif-utils-api.js @@ -1,5 +1,10 @@ // @flow +import { + generateKeyCommon, + encryptCommon, + generateIVCommon, +} from 'lib/media/aes-crypto-utils-common.js'; import type { EncryptedNotifUtilsAPI } from 'lib/types/notif-types.js'; import { getConfig } from 'lib/utils/config.js'; @@ -33,6 +38,37 @@ const hashBytes = await crypto.subtle.digest('SHA-256', notificationBytes); return btoa(String.fromCharCode(...new Uint8Array(hashBytes))); }, + getBlobHash: async (blob: Uint8Array) => { + const hashBytes = await crypto.subtle.digest('SHA-256', blob.buffer); + return btoa(String.fromCharCode(...new Uint8Array(hashBytes))); + }, + generateAESKey: async () => { + const aesKeyBytes = await generateKeyCommon(crypto); + return Buffer.from(aesKeyBytes).toString('base64'); + }, + generateAESIV: async () => { + const ivBytes = await generateIVCommon(crypto); + return Buffer.from(ivBytes).toString('base64'); + }, + encryptWithAESKey: async ( + encryptionKey: string, + initializationVector: string, + unencrypotedData: string, + ) => { + const encryptionKeyBytes = new Uint8Array( + Buffer.from(encryptionKey, 'base64'), + ); + const unencrypotedDataBytes = new TextEncoder().encode(unencrypotedData); + const initializationVectorBytes = new Uint8Array( + Buffer.from(initializationVector, 'base64'), + ); + return await encryptCommon( + crypto, + encryptionKeyBytes, + unencrypotedDataBytes, + initializationVectorBytes, + ); + }, }; export default encryptedNotifUtilsAPI;