1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 18:23:31 +00:00

Add support for Emergency Access (#204)

* Add support for Emergency Access

* Resolve review comments
This commit is contained in:
Oscar Hinton
2020-12-22 16:53:48 +01:00
committed by GitHub
parent 12321e53b9
commit 573eea66ee
22 changed files with 358 additions and 117 deletions

View File

@@ -380,8 +380,10 @@ export class CryptoService implements CryptoServiceAbstraction {
return this.buildEncKey(theKey, encKey);
}
async remakeEncKey(key: SymmetricCryptoKey): Promise<[SymmetricCryptoKey, CipherString]> {
const encKey = await this.getEncKey();
async remakeEncKey(key: SymmetricCryptoKey, encKey?: SymmetricCryptoKey): Promise<[SymmetricCryptoKey, CipherString]> {
if (encKey == null) {
encKey = await this.getEncKey();
}
return this.buildEncKey(key, encKey.key);
}
@@ -434,6 +436,58 @@ export class CryptoService implements CryptoServiceAbstraction {
return new CipherString(EncryptionType.Rsa2048_OaepSha1_B64, Utils.fromBufferToB64(encBytes));
}
async rsaDecrypt(encValue: string): Promise<ArrayBuffer> {
const headerPieces = encValue.split('.');
let encType: EncryptionType = null;
let encPieces: string[];
if (headerPieces.length === 1) {
encType = EncryptionType.Rsa2048_OaepSha256_B64;
encPieces = [headerPieces[0]];
} else if (headerPieces.length === 2) {
try {
encType = parseInt(headerPieces[0], null);
encPieces = headerPieces[1].split('|');
} catch (e) { }
}
switch (encType) {
case EncryptionType.Rsa2048_OaepSha256_B64:
case EncryptionType.Rsa2048_OaepSha1_B64:
// HmacSha256 types are deprecated
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
break;
default:
throw new Error('encType unavailable.');
}
if (encPieces == null || encPieces.length <= 0) {
throw new Error('encPieces unavailable.');
}
const data = Utils.fromB64ToArray(encPieces[0]).buffer;
const privateKey = await this.getPrivateKey();
if (privateKey == null) {
throw new Error('No private key.');
}
let alg: 'sha1' | 'sha256' = 'sha1';
switch (encType) {
case EncryptionType.Rsa2048_OaepSha256_B64:
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
alg = 'sha256';
break;
case EncryptionType.Rsa2048_OaepSha1_B64:
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
break;
default:
throw new Error('encType unavailable.');
}
return this.cryptoFunctionService.rsaDecrypt(data, privateKey, alg);
}
async decryptToBytes(cipherString: CipherString, key?: SymmetricCryptoKey): Promise<ArrayBuffer> {
const iv = Utils.fromB64ToArray(cipherString.iv).buffer;
const data = Utils.fromB64ToArray(cipherString.data).buffer;
@@ -604,58 +658,6 @@ export class CryptoService implements CryptoServiceAbstraction {
return await this.cryptoFunctionService.aesDecrypt(data, iv, theKey.encKey);
}
private async rsaDecrypt(encValue: string): Promise<ArrayBuffer> {
const headerPieces = encValue.split('.');
let encType: EncryptionType = null;
let encPieces: string[];
if (headerPieces.length === 1) {
encType = EncryptionType.Rsa2048_OaepSha256_B64;
encPieces = [headerPieces[0]];
} else if (headerPieces.length === 2) {
try {
encType = parseInt(headerPieces[0], null);
encPieces = headerPieces[1].split('|');
} catch (e) { }
}
switch (encType) {
case EncryptionType.Rsa2048_OaepSha256_B64:
case EncryptionType.Rsa2048_OaepSha1_B64:
// HmacSha256 types are deprecated
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
break;
default:
throw new Error('encType unavailable.');
}
if (encPieces == null || encPieces.length <= 0) {
throw new Error('encPieces unavailable.');
}
const data = Utils.fromB64ToArray(encPieces[0]).buffer;
const privateKey = await this.getPrivateKey();
if (privateKey == null) {
throw new Error('No private key.');
}
let alg: 'sha1' | 'sha256' = 'sha1';
switch (encType) {
case EncryptionType.Rsa2048_OaepSha256_B64:
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
alg = 'sha256';
break;
case EncryptionType.Rsa2048_OaepSha1_B64:
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
break;
default:
throw new Error('encType unavailable.');
}
return this.cryptoFunctionService.rsaDecrypt(data, privateKey, alg);
}
private async getKeyForEncryption(key?: SymmetricCryptoKey): Promise<SymmetricCryptoKey> {
if (key != null) {
return key;