Skip to content
This repository has been archived by the owner on Jun 15, 2022. It is now read-only.

Commit

Permalink
Migrate encrypted account keys to storage, fixes #204, fixes #206"
Browse files Browse the repository at this point in the history
  • Loading branch information
moughxyz committed Nov 19, 2019
1 parent 8dd779d commit dbb4ad7
Showing 1 changed file with 34 additions and 22 deletions.
56 changes: 34 additions & 22 deletions src/lib/keysManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Keychain from "./keychain"
import SNReactNative from 'standard-notes-rn';

let OfflineParamsKey = "pc_params";
let EncryptedAccountKeysKey = "encrypted_account_keys";
let BiometricsPrefs = "biometrics_prefs";
let FirstRunKey = "first_run";
let StorageEncryptionKey = "storage_encryption";
Expand Down Expand Up @@ -57,7 +58,7 @@ export default class KeysManager {
}

if(this.legacy_fingerprint) {
await this.persistKeysToKeychain();
await this.persistKeys();
}
}

Expand All @@ -75,14 +76,15 @@ export default class KeysManager {
this.user.jwt = null;
this.activeKeys().jwt = jwt;
await this.saveUser(this.user);
await this.persistKeysToKeychain();
await this.persistKeys();
}

async loadInitialData() {
let storageKeys = [
"auth_params",
"user",
OfflineParamsKey,
EncryptedAccountKeysKey,
FirstRunKey,
StorageEncryptionKey,
BiometricsPrefs
Expand Down Expand Up @@ -125,6 +127,11 @@ export default class KeysManager {
this.offlineAuthParams = JSON.parse(pcParams);
}

let encryptedAccountKeys = items[EncryptedAccountKeysKey];
if(encryptedAccountKeys) {
this.encryptedAccountKeys = JSON.parse(encryptedAccountKeys);
}

// storage encryption
if(items[StorageEncryptionKey] == null || items[StorageEncryptionKey] == undefined) {
// default is true
Expand Down Expand Up @@ -238,6 +245,7 @@ export default class KeysManager {
}

if(keys.encryptedAccountKeys) {
// LEGACY: storing encryptedAccountKeys in keychain is legacy behavior. Now stored in storage.
// We won't handle this case here. We'll wait until setOfflineKeys is called
// by whoever authenticates local passcode. That's when we actually get the offline
// keys we can use to decrypt encryptedAccountKeys
Expand All @@ -259,20 +267,9 @@ export default class KeysManager {
async generateKeychainStoreValue() {
let value = {};

if(this.accountKeys) {
// If offline local passcode keys are available, use that to encrypt account keys
// Don't encrypt offline pw because then we don't be able to verify passcode
if(this.offlineKeys) {
var encryptedKeys = new SFItem();
encryptedKeys.uuid = await SF.get().crypto.generateUUID();
encryptedKeys.content_type = "SN|Mobile|EncryptedKeys"
encryptedKeys.content.accountKeys = this.accountKeys;
var params = new SFItemParams(encryptedKeys, this.offlineKeys, this.offlineAuthParams);
let results = await params.paramsForSync();
value.encryptedAccountKeys = results;
} else {
_.merge(value, this.accountKeys);
}
// If no offline keys, store account keys directly. Otherwise we'll encrypt account keys and store in storage.
if(this.accountKeys && !this.offlineKeys) {
_.merge(value, this.accountKeys);
}

if(this.offlineKeys) {
Expand All @@ -282,9 +279,24 @@ export default class KeysManager {
return value;
}

async persistKeysToKeychain() {
async persistKeys() {
// This funciton is called when changes are made to authentication state
this.updateScreenshotPrivacy();

if(this.accountKeys && this.offlineKeys) {
// If offline local passcode keys are available, use that to encrypt account keys
// Don't encrypt offline pw because then we don't be able to verify passcode
var encryptedKeys = new SFItem();
encryptedKeys.uuid = await SF.get().crypto.generateUUID();
encryptedKeys.content_type = "SN|Mobile|EncryptedKeys"
encryptedKeys.content.accountKeys = this.accountKeys;
var params = new SFItemParams(encryptedKeys, this.offlineKeys, this.offlineAuthParams);
let results = await params.paramsForSync();
await Storage.get().setItem(EncryptedAccountKeysKey, JSON.stringify(results));
} else {
await Storage.get().removeItem(EncryptedAccountKeysKey);
}

let value = await this.generateKeychainStoreValue();
return Keychain.setKeys(value);
}
Expand All @@ -307,7 +319,7 @@ export default class KeysManager {

async persistAccountKeys(keys) {
this.accountKeys = keys;
return this.persistKeysToKeychain();
return this.persistKeys();
}

async saveUser(user) {
Expand Down Expand Up @@ -349,7 +361,7 @@ export default class KeysManager {
this.accountAuthParams = null;
this.user = null;
await Storage.get().clearKeys(this.accountRelatedStorageKeys);
return this.persistKeysToKeychain();
return this.persistKeys();
}

jwt() {
Expand Down Expand Up @@ -452,15 +464,15 @@ export default class KeysManager {
this.offlineKeys = null;
this.offlineAuthParams = null;
await Storage.get().removeItem(OfflineParamsKey);
return this.persistKeysToKeychain();
return this.persistKeys();
}

async persistOfflineKeys(keys) {
this.setOfflineKeys(keys);
if(!this.passcodeTiming) {
this.passcodeTiming = "on-quit";
}
return this.persistKeysToKeychain();
return this.persistKeys();
}

async setOfflineKeys(keys) {
Expand Down Expand Up @@ -497,7 +509,7 @@ export default class KeysManager {

async setPasscodeTiming(timing) {
this.passcodeTiming = timing;
return this.persistKeysToKeychain();
return this.persistKeys();
}

async setBiometricsTiming(timing) {
Expand Down

0 comments on commit dbb4ad7

Please sign in to comment.