1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-24 16:49:26 +01:00

added public key and share key to crypto service

This commit is contained in:
Kyle Spearrin 2018-07-02 17:09:45 -04:00
parent 0033b92a2d
commit e22915818c
2 changed files with 44 additions and 0 deletions

View File

@ -12,6 +12,7 @@ export abstract class CryptoService {
getKey: () => Promise<SymmetricCryptoKey>; getKey: () => Promise<SymmetricCryptoKey>;
getKeyHash: () => Promise<string>; getKeyHash: () => Promise<string>;
getEncKey: () => Promise<SymmetricCryptoKey>; getEncKey: () => Promise<SymmetricCryptoKey>;
getPublicKey: () => Promise<ArrayBuffer>;
getPrivateKey: () => Promise<ArrayBuffer>; getPrivateKey: () => Promise<ArrayBuffer>;
getOrgKeys: () => Promise<Map<string, SymmetricCryptoKey>>; getOrgKeys: () => Promise<Map<string, SymmetricCryptoKey>>;
getOrgKey: (orgId: string) => Promise<SymmetricCryptoKey>; getOrgKey: (orgId: string) => Promise<SymmetricCryptoKey>;
@ -24,6 +25,7 @@ export abstract class CryptoService {
clearKeys: () => Promise<any>; clearKeys: () => Promise<any>;
toggleKey: () => Promise<any>; toggleKey: () => Promise<any>;
makeKey: (password: string, salt: string) => Promise<SymmetricCryptoKey>; makeKey: (password: string, salt: string) => Promise<SymmetricCryptoKey>;
makeShareKey: () => Promise<[CipherString, SymmetricCryptoKey]>;
hashPassword: (password: string, key: SymmetricCryptoKey) => Promise<string>; hashPassword: (password: string, key: SymmetricCryptoKey) => Promise<string>;
makeEncKey: (key: SymmetricCryptoKey) => Promise<CipherString>; makeEncKey: (key: SymmetricCryptoKey) => Promise<CipherString>;
encrypt: (plainValue: string | ArrayBuffer, key?: SymmetricCryptoKey) => Promise<CipherString>; encrypt: (plainValue: string | ArrayBuffer, key?: SymmetricCryptoKey) => Promise<CipherString>;

View File

@ -26,6 +26,7 @@ export class CryptoService implements CryptoServiceAbstraction {
private encKey: SymmetricCryptoKey; private encKey: SymmetricCryptoKey;
private legacyEtmKey: SymmetricCryptoKey; private legacyEtmKey: SymmetricCryptoKey;
private keyHash: string; private keyHash: string;
private publicKey: ArrayBuffer;
private privateKey: ArrayBuffer; private privateKey: ArrayBuffer;
private orgKeys: Map<string, SymmetricCryptoKey>; private orgKeys: Map<string, SymmetricCryptoKey>;
@ -135,6 +136,20 @@ export class CryptoService implements CryptoServiceAbstraction {
return this.encKey; return this.encKey;
} }
async getPublicKey(): Promise<ArrayBuffer> {
if (this.publicKey != null) {
return this.publicKey;
}
const privateKey = await this.getPrivateKey();
if (privateKey == null) {
return null;
}
this.publicKey = null; // TODO:
return this.publicKey;
}
async getPrivateKey(): Promise<ArrayBuffer> { async getPrivateKey(): Promise<ArrayBuffer> {
if (this.privateKey != null) { if (this.privateKey != null) {
return this.privateKey; return this.privateKey;
@ -258,6 +273,14 @@ export class CryptoService implements CryptoServiceAbstraction {
return new SymmetricCryptoKey(key); return new SymmetricCryptoKey(key);
} }
async makeShareKey(): Promise<[CipherString, SymmetricCryptoKey]> {
const shareKey = await this.cryptoFunctionService.randomBytes(64);
const publicKey = await this.getPublicKey();
const encKey = await this.getEncKey();
const encShareKey = await this.rsaEncrypt(shareKey, publicKey, encKey);
return [encShareKey, new SymmetricCryptoKey(shareKey)];
}
async hashPassword(password: string, key: SymmetricCryptoKey): Promise<string> { async hashPassword(password: string, key: SymmetricCryptoKey): Promise<string> {
if (key == null) { if (key == null) {
key = await this.getKey(); key = await this.getKey();
@ -497,6 +520,25 @@ export class CryptoService implements CryptoServiceAbstraction {
return await this.cryptoFunctionService.aesDecrypt(data, iv, theKey.encKey); return await this.cryptoFunctionService.aesDecrypt(data, iv, theKey.encKey);
} }
private async rsaEncrypt(data: ArrayBuffer, publicKey?: ArrayBuffer, key?: SymmetricCryptoKey) {
if (publicKey == null) {
publicKey = await this.getPublicKey();
}
if (publicKey == null) {
throw new Error('Public key unavailable.');
}
let type = EncryptionType.Rsa2048_OaepSha1_B64;
const encBytes = await this.cryptoFunctionService.rsaEncrypt(data, publicKey, 'sha1');
let mac: string = null;
if (key != null && key.macKey != null) {
type = EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64;
const macBytes = await this.cryptoFunctionService.hmac(encBytes, key.macKey, 'sha256');
mac = Utils.fromBufferToB64(macBytes);
}
return new CipherString(type, Utils.fromBufferToB64(encBytes), null, mac);
}
private async rsaDecrypt(encValue: string): Promise<ArrayBuffer> { private async rsaDecrypt(encValue: string): Promise<ArrayBuffer> {
const headerPieces = encValue.split('.'); const headerPieces = encValue.split('.');
let encType: EncryptionType = null; let encType: EncryptionType = null;