1
0
mirror of https://github.com/bitwarden/jslib synced 2025-12-23 19:53:55 +00:00

[Provider] Add initial support for providers (#399)

This commit is contained in:
Oscar Hinton
2021-07-15 15:07:38 +02:00
committed by GitHub
parent c9b13e4d1b
commit 9f0ca7e4d2
34 changed files with 680 additions and 5 deletions

View File

@@ -24,10 +24,13 @@ import { ConstantsService } from './constants.service';
import { sequentialize } from '../misc/sequentialize';
import { Utils } from '../misc/utils';
import { EEFLongWordList } from '../misc/wordlist';
import { ProfileProviderOrganizationResponse } from '../models/response/profileProviderOrganizationResponse';
import { ProfileProviderResponse } from '../models/response/profileProviderResponse';
export const Keys = {
key: 'key', // Master Key
encOrgKeys: 'encOrgKeys',
encProviderKeys: 'encProviderKeys',
encPrivateKey: 'encPrivateKey',
encKey: 'encKey', // Generated Symmetric Key
keyHash: 'keyHash',
@@ -41,6 +44,7 @@ export class CryptoService implements CryptoServiceAbstraction {
private publicKey: ArrayBuffer;
private privateKey: ArrayBuffer;
private orgKeys: Map<string, SymmetricCryptoKey>;
private providerKeys: Map<string, SymmetricCryptoKey>;
constructor(private storageService: StorageService, protected secureStorageService: StorageService,
private cryptoFunctionService: CryptoFunctionService, protected platformUtilService: PlatformUtilsService,
@@ -76,16 +80,33 @@ export class CryptoService implements CryptoServiceAbstraction {
this.privateKey = null;
}
setOrgKeys(orgs: ProfileOrganizationResponse[]): Promise<{}> {
async setOrgKeys(orgs: ProfileOrganizationResponse[], providerOrgs: ProfileProviderOrganizationResponse[]): Promise<{}> {
const orgKeys: any = {};
orgs.forEach(org => {
orgKeys[org.id] = org.key;
});
for (const providerOrg of providerOrgs) {
// Convert provider encrypted keys to user encrypted.
const providerKey = await this.getProviderKey(providerOrg.providerId);
const decValue = await this.decryptToBytes(new EncString(providerOrg.key), providerKey);
orgKeys[providerOrg.id] = await (await this.rsaEncrypt(decValue)).encryptedString;
}
this.orgKeys = null;
return this.storageService.save(Keys.encOrgKeys, orgKeys);
}
setProviderKeys(providers: ProfileProviderResponse[]): Promise<{}> {
const providerKeys: any = {};
providers.forEach(provider => {
providerKeys[provider.id] = provider.key;
});
this.providerKeys = null;
return this.storageService.save(Keys.encProviderKeys, providerKeys);
}
async getKey(keySuffix?: KeySuffixOptions): Promise<SymmetricCryptoKey> {
if (this.key != null) {
return this.key;
@@ -270,6 +291,50 @@ export class CryptoService implements CryptoServiceAbstraction {
return orgKeys.get(orgId);
}
@sequentialize(() => 'getProviderKeys')
async getProviderKeys(): Promise<Map<string, SymmetricCryptoKey>> {
if (this.providerKeys != null && this.providerKeys.size > 0) {
return this.providerKeys;
}
const encProviderKeys = await this.storageService.get<any>(Keys.encProviderKeys);
if (encProviderKeys == null) {
return null;
}
const providerKeys: Map<string, SymmetricCryptoKey> = new Map<string, SymmetricCryptoKey>();
let setKey = false;
for (const orgId in encProviderKeys) {
if (!encProviderKeys.hasOwnProperty(orgId)) {
continue;
}
const decValue = await this.rsaDecrypt(encProviderKeys[orgId]);
providerKeys.set(orgId, new SymmetricCryptoKey(decValue));
setKey = true;
}
if (setKey) {
this.providerKeys = providerKeys;
}
return this.providerKeys;
}
async getProviderKey(providerId: string): Promise<SymmetricCryptoKey> {
if (providerId == null) {
return null;
}
const providerKeys = await this.getProviderKeys();
if (providerKeys == null || !providerKeys.has(providerId)) {
return null;
}
return providerKeys.get(providerId);
}
async hasKey(): Promise<boolean> {
return this.hasKeyInMemory() || await this.hasKeyStored('auto') || await this.hasKeyStored('biometric');
}
@@ -329,6 +394,14 @@ export class CryptoService implements CryptoServiceAbstraction {
return this.storageService.remove(Keys.encOrgKeys);
}
clearProviderKeys(memoryOnly?: boolean): Promise<any> {
this.providerKeys = null;
if (memoryOnly) {
return Promise.resolve();
}
return this.storageService.remove(Keys.encOrgKeys);
}
clearPinProtectedKey(): Promise<any> {
return this.storageService.remove(ConstantsService.pinProtectedKey);
}
@@ -337,6 +410,7 @@ export class CryptoService implements CryptoServiceAbstraction {
await this.clearKey();
await this.clearKeyHash();
await this.clearOrgKeys();
await this.clearProviderKeys();
await this.clearEncKey();
await this.clearKeyPair();
await this.clearPinProtectedKey();