secure protected value checking

This commit is contained in:
Antelle 2016-01-17 14:36:52 +03:00
parent 9f890e556c
commit fc51ac7274
2 changed files with 76 additions and 26 deletions

View File

@ -4,36 +4,77 @@ var kdbxweb = require('kdbxweb');
kdbxweb.ProtectedValue.prototype.isProtected = true;
kdbxweb.ProtectedValue.prototype.forEachChar = function(fn) {
var value = this._value, salt = this._salt;
var b, b1, b2, b3;
for (var i = 0, len = value.length; i < len; i++) {
b = value[i] ^ salt[i];
if (b < 128) {
fn(b);
continue;
}
i++; b1 = value[i] ^ salt[i];
if (i === len) { break; }
if (b >= 192 && b < 224) {
fn(((b & 0x1f) << 6) | (b1 & 0x3f));
continue;
}
i++; b2 = value[i] ^ salt[i];
if (i === len) { break; }
if (b >= 224 && b < 240) {
fn(((b & 0xf) << 12) | ((b1 & 0x3f) << 6) | (b2 & 0x3f));
}
i++; b3 = value[i] ^ salt[i];
if (i === len) { break; }
if (b >= 240 && b < 248) {
var c = ((b & 7) << 18) | ((b1 & 0x3f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f);
if (c <= 0xffff) {
fn(c);
} else {
c ^= 0x10000;
fn(0xd800 | (c >> 10));
fn(0xdc00 | (c & 0x3ff));
}
}
// skip error
}
};
Object.defineProperty(kdbxweb.ProtectedValue.prototype, 'textLength', {
get: function() {
var textLength = 0;
var value = this._value, salt = this._salt;
for (var i = 0, len = value.length; i < len; i++) {
var b = value[i] ^ salt[i];
if (b < 128) {
textLength++;
} else if (b >= 192 && b < 224 && i+1 < len) {
i++;
textLength++;
} else if (b >= 224 && b < 240 && i+2 < len) {
i += 2;
textLength++;
} else if (b >= 240 && b < 248 && i+3 < len) {
i++; var b1 = value[i] ^ salt[i];
i++; var b2 = value[i] ^ salt[i];
i++; var b3 = value[i] ^ salt[i];
var c = ((b & 7) << 18) | ((b1 & 0x3f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f);
if (c <= 0xffff) {
textLength++;
} else {
textLength += 2;
}
} else {
textLength++; // skip error
}
}
this.forEachChar(function() { textLength++; });
return textLength;
}
});
kdbxweb.ProtectedValue.prototype.includesLower = function(findLower) {
var matches = false;
var foundSeqs = [];
var ix = 0;
var len = findLower.length;
this.forEachChar(function(ch) {
ch = String.fromCharCode(ch).toLowerCase();
if (matches) {
return;
}
for (var i = 0; i < foundSeqs.length; i++) {
var seqIx = ++foundSeqs[i];
if (seqIx === len - 1) {
matches = true;
return;
}
if (findLower[seqIx] !== ch) {
foundSeqs.splice(i, 1);
i--;
}
}
if (findLower[0] === ch) {
foundSeqs.push(0);
}
ix++;
});
return matches;
};
module.exports = kdbxweb.ProtectedValue;

View File

@ -174,14 +174,23 @@ var EntryModel = Backbone.Model.extend({
},
matchString: function(str, find) {
if (str.isProtected) {
return str.includes(find);
}
return str.indexOf(find) >= 0;
},
matchStringLower: function(str, findLower) {
if (str.isProtected) {
return str.includesLower(findLower);
}
return str.toLowerCase().indexOf(findLower) >= 0;
},
matchRegex: function(str, regex) {
if (str.isProtected) {
str = str.getText();
}
return regex.test(str);
},
@ -222,7 +231,7 @@ var EntryModel = Backbone.Model.extend({
matchField: function(entry, field, compare, search) {
var val = entry.fields[field];
return val ? compare(val.isProtected ? val.getText() : val, search) : false;
return val ? compare(val, search) : false;
},
setColor: function(color) {