mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-17 01:31:25 +01:00
Add support for communicating with multiple extensions at the same time
This commit is contained in:
parent
ac870ef31a
commit
c13d6f810e
@ -16,7 +16,7 @@ const MessageValidTimeout = 10 * 1000;
|
|||||||
const EncryptionAlgorithm = 'sha1';
|
const EncryptionAlgorithm = 'sha1';
|
||||||
|
|
||||||
export class NativeMessagingService {
|
export class NativeMessagingService {
|
||||||
private sharedSecret: any;
|
private sharedSecrets = new Map<string, SymmetricCryptoKey>();
|
||||||
|
|
||||||
constructor(private cryptoFunctionService: CryptoFunctionService, private cryptoService: CryptoService,
|
constructor(private cryptoFunctionService: CryptoFunctionService, private cryptoService: CryptoService,
|
||||||
private platformUtilService: PlatformUtilsService, private logService: LogService, private i18nService: I18nService,
|
private platformUtilService: PlatformUtilsService, private logService: LogService, private i18nService: I18nService,
|
||||||
@ -26,7 +26,9 @@ export class NativeMessagingService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async messageHandler(rawMessage: any) {
|
private async messageHandler(msg: any) {
|
||||||
|
const appId = msg.appId;
|
||||||
|
const rawMessage = msg.message;
|
||||||
|
|
||||||
// Request to setup secure encryption
|
// Request to setup secure encryption
|
||||||
if (rawMessage.command === 'setupEncryption') {
|
if (rawMessage.command === 'setupEncryption') {
|
||||||
@ -50,15 +52,15 @@ export class NativeMessagingService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.secureCommunication(remotePublicKey);
|
this.secureCommunication(remotePublicKey, appId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = JSON.parse(await this.cryptoService.decryptToUtf8(rawMessage, this.sharedSecret));
|
const message = JSON.parse(await this.cryptoService.decryptToUtf8(rawMessage, this.sharedSecrets.get(appId)));
|
||||||
|
|
||||||
// Shared secret is invalidated, force re-authentication
|
// Shared secret is invalidated, force re-authentication
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
ipcRenderer.send('nativeMessagingReply', {command: 'invalidateEncryption'});
|
ipcRenderer.send('nativeMessagingReply', {command: 'invalidateEncryption', appId: appId});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,14 +72,14 @@ export class NativeMessagingService {
|
|||||||
switch (message.command) {
|
switch (message.command) {
|
||||||
case 'biometricUnlock':
|
case 'biometricUnlock':
|
||||||
if (! this.platformUtilService.supportsBiometric()) {
|
if (! this.platformUtilService.supportsBiometric()) {
|
||||||
return this.send({command: 'biometricUnlock', response: 'not supported'});
|
return this.send({command: 'biometricUnlock', response: 'not supported'}, appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await this.platformUtilService.authenticateBiometric();
|
const response = await this.platformUtilService.authenticateBiometric();
|
||||||
if (response) {
|
if (response) {
|
||||||
this.send({command: 'biometricUnlock', response: 'unlocked', keyB64: (await this.cryptoService.getKey()).keyB64});
|
this.send({command: 'biometricUnlock', response: 'unlocked', keyB64: (await this.cryptoService.getKey()).keyB64}, appId);
|
||||||
} else {
|
} else {
|
||||||
this.send({command: 'biometricUnlock', response: 'canceled'});
|
this.send({command: 'biometricUnlock', response: 'canceled'}, appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -86,19 +88,19 @@ export class NativeMessagingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async send(message: any) {
|
private async send(message: any, appId: string) {
|
||||||
message.timestamp = Date.now();
|
message.timestamp = Date.now();
|
||||||
|
|
||||||
const encrypted = await this.cryptoService.encrypt(JSON.stringify(message), this.sharedSecret);
|
const encrypted = await this.cryptoService.encrypt(JSON.stringify(message), this.sharedSecrets.get(appId));
|
||||||
|
|
||||||
ipcRenderer.send('nativeMessagingReply', encrypted);
|
ipcRenderer.send('nativeMessagingReply', {appId: appId, message: encrypted});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async secureCommunication(remotePublicKey: ArrayBuffer) {
|
private async secureCommunication(remotePublicKey: ArrayBuffer, appId: string) {
|
||||||
const secret = await this.cryptoFunctionService.randomBytes(64);
|
const secret = await this.cryptoFunctionService.randomBytes(64);
|
||||||
this.sharedSecret = new SymmetricCryptoKey(secret);
|
this.sharedSecrets.set(appId, new SymmetricCryptoKey(secret));
|
||||||
|
|
||||||
const encryptedSecret = await this.cryptoFunctionService.rsaEncrypt(secret, remotePublicKey, EncryptionAlgorithm);
|
const encryptedSecret = await this.cryptoFunctionService.rsaEncrypt(secret, remotePublicKey, EncryptionAlgorithm);
|
||||||
ipcRenderer.send('nativeMessagingReply', {command: 'setupEncryption', sharedSecret: Utils.fromBufferToB64(encryptedSecret)});
|
ipcRenderer.send('nativeMessagingReply', {appId: appId, command: 'setupEncryption', sharedSecret: Utils.fromBufferToB64(encryptedSecret)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user