Validate key before using it (#366)

* Validate key before using it
This commit is contained in:
Oscar Hinton 2021-04-28 22:02:43 +02:00 committed by GitHub
parent 672d07e1e2
commit 5b7d918f29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 5 deletions

View File

@ -48,4 +48,5 @@ export abstract class CryptoService {
decryptToUtf8: (encString: EncString, key?: SymmetricCryptoKey) => Promise<string>;
decryptFromBytes: (encBuf: ArrayBuffer, key: SymmetricCryptoKey) => Promise<ArrayBuffer>;
randomNumber: (min: number, max: number) => Promise<number>;
validateKey: (key: SymmetricCryptoKey) => Promise<boolean>;
}

View File

@ -46,10 +46,7 @@ export class CryptoService implements CryptoServiceAbstraction {
async setKey(key: SymmetricCryptoKey): Promise<any> {
this.key = key;
const option = await this.storageService.get<number>(ConstantsService.vaultTimeoutKey);
const biometric = await this.storageService.get<boolean>(ConstantsService.biometricUnlockKey);
if (option != null && !(biometric && this.platformUtilService.supportsSecureStorage())) {
// if we have a lock option set, we do not store the key
if (!await this.shouldStoreKey()) {
return;
}
@ -96,7 +93,21 @@ export class CryptoService implements CryptoServiceAbstraction {
const key = await this.secureStorageService.get<string>(Keys.key);
if (key != null) {
this.key = new SymmetricCryptoKey(Utils.fromB64ToArray(key).buffer);
if (!await this.shouldStoreKey()) {
this.logService.warning('Throwing away stored key since settings have changed');
this.secureStorageService.remove(Keys.key);
return null;
}
const symmetricKey = new SymmetricCryptoKey(Utils.fromB64ToArray(key).buffer);
if (!await this.validateKey(symmetricKey)) {
this.logService.warning('Wrong key, throwing away stored key');
this.secureStorageService.remove(Keys.key);
return null;
}
this.key = symmetricKey;
}
return key == null ? null : this.key;
@ -580,8 +591,35 @@ export class CryptoService implements CryptoServiceAbstraction {
return min + rval;
}
async validateKey(key: SymmetricCryptoKey) {
try {
const encPrivateKey = await this.storageService.get<string>(Keys.encPrivateKey);
if (encPrivateKey == null) {
return false;
}
const encKey = await this.getEncKey(key);
const privateKey = await this.decryptToBytes(new EncString(encPrivateKey), encKey);
await this.cryptoFunctionService.rsaExtractPublicKey(privateKey);
} catch (e) {
return false;
}
return true;
}
// Helpers
private async shouldStoreKey() {
const vaultTimeout = await this.storageService.get<number>(ConstantsService.vaultTimeoutKey);
const biometricUnlock = await this.storageService.get<boolean>(ConstantsService.biometricUnlockKey);
const biometricsEnabled = biometricUnlock && this.platformUtilService.supportsSecureStorage();
const noVaultTimeout = vaultTimeout == null;
return noVaultTimeout || biometricsEnabled;
}
private async aesEncrypt(data: ArrayBuffer, key: SymmetricCryptoKey): Promise<EncryptedObject> {
const obj = new EncryptedObject();
obj.key = await this.getKeyForEncryption(key);