1
0
mirror of https://github.com/keeweb/keeweb.git synced 2024-06-22 07:16:38 +02:00

argon2 kdf settings editor

This commit is contained in:
antelle 2017-01-31 23:18:58 +01:00
parent a77f61cc5d
commit ab46c0d08b
7 changed files with 129 additions and 22 deletions

View File

@ -397,6 +397,10 @@
"setFileBackupMonthly": "Monthly",
"setFileBackupManually": "Manually, no auto-backups",
"setFileRounds": "Key encryption rounds",
"setFileKdfParams": "Key derivation function",
"setFileKdfParamsIter": "Iterations",
"setFileKdfParamsMem": "Memory, KB",
"setFileKdfParamsPar": "Parallelism",
"setFileKeyChangeForce": "Ask to change key after (days)",
"setFileUseKeyFile": "Use key file",
"setFileUseGenKeyFile": "Use generated key file",

View File

@ -59,23 +59,8 @@ const FileModel = Backbone.Model.extend({
if (keyFileData) {
kdbxweb.ByteUtils.zeroBuffer(keyFileData);
}
let kdfParams = '';
if (db.header.kdfParameters) {
kdfParams = db.header.kdfParameters.keys().map(key => {
let val = db.header.kdfParameters.get(key);
if (val instanceof ArrayBuffer) {
return;
}
if (val.value) {
val = val.value;
}
return key + '=' + val;
}).filter(p => p).join('&');
} else if (db.header.keyEncryptionRounds) {
kdfParams = db.header.keyEncryptionRounds + ' rounds';
}
logger.info('Opened file ' + this.get('name') + ': ' + logger.ts(ts) + ', ' +
kdfParams + ', ' + Math.round(fileData.byteLength / 1024) + ' kB');
this.kdfArgsToString(db.header) + ', ' + Math.round(fileData.byteLength / 1024) + ' kB');
callback();
})
.catch(err => {
@ -92,6 +77,22 @@ const FileModel = Backbone.Model.extend({
}
},
kdfArgsToString: function(header) {
if (header.kdfParameters) {
return header.kdfParameters.keys().map(key => {
const val = header.kdfParameters.get(key);
if (val instanceof ArrayBuffer) {
return;
}
return key + '=' + val;
}).filter(p => p).join('&');
} else if (header.keyEncryptionRounds) {
return header.keyEncryptionRounds + ' rounds';
} else {
return '?';
}
},
create: function(name) {
const password = kdbxweb.ProtectedValue.fromString('');
const credentials = new kdbxweb.Credentials(password);
@ -162,7 +163,8 @@ const FileModel = Backbone.Model.extend({
historyMaxItems: this.db.meta.historyMaxItems,
historyMaxSize: this.db.meta.historyMaxSize,
keyEncryptionRounds: this.db.header.keyEncryptionRounds,
keyChangeForce: this.db.meta.keyChangeForce
keyChangeForce: this.db.meta.keyChangeForce,
kdfParameters: this.readKdfParams()
}, { silent: true });
this.db.groups.forEach(function(group) {
let groupModel = this.getGroup(this.subId(group.uuid.id));
@ -177,6 +179,26 @@ const FileModel = Backbone.Model.extend({
this.resolveFieldReferences();
},
readKdfParams: function() {
const kdfParameters = this.db.header.kdfParameters;
if (!kdfParameters) {
return undefined;
}
let uuid = kdfParameters.get('$UUID');
if (!uuid) {
return undefined;
}
uuid = kdbxweb.ByteUtils.bytesToBase64(uuid);
if (uuid !== kdbxweb.Consts.KdfId.Argon2) {
return undefined;
}
return {
parallelism: kdfParameters.get('P').valueOf(),
iterations: kdfParameters.get('I').valueOf(),
memory: kdfParameters.get('M').valueOf()
};
},
subId: function(id) {
return this.id + ':' + id;
},
@ -496,6 +518,25 @@ const FileModel = Backbone.Model.extend({
this.setModified();
},
setKdfParameter: function(field, value) {
const ValueType = kdbxweb.VarDictionary.ValueType;
switch (field) {
case 'memory':
this.db.header.kdfParameters.set('M', ValueType.UInt64, kdbxweb.Int64.from(value));
break;
case 'iterations':
this.db.header.kdfParameters.set('I', ValueType.UInt64, kdbxweb.Int64.from(value));
break;
case 'parallelism':
this.db.header.kdfParameters.set('P', ValueType.UInt32, value);
break;
default:
return;
}
this.set('kdfParameters', this.readKdfParams());
this.setModified();
},
emptyTrash: function() {
const trashGroup = this.getTrashGroup();
if (trashGroup) {

View File

@ -43,7 +43,8 @@ const SettingsFileView = Backbone.View.extend({
'input #settings__file-hist-len': 'changeHistoryLength',
'input #settings__file-hist-size': 'changeHistorySize',
'input #settings__file-key-rounds': 'changeKeyRounds',
'input #settings__file-key-change-force': 'changeKeyChangeForce'
'input #settings__file-key-change-force': 'changeKeyChangeForce',
'input .settings__input-kdf': 'changeKdfParameter'
},
appModel: null,
@ -86,6 +87,7 @@ const SettingsFileView = Backbone.View.extend({
historyMaxSize: Math.round(this.model.get('historyMaxSize') / 1024 / 1024),
keyEncryptionRounds: this.model.get('keyEncryptionRounds'),
keyChangeForce: this.model.get('keyChangeForce') > 0 ? this.model.get('keyChangeForce') : null,
kdfParameters: this.kdfParametersToUi(this.model.get('kdfParameters')),
storageProviders: storageProviders
});
if (!this.model.get('created')) {
@ -94,6 +96,10 @@ const SettingsFileView = Backbone.View.extend({
this.renderKeyFileSelect();
},
kdfParametersToUi: function(kdfParameters) {
return kdfParameters ? _.extend({}, kdfParameters, { memory: Math.round(kdfParameters.memory / 1024) }) : null;
},
renderKeyFileSelect: function() {
const keyFileName = this.model.get('keyFileName');
const oldKeyFileName = this.model.get('oldKeyFileName');
@ -494,6 +500,19 @@ const SettingsFileView = Backbone.View.extend({
value = -1;
}
this.model.setKeyChange(true, value);
},
changeKdfParameter: function(e) {
const field = $(e.target).data('field');
const mul = $(e.target).data('mul') || 1;
const value = e.target.value * mul;
if (isNaN(value)) {
e.target.value = Math.round(this.model.get('kdfParameters')[field] / mul);
return;
}
if (value > 0) {
this.model.setKdfParameter(field, value);
}
}
});

View File

@ -62,6 +62,26 @@
height: 2em;
}
&__row {
display: flex;
justify-content: space-between;
@extend .input-size-base;
}
&__col-small {
width: 30%;
position: relative;
>.settings__input {
width: 100%;
}
}
&__col-small-label {
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
}
&__pre {
@include user-select(text);
white-space: pre-wrap;

View File

@ -250,11 +250,13 @@ input[type=range] {
}
}
.input-base {
.input-size-base {
width: 60%;
@include tablet {
width: calc(100% - 20px);
}
}
.input-base {
@extend .input-size-base;
}

View File

@ -101,8 +101,29 @@
<input type="text" pattern="\d+" required class="settings__input input-base" id="settings__file-hist-size" value="{{historyMaxSize}}" />
<h2>{{res 'advanced'}}</h2>
{{#if keyEncryptionRounds}}
<label for="settings__file-key-rounds">{{res 'setFileRounds'}}:</label>
<input type="text" pattern="\d+" required class="settings__input input-base" id="settings__file-key-rounds" value="{{keyEncryptionRounds}}" />
{{else if kdfParameters}}
<label>{{res 'setFileKdfParams'}}: Argon2</label>
<div class="settings__row">
<div class="settings__col-small">
<label class="settings__col-small-label" for="settings__file-kdf-iter">{{res 'setFileKdfParamsIter'}}:</label>
<input type="text" pattern="\d+" required class="settings__input input-base settings__input-kdf"
data-field="iterations" id="settings__file-kdf-iter" value="{{kdfParameters.iterations}}" maxlength="10" />
</div>
<div class="settings__col-small">
<label class="settings__col-small-label" for="settings__file-kdf-mem">{{res 'setFileKdfParamsMem'}}:</label>
<input type="text" pattern="\d+" required class="settings__input input-base settings__input-kdf"
data-field="memory" data-mul="1024" id="settings__file-kdf-mem" value="{{kdfParameters.memory}}" maxlength="10" />
</div>
<div class="settings__col-small">
<label class="settings__col-small-label" for="settings__file-kdf-par">{{res 'setFileKdfParamsPar'}}:</label>
<input type="text" pattern="\d+" required class="settings__input input-base settings__input-kdf"
data-field="parallelism" id="settings__file-kdf-par" value="{{kdfParameters.parallelism}}" maxlength="2" />
</div>
</div>
{{/if}}
<label for="settings__file-key-change-force">{{res 'setFileKeyChangeForce'}}:</label>
<input type="text" pattern="\d*" class="settings__input input-base" id="settings__file-key-change-force" value="{{keyChangeForce}}" />

View File

@ -27,7 +27,7 @@
"bourbon": "4.2.7",
"dropbox": "keeweb/dropbox-js#0ac0efdc2711eece73f6ac044459e1fd0d5e9390",
"font-awesome": "4.6.3",
"kdbxweb": "c44761da37d41c799ece04799e3c164cfa79804c",
"kdbxweb": "a4d58631f2c98667e0de2f46915db2dd79bddd07",
"normalize.css": "4.2.0",
"pikaday": "1.4.0",
"FileSaver.js": "eligrey/FileSaver.js",