Store SQLCipher decryption key in separate file
First, we write the key a whole lot less. We write it on creation, then never again. Second, it's in a file we control very closely. Instead of blindly regenerating the key if the target file generates an error on read, we block startup unless the error is 'ENOENT' - the file isn't there at all. This still allows for the key.txt file to be deleted or corrupted somehow, but it should be a lot less common than the high-traffic config.json used for window location and media permissions.
This commit is contained in:
parent
006700f9a2
commit
496ebf2a47
3 changed files with 93 additions and 39 deletions
61
main.js
61
main.js
|
@ -4,14 +4,17 @@ const path = require('path');
|
|||
const url = require('url');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const crypto = require('crypto');
|
||||
|
||||
const _ = require('lodash');
|
||||
const pify = require('pify');
|
||||
const electron = require('electron');
|
||||
|
||||
const getRealPath = pify(fs.realpath);
|
||||
const packageJson = require('./package.json');
|
||||
const GlobalErrors = require('./app/global_errors');
|
||||
|
||||
GlobalErrors.addHandler();
|
||||
|
||||
const getRealPath = pify(fs.realpath);
|
||||
const {
|
||||
app,
|
||||
BrowserWindow,
|
||||
|
@ -22,26 +25,6 @@ const {
|
|||
shell,
|
||||
} = electron;
|
||||
|
||||
const packageJson = require('./package.json');
|
||||
|
||||
const sql = require('./app/sql');
|
||||
const sqlChannels = require('./app/sql_channel');
|
||||
const attachments = require('./app/attachments');
|
||||
const attachmentChannel = require('./app/attachment_channel');
|
||||
const autoUpdate = require('./app/auto_update');
|
||||
const createTrayIcon = require('./app/tray_icon');
|
||||
const GlobalErrors = require('./app/global_errors');
|
||||
const logging = require('./app/logging');
|
||||
const windowState = require('./app/window_state');
|
||||
const { createTemplate } = require('./app/menu');
|
||||
const {
|
||||
installFileHandler,
|
||||
installWebHandler,
|
||||
} = require('./app/protocol_filter');
|
||||
const { installPermissionsHandler } = require('./app/permissions');
|
||||
|
||||
GlobalErrors.addHandler();
|
||||
|
||||
const appUserModelId = `org.whispersystems.${packageJson.name}`;
|
||||
console.log('Set Windows Application User Model ID (AUMID)', {
|
||||
appUserModelId,
|
||||
|
@ -64,14 +47,32 @@ const usingTrayIcon =
|
|||
|
||||
const config = require('./app/config');
|
||||
|
||||
// Very important to put before the single instance check, since it is based on the
|
||||
// userData directory.
|
||||
const userConfig = require('./app/user_config');
|
||||
|
||||
const importMode =
|
||||
process.argv.some(arg => arg === '--import') || config.get('import');
|
||||
|
||||
const development = config.environment === 'development';
|
||||
|
||||
// Very important to put before the single instance check, since it is based on the
|
||||
// userData directory.
|
||||
const userConfig = require('./app/user_config');
|
||||
// We generally want to pull in our own modules after this point, after the user
|
||||
// data directory has been set.
|
||||
const attachments = require('./app/attachments');
|
||||
const attachmentChannel = require('./app/attachment_channel');
|
||||
const autoUpdate = require('./app/auto_update');
|
||||
const createTrayIcon = require('./app/tray_icon');
|
||||
const keyManagement = require('./app/key_management');
|
||||
const logging = require('./app/logging');
|
||||
const sql = require('./app/sql');
|
||||
const sqlChannels = require('./app/sql_channel');
|
||||
const windowState = require('./app/window_state');
|
||||
const { createTemplate } = require('./app/menu');
|
||||
const {
|
||||
installFileHandler,
|
||||
installWebHandler,
|
||||
} = require('./app/protocol_filter');
|
||||
const { installPermissionsHandler } = require('./app/permissions');
|
||||
|
||||
function showWindow() {
|
||||
if (!mainWindow) {
|
||||
|
@ -618,15 +619,9 @@ app.on('ready', async () => {
|
|||
locale = loadLocale({ appLocale, logger });
|
||||
}
|
||||
|
||||
let key = userConfig.get('key');
|
||||
if (!key) {
|
||||
// https://www.zetetic.net/sqlcipher/sqlcipher-api/#key
|
||||
key = crypto.randomBytes(32).toString('hex');
|
||||
userConfig.set('key', key);
|
||||
}
|
||||
|
||||
const key = keyManagement.initialize({ userConfig });
|
||||
await sql.initialize({ configDir: userDataPath, key });
|
||||
await sqlChannels.initialize({ userConfig });
|
||||
await sqlChannels.initialize();
|
||||
|
||||
async function cleanupOrphanedAttachments() {
|
||||
const allAttachments = await attachments.getAllAttachments(userDataPath);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue