From f6fbf3ba0f33204361c323630ecc624e80fb0b1e Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Tue, 12 Dec 2017 21:58:57 +0000 Subject: [PATCH] All: Handle master key in backend --- CliClient/app/command-encrypt-config.js | 19 ++++++++++++++----- ReactNativeClient/lib/base-model.js | 1 + ReactNativeClient/lib/database.js | 1 + ReactNativeClient/lib/models/base-item.js | 1 + ReactNativeClient/lib/models/setting.js | 1 + .../lib/services/EncryptionService.js | 6 +++++- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CliClient/app/command-encrypt-config.js b/CliClient/app/command-encrypt-config.js index d4f9da6343..86eeff97d4 100644 --- a/CliClient/app/command-encrypt-config.js +++ b/CliClient/app/command-encrypt-config.js @@ -1,10 +1,9 @@ const { BaseCommand } = require('./base-command.js'); -const { app } = require('./app.js'); const { _ } = require('lib/locale.js'); -const { Folder } = require('lib/models/folder.js'); -const { importEnex } = require('lib/import-enex'); -const { filename, basename } = require('lib/path-utils.js'); const { cliUtils } = require('./cli-utils.js'); +const EncryptionService = require('lib/services/EncryptionService'); +const MasterKey = require('lib/models/MasterKey'); +const { Setting } = require('lib/models/setting.js'); class Command extends BaseCommand { @@ -22,7 +21,17 @@ class Command extends BaseCommand { if (args.command === 'init') { const password = await this.prompt(_('Enter master password:'), { type: 'string', secure: true }); - this.logger().info(password); + if (!password) { + this.stdout(_('Operation cancelled')); + return; + } + + const service = new EncryptionService(); + const masterKey = await service.generateMasterKey(password); + + await MasterKey.save(masterKey); + + Setting.setValue('encryption.enabled', true); } } diff --git a/ReactNativeClient/lib/base-model.js b/ReactNativeClient/lib/base-model.js index d4a9a0cbff..c7beca81a5 100644 --- a/ReactNativeClient/lib/base-model.js +++ b/ReactNativeClient/lib/base-model.js @@ -401,6 +401,7 @@ BaseModel.TYPE_TAG = 5; BaseModel.TYPE_NOTE_TAG = 6; BaseModel.TYPE_SEARCH = 7; BaseModel.TYPE_ALARM = 8; +BaseModel.TYPE_MASTER_KEY = 9; BaseModel.db_ = null; BaseModel.dispatch = function(o) {}; diff --git a/ReactNativeClient/lib/database.js b/ReactNativeClient/lib/database.js index 940bac41e4..b2357680c6 100644 --- a/ReactNativeClient/lib/database.js +++ b/ReactNativeClient/lib/database.js @@ -153,6 +153,7 @@ class Database { if (s == 'string') return 2; } if (type == 'fieldType') { + if (s) s = s.toUpperCase(); if (s == 'INTEGER') s = 'INT'; if (!(('TYPE_' + s) in this)) throw new Error('Unkonwn fieldType: ' + s); return this['TYPE_' + s]; diff --git a/ReactNativeClient/lib/models/base-item.js b/ReactNativeClient/lib/models/base-item.js index 1066a0eaa5..019b6d8a6a 100644 --- a/ReactNativeClient/lib/models/base-item.js +++ b/ReactNativeClient/lib/models/base-item.js @@ -457,6 +457,7 @@ BaseItem.syncItemDefinitions_ = [ { type: BaseModel.TYPE_RESOURCE, className: 'Resource' }, { type: BaseModel.TYPE_TAG, className: 'Tag' }, { type: BaseModel.TYPE_NOTE_TAG, className: 'NoteTag' }, + { type: BaseModel.TYPE_MASTER_KEY, className: 'MasterKey' }, ]; module.exports = { BaseItem }; \ No newline at end of file diff --git a/ReactNativeClient/lib/models/setting.js b/ReactNativeClient/lib/models/setting.js index 0dceaf719f..98d2a3c1df 100644 --- a/ReactNativeClient/lib/models/setting.js +++ b/ReactNativeClient/lib/models/setting.js @@ -60,6 +60,7 @@ class Setting extends BaseModel { // })}, 'uncompletedTodosOnTop': { value: true, type: Setting.TYPE_BOOL, public: true, label: () => _('Show uncompleted todos on top of the lists') }, 'trackLocation': { value: true, type: Setting.TYPE_BOOL, public: true, label: () => _('Save geo-location with notes') }, + 'encryption.enabled': { value: false, type: Setting.TYPE_BOOL, public: false }, 'sync.interval': { value: 300, type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation interval'), options: () => { return { 0: _('Disabled'), diff --git a/ReactNativeClient/lib/services/EncryptionService.js b/ReactNativeClient/lib/services/EncryptionService.js index c3779695f2..b53486ee1c 100644 --- a/ReactNativeClient/lib/services/EncryptionService.js +++ b/ReactNativeClient/lib/services/EncryptionService.js @@ -1,6 +1,5 @@ const { padLeft } = require('lib/string-utils.js'); const { shim } = require('lib/shim.js'); -const sjcl = shim.sjclModule; class EncryptionService { @@ -10,6 +9,7 @@ class EncryptionService { } sha256(string) { + const sjcl = shim.sjclModule; const bitArray = sjcl.hash.sha256.hash(string); return sjcl.codec.hex.fromBits(bitArray); } @@ -39,6 +39,8 @@ class EncryptionService { } async encrypt(method, key, plainText) { + const sjcl = shim.sjclModule; + if (method === EncryptionService.METHOD_SJCL) { // Good demo to understand each parameter: https://bitwiseshiftleft.github.io/sjcl/demo/ return sjcl.json.encrypt(key, plainText, { @@ -68,6 +70,8 @@ class EncryptionService { } async decrypt(method, key, cipherText) { + const sjcl = shim.sjclModule; + if (method === EncryptionService.METHOD_SJCL || method === EncryptionService.METHOD_SJCL_2) { return sjcl.json.decrypt(key, cipherText); }